[
  {
    "path": ".clang-tidy",
    "content": "# Disabled checks:\n# - bugprone-easily-swappable-parameters\n#     Not needed\n# - bugprone-suspicious-include\n#     Too many false positives in \"build/smuview_autogen\". Maybe activate again\n#     when HeaderFilterRegex is working correctly.\n# - misc-definitions-in-headers\n#     TODO: Used in deviceutil.hpp and datautil.hpp. Maybe to const static?\n# - misc-non-private-member-variables-in-classes\n#     protected member variables are used all over the place...\n# - misc-static-assert\n#     TODO: Replace all `assert(\"ex\")` with `throw Ex()` and activate check!\n# - misc-no-recursion\n#     We do use recursions\n# - performance-unnecessary-value-param\n#     TODO: !\n# - readability-avoid-const-params-in-decls\n#     TODO: Keep Decl and Def signatures the same! Recheck after\n#     performance-unnecessary-value-param solved! Maybe `const type` makes\n#     no sense:\n#     https://stackoverflow.com/questions/52916410/why-is-const-allowed-in-function-declarations\n# - readability-braces-around-statements\n#     Even with `ShortStatementLines` = 3 there are too many false positives.\n# - readability-convert-member-functions-to-static,\n#     TODO: Could this be useful in some cases?\n# - readability-inconsistent-declaration-parameter-name\n#     This check shows to many false positives for Qt signal declarations. We can\n#     use CppChecks \"funcArgNamesDifferent\" instead.\n# - readability-magic-numbers\n#     Magic numbers are ok. Maybe replace with macros(?) in the future?\n# - readability-redundant-access-specifiers\n#     Used to often in header files, also not complatible with Qt access specifiers.\n#         public Q_SLOTS:\n#         public:\n# - readability-function-cognitive-complexity\n#     TODO: Enable!\n# - readability-use-anyofallof\n#     Foreach loops are ok for now\n#\n# TODO:\n# - google-*,\n#   -google-readability-braces-around-statements,\n#   -google-readability-todo,\n# - modernize-*,\n#   -modernize-raw-string-literal\n#\nChecks: >-\n  bugprone-*,\n  -bugprone-easily-swappable-parameters,\n  -bugprone-suspicious-include,\n  clang-diagnostic-*,\n  clang-analyzer-*,\n  google-explicit-constructor,\n  misc-*,\n  -misc-definitions-in-headers,\n  -misc-non-private-member-variables-in-classes,\n  -misc-static-assert,\n  -misc-no-recursion,\n  performance-*,\n  -performance-unnecessary-value-param,\n  readability-*,\n  -readability-avoid-const-params-in-decls,\n  -readability-braces-around-statements,\n  -readability-convert-member-functions-to-static,\n  -readability-inconsistent-declaration-parameter-name,\n  -readability-magic-numbers,\n  -readability-redundant-access-specifiers,\n  -readability-function-cognitive-complexity,\n  -readability-use-anyofallof,\n\nWarningsAsErrors:      ''\nHeaderFilterRegex:     '^src/.*$'\nAnalyzeTemporaryDtors: false\nFormatStyle:           none\nUser:                  frank\nCheckOptions:\n  - key:             cert-dcl16-c.NewSuffixes\n    value:           'L;LL;LU;LLU'\n  - key:             cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic\n    value:           '1'\n  - key:             google-readability-braces-around-statements.ShortStatementLines\n    value:           '1'\n  - key:             google-readability-function-size.StatementThreshold\n    value:           '800'\n  - key:             google-readability-namespace-comments.ShortNamespaceLines\n    value:           '10'\n  - key:             google-readability-namespace-comments.SpacesBeforeComments\n    value:           '2'\n  - key:             modernize-loop-convert.MaxCopySize\n    value:           '16'\n  - key:             modernize-loop-convert.MinConfidence\n    value:           reasonable\n  - key:             modernize-loop-convert.NamingStyle\n    value:           CamelCase\n  - key:             modernize-pass-by-value.IncludeStyle\n    value:           llvm\n  - key:             modernize-replace-auto-ptr.IncludeStyle\n    value:           llvm\n  - key:             modernize-use-nullptr.NullMacros\n    value:           'NULL'\n  - key:             readability-braces-around-statements.ShortStatementLines\n    value:           '3'\n  - key:             readability-implicit-bool-conversion.AllowPointerConditions\n    value:           '1'\n  - key:             readability-implicit-bool-conversion.AllowIntegerConditions\n    value:           '1'\n  - key:             readability-redundant-member-init.IgnoreBaseInCopyConstructors\n    value:           '1'\n  - key:             readability-identifier-length.MinimumVariableNameLength\n    value:           '2'\n  - key:             readability-identifier-length.MinimumParameterNameLength\n    value:           '2'\n  - key:             readability-identifier-length.MinimumLoopCounterNameLength\n    value:           '1'\n  - key:             readability-identifier-length.MinimumExceptionNameLength\n    value:           '1'\n  - key:             readability-qualified-auto.AddConstToQualified\n    value:           '1'\n"
  },
  {
    "path": ".editorconfig",
    "content": "# EditorConfig file (https://editorconfig.org) for the SmuView project\n\nroot = true\n\n[*]\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n\n# SmuView C++ and C files\n[**.{c,h,cpp,hpp}]\nindent_style = tab\nindent_size = 4\n\n# SmuScript python files\n[smuscript/**.py]\nindent_style = space\nindent_size = 4\n\n# SmuScript XML files\n[**.xml]\nindent_style = tab\nindent_size = 4\n[**.qrc]\nindent_style = tab\nindent_size = 4\n\n# SmuScript CMake files\n[CMakeLists.txt]\nindent_style = tab\nindent_size = 2\n[**.cmake]\nindent_style = space\nindent_size = 2\n\n# SmuView yml files\n[**.yml]\nindent_style = space\nindent_size = 2\n\n\n# external: QCodeEditor C++ files\n[external/QCodeEditor/**.{cpp,hpp}]\nindent_style = space\nindent_size = 4\n\n# external: QCodeEditor XML files\n[external/QCodeEditor/**.xml]\nindent_style = space\nindent_size = 4\n[external/QCodeEditor/**.qrc]\nindent_style = space\nindent_size = 4\n\n# external: QCodeEditor CMake files\n[external/QCodeEditor/CMakeLists.txt]\nindent_style = space\nindent_size = 4\n\n\n# external: pybind11 C++ header files\n[external/pybind11*/**.h]\nindent_style = space\nindent_size = 4\n\n# external: pybind11 CMake files\n[external/pybind11*/CMakeLists.txt]\nindent_style = space\nindent_size = 2\n[external/pybind11*/**.cmake]\nindent_style = space\nindent_size = 2\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior:\n1. Go to '...'\n2. Click on '....'\n3. Scroll down to '....'\n4. See error\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots or log**\nIf applicable, add screenshots or logs to help explain your problem.\n\n**Enviroment (please complete the following information):**\n - SmuView version / git commit\n - AppImage, Windows installer or self compiled [gcc version, ...]\n - OS: [e.g. Debian 9, openSUSE 15.1, Windows 10, ...]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: SmuView Build\n\non:\n  push:\n    paths-ignore:\n      - \"doxy/**\"\n      - \"manual/**\"\n      - \"stuff/**\"\n  pull_request:\n    paths-ignore:\n      - \"doxy/**\"\n      - \"manual/**\"\n      - \"stuff/**\"\n  workflow_dispatch:\n\ndefaults:\n  run:\n    shell: bash\n\nenv:\n  # The path where the compiled packages will be installed.\n  INSTALL_DIR: \"${{ github.workspace }}/sr\"\n  # Git URL for the libserialport dependency\n  LIBSERIALPORT_REPO: \"git://sigrok.org/libserialport\"\n  # Git URL for the libsigrok dependency\n  LIBSIGROK_REPO: \"git://sigrok.org/libsigrok\"\n  # Git branch for the libsigrok dependency\n  LIBSIGROK_BRANCH: \"master\"\n  # Build type for SmuView (Debug, Release, RelWithDebInfo, MinSizeRel)\n  BUILD_TYPE: \"Release\"\n  # Misc commands\n  WGET: \"wget -c --quiet\"\n  GIT_CLONE: \"git clone --depth=1\"\n  # AppImage related properties are set as container ENVs if needed.\n\njobs:\n\n  build_linux:\n    name: SmuView Linux build (${{ matrix.target }}, ${{ matrix.compiler.compiler }},  Qt ${{ matrix.qt.version }})\n\n    runs-on: ubuntu-latest\n\n    strategy:\n      matrix:\n        # i686 build is disabled for now!\n        target: [\"x86_64\"]\n        compiler:\n          - { compiler: GCC, cc: \"gcc\", cxx: \"g++\" }\n          - { compiler: LLVM, cc: \"clang\", cxx: \"clang++\" }\n        qt:\n          - { version: 5.12.11, system_qwt: false }\n          - { version: 5.13.2, system_qwt: false }\n          - { version: 5.14.2, system_qwt: false }\n          - { version: 5.15.2, system_qwt: true }\n\n    env:\n      BUILD_TYPE: \"Release\"\n      CC: ${{ matrix.compiler.cc }}\n      CXX: ${{ matrix.compiler.cxx }}\n\n    steps:\n      - name: Set up Qt environment\n        uses: jurplel/install-qt-action@v3\n        with:\n          version: ${{ matrix.qt.version }}\n\n      - name: Install dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y \\\n            git-core gcc make autoconf automake libtool \\\n            g++ autoconf-archive pkg-config libglib2.0-dev libglibmm-2.4-dev \\\n            libzip-dev libusb-1.0-0-dev libftdi1-dev libieee1284-3-dev \\\n            libvisa-dev nettle-dev libavahi-client-dev libhidapi-dev check \\\n            doxygen swig \\\n            cmake libboost-dev libboost-test-dev \\\n            python3-dev python-gi-dev python-setuptools\n\n      - name: Checkout sigrok-utils\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/sigrok-util\n          path: sigrok-util\n          ref: github\n\n      - name: Install system Qwt\n        if: ${{ matrix.qt.system_qwt }}\n        run: |\n          sudo apt-get install -y libqwt-qt5-dev\n\n      - name: Build custom Qwt\n        if: ${{ !matrix.qt.system_qwt }}\n        run: |\n          sudo apt-get install -y mesa-common-dev libgl1-mesa-dev\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-linux-init-toolchain.sh\n          ./sigrok-linux-build-qwt.sh\n\n      - name: Build dependencies\n        run: |\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-linux-init-toolchain.sh\n          ./sigrok-linux-build-dependencies.sh\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build smuview\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-linux-init-toolchain.sh\n          mkdir -p smuview/build\n          cd smuview/build\n          PKG_CONFIG_PATH=$P cmake \\\n            -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR \\\n            -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n            -DDISABLE_WERROR=FALSE \\\n            -DENABLE_TESTS=TRUE \\\n            ..\n          make $PARALLEL $V\n\n\n  build_appimage:\n    name: SmuView AppImage build (${{ matrix.target.target }})\n\n    runs-on: ubuntu-latest\n    container:\n      image: ghcr.io/knarfs/sigrok-appimage-${{ matrix.target.container }}:latest\n\n    strategy:\n      matrix:\n        target:\n          - target: \"i386\"\n            container: \"x86_64-i386\"\n            cc: \"gcc -m32\"\n            cxx: \"g++ -m32\"\n            ld: \"ld -melf_i386\"\n            ldflags: \"-m32\"\n          - target: \"x86_64\"\n            container: \"x86_64\"\n            cc: \"gcc\"\n            cxx: \"g++\"\n            ld: \"ld\"\n            ldflags: \"\"\n\n    env:\n      CC: ${{ matrix.target.cc }}\n      CXX: ${{ matrix.target.cxx }}\n      LD:  ${{ matrix.target.ld }}\n      LDFLAGS: ${{ matrix.target.ldflags }}\n\n    steps:\n      - name: Update dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get upgrade -y\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build AppImage\n        run: |\n          wget https://github.com/knarfS/appimagecraft/releases/download/continuous/appimagecraft-${{ matrix.target.target }}.AppImage\n          #wget https://github.com/TheAssassin/appimagecraft/releases/download/continuous/appimagecraft-${{ matrix.target.target }}.AppImage\n          chmod ug+x appimagecraft-${{ matrix.target.target }}.AppImage\n\n          export PKG_CONFIG_PATH=\"/usr/lib/i386-linux-gnu/pkgconfig:$PKG_CONFIG_PATH\"\n\n          cd smuview\n          ../appimagecraft-${{ matrix.target.target }}.AppImage build -d build/\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v3\n        with:\n          name: SmuView ${{ matrix.target.target }} AppImage\n          path: smuview/SmuView*.AppImage*\n\n\n  build_mxe:\n    name: SmuView MXE build (${{ matrix.target.target }})\n\n    runs-on: ubuntu-latest\n    container:\n      image: ghcr.io/knarfs/sigrok-mxe:latest\n\n    strategy:\n      matrix:\n        target:\n          - { target: \"i686\", nsis_param: \"\" }\n          - { target: \"x86_64\", nsis_param: \"-DPE64=1\" }\n\n    env:\n      TARGET: ${{ matrix.target.target }}\n      DEBUG: 0\n      # Download python from sigrok.org and smth is wrong with the cert\n      WGET: \"wget -c --quiet --no-check-certificate\"\n\n    steps:\n      - name: Checkout sigrok-utils\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/sigrok-util\n          path: sigrok-util\n          ref: github\n\n      - name: Build dependencies\n        run: |\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-mxe-init-toolchain.sh\n          ./sigrok-mxe-build-dependencies.sh\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build smuview\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-mxe-init-toolchain.sh\n          mkdir -p smuview/build\n          cd smuview/build\n          $CMAKE \\\n            -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR \\\n            -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n            -DDISABLE_WERROR=FALSE \\\n            -DENABLE_TESTS=TRUE \\\n            ..\n          make $PARALLEL $V\n          make install/strip $V\n\n      - name: Build NSIS installer\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-mxe-init-toolchain.sh\n\n          # Zadig (we ship this with frontends for easy driver switching).\n          $WGET https://github.com/pbatard/libwdi/releases/download/b721/zadig-2.4.exe -O $INSTALL_DIR/zadig.exe\n          $WGET https://github.com/pbatard/libwdi/releases/download/v1.2.5/zadig_xp-2.2.exe -O $INSTALL_DIR/zadig_xp.exe\n\n          cp sigrok-util/cross-compile/github-actions/contrib-mxe/FileAssociation.nsh smuview/build/contrib\n          makensis ${{ matrix.target.nsis_param }} smuview/build/contrib/smuview_cross.nsi\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v3\n        with:\n          name: SmuView NSIS ${{ matrix.target.target }} installer\n          path: smuview/build/contrib/SmuView*installer.exe\n\n\n  build_macos:\n    name: SmuView MacOS build (${{ matrix.compiler.compiler }})\n\n    runs-on: macos-11\n\n    strategy:\n      matrix:\n        compiler:\n          - { compiler: GCC, cc: \"gcc\", cxx: \"g++\" }\n          - { compiler: LLVM, cc: \"llvm-gcc\", cxx: \"llvm-g++\" }\n\n    env:\n      CC: ${{ matrix.compiler.cc }}\n      CXX: ${{ matrix.compiler.cxx }}\n      # We use Homebrew Qt 5.15.x (current)\n      HB_QTVER: \"qt@5\"\n      # We use Homebrew Python 3.x (current)\n      HB_PYVER: \"python@3\"\n\n    steps:\n      - name: Install dependencies\n        run: |\n          brew install autoconf automake autoconf-archive pkg-config \\\n            libtool libzip libusb libftdi hidapi nettle check doxygen swig \\\n            glib glibmm@2.66 cmake \"$HB_PYVER\" boost \"$HB_QTVER\" qwt-qt5\n\n      - name: Checkout sigrok-utils\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/sigrok-util\n          path: sigrok-util\n          ref: github\n\n      - name: Build dependencies\n        run: |\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-macos-init-toolchain.sh\n          ./sigrok-macos-build-dependencies.sh\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build smuview\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-macos-init-toolchain.sh\n          mkdir -p smuview/build\n          cd smuview/build\n          PKG_CONFIG_PATH=$P cmake \\\n            -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR \\\n            -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n            -DDISABLE_WERROR=FALSE \\\n            -DENABLE_TESTS=TRUE \\\n            ..\n          make $PARALLEL $V\n          make install $V\n\n      - name: Build DMG\n        run: |\n          # Source SmuView versions and names\n          source smuview/build/contrib/config_version.sh\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-macos-init-toolchain.sh\n          ./sigrok-macos-create-dmg.sh\n\n      - name: Upload artifact\n        # Only upload artifact from the LLVM build!\n        if: startsWith(matrix.compiler.compiler, 'LLVM')\n        uses: actions/upload-artifact@v3\n        with:\n          name: SmuView DMG\n          path: sigrok-util/cross-compile/github-actions/SmuView*.dmg\n\n\n  publish:\n    name: SmuView publish\n\n    runs-on: ubuntu-latest\n\n    if: |\n      (github.event_name == 'push' && github.ref == 'refs/heads/master') ||\n      (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master')\n    needs:\n      - build_linux\n      - build_appimage\n      - build_mxe\n      - build_macos\n\n    steps:\n      - name: Install dependencies\n        run: |\n          # AppImage needs libfuse2 to start\n          sudo apt-get update\n          sudo apt-get install -y libfuse2\n      - name: Download artifacts\n        uses: actions/download-artifact@v2\n      - name: Inspect directory after downloading artifacts\n        run: ls -alFR\n      - name: Upload artifacts and create (continuous) release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n            wget -q https://github.com/TheAssassin/pyuploadtool/releases/download/continuous/pyuploadtool-x86_64.AppImage\n            chmod +x pyuploadtool-x86_64.AppImage\n            ./pyuploadtool-x86_64.AppImage **/SmuView-*.*\n"
  },
  {
    "path": ".github/workflows/documentation.yml",
    "content": "name: SmuView Documentation\n\non:\n  push:\n    branches:\n      - master\n    paths:\n      - \"manual/**\"\n      - \"src/python/bindings.cpp\"\n  workflow_dispatch:\n\ndefaults:\n  run:\n    shell: bash\n\nenv:\n  # The path where the compiled packages will be installed.\n  INSTALL_DIR: \"${{ github.workspace }}/sr\"\n  # Git URL for the sigrok dependencies\n  SIGROK_REPO_BASE: \"https://github.com/sigrokproject\"\n  # Build type for SmuView (Debug, Release, RelWithDebInfo, MinSizeRel)\n  BUILD_TYPE: \"Release\"\n  # Misc commands\n  WGET: \"wget -c --quiet\"\n  GIT_CLONE: \"git clone --depth=1\"\n\n\njobs:\n\n  build_manual:\n    name: SmuView Manual\n\n    runs-on: ubuntu-latest\n\n    env:\n      BUILD_TYPE: \"Release\"\n\n    steps:\n      - name: Install dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y \\\n            git-core gcc make autoconf automake libtool \\\n            g++ autoconf-archive pkg-config libglib2.0-dev libglibmm-2.4-dev \\\n            libzip-dev check doxygen swig \\\n            cmake libboost-dev libqt5svg5-dev qtbase5-dev libqwt-qt5-dev \\\n            python3-dev python-gi-dev python-setuptools \\\n            asciidoctor ruby-asciidoctor-pdf coderay\n\n      - name: Checkout sigrok-utils\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/sigrok-util\n          path: sigrok-util\n          ref: github\n\n      - name: Build dependencies\n        run: |\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-linux-init-toolchain.sh\n          ./sigrok-linux-build-dependencies.sh\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build manual\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-linux-init-toolchain.sh\n          mkdir -p smuview/build\n          cd smuview/build\n          PKG_CONFIG_PATH=$P cmake \\\n            -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR \\\n            -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n            -DDISABLE_WERROR=TRUE \\\n            -DENABLE_TESTS=FALSE \\\n            ..\n          make manual $V\n          make manual-publish $V\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v3\n        with:\n          name: SmuView_manual\n          path: smuview/build/manual_publish/\n\n\n  build_python_doc:\n    name: SmuView Python API\n\n    runs-on: ubuntu-latest\n\n    env:\n      BUILD_TYPE: \"Release\"\n\n    steps:\n      - name: Install dependencies\n        run: |\n          sudo apt-get update\n          sudo apt-get install -y \\\n            git-core gcc make autoconf automake libtool \\\n            g++ autoconf-archive pkg-config libglib2.0-dev libglibmm-2.4-dev \\\n            libzip-dev check doxygen swig \\\n            cmake libboost-dev libqt5svg5-dev qtbase5-dev libqwt-qt5-dev \\\n            python3-dev python-gi-dev python-setuptools coreutils\n\n      - name: Checkout sigrok-utils\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/sigrok-util\n          path: sigrok-util\n          ref: github\n\n      - name: Build dependencies\n        run: |\n          cd sigrok-util/cross-compile/github-actions\n          source sigrok-linux-init-toolchain.sh\n          ./sigrok-linux-build-dependencies.sh\n\n      - name: Checkout smuview\n        uses: actions/checkout@v3\n        with:\n          path: smuview\n\n      - name: Build smuview\n        run: |\n          source sigrok-util/cross-compile/github-actions/sigrok-linux-init-toolchain.sh\n          mkdir -p smuview/build\n          cd smuview/build\n          PKG_CONFIG_PATH=$P cmake \\\n            -DCMAKE_INSTALL_PREFIX:PATH=$INSTALL_DIR \\\n            -DCMAKE_BUILD_TYPE=$BUILD_TYPE \\\n            -DDISABLE_WERROR=y \\\n            -DENABLE_TESTS=FALSE \\\n            ..\n          make $PARALLEL $V\n          make install $V\n\n      - name: Build API doc\n        run: |\n          pip3 install pdoc3\n          export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:\"$INSTALL_DIR/lib\"\n          # Source versions  and create destination folders\n          source smuview/build/contrib/config_version.sh\n          mkdir -p api_doc/\"$SV_MANUAL_VERSION\"\n          # Create script for generating the API doc\n          cat > gen_api.py << EOF\n          import smuview\n          import pdoc\n          html_str = pdoc.html(\"smuview\", show_type_annotations=True)\n          f = open('./api_doc/$SV_MANUAL_VERSION/python_bindings_api.html', 'w')\n          print(html_str, file=f)\n          f.close()\n          EOF\n          # Generating the API doc\n          timeout --preserve-status 60 $INSTALL_DIR/bin/smuview -s gen_api.py -platform offscreen\n\n      - name: Upload artifact\n        uses: actions/upload-artifact@v3\n        with:\n          name: SmuView_Python_API\n          path: api_doc/\n\n\n  publish:\n    name: SmuView documentation publish\n\n    runs-on: ubuntu-latest\n\n    needs:\n      - build_manual\n      - build_python_doc\n\n    steps:\n      - name: Download artifacts\n        uses: actions/download-artifact@v2\n\n      - name: Inspect directory after downloading artifacts\n        run: ls -alFR\n\n      - name: Checkout knarfS.github.io\n        uses: actions/checkout@v3\n        with:\n          repository: knarfS/knarfS.github.io\n          path: knarfS.github.io\n          persist-credentials: false\n\n      - name: Copy documentation\n        run: |\n          cp -r SmuView_manual/* knarfS.github.io/doc/smuview\n          cp -r SmuView_Python_API/* knarfS.github.io/doc/smuview\n\n      - name: Publish documentation\n        uses: cpina/github-action-push-to-another-repository@main\n        env:\n          SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}\n        with:\n          source-directory: \"knarfS.github.io\"\n          destination-github-username: \"knarfS\"\n          destination-repository-name: \"knarfS.github.io\"\n          user-email: \"frank-stettner@gmx.net\"\n          target-branch: \"master\"\n          commit-message: \"Automated update for ORIGIN_COMMIT\"\n"
  },
  {
    "path": ".gitignore",
    "content": "# Unwanted smuview files\nTOASK\ndoc/linuxgpib_build.txt\ndoc/parameter.txt\ndoc/pps-wiki.txt\ndoc/relays/\ntesting/\n\n# CMake\nCMakeCache.txt\nCMakeFiles\nCMakeScripts\nTesting\nMakefile\ncmake_install.cmake\ninstall_manifest.txt\ncompile_commands.json\nCTestTestfile.cmake\nbuild/\n\n# clangd cache\n.cache/\n\n# C++ objects and libs\n*.slo\n*.lo\n*.o\n*.a\n*.la\n*.lai\n*.so\n*.dll\n*.lib\n*.dylib\n*.exe\n*.out\n*.app\n\n# Qt-es\nobject_script.*.Release\nobject_script.*.Debug\n*_plugin_import.cpp\n/.qmake.cache\n/.qmake.stash\n*.pro.user\n*.pro.user.*\n*.qbs.user\n*.qbs.user.*\n*.moc\nmoc_*.cpp\nmoc_*.h\nqrc_*.cpp\nui_*.h\n*.qmlc\n*.jsc\nMakefile*\n*build-*\n!build-*.yml\n\n# Qt unit tests\ntarget_wrapper.*\n\n# doxygen\ndoxy/\n\n# QtCreator\n*.autosave\n\n# QtCtreator Qml\n*.qmlproject.user\n*.qmlproject.user.*\n\n# QtCtreator CMake\nCMakeLists.txt.user*\n\n# KDEvelop\n.kdev4/\n\n# JetBrains\n.idea/\n\n# Editor backups\n*.save\n*.swp\n\n# Build artifacts\n*.AppImage\n"
  },
  {
    "path": "CMake/CheckSigrokFeatures.cmake",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\n# Check if the installed libsigrok has the required features.\nfunction(check_libsigrok_features additional_header additional_lib)\n  include(CheckCXXSourceCompiles)\n  include(CMakePushCheckState)\n  cmake_push_check_state()\n  set(CMAKE_REQUIRED_FLAGS \"-std=c++11\")\n  set(CMAKE_REQUIRED_INCLUDES \"${additional_header}\")\n  set(CMAKE_REQUIRED_LIBRARIES \"${additional_lib}\")\n  set(CMAKE_REQUIRED_QUIET 1)\n  check_cxx_source_compiles(\"\n#include <libsigrokcxx/libsigrokcxx.hpp>\nconst sigrok::ConfigKey *config_key;\nint main() {\n\tconfig_key = sigrok::ConfigKey::MULTIPLEXER;\n\treturn 0;\n}\n\" HAS_FEATURES)\n  cmake_pop_check_state()\n\n  if (NOT HAS_FEATURES)\n    message(FATAL_ERROR \"libsigrok is too old, minimum required version is 0.6.0-git-522381a3\")\n  endif()\nendfunction(check_libsigrok_features)\n"
  },
  {
    "path": "CMake/FindQwt.cmake",
    "content": "# Find Qwt\n# ~~~~~~~~\n# Copyright (c) 2010, Tim Sutton <tim at linfiniti.com>\n# Redistribution and use is allowed according to the terms of the BSD license.\n# For details see the accompanying COPYING-CMAKE-SCRIPTS file.\n#\n# Once run this will define:\n#\n# QWT_FOUND       = system has QWT lib\n# QWT_LIBRARY     = full path to the QWT library\n# QWT_INCLUDE_DIR = where to find headers\n#\n\n\nset(QWT_LIBRARY_NAMES qwt-qt5 qwt6-qt5 qwt)\nset(QWT_HOMEBREW_INSTALL_PATH /usr/local/opt/qwt-qt5)\nfile(GLOB QWT_CUSTOM_INSTALL_PATH /usr/local/qwt-6.1.[0-9])\n\nfind_library(QWT_LIBRARY\n  NAMES ${QWT_LIBRARY_NAMES}\n  PATHS\n    /usr/lib\n    /usr/local/lib\n    \"${QWT_HOMEBREW_INSTALL_PATH}/lib\"\n    \"${QWT_CUSTOM_INSTALL_PATH}/lib\"\n    \"$ENV{LIB_DIR}/lib\"\n    \"$ENV{LIB}\"\n)\n\nset(_qwt_fw)\nif(QWT_LIBRARY MATCHES \"/qwt.*\\\\.framework\")\n  string(REGEX REPLACE \"^(.*/qwt.*\\\\.framework).*$\" \"\\\\1\" _qwt_fw \"${QWT_LIBRARY}\")\nendif()\n\nFIND_PATH(QWT_INCLUDE_DIR NAMES qwt.h PATHS\n  \"${_qwt_fw}/Headers\"\n  /usr/include\n  /usr/local/include\n  \"${QWT_HOMEBREW_INSTALL_PATH}/include\"\n  \"${QWT_CUSTOM_INSTALL_PATH}/include\"\n  \"$ENV{LIB_DIR}/include\"\n  \"$ENV{INCLUDE}\"\n  PATH_SUFFIXES qwt-qt5 qt5/qwt qwt qwt6\n)\n\nIF (QWT_INCLUDE_DIR AND QWT_LIBRARY)\n  SET(QWT_FOUND TRUE)\nENDIF (QWT_INCLUDE_DIR AND QWT_LIBRARY)\n\nIF (QWT_FOUND)\n  FILE(READ ${QWT_INCLUDE_DIR}/qwt_global.h qwt_header)\n  STRING(REGEX REPLACE \"^.*QWT_VERSION_STR +\\\"([^\\\"]+)\\\".*$\" \"\\\\1\" QWT_VERSION_STR \"${qwt_header}\")\n  IF (NOT QWT_FIND_QUIETLY)\n    MESSAGE(STATUS \"Found Qwt: ${QWT_LIBRARY} (${QWT_VERSION_STR})\")\n  ENDIF (NOT QWT_FIND_QUIETLY)\nELSE (QWT_FOUND)\n  IF (QWT_FIND_REQUIRED)\n    MESSAGE(FATAL_ERROR \"Could not find Qwt\")\n  ENDIF (QWT_FIND_REQUIRED)\nENDIF (QWT_FOUND)\n"
  },
  {
    "path": "CMake/GetGitRevisionDescription.cmake",
    "content": "# - Returns a version string from Git\n#\n# These functions force a re-configure on each git commit so that you can\n# trust the values of the variables in your build system.\n#\n#  get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...])\n#\n# Returns the refspec and sha hash of the current head revision\n#\n#  git_describe(<var> [<additional arguments to git describe> ...])\n#\n# Returns the results of git describe on the source tree, and adjusting\n# the output so that it tests false if an error occurs.\n#\n#  git_get_exact_tag(<var> [<additional arguments to git describe> ...])\n#\n# Returns the results of git describe --exact-match on the source tree,\n# and adjusting the output so that it tests false if there was no exact\n# matching tag.\n#\n# Requires CMake 2.6 or newer (uses the 'function' command)\n#\n# Original Author:\n# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>\n# http://academic.cleardefinition.com\n# Iowa State University HCI Graduate Program/VRAC\n#\n# Copyright Iowa State University 2009-2010.\n# Distributed under the Boost Software License, Version 1.0.\n# (See accompanying file LICENSE_1_0.txt or copy at\n# http://www.boost.org/LICENSE_1_0.txt)\n\nif(__get_git_revision_description)\n\treturn()\nendif()\nset(__get_git_revision_description YES)\n\n# We must run the following at \"include\" time, not at function call time,\n# to find the path to this module rather than the path to a calling list file\nget_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH)\n\nfunction(get_git_head_revision _refspecvar _hashvar)\n\tset(GIT_PARENT_DIR \"${CMAKE_CURRENT_SOURCE_DIR}\")\n\tset(GIT_DIR \"${GIT_PARENT_DIR}/.git\")\n\twhile(NOT EXISTS \"${GIT_DIR}\")\t# .git dir not found, search parent directories\n\t\tset(GIT_PREVIOUS_PARENT \"${GIT_PARENT_DIR}\")\n\t\tget_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH)\n\t\tif(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT)\n\t\t\t# We have reached the root directory, we are not in git\n\t\t\tset(${_refspecvar} \"GITDIR-NOTFOUND\" PARENT_SCOPE)\n\t\t\tset(${_hashvar} \"GITDIR-NOTFOUND\" PARENT_SCOPE)\n\t\t\treturn()\n\t\tendif()\n\t\tset(GIT_DIR \"${GIT_PARENT_DIR}/.git\")\n\tendwhile()\n\t# check if this is a submodule\n\tif(NOT IS_DIRECTORY ${GIT_DIR})\n\t\tfile(READ ${GIT_DIR} submodule)\n\t\tstring(REGEX REPLACE \"gitdir: (.*)\\n$\" \"\\\\1\" GIT_DIR_RELATIVE ${submodule})\n\t\tget_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH)\n\t\tget_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE)\n\tendif()\n\tset(GIT_DATA \"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data\")\n\tif(NOT EXISTS \"${GIT_DATA}\")\n\t\tfile(MAKE_DIRECTORY \"${GIT_DATA}\")\n\tendif()\n\n\tif(NOT EXISTS \"${GIT_DIR}/HEAD\")\n\t\treturn()\n\tendif()\n\tset(HEAD_FILE \"${GIT_DATA}/HEAD\")\n\tconfigure_file(\"${GIT_DIR}/HEAD\" \"${HEAD_FILE}\" COPYONLY)\n\n\tconfigure_file(\"${_gitdescmoddir}/GetGitRevisionDescription.cmake.in\"\n\t\t\"${GIT_DATA}/grabRef.cmake\"\n\t\t@ONLY)\n\tinclude(\"${GIT_DATA}/grabRef.cmake\")\n\n\tset(${_refspecvar} \"${HEAD_REF}\" PARENT_SCOPE)\n\tset(${_hashvar} \"${HEAD_HASH}\" PARENT_SCOPE)\nendfunction()\n\nfunction(git_describe _var)\n\tif(NOT GIT_FOUND)\n\t\tfind_package(Git QUIET)\n\tendif()\n\tget_git_head_revision(refspec hash)\n\tif(NOT GIT_FOUND)\n\t\tset(${_var} \"GIT-NOTFOUND\" PARENT_SCOPE)\n\t\treturn()\n\tendif()\n\tif(NOT hash)\n\t\tset(${_var} \"HEAD-HASH-NOTFOUND\" PARENT_SCOPE)\n\t\treturn()\n\tendif()\n\n\t# TODO sanitize\n\t#if((${ARGN}\" MATCHES \"&&\") OR\n\t#\t(ARGN MATCHES \"||\") OR\n\t#\t(ARGN MATCHES \"\\\\;\"))\n\t#\tmessage(\"Please report the following error to the project!\")\n\t#\tmessage(FATAL_ERROR \"Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}\")\n\t#endif()\n\n\t#message(STATUS \"Arguments to execute_process: ${ARGN}\")\n\n\texecute_process(COMMAND\n\t\t\"${GIT_EXECUTABLE}\"\n\t\tdescribe\n\t\t${hash}\n\t\t${ARGN}\n\t\tWORKING_DIRECTORY\n\t\t\"${CMAKE_SOURCE_DIR}\"\n\t\tRESULT_VARIABLE\n\t\tres\n\t\tOUTPUT_VARIABLE\n\t\tout\n\t\tERROR_QUIET\n\t\tOUTPUT_STRIP_TRAILING_WHITESPACE)\n\tif(NOT res EQUAL 0)\n\t\tset(out \"${out}-${res}-NOTFOUND\")\n\tendif()\n\n\tset(${_var} \"${out}\" PARENT_SCOPE)\nendfunction()\n\nfunction(git_get_exact_tag _var)\n\tgit_describe(out --exact-match ${ARGN})\n\tset(${_var} \"${out}\" PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "CMake/GetGitRevisionDescription.cmake.in",
    "content": "#\n# Internal file for GetGitRevisionDescription.cmake\n#\n# Requires CMake 2.6 or newer (uses the 'function' command)\n#\n# Original Author:\n# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net>\n# http://academic.cleardefinition.com\n# Iowa State University HCI Graduate Program/VRAC\n#\n# Copyright Iowa State University 2009-2010.\n# Distributed under the Boost Software License, Version 1.0.\n# (See accompanying file LICENSE_1_0.txt or copy at\n# http://www.boost.org/LICENSE_1_0.txt)\n\nset(HEAD_HASH)\n\nfile(READ \"@HEAD_FILE@\" HEAD_CONTENTS LIMIT 1024)\n\nstring(STRIP \"${HEAD_CONTENTS}\" HEAD_CONTENTS)\nif(HEAD_CONTENTS MATCHES \"ref\")\n\t# named branch\n\tstring(REPLACE \"ref: \" \"\" HEAD_REF \"${HEAD_CONTENTS}\")\n\tif(EXISTS \"@GIT_DIR@/${HEAD_REF}\")\n\t\tconfigure_file(\"@GIT_DIR@/${HEAD_REF}\" \"@GIT_DATA@/head-ref\" COPYONLY)\n\telse()\n\t\tconfigure_file(\"@GIT_DIR@/packed-refs\" \"@GIT_DATA@/packed-refs\" COPYONLY)\n\t\tfile(READ \"@GIT_DATA@/packed-refs\" PACKED_REFS)\n\t\tif(${PACKED_REFS} MATCHES \"([0-9a-z]*) ${HEAD_REF}\")\n\t\t\tset(HEAD_HASH \"${CMAKE_MATCH_1}\")\n\t\tendif()\n\tendif()\nelse()\n\t# detached HEAD\n\tconfigure_file(\"@GIT_DIR@/HEAD\" \"@GIT_DATA@/head-ref\" COPYONLY)\nendif()\n\nif(NOT HEAD_HASH)\n\tfile(READ \"@GIT_DATA@/head-ref\" HEAD_HASH LIMIT 1024)\n\tstring(STRIP \"${HEAD_HASH}\" HEAD_HASH)\nendif()\n"
  },
  {
    "path": "CMake/memaccess.cmake",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2014 Marcus Comstedt <marcus@mc.pp.se>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\ninclude(CheckCSourceRuns)\n\nfunction(memaccess_check_unaligned_le _var)\nif(NOT CMAKE_CROSSCOMPILING)\nCHECK_C_SOURCE_RUNS(\"\n#include <stdint.h>\nint main() {\n    int i;\n    union { uint64_t u64; uint8_t u8[16]; } d;\n    uint64_t v;\n    for (i=0; i<16; i++)\n        d.u8[i] = i;\n    v = *(uint64_t *)(d.u8+1);\n    if (v != 0x0807060504030201ULL)\n       return 1;\n    return 0;\n}\" ${_var})\nendif()\nif(CMAKE_CROSSCOMPILING)\n  message(STATUS \"Cross compiling - using portable code for memory access\")\nendif()\nendfunction()\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n## Copyright (C) 2012-2013 Alexandru Gagniuc <mr.nuke.me@gmail.com>\n## Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 3 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\ncmake_minimum_required(VERSION 3.6)\n\nproject(smuview C CXX)\n\ninclude(GNUInstallDirs)\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_SOURCE_DIR}/CMake\")\n\n\n#===============================================================================\n#= User Options\n#-------------------------------------------------------------------------------\n\noption(DISABLE_WERROR \"Build without -Werror\" FALSE)\noption(ENABLE_SIGNALS \"Build with UNIX signals\" TRUE)\noption(ENABLE_TESTS \"Enable unit tests\" TRUE)\noption(STATIC_PKGDEPS_LIBS \"Statically link to (pkg-config) libraries\" FALSE)\n\n# Let AUTOMOC and AUTOUIC process GENERATED files.\nif(POLICY CMP0071)\n\tcmake_policy(SET CMP0071 NEW)\nendif()\n\n# Only interpret if() arguments as variables or keywords when unquoted.\nif(POLICY CMP0054)\n\tcmake_policy(SET CMP0054 NEW)\nendif()\n\n# SmuView, QCodeEditor and pybind11 only need C++11, but the upcoming Boost.Math\n# (Boost 1.82 release) library requires C++14 as minimum language standard.\nset(CMAKE_CXX_STANDARD 14)\n\nif(WIN32)\n\t# On Windows/MinGW we need to statically link to libraries.\n\t# This option is user configurable, but enable it by default on win32.\n\tset(STATIC_PKGDEPS_LIBS TRUE)\n\n\t# Windows does not support UNIX signals.\n\tset(ENABLE_SIGNALS FALSE)\n\n\t# When cross compiling this is needed for pkg-config\n\tset(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)\nendif()\n\nif(NOT CMAKE_BUILD_TYPE)\n\tset(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING\n\t\"Choose the type of build (None, Debug, Release, RelWithDebInfo, MinSizeRel).\"\n\tFORCE)\nendif()\n\n# Generate compile_commands.json in build/ for analyzers like clang-tidy.\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\nmessage(STATUS \"DISABLE_WERROR: ${DISABLE_WERROR}\")\nmessage(STATUS \"ENABLE_SIGNALS: ${ENABLE_SIGNALS}\")\nmessage(STATUS \"ENABLE_TESTS: ${ENABLE_TESTS}\")\nmessage(STATUS \"STATIC_PKGDEPS_LIBS: ${STATIC_PKGDEPS_LIBS}\")\n\n#===============================================================================\n#= Dependencies\n#-------------------------------------------------------------------------------\n\nlist(APPEND PKGDEPS glib-2.0>=2.28.0)\nlist(APPEND PKGDEPS glibmm-2.4>=2.28.0)\n\nset(LIBSR_CXX_BINDING \"libsigrokcxx>=0.5.2\")\nlist(APPEND PKGDEPS \"${LIBSR_CXX_BINDING}\")\n\nfind_package(PkgConfig)\npkg_check_modules(LIBSRCXX ${LIBSR_CXX_BINDING} IMPORTED_TARGET)\nif(NOT LIBSRCXX_FOUND OR NOT LIBSRCXX_VERSION)\n\tmessage(FATAL_ERROR \"libsigrok C++ bindings missing, check libsigrok's 'configure' output (missing dependencies?)\")\nendif()\npkg_check_modules(PKGDEPS REQUIRED IMPORTED_TARGET ${PKGDEPS})\n\ninclude(CheckSigrokFeatures)\nif(STATIC_PKGDEPS_LIBS)\n\tcheck_libsigrok_features(\"${LIBSRCXX_STATIC_INCLUDE_DIRS}\" PkgConfig::PKGDEPS)\nelse()\n\tcheck_libsigrok_features(\"${LIBSRCXX_INCLUDE_DIRS}\" PkgConfig::PKGDEPS)\nendif()\n\nset(CMAKE_INCLUDE_CURRENT_DIR ON)\nset(CMAKE_AUTOMOC ON)\n\nfind_package(Qt5 5.7 COMPONENTS Core Gui Widgets Svg REQUIRED)\n\nif(MINGW)\n\t# MXE workaround: Use pkg-config to find Qt5 libs.\n\t# https://github.com/mxe/mxe/issues/1642\n\t# Not required (and doesn't work) on MSYS2.\n\tif(NOT DEFINED ENV{MSYSTEM})\n\t\tpkg_check_modules(QT5ALL REQUIRED Qt5Widgets Qt5Gui Qt5Svg)\n\tendif()\nendif()\n\nset(QT_LIBRARIES Qt5::Gui Qt5::Widgets Qt5::Svg)\n\nfind_package(Qwt 6.1.2 REQUIRED)\n\n# boost::multiprecision is required, but it's header only. So no need to specify\nset(BOOSTCOMPS)\nif(ENABLE_TESTS)\n\tlist(APPEND BOOSTCOMPS unit_test_framework)\nendif()\nfind_package(Boost 1.54 COMPONENTS ${BOOSTCOMPS} REQUIRED)\n\n# Find the platform's thread library (needed for C++11 threads).\n# This will set ${CMAKE_THREAD_LIBS_INIT} to the correct, OS-specific value.\nfind_package(Threads REQUIRED)\n\nif(MINGW)\n\t# MXE workaround: Use PkgConfig to find the supplied Python 3.4 (see MXE build\n\t# script sigrok-cross-mingw-smuview in sigrok-util) and disable the find\n\t# python functionality in pybind11\n\tset(PYBIND11_NOPYTHON ON)\n\n\t# This is not needed atm, but might come in handy in the future:\n\t# Python 3.8 no longer links to libpython, but it provides a python3-embed.pc\n\t# now, so let's try using that first and only fall back on the normal case if\n\t# that fails.\n\t# See: https://docs.python.org/3.8/whatsnew/3.8.html#debug-build-uses-the-same-abi-as-release-build\n\tpkg_check_modules(PYTHON3 python3-embed)\n\tif(NOT PYTHON3_FOUND)\n\t\tpkg_check_modules(PYTHON3 python3)\n\tendif()\nendif()\n\n# SmuView has its own copy of pybind11\nif(MINGW)\n\t# Use pybind11 2.9.2 with the emum_docstring patch for the MXE build. 2.9.2\n\t# is the last pybind11 version that supports Python 3.4.4 which is needed for\n\t# static linking in the MXE cross build\n\tset(PYBIND11_SUBDIRECTORY external/pybind11_2.9.2)\nelse()\n\t# Use pybind11 2.11 dev1 with the emum_docstring patch for all other builds\n\tset(PYBIND11_SUBDIRECTORY external/pybind11_2.11_dev1)\nendif()\nadd_subdirectory(${PYBIND11_SUBDIRECTORY})\n# SmuView has its own copy of QCodeEditor\nadd_subdirectory(external/QCodeEditor)\n# SmuView has its own copy of QtFindReplaceDialog\nadd_subdirectory(external/QtFindReplaceDialog/dialogs)\n\n#===============================================================================\n#= System Introspection\n#-------------------------------------------------------------------------------\n\ninclude(memaccess)\nmemaccess_check_unaligned_le(HAVE_UNALIGNED_LITTLE_ENDIAN_ACCESS)\n\n\n#===============================================================================\n#= Config Header\n#-------------------------------------------------------------------------------\n\nset(SV_TITLE SmuView)\nset(SV_VERSION_STRING \"0.0.6\")\n\n# Append the revision hash unless we are exactly on a tagged release.\ninclude(GetGitRevisionDescription)\ngit_describe(SV_TAG_VERSION_STRING --match \"v${SV_VERSION_STRING}\" --exact-match)\nif(NOT SV_TAG_VERSION_STRING)\n\tget_git_head_revision(SV_REVSPEC SV_HASH)\n\tif(SV_HASH)\n\t\tstring(SUBSTRING \"${SV_HASH}\" 0 7 SV_SHORTHASH)\n\t\tset(SV_VERSION_STRING \"${SV_VERSION_STRING}-git-${SV_SHORTHASH}\")\n\tendif()\n\n\t# Non-tagged releases use the continuous manual\n\tset(SV_MANUAL_VERSION \"continuous\")\nelse()\n\t# Tagged releases use a fixed manual version\n\tset(SV_MANUAL_VERSION ${SV_VERSION_STRING})\nendif()\n\nif(SV_VERSION_STRING MATCHES \"^([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)(-[-0-9a-z]*)?$\")\n\tset(SV_VERSION_MAJOR ${CMAKE_MATCH_1})\n\tset(SV_VERSION_MINOR ${CMAKE_MATCH_2})\n\tset(SV_VERSION_MICRO ${CMAKE_MATCH_3})\n\tset(SV_VERSION_SUFFIX ${CMAKE_MATCH_4})\nendif()\n\nmessage(STATUS \"${SV_TITLE} version: ${SV_VERSION_STRING}\")\n\n# Library versions\nset(SV_GLIBMM_VERSION ${PKGDEPS_glibmm-2.4_VERSION})\nget_directory_property(pybind11_VERSION DIRECTORY ${PYBIND11_SUBDIRECTORY} DEFINITION pybind11_VERSION)\nget_directory_property(pybind11_VERSION_TYPE DIRECTORY ${PYBIND11_SUBDIRECTORY} DEFINITION pybind11_VERSION_TYPE)\nset(SV_PYBIND11_VERSION \"${pybind11_VERSION} ${pybind11_VERSION_TYPE}\")\nif(MINGW)\n\t# MXE workaround: Use PkgConfig to find Python\n\tset(SV_PYTHON_VERSION ${PYTHON3_VERSION})\nelse()\n\tset(SV_PYTHON_VERSION ${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR})\nendif()\n\nconfigure_file (\n\t${PROJECT_SOURCE_DIR}/config.h.in\n\t${PROJECT_BINARY_DIR}/config.h\n)\nconfigure_file (\n\t${PROJECT_SOURCE_DIR}/contrib/config_version.sh.in\n\t${PROJECT_BINARY_DIR}/contrib/config_version.sh\n)\n\n\n#===============================================================================\n#= Sources\n#-------------------------------------------------------------------------------\n\nset(smuview_SOURCES\n\tmain.cpp\n\tsrc/application.cpp\n\tsrc/devicemanager.cpp\n\tsrc/mainwindow.cpp\n\tsrc/session.cpp\n\tsrc/settingsmanager.cpp\n\tsrc/util.cpp\n\tsrc/channels/addscchannel.cpp\n\tsrc/channels/basechannel.cpp\n\tsrc/channels/dividechannel.cpp\n\tsrc/channels/hardwarechannel.cpp\n\tsrc/channels/integratechannel.cpp\n\tsrc/channels/mathchannel.cpp\n\tsrc/channels/movingavgchannel.cpp\n\tsrc/channels/multiplysfchannel.cpp\n\tsrc/channels/multiplysschannel.cpp\n\tsrc/channels/userchannel.cpp\n\tsrc/data/analogbasesignal.cpp\n\tsrc/data/analogsamplesignal.cpp\n\tsrc/data/analogtimesignal.cpp\n\tsrc/data/basesignal.cpp\n\tsrc/data/datautil.cpp\n\tsrc/data/properties/baseproperty.cpp\n\tsrc/data/properties/boolproperty.cpp\n\tsrc/data/properties/doubleproperty.cpp\n\tsrc/data/properties/doublerangeproperty.cpp\n\tsrc/data/properties/int32property.cpp\n\tsrc/data/properties/measuredquantityproperty.cpp\n\tsrc/data/properties/rationalproperty.cpp\n\tsrc/data/properties/stringproperty.cpp\n\tsrc/data/properties/uint64property.cpp\n\tsrc/data/properties/uint64rangeproperty.cpp\n\tsrc/devices/basedevice.cpp\n\tsrc/devices/configurable.cpp\n\tsrc/devices/deviceutil.cpp\n\tsrc/devices/hardwaredevice.cpp\n\tsrc/devices/measurementdevice.cpp\n\tsrc/devices/oscilloscopedevice.cpp\n\tsrc/devices/sourcesinkdevice.cpp\n\tsrc/devices/userdevice.cpp\n\n\tsrc/python/bindings.cpp\n\tsrc/python/pystreambuf.cpp\n\tsrc/python/pystreamredirect.hpp\n\tsrc/python/smuscriptrunner.cpp\n\tsrc/python/uihelper.cpp\n\tsrc/python/uiproxy.cpp\n\n\tsrc/ui/data/quantitycombobox.cpp\n\tsrc/ui/data/quantityflagslist.cpp\n\tsrc/ui/data/unitcombobox.cpp\n\tsrc/ui/datatypes/basewidget.cpp\n\tsrc/ui/datatypes/boolbutton.cpp\n\tsrc/ui/datatypes/boolcheckbox.cpp\n\tsrc/ui/datatypes/boolled.cpp\n\tsrc/ui/datatypes/datatypehelper.cpp\n\tsrc/ui/datatypes/doublecontrol.cpp\n\tsrc/ui/datatypes/doubledisplay.cpp\n\tsrc/ui/datatypes/doubleknob.cpp\n\tsrc/ui/datatypes/doublerangecombobox.cpp\n\tsrc/ui/datatypes/doubleslider.cpp\n\tsrc/ui/datatypes/doublesmallcontrol.cpp\n\tsrc/ui/datatypes/doublespinbox.cpp\n\tsrc/ui/datatypes/int32spinbox.cpp\n\tsrc/ui/datatypes/measuredquantitycombobox.cpp\n\tsrc/ui/datatypes/rationalcombobox.cpp\n\tsrc/ui/datatypes/stringcombobox.cpp\n\tsrc/ui/datatypes/stringlabel.cpp\n\tsrc/ui/datatypes/stringled.cpp\n\tsrc/ui/datatypes/thresholdcontrol.cpp\n\tsrc/ui/datatypes/uint64combobox.cpp\n\tsrc/ui/datatypes/uint64label.cpp\n\tsrc/ui/datatypes/uint64rangecombobox.cpp\n\tsrc/ui/datatypes/uint64spinbox.cpp\n\tsrc/ui/devices/channelcombobox.cpp\n\tsrc/ui/devices/channelgroupcombobox.cpp\n\tsrc/ui/devices/configkeycombobox.cpp\n\tsrc/ui/devices/configurablecombobox.cpp\n\tsrc/ui/devices/devicecombobox.cpp\n\tsrc/ui/devices/selectconfigurableform.cpp\n\tsrc/ui/devices/selectpropertyform.cpp\n\tsrc/ui/devices/selectsignalwidget.cpp\n\tsrc/ui/devices/signalcombobox.cpp\n\tsrc/ui/devices/devicetree/devicetreemodel.cpp\n\tsrc/ui/devices/devicetree/devicetreeview.cpp\n\tsrc/ui/devices/devicetree/treeitem.cpp\n\tsrc/ui/dialogs/aboutdialog.cpp\n\tsrc/ui/dialogs/addmathchanneldialog.cpp\n\tsrc/ui/dialogs/adduserchanneldialog.cpp\n\tsrc/ui/dialogs/addviewdialog.cpp\n\tsrc/ui/dialogs/addviewdialog.cpp\n\tsrc/ui/dialogs/connectdialog.cpp\n\tsrc/ui/dialogs/generatewaveformdialog.cpp\n\tsrc/ui/dialogs/plotconfigdialog.cpp\n\tsrc/ui/dialogs/plotcurveconfigdialog.cpp\n\tsrc/ui/dialogs/plotdiffmarkerdialog.cpp\n\tsrc/ui/dialogs/selectsignaldialog.cpp\n\tsrc/ui/dialogs/selectxysignalsdialog.cpp\n\tsrc/ui/dialogs/signalsavedialog.cpp\n\tsrc/ui/tabs/basetab.cpp\n\tsrc/ui/tabs/devicetab.cpp\n\tsrc/ui/tabs/measurementtab.cpp\n\tsrc/ui/tabs/oscilloscopetab.cpp\n\tsrc/ui/tabs/smuscripttab.cpp\n\tsrc/ui/tabs/sourcesinktab.cpp\n\tsrc/ui/tabs/tabdockwidget.cpp\n\tsrc/ui/tabs/tabhelper.cpp\n\tsrc/ui/tabs/usertab.cpp\n\tsrc/ui/tabs/welcometab.cpp\n\tsrc/ui/views/baseplotview.cpp\n\tsrc/ui/views/baseview.cpp\n\tsrc/ui/views/dataview.cpp\n\tsrc/ui/views/devicesview.cpp\n\tsrc/ui/views/democontrolview.cpp\n\tsrc/ui/views/genericcontrolview.cpp\n\tsrc/ui/views/measurementcontrolview.cpp\n\tsrc/ui/views/powerpanelview.cpp\n\tsrc/ui/views/scopehorizontalcontrolview.cpp\n\tsrc/ui/views/scopetriggercontrolview.cpp\n\tsrc/ui/views/scopeverticalcontrolview.cpp\n\tsrc/ui/views/sequenceoutputview.cpp\n\tsrc/ui/views/smuscriptoutputview.cpp\n\tsrc/ui/views/smuscripttreeview.cpp\n\tsrc/ui/views/smuscriptview.cpp\n\tsrc/ui/views/sourcesinkcontrolview.cpp\n\tsrc/ui/views/timeplotview.cpp\n\tsrc/ui/views/valuepanelview.cpp\n\tsrc/ui/views/viewhelper.cpp\n\tsrc/ui/views/xyplotview.cpp\n\tsrc/ui/widgets/clickablelabel.cpp\n\tsrc/ui/widgets/colorbutton.cpp\n\tsrc/ui/widgets/monofontdisplay.cpp\n\tsrc/ui/widgets/popup.cpp\n\tsrc/ui/widgets/plot/axislocklabel.cpp\n\tsrc/ui/widgets/plot/axispopup.cpp\n\tsrc/ui/widgets/plot/basecurvedata.cpp\n\tsrc/ui/widgets/plot/curve.cpp\n\tsrc/ui/widgets/plot/plot.cpp\n\tsrc/ui/widgets/plot/plotmagnifier.cpp\n\tsrc/ui/widgets/plot/plotscalepicker.cpp\n\tsrc/ui/widgets/plot/timecurvedata.cpp\n\tsrc/ui/widgets/plot/xycurvedata.cpp\n)\n\nif(ENABLE_SIGNALS)\n\tlist(APPEND smuview_SOURCES signalhandler.cpp)\nendif()\n\nset(smuview_RESOURCES\n\tsmuview.qrc\n)\n\nif(WIN32)\n\t# Use the sigrok icon for the smuview.exe executable.\n\tset(CMAKE_RC_COMPILE_OBJECT \"${CMAKE_RC_COMPILER} -O coff -I${CMAKE_CURRENT_SOURCE_DIR} <SOURCE> <OBJECT>\")\n\tenable_language(RC)\n\tlist(APPEND smuview_SOURCES smuviewico.rc)\nendif()\n\nqt5_add_resources(smuview_RESOURCES_RCC ${smuview_RESOURCES})\n\n\n#===============================================================================\n#= Global Definitions\n#-------------------------------------------------------------------------------\n\nadd_definitions(-DQT_NO_KEYWORDS)\nadd_definitions(-D__STDC_LIMIT_MACROS)\nadd_definitions(-Wall -Wextra -Woverloaded-virtual -Wdeprecated-declarations) # -Weffc++ -Wconversion -Wsign-conversion)\nadd_definitions(-std=c++14)\nadd_definitions(-DBOOST_MATH_DISABLE_FLOAT128=1)\n\nif(NOT DISABLE_WERROR)\n\t#add_definitions(-Werror -pedantic-errors)\n\tadd_definitions(-Werror=pedantic -pedantic-errors)\nendif()\n\nif(ENABLE_SIGNALS)\n\tadd_definitions(-DENABLE_SIGNALS)\nendif()\n\nif(MINGW)\n\t# MXE workaround: Prevents compile error:\n\t# mxe-git-x86_64/usr/lib/gcc/x86_64-w64-mingw32.static.posix/5.5.0/include/c++/cmath:1147:11: error: '::hypot' has not been declared\n\t#    using ::hypot;\n\t# Alternativ solution:\n\t# Add \"#include <cmath>\" before the pybind11 includes in bindings.cpp and smuscriptrunner.cpp\n\tadd_compile_options(-D_hypot=hypot)\nendif()\n\nif(MINGW AND ${CMAKE_BUILD_TYPE} STREQUAL \"Debug\")\n\t# Fix error \"too many sections (37653)\" and \"file too big\" for mingw/MXE when building for Debug\n\tadd_definitions(-Wa,-mbig-obj)\nendif()\n\n#===============================================================================\n#= Global Include Directories\n#-------------------------------------------------------------------------------\n\ninclude_directories(\n\t${CMAKE_CURRENT_BINARY_DIR}\n\t${CMAKE_CURRENT_SOURCE_DIR}\n\t${QWT_INCLUDE_DIR}\n\t${Boost_INCLUDE_DIRS}\n)\n\nif(MINGW)\n\t# MXE workaround: Use PkgConfig to find Python\n\tinclude_directories(${PYTHON3_INCLUDE_DIRS})\nendif()\n\nif(STATIC_PKGDEPS_LIBS)\n\tinclude_directories(${PKGDEPS_STATIC_INCLUDE_DIRS})\nelse()\n\tinclude_directories(${PKGDEPS_INCLUDE_DIRS})\nendif()\n\n\n#===============================================================================\n#= Linker Configuration\n#-------------------------------------------------------------------------------\n\nlink_directories(${Boost_LIBRARY_DIRS})\n\nset(SMUVIEW_LINK_LIBS\n\t${Boost_LIBRARIES}\n\t${QT_LIBRARIES}\n\t${QWT_LIBRARY}\n\t${CMAKE_THREAD_LIBS_INIT}\n\t#${LIBATOMIC_LIBRARY}\n\tPkgConfig::PKGDEPS\n\tpybind11::embed\n\tQCodeEditor\n\tQtFindReplaceDialog\n)\n\nif(MINGW)\n\t# MXE workaround: Use PkgConfig to find Python\n\tif(PYTHON3_LINK_LIBRARIES)\n\t\t# Try to use the fully qualified name for cross compiling\n\t\tlist(APPEND SMUVIEW_LINK_LIBS ${PYTHON3_LINK_LIBRARIES})\n\telse()\n\t\tlist(APPEND SMUVIEW_LINK_LIBS ${PYTHON3_LIBRARIES})\n\tendif()\nendif()\n\nif(WIN32)\n\t# On Windows we need to statically link the libqsvg imageformat\n\t# plugin (and the QtSvg component) for SVG graphics/icons to work.\n\t# We also need QWindowsIntegrationPlugin, Qt5PlatformSupport, and all\n\t# Qt libs and their dependencies.\n\tadd_definitions(-DQT_STATICPLUGIN)\n\tlist(APPEND SMUVIEW_LINK_LIBS Qt5::QSvgPlugin)\n\tlist(APPEND SMUVIEW_LINK_LIBS Qt5::QWindowsIntegrationPlugin)\n\n\t# Form Qt 5.8 on, Qt5PlatformSupport is split into several plugins:\n\t# QtAccessibilitySupport QtCliboardSupport QtEventDispatcherSupport\n\t# QtFontDatabaseSupport QtGraphicsSupport QtThemeSupport\n\t# TODO: Some of the plugins are wrong?\n\tif(Qt5Core_VERSION VERSION_LESS \"5.8.0\")\n\t\tlist(APPEND SMUVIEW_LINK_LIBS -lQt5PlatformSupport ${QT5ALL_LDFLAGS})\n\telse()\n\t\tlist(APPEND SMUVIEW_LINK_LIBS -lQt5AccessibilitySupport)\n\t\tlist(APPEND SMUVIEW_LINK_LIBS -lQt5EventDispatcherSupport)\n\t\tlist(APPEND SMUVIEW_LINK_LIBS -lQt5FontDatabaseSupport)\n\t\tlist(APPEND SMUVIEW_LINK_LIBS -lQt5ThemeSupport)\n\t\t#list(APPEND SMUVIEW_LINK_LIBS -lQt5ClipboardSupport)\n\t\t#list(APPEND SMUVIEW_LINK_LIBS -lQt5GraphicsSupport)\n\t\tlist(APPEND SMUVIEW_LINK_LIBS ${QT5ALL_LDFLAGS})\n\tendif()\nendif()\n\nadd_executable(${PROJECT_NAME} ${smuview_SOURCES} ${smuview_RESOURCES_RCC})\n\ntarget_link_libraries(${PROJECT_NAME} ${SMUVIEW_LINK_LIBS})\n\nif(WIN32 AND NOT ${CMAKE_BUILD_TYPE} STREQUAL \"Debug\")\n\t# Pass -mwindows so that no \"DOS box\" opens when SmuView is started.\n\tset_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS \"-mwindows\")\nendif()\n\n\n#===============================================================================\n#= Installation\n#-------------------------------------------------------------------------------\n\n# Install the executable.\ninstall(TARGETS ${PROJECT_NAME} DESTINATION bin/)\n\n# Install the manpage.\ninstall(FILES doc/smuview.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 COMPONENT doc)\n\n# Install the desktop file.\ninstall(FILES contrib/org.sigrok.SmuView.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)\n\n# Install the AppData/AppStream file.\ninstall(FILES contrib/org.sigrok.SmuView.appdata.xml DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo)\n\n# Install the SmuView icons.\ninstall(FILES icons/smuview.png DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/48x48/apps)\ninstall(FILES icons/smuview.svg DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps)\n\n# Install the SmuScript examples.\ninstall(DIRECTORY smuscript/ DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/smuscript)\n\n# Generate Windows installer script.\nconfigure_file(contrib/smuview_cross.nsi.in ${CMAKE_CURRENT_BINARY_DIR}/contrib/smuview_cross.nsi @ONLY)\n\n\n#===============================================================================\n#= Documentation\n#-------------------------------------------------------------------------------\n\nadd_subdirectory(manual)\n\n\n#===============================================================================\n#= Packaging (handled by CPack)\n#-------------------------------------------------------------------------------\n\n\n#===============================================================================\n#= Tests\n#-------------------------------------------------------------------------------\n\nif(ENABLE_TESTS)\n\tadd_subdirectory(test)\n\tenable_testing()\n\tadd_test(test ${CMAKE_CURRENT_BINARY_DIR}/test/smuview-test)\nendif()\n"
  },
  {
    "path": "COPYING",
    "content": "\n                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "Doxyfile",
    "content": "# Doxyfile 1.8.6\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\nDOXYFILE_ENCODING      = UTF-8\nPROJECT_NAME           = \"SmuView\"\nPROJECT_NUMBER         = \"unreleased development snapshot\"\nPROJECT_BRIEF          = \"A Qt-based sigrok GUI\"\nPROJECT_LOGO           = icons/smuview.png\nOUTPUT_DIRECTORY       = doxy\nCREATE_SUBDIRS         = NO\nOUTPUT_LANGUAGE        = English\nBRIEF_MEMBER_DESC      = YES\nREPEAT_BRIEF           = YES\nABBREVIATE_BRIEF       =\nALWAYS_DETAILED_SEC    = NO\nINLINE_INHERITED_MEMB  = NO\nFULL_PATH_NAMES        = YES\nSTRIP_FROM_PATH        =\nSTRIP_FROM_INC_PATH    =\nSHORT_NAMES            = NO\nJAVADOC_AUTOBRIEF      = NO\nQT_AUTOBRIEF           = NO\nMULTILINE_CPP_IS_BRIEF = NO\nINHERIT_DOCS           = YES\nSEPARATE_MEMBER_PAGES  = NO\nTAB_SIZE               = 4\nALIASES                =\nMARKDOWN_SUPPORT       = YES\nAUTOLINK_SUPPORT       = YES\nBUILTIN_STL_SUPPORT    = YES\nSUBGROUPING            = YES\nINLINE_GROUPED_CLASSES = NO\nINLINE_SIMPLE_STRUCTS  = YES\nTYPEDEF_HIDES_STRUCT   = NO\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\nEXTRACT_ALL            = YES\nEXTRACT_PRIVATE        = YES\nEXTRACT_PACKAGE        = NO\nEXTRACT_STATIC         = YES\nEXTRACT_LOCAL_CLASSES  = YES\nHIDE_UNDOC_MEMBERS     = NO\nHIDE_UNDOC_CLASSES     = NO\nHIDE_FRIEND_COMPOUNDS  = NO\nHIDE_IN_BODY_DOCS      = NO\nINTERNAL_DOCS          = YES\nCASE_SENSE_NAMES       = YES\nHIDE_SCOPE_NAMES       = NO\nSHOW_INCLUDE_FILES     = YES\nSHOW_GROUPED_MEMB_INC  = NO\nFORCE_LOCAL_INCLUDES   = NO\nINLINE_INFO            = YES\nSORT_MEMBER_DOCS       = YES\nSORT_BRIEF_DOCS        = NO\nSORT_MEMBERS_CTORS_1ST = YES\nSORT_GROUP_NAMES       = NO\nSORT_BY_SCOPE_NAME     = NO\nSTRICT_PROTO_MATCHING  = NO\nGENERATE_TODOLIST      = NO\nGENERATE_TESTLIST      = YES\nGENERATE_BUGLIST       = NO\nGENERATE_DEPRECATEDLIST= NO\nENABLED_SECTIONS       =\nMAX_INITIALIZER_LINES  = 30\nSHOW_USED_FILES        = YES\nSHOW_FILES             = YES\nSHOW_NAMESPACES        = YES\nFILE_VERSION_FILTER    =\nLAYOUT_FILE            =\n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\nQUIET                  = YES\nWARNINGS               = YES\nWARN_IF_UNDOCUMENTED   = YES\nWARN_IF_DOC_ERROR      = YES\nWARN_NO_PARAMDOC       = NO\nWARN_FORMAT            = \"$file:$line: $text\"\nWARN_LOGFILE           =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\nINPUT                  = .\nINPUT_ENCODING         = UTF-8\nFILE_PATTERNS          =\nRECURSIVE              = YES\nEXCLUDE                =\nEXCLUDE_SYMLINKS       = NO\nEXCLUDE_PATTERNS       = moc_*.c* */external/*\nEXCLUDE_SYMBOLS        =\nEXAMPLE_PATH           =\nEXAMPLE_PATTERNS       =\nEXAMPLE_RECURSIVE      = NO\nIMAGE_PATH             =\nINPUT_FILTER           =\nFILTER_PATTERNS        =\nFILTER_SOURCE_FILES    = NO\nFILTER_SOURCE_PATTERNS =\nUSE_MDFILE_AS_MAINPAGE =\n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\nSOURCE_BROWSER         = YES\nINLINE_SOURCES         = NO\nSTRIP_CODE_COMMENTS    = YES\nREFERENCED_BY_RELATION = NO\nREFERENCES_RELATION    = NO\nREFERENCES_LINK_SOURCE = YES\nSOURCE_TOOLTIPS        = YES\nUSE_HTAGS              = NO\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\nALPHABETICAL_INDEX     = YES\nCOLS_IN_ALPHA_INDEX    = 5\nIGNORE_PREFIX          =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\nGENERATE_HTML          = YES\nHTML_OUTPUT            = html-api\nHTML_FILE_EXTENSION    = .html\nHTML_HEADER            =\nHTML_FOOTER            =\nHTML_STYLESHEET        =\nHTML_EXTRA_STYLESHEET  =\nHTML_EXTRA_FILES       =\nHTML_COLORSTYLE_HUE    = 220\nHTML_COLORSTYLE_SAT    = 100\nHTML_COLORSTYLE_GAMMA  = 80\nHTML_TIMESTAMP         = YES\nHTML_DYNAMIC_SECTIONS  = NO\nHTML_INDEX_NUM_ENTRIES = 100\nDISABLE_INDEX          = NO\nGENERATE_TREEVIEW      = YES\nENUM_VALUES_PER_LINE   = 4\nTREEVIEW_WIDTH         = 250\nEXT_LINKS_IN_WINDOW    = NO\nFORMULA_FONTSIZE       = 10\nFORMULA_TRANSPARENT    = YES\nSEARCHENGINE           = YES\nSERVER_BASED_SEARCH    = NO\nEXTERNAL_SEARCH        = NO\nSEARCHENGINE_URL       =\nSEARCHDATA_FILE        = searchdata.xml\nEXTERNAL_SEARCH_ID     =\nEXTRA_SEARCH_MAPPINGS  =\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Latex output\n#---------------------------------------------------------------------------\n\nGENERATE_LATEX         = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\nENABLE_PREPROCESSING   = YES\nMACRO_EXPANSION        = NO\nEXPAND_ONLY_PREDEF     = NO\nSEARCH_INCLUDES        = YES\nINCLUDE_PATH           =\nINCLUDE_FILE_PATTERNS  =\nPREDEFINED             =\nEXPAND_AS_DEFINED      =\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\nTAGFILES               =\nGENERATE_TAGFILE       =\nALLEXTERNALS           = NO\nEXTERNAL_GROUPS        = YES\nEXTERNAL_PAGES         = YES\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\nCLASS_DIAGRAMS         = YES\nMSCGEN_PATH            =\nDIA_PATH               =\nHIDE_UNDOC_RELATIONS   = NO\nHAVE_DOT               = YES\nDOT_NUM_THREADS        = 0\nDOT_FONTNAME           = Helvetica\nDOT_FONTSIZE           = 10\nDOT_FONTPATH           =\nCLASS_GRAPH            = YES\nCOLLABORATION_GRAPH    = YES\nGROUP_GRAPHS           = YES\nUML_LOOK               = YES\nUML_LIMIT_NUM_FIELDS   = 10\nTEMPLATE_RELATIONS     = NO\nINCLUDE_GRAPH          = YES\nINCLUDED_BY_GRAPH      = YES\nCALL_GRAPH             = YES\nCALLER_GRAPH           = YES\nGRAPHICAL_HIERARCHY    = YES\nDIRECTORY_GRAPH        = YES\nDOT_IMAGE_FORMAT       = svg\nINTERACTIVE_SVG        = YES\nDOT_PATH               =\nDOTFILE_DIRS           =\nMSCFILE_DIRS           =\nDIAFILE_DIRS           =\nDOT_GRAPH_MAX_NODES    = 50\nMAX_DOT_GRAPH_DEPTH    = 0\nDOT_TRANSPARENT        = YES\nDOT_MULTI_TARGETS      = YES\nGENERATE_LEGEND        = YES\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "INSTALL",
    "content": "-------------------------------------------------------------------------------\nINSTALL\n-------------------------------------------------------------------------------\n\nRequirements\n------------\n\n - git (only needed when building from git)\n - A C++ compiler with C++11 support (-std=c++11 option), e.g.\n   - g++ (>= 4.8.1)\n   - clang++ (>= 3.3)\n - make\n - libtool (only needed when building from git)\n - pkg-config (>= 0.22)\n - cmake (>= 2.8.12)\n - libglib (>= 2.28.0)\n - glibmm-2.4 (>= 2.28.0)\n - Qt5 >= 5.7 (including the following components):\n    - Qt5Core, Qt5Gui, Qt5Widgets, Qt5Svg\n - Boost (>= 1.55)\n - Qwt (>= 6.1.2)\n - Python (>= 3)\n - libsigrokcxx (>= 0.5.2) (libsigrok C++ bindings)\n - Asciidoctor (optional, only needed to build the manual)\n\nBuilding and installing\n-----------------------\n\nIn order to get the SmuView source code and build it, run:\n\n $ git clone https://github.com/knarfS/smuview.git\n $ cd smuview\n $ mkdir build\n $ cd build\n $ cmake ../\n $ make\n\nFor installing SmuView:\n\n $ sudo make install\n\n\nCreating a source distribution package\n--------------------------------------\n\nIn order to build a source package begin with an unconfigured source tree.\n\n $ cd smuview\n $ mkdir dist\n $ cd dist\n $ cmake ../\n $ make package_source\n\n"
  },
  {
    "path": "NEWS",
    "content": "0.0.5 (2021-01-09)\n------------------\n\nFor a detailed list of changes, please see the git commit history.\n\n * Save and restore settings:\n   - Save/restore the size and position of the main window.\n   - Save/restore the shown views and their size/position for a specific device.\n   - Add a tab for curve color settings in the plot config dialog.\n   - Add -c cmd line parameter for don't restoring the settings.\n   - Save/restore the settings of the find and replace dialog.\n   - Save/restore last directory of the SmuScript tree.\n   - Save/restore the settings of the save signals dialog.\n * Enhance the Python API:\n   - Message Boxes and input dialoges for various data types.\n   - Return the view id when adding a new view.\n   - Improve bindings for time and x/y plots.\n   - Add function to set/change a curve color.\n   - Add function to set a custom signal name.\n   - Add function to set a custom plot curve name.\n   - Add functions for getting the available config keys.\n * More verbose device info in the about dialog.\n * Plot view:\n   - Make curve name editable and curve removable.\n   - Fix the axis lock labels.\n * Many improvements for the python editor.\n * Add a find and replace dialog for the python editor.\n * Add a time window option to combine analog values when saving signals (Thanks to Cymaphore).\n * Support for the new \"force_detect\" connection parameter of libsigrok.\n * Update libsigrok for new devices and bugfixes.\n * Update manual for SmuView.\n * Many more bug fixes and improvements.\n\n0.0.4 (2020-02-18)\n------------------\n\nFor a detailed list of changes, please see the git commit history.\n\n * Embed a Python interpreter to automate measurements and device control.\n * Add an editor to create and modify Python scripts.\n * Add a command line parameter to load and execute Python scripts.\n * Countless layout and GUI improvements, for example:\n   - Improve device control views.\n   - Replace the knob in the control views with a slider widget.\n   - Don't freeze the connection dialog when loading bluetooth LE devices.\n   - Ability to add a single signal to a XY-plot.\n   - Improve changing plot modes.\n   - Make the plot markers box position configurable.\n   - Nicer looking plot markers and better initial plot marker position.\n   - Support multiple signals per data table view.\n   - Add plot curve colors for various quantities and use random color for unknown quantities.\n   - Use embedded mono space font for the value displays.\n   - Stack views to save space.\n   - Settings for line and symbol style in the plot config dialog.\n   - Don't mess up the plot axis, when the signal value overflows.\n   - Add function to save plots as image.\n * Add class AnalogSampleSignal to store sample via Python.\n * Add a view to apply sequences to (device) controls like the output voltage.\n * Create a manual for SmuView.\n * Many bug fixes.\n\n0.0.3 (2019-04-04)\n------------------\n\nFor a detailed list of changes, please see the git commit history.\n\n * Various layout improvements\n * Revert \"feature\" that only one signal can be added to fixed channels\n * Plot view:\n   - Improve axis locking\n   - Improve axis scale updates\n   - Add the same signal only once\n * Commit spin box values only when enter is pressed or widget is leaved\n * Use a monospace font instead of the LCD font for various views\n * Add ConfigKey OFFSET\n\n0.0.2 (2019-03-21)\n------------------\n\nFor a detailed list of changes, please see the git commit history.\n\n * Add manpage\n * Add Fedora support (Thanks to gvegidy)\n * Plot view:\n   - Curve colors\n   - Better legend titles\n   - Add AC/DC to curve unit names (axis labels)\n   - Use one axis for data with the same quantity / quantity flags\n   - Fix non working mouse wheel over axis\n * Use linear interpolation to combine signals with different time intervals:\n   - Used in math channles\n   - Used in x/y-plot view\n * Use session start timestamp as start timestamp for channels and signals\n * Fix bug when listing ConfigKey SAMPLERATE\n * Fix bugs in ui datatype widgets\n * Add GenericControlView\n * Add support for the demo device\n * Initially populate serial connections in the connection dialog\n * Add \"addition with constant\" math channel\n * Add \"moving average\" math channel\n * New device tree\n * Move \"add device\" and \"add user device\" to new device tree\n * Add start/stop aquisition to device tab\n * Add disconnect device in device tree\n * Add clear signal to device tree\n * Add configurabel and config keys to device tree\n * Add support for interleaved samples (demo device and oscilloscopes)\n * Auto resize (device) combo boxes\n\n0.0.1 (2019-01-21)\n------------------\n\n * Initial release.\n"
  },
  {
    "path": "README",
    "content": "-------------------------------------------------------------------------------\nREADME\n-------------------------------------------------------------------------------\n\nThe sigrok project aims at creating a portable, cross-platform,\nFree/Libre/Open-Source signal analysis software suite that supports various\ndevice types (such as logic analyzers, oscilloscopes, multimeters, and more).\n\nSmuView is a Qt-based source measurement unit GUI for sigrok.\n\n\nStatus\n------\n\nSmuView is in a development state.\n\n\nCopyright and license\n---------------------\n\nSmuView is licensed under the terms of the GNU General Public License\n(GPL), version 3 or later.\n\nWhile some individual source code files are licensed under the GPLv2+, and\nsome files are licensed under the GPLv3+, this doesn't change the fact that\nthe program as a whole is licensed under the terms of the GPLv3+ (e.g. also\ndue to the fact that it links against GPLv3+ libraries).\n\nPlease see the individual source files for the full list of copyright holders.\n\n\nCopyright notices\n-----------------\n\nA copyright notice indicating a range of years, must be interpreted as having\nhad copyrightable material added in each of those years.\n\nExample:\n\n Copyright (C) 2010-2013 Contributor Name\n\nis to be interpreted as\n\n Copyright (C) 2010,2011,2012,2013 Contributor Name\n\n\nIcons authors and licenses\n--------------------------\n\nicons/information.svg: Bobarino\n  https://en.wikipedia.org/wiki/File:Information.svg\n\nAll other icons:\n  Oxygen Icon Theme, GNU LGPLv3\n\n\nFonts licenses\n--------------\n\nDejaVue Sana Mono:\n  Bitstream Vera Fonts Copyright and Arev Fonts Copyright\n\n\nMailing list\n------------\n\n https://lists.sourceforge.net/lists/listinfo/sigrok-devel\n\n\nIRC\n---\n\nYou can find the sigrok developers in the #sigrok IRC channel on Libera.Chat.\n\n\nWebsite\n-------\n\n https://github.com/knarfS/smuview\n\n"
  },
  {
    "path": "TODO",
    "content": "SmuView\n=======\n\nToDo clang-tidy\n---------------\n\n- Unify readability-implicit-bool-conversion (AllowPointerConditions) -> \" == nullptr\" and \" != nullptr\"\n- readability-redundant-member-init.IgnoreBaseInCopyConstructors = 1 not always working!\n- src/ui/datatypes/doubledisplay.hpp \tvoid setup_ui(); // TODO: widgets::MonoFontDisplay also has setup_ui()\n- src/ui/datatypes/basewidget.hpp Q_SLOTS redesign?\n- src/ui/datatypes/doubledisplay.hpp: setup_ui() override, b/c of widgets::MonoFontDisplay.\n- bugprone-narrowing-conversions: Maybe use boost convert_to<>() -> see util.cpp, format_time_minutes()\n\nToDo Release\n------------\n\n- Python binding for save CSV\n\nToDo clazy\n----------\n\n- Disabled due to false positives:\n\t- connect-non-signal\n\t- incorrect-emit\n\n\nToDo Scope\n----------\n\n- Fix ConfigKey sample_rate in UInt64Property::change_value(const QVariant qvar)\n\nToDo\n----\n\n- Use util::Timestamp?\n- last_value_, min_value_, max_value_ -> std::atomic!\n- Plot: Sampling\n- Mutex for aquisition_state_?\n- Save all data (gnuplot, octave, ...)\n\t- add a saveutil.cpp\n- Configurable:\n\t- default check for getable/setable in get/set functions without assert(false)?\n\t- add button to sink/source/demodmm/measurement-ControlViews to control non default config keys.\n\t- Check getable/setable/listable also in the properties\n\t- Enhance ThresholdControl widget (e.g for re:load pro). Maybe a dedicated property?\n\t\t- Dedicated SvDoubleSpinBox and SvBoolButton?\n- Breeze icons action/labplot-* for plots?\n- Get fixed quantity signals from channel(/channel group) (q/qf/u is set in ch.meaning at the beginning). Implement in sigrok!\n- Implement something like ch.meanings for config keys in sigrok, so smuview known the quantity/unit of config keys.\n- Start timestamp on_update() -> device ctor -> timestamp = .0\n- Start timestamp to session\n- Use new connect/disconnet variant whenever possible.\n- Use connect(obj, SIGNAL, SIGNAL) when possible (UIProxy/UIHelper)\n- Lookup: std::atomic, std::condition_variable, std::mutex\n- Remove \"const Session &session\" form ui::devices::* ctors and more??\n- Maybe: In all ctors \"Session &session\" -> \"const Session &session\"\n- Resize the DockWidgets/Views to their best sizes (value panels minimum, plot views max, ...). Maybe with QMainWindow->resizeDocks, SizePolicy in QDockWidget does not work....\n- boost::stacktrace, see pv\n- BaseDevice open()/close(): move aquisition stuff to HardwareDevice, move VirtualDevice stuff to BaseDevice\n- util.cpp: use cmath instead of math.h, but Timestamp is boost and only works with non std::?\n- Use AnalogBaseSignal in all(?) Channel classes, in View classes and in Plot classes\n- Remove Configurable and ConfigKey from data::properties::*\n- Session: shared_ptr or reference?\n- Missing msvcr100.dll (Windows Server 2016) SmuView/PulseView\n- DeviceTree: Button for expand/close all\n- Plot: Add gradient (dY/dX) to diff marker in plot marker box\n- Plot: Movable polt marker box. Maybe not possible b/c of missing stuff in qwt?\n- Plot: Highlight polt marker and plot marker box when mouse over (near by for marker)\n- Plot: Class for marker -> qwt curve tracker playground\n- SequenceView: Handle headers (order of columns, time abs/rel) in CSV\n- SequenceView: Handle units (ms, s, h, ...) in CSV\n- PlotView: Make resolution and dpi configurable when saving as image\n- Implement AnalogXYDataSignal (for python automatisation)? See scope support?\n- MonoFontDisplay/PowerPanelView: To small for neg. values (esp. W/Ah/Wh with 6632B). B/c of the decimal point?\n- Remove LCDDisplay?\n- Reduce/Simplyfy BaseDevice name methods\n- Bindings: Implement add_math_channel()\n- Can we inherit MathChannel from UserChannel?\n- Unify name of static (const) variables\n- Remove devicetab.hpp time_unit_\n- Cycle: replace BaseChannel::parent_device_ with device_id_, and so on....\n- main.cpp: Remove while loop.\n- AnalogTimeSignal: Move signal_start_timestamp_ to BaseSignal\n- *Signal: Clean up Signal classes\n- Add a way to change a channel/signal name in the GUI. Connect BaseSignal::name_changed() signal.\n- Add a way to change the plot curves that have a default color to the new default color configured in the PlotConfigDialog. E.g. with a singleton to connect a dialog to multiple curves from different plots.\n- Use singleton for SettingsManager instead of static methods?\n- Use deleteLater() instead of delete\n- Add AddPlotCurveDialog with channel and signals.\n- Manage axes in plot.cpp: Per Quantity and not per curve! Test: Remove all curves and add a new one....\n- UiHelper/UiProxy: Remove tab_id?\n- SettingsManager: Method for getting the QSettings object and maybe load an user defined QSettings-file.\n- example_multiplexer.py: Checkboxes in control views don't change.\n- Keyboard shortcuts (Ctrl-Q -> Close App, Ctrl-W -> Close tab)\n\nDone\n----\n\n- Check in connect.cpp if GPIB is part of build info (libsigrok -> backend.c)\n- Everey device must have its own session:\n\t1. Performance: With one sessions the aquisition functions are processed in sequence.\n\t\tThe HP 3478A f.e. takes for ever, and so the other devices to. There are NO parallel\n\t\trequests.\n\t2. Adding new device to a running session: Chicken/Egg problem! Dev->open() tries to\n\t\tstart aquisition, but device is not added to session yet (cxx binding).\n\t\tsession->add_device() tries to start aquisition, but device is not opened yet...\n\t3. Solves the sr_session_source_add_internal() dublicate key problem.\n\t4. Propably use the multidevice API functions from linux gpib in scpi_libgpib.c\n\n- Better detection of common_time_data_ (when in frame). Who is this possible when in\n\tinit_signal() and not afterwards when in feed_in()\n- QIcon (On/Off/Dis) -> Led: State(On/Off), Mode(En/Dis)\n- ValueControl implement is_value_setable_/is_value_getable_ and disable/enable controls\n- Save signals as CSV\n- Math channels (for Power, resistance, Wh, Ah)\n- Correlation between time bases (common, same count+fixed diff, \"random\") in (Analog)Data\n- Configurable:\n\t- list_config\n\t- default check for listable in list function without assert(false)\n\t- Remove unused specific functions\n\t- min/max/step in views when not listable\n\t- Add functions for datatypes -> determin what list_* function to use\n\t- make the sink/source/demodmm/measurement-ControlViews more generic\n\t- signals for controls (views) to work with processing\n\t- Cache stuff\n\t- Missing sigok::ConfigKey::OFFSET\n\t- get_mq / set_mq problem with template?\n\t- Move is_controllable() to tab/view? Make more generic... -> Generic is_controllable() function, and specialized function in viewhelper.cpp\n- namespace src/data/datautil.hpp\n- Refactor ui class members CamelCase -> _ _ _\n- Replace all \"    Q_OBJECT\" with \"\tQ_OBJECT\" (4 spaces -> 1 tab)\n- Replace other \"    \" -> \"\t\" (4 spaces -> 1 tab)\n- Autoscale plot. Plot doesn't always auto-update scale (rlp without load)\n- Remove \"hp3478a\" from gpib_libgpib_name_ and list all available names.\n- DataView: Add toolbar with \"StayAtBottom\" switchable action.\n- Remove all items in combo box when parent has changed and setup_ui() is recalled?\tsee ConfigKeyComboBox and ConfigurableComboBox\n- Refactore:\n\t- src/data/datautil.cpp -> src/data/\n\t- src/devices/deviceutil.cpp -> src/data/\n\t- src/devices/properties/ -> src/data/\n- DataView: add signal (into this table) action\n- static unsigned int device_counter; is changing\n- License headers are not the same\n- Session: move init to main.cpp\n- Bindings: Binding for setting the color of a plot curve\n- Bindings: Set name for new signal? e.g. f(x, y, name=nullptr)\n- Add \"E\" for detecting energy (Wh) channels\n- ValueDisplay SLOTS: CallByRef &?\n- Connection dialog thread\n- BaseChannel::add_signal(), L. 156, Korad PSU TODO\n- Save session\n- Segfault when closing/disconnet devices via UI/DevicesView\n\nWon't fix\n---------\n\n- QWT Multiaxis\n- Refactore:\n\t- src/data -> src/signals\n- src/data/properties/* on_value_changed(gvar) -> on_value_changed(const gvar)\n- *.hpp: virtual f_name() = 0; -> virtual f_name() = nullptr;\n\n\n\nlibsigrok\n=========\n\n- Add GPIB address to libgpib:conn as paramenter\n- Re:load Pro: when acquisition is running and we send a command (e.g. \"set xxx\"), there are 2 listeners (1st send_cmd() (<-serial_write_blocking) and 2nd handle_new_data() (<-serial_read_nonblocking))\n\t- Make devc->acquisition_running thread safe, bool is NOT thread safe!\n- Re:load Pro: when 2 responses are send fast afer each other, serial_read_nonblocking reads them both and the \\r\\n gets in beetween\n- Re:load Pro: sometimes only a ^M is send from the rlp\n- Re:load Pro: Sometimes the responses are mixed up (2 listeners??, Re:load Pro not keeping up??)\n- Re:load Pro: how to clear otp_active and uvc_active?\n- hp3478a: device isn't closed after stopping acquisition\n- scpi-pps: protocol.c -> scpi_pps_receive_data() uses double, but output (e.g. analog) and DF_ANALOG receivers use hardcoded float. Using sr_analog_encoding.unitsize and .is_float to define the datatype (and size) (.unitsize = sizeof(double) (or by lurchi_: .unitsize=8 + float is double)) in the receiver functions!\n- dev_acquisition_start() has to do first measurement (3478a, scpi-pps, reload(?)), because 1. DF_HEADER, 2. trigger measurement\n\t- If not: 3378a use scpi_cmd_resp() for use of mutex (wrt+read);\n- Can't add 2x scpi_libgpib devices: scpi_libgpib.c -> scpi_gpib_source_add() calls session.c -> sr_session_source_add() with fd = -1. This calls session.c -> sr_session_fd_source_add() with key = GINT_TO_POINTER(fd) and finally throws an error in session.c -> sr_session_source_add_internal() because \"Event source with key %p already exists.\"\n- scpi-pps: when in acquisition send one write \":MEAS:VOLT?;:MEAS:CURR?\" instead of 2 writes when possible\n- Add channel.meaning.mq, channel.meaning.mqflags, channel.meaning.unit (+channel.fixed) to PPU and load channels, to make it easy to init signals in smuview\n- Add missing units: sigrok::Unit::DECIBEL\n- scpi-pps/hp66xxx: Return always TRUE for OVP_ENABLED\n- hp3478a: spec_digits and enc_digits are used in the wrong way!\n- Fix UserDevice::open() and ::close() -> virtual in BaseDevice and empty in UserDevice\n\nWIP\n---\n\n- Change key naming (see load + psu wiki pages)\n\nDone\n----\n\n- Re:load Pro: send \"monitor 0\" when device is scaned to stop eventually running monitoring and version can be read properly\n- Re:load Pro: send \"monitor 0\" when device is closed\n- Wrong string to float/double conversion (because of locale settings):\n\t- dmm/m2110.c: 2x sscanf((const char *)buf, \"%f\", &val) == 1 -> sr_atof_ascii((const char *)buf, &val) == SR_OK\n\t- motech-lps-30x/protocol.c: sr_atod(devc->buf, &dbl)\n\t- dmm/metex14.c: sscanf((const char *)&valstr, \"%f\", result) -> sr_atof_ascii((const char *)&valstr, result)\n\t- scpi/scpi.c: sr_atod(response, scpi_response) -> sr_atod_ascii(response, scpi_response)\n- hp3478a: acquisition doesn't stop (sigrok-cli/smuview must be killed)\n- Tests for convertion (st_ascii_tod) for locale \"bugs\"\n- use mutex around ibwrt() and ibrd() (scpi_libgpib.c) per device, so they are thread safe\n- use mutex around scpi_cmd_resp() and scpi_cmd() (helpers.c), so when a request has a response, they are thread safe.\n- Mutex of scpi/helpers.c:\n\t- find all ocurrence of (sr_scpi_send_variadic(), sr_scpi_send(), scpi_cmd(), scpi_cmd_resp(), rigol_ds_config_set(), ....) and check if thread safe\n\t- Any functions missing, that need the mutex\n\t- Valid for SCPI over something something?\n- Mutex of scpi_libgpib: Add to other transport variants (serial, tcp, ...), if so is the mutex in scpi/helpers.c enough?\n- scpi-pps: add otp/ovp/ocp to pps_profiles[] (or to channel(group)) for HP 663xx\n- HP3478A: Implement SPoll,\n- Add missing confg key sigok::ConfigKey::OFFSET\n- Provied SR_DF_META packets for the Re:load Pro and the HP3478A for changed values/states (e.g. output switched on/off, ovp, otp, ...)\n- Add mqflags (AC/DC) to channel_group_spec for scpi-pps\n- scpi-pps/hp66xxB: Don't send SCPI_CMD_REMOTE and SCPI_CMD_LOCAL when GPIB is used. Will result in error 602.\n- scpi-pps/hp66xxx: Check if SPoll is faster than sending *STB? / FAULT?, if so implement and use SPoll (or SRQ) when using GPIB.\n- scpi-pps's have channel groups but options/keys/_lists_ (voltage_target, ...) apply to device\n- Add missing units: sigrok::Unit::JOULE, sigrok::Unit::AMPEREHOUR, sigrok::Unit::COULOMB\n- HP-3478A: R4W -> R2W not working\n\nWon't fix\n---------\n\n- Re:load Pro: Don't use \"monitor 200\", Instead \"read\" values every aquisition cycle with serial \"read line blocking\" and use a mutex around every read, write and write+read\n- Add missing units: sigrok::Unit::(HECTO)PASCAL\n\n\n\nDoku\n====\n\n- Link API to the psu and load wiki pages\n\n\n\nRe:load Pro Firmware\n====================\n\n- Add \"output\" command (returns \"on\" / \"off\") to determin in wich state the output is (git commit 448cf71, 558bc0e (part))\n- Send \"on\" / \"off\" when output state was changed at the device directly\n- Send \"uvlo xxx\" when undervoltage threshold was changed at the device directly (git commit 224ab62)\n"
  },
  {
    "path": "appimagecraft.yml",
    "content": "version: 1\n\nproject:\n  name: com.github.knarfs.smuview\n  #version_command: git describe --tags\n\nbuild:\n  cmake:\n    extra_variables:\n      # Taken from some other script\n      - DISABLE_WERROR=y\n      - ENABLE_TESTS=n\n      - CMAKE_EXPORT_COMPILE_COMMANDS=y\n      - PYBIND11_FINDPYTHON=ON\n    raw_environment:\n      # We have to pre-build some dependencies, and also want to ship our own custom Python environment\n      # the CMake build system has been instructed to load the dependencies via pkg-config\n      - PKG_CONFIG_PATH=\"$BUILD_DIR\"/deps/lib/pkgconfig:\"$BUILD_DIR\"/AppDir/usr/conda/lib/pkgconfig:\"$PKG_CONFIG_PATH\"\n      # Also we want to use a newer CMake version\n      - PATH=\"$BUILD_DIR\"/deps/bin:\"$PATH\"\n    script:\n      - |2\n        . AppDir/usr/conda/bin/activate\n        echo \"PKG_CONFIG_PATH (cmake): $PKG_CONFIG_PATH\"\n\nscripts:\n  pre_build:\n    - pushd \"$BUILD_DIR\"\n    - |2\n      # We need the Python environment before the build already, therefore we have to run the conda\n      # plugin manually before the build\n      #wget https://github.com/linuxdeploy/linuxdeploy-plugin-conda/raw/master/linuxdeploy-plugin-conda.sh\n      wget https://github.com/knarfS/linuxdeploy-plugin-conda/raw/master/linuxdeploy-plugin-conda.sh\n      # Skip the built-in cleanup as the build needs the development files (headers, libs, ...)\n      export CONDA_SKIP_CLEANUP=1\n      export CONDA_SKIP_ADJUST_PATHS=1\n      chmod +x linuxdeploy-plugin-conda.sh\n      ./linuxdeploy-plugin-conda.sh --appdir AppDir\n      . AppDir/usr/conda/bin/activate\n    - popd\n    - |2\n      # Build libserialport and libsigrok\n      for i in libserialport libsigrok; do\n          git clone --depth=1 git://sigrok.org/\"$i\"\n          pushd \"$i\"\n          ./autogen.sh\n          # Once libserialport is built, libsigrok can be linked against it\n          export PKG_CONFIG_PATH=\"$BUILD_DIR\"/deps/lib/pkgconfig:\"$PKG_CONFIG_PATH\"\n          echo \"PKG_CONFIG_PATH (pre_build): $PKG_CONFIG_PATH\"\n          ./configure --prefix=\"$BUILD_DIR\"/deps\n          make -j$(nprocs)\n          make install\n          popd\n      done\n\n  post_build:\n    - |2\n      # Cleanup conda\n      export CONDA_SKIP_INSTALL=1\n      export CONDA_SKIP_ADJUST_PATHS=0\n      ./linuxdeploy-plugin-conda.sh --appdir AppDir\n    - |2\n      # Generate AppRun.sh scrip\n      cat > \"$BUILD_DIR\"/AppRun.sh <<\\EOF\n      #! /bin/bash\n\n      # Load miniconda environment\n      . \"$APPDIR\"/usr/conda/etc/profile.d/conda.sh\n      conda activate\n\n      # Run SmuView\n      exec \"$APPDIR\"/usr/bin/smuview \"$@\"\n      EOF\n    - chmod +x \"$BUILD_DIR\"/AppRun.sh\n    - |2\n      # Set VERSION from CMake generated shell script\n      source cmake-build/contrib/config_version.sh\n      export VERSION=${SV_VERSION_STRING}\n\nappimage:\n  linuxdeploy:\n    plugins:\n      - qt\n    extra_args: --custom-apprun \"$BUILD_DIR\"/AppRun.sh\n    raw_environment:\n      - LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH\":\"$BUILD_DIR\"/deps/lib:\"$BUILD_DIR\"/AppDir/usr/conda/lib\n"
  },
  {
    "path": "config.h.in",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CONFIG_H\n#define CONFIG_H\n\n/* Application details */\n#define SV_TITLE \"@SV_TITLE@\"\n#define SV_BIN_NAME \"@PROJECT_NAME@\"\n\n/* SmuView version information */\n#define SV_VERSION_MAJOR @SV_VERSION_MAJOR@\n#define SV_VERSION_MINOR @SV_VERSION_MINOR@\n#define SV_VERSION_MICRO @SV_VERSION_MICRO@\n#define SV_VERSION_SUFFIX \"@SV_VERSION_SUFFIX@\"\n#define SV_VERSION_STRING \"@SV_VERSION_STRING@\"\n#define SV_MANUAL_VERSION \"@SV_MANUAL_VERSION@\"\n\n/* Platform properties */\n#cmakedefine HAVE_UNALIGNED_LITTLE_ENDIAN_ACCESS\n\n#define SV_GLIBMM_VERSION \"@SV_GLIBMM_VERSION@\"\n#define SV_PYBIND11_VERSION \"@SV_PYBIND11_VERSION@\"\n#define SV_PYTHON_VERSION \"@SV_PYTHON_VERSION@\"\n\n#endif // CONFIG_H\n"
  },
  {
    "path": "contrib/config_version.sh.in",
    "content": "#!/bin/sh\n##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software; you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation; either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program; if not, see <http://www.gnu.org/licenses/>.\n##\n\n# Application details\nexport SV_TITLE=\"@SV_TITLE@\"\nexport SV_BIN_NAME=\"@PROJECT_NAME@\"\n\n# SmuView version information\nexport SV_VERSION_MAJOR=@SV_VERSION_MAJOR@\nexport SV_VERSION_MINOR=@SV_VERSION_MINOR@\nexport SV_VERSION_MICRO=@SV_VERSION_MICRO@\nexport SV_VERSION_SUFFIX=\"@SV_VERSION_SUFFIX@\"\nexport SV_VERSION_STRING=\"@SV_VERSION_STRING@\"\nexport SV_MANUAL_VERSION=\"@SV_MANUAL_VERSION@\"\n\n# Platform properties\nexport SV_GLIBMM_VERSION=\"@SV_GLIBMM_VERSION@\"\nexport SV_PYBIND11_VERSION=\"@SV_PYBIND11_VERSION@\"\nexport SV_PYTHON_VERSION=\"@SV_PYTHON_VERSION@\"\n"
  },
  {
    "path": "contrib/org.sigrok.SmuView.appdata.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!-- Creative Commons CC0 1.0 Universal (CC0-1.0, Public Domain Dedication). -->\n<component type=\"desktop\">\n  <id>org.sigrok.SmuView.desktop</id>\n  <metadata_license>CC0-1.0</metadata_license>\n  <project_license>GPL-3.0+</project_license>\n  <name>SmuView</name>\n  <summary>Power supplies, electronic loads, multimeters and more</summary>\n  <description>\n    <p>SmuView is a Qt based source measure unit GUI for sigrok.</p>\n    <p>Features:</p>\n    <ul>\n      <li>Remote control devices</li>\n\t  <li>Data acquisition</li>\n      <li>Multiple devices at the same time</li>\n      <li>Math channels</li>\n      <li>Data export as CSV</li>\n    </ul>\n  </description>\n  <url type=\"homepage\">https://sigrok.org/wiki/SmuView</url>\n  <url type=\"bugtracker\">https://github.com/knarfS/smuview/issues</url>\n  <url type=\"faq\">https://sigrok.org/wiki/FAQ</url>\n  <screenshots>\n    <screenshot type=\"default\">\n      <image>https://sigrok.org/wimg/8/88/Sv_with_psu.png</image>\n    </screenshot>\n  </screenshots>\n  <provides>\n    <binary>smuview</binary>\n  </provides>\n  <launchable type=\"desktop-id\">org.sigrok.SmuView.desktop</launchable>\n  <content_rating type=\"oars-1.0\" />\n</component>\n"
  },
  {
    "path": "contrib/org.sigrok.SmuView.desktop",
    "content": "[Desktop Entry]\n# Creative Commons CC0 1.0 Universal (CC0-1.0, Public Domain Dedication).\nName=SmuView\nGenericName=A sigrok GUI for power supplies, loads and measurement devices\nCategories=Development;Electronics;\nComment=SmuView is a Qt based source measure unit GUI for sigrok.\nExec=smuview\nIcon=smuview\nType=Application\n"
  },
  {
    "path": "contrib/smuview.spec",
    "content": "# .SPEC-file to package RPMs for Fedora\n\n# download and build like this\n# (you need an rpmbuild dir, can be created with rpmdev-setuptree)\n#\n# cp smuview.spec $HOME/rpmbuild/SPECS\n# cd $HOME/rpmbuild\n# spectool -g -R SPECS/smuview.spec\n# rpmbuild -ba SPECS/smuview.spec\n\nSummary: SmuView is a Qt based source measure unit GUI for sigrok.\nName: smuview\nVersion: 0.0.1\nRelease: 1%{?dist}\nLicense: GPLv3\nURL: https://github.com/knarfS/smuview\nSource: https://github.com/knarfS/%{name}/archive/%{name}-%{version}.tar.gz\nBuildRequires: libsigrok-cxx-devel\nBuildRequires: qwt-qt5-devel\nBuildRequires: qt5-devel\nBuildRequires: qt5-qtsvg-devel\nBuildRequires: qt5-qtbase-devel\nBuildRequires: glibmm24-devel\nBuildRequires: boost-devel\nBuildRequires: rubygem-asciidoctor\n\n%description\nThe sigrok project aims at creating a portable, cross-platform,\nFree/Libre/Open-Source signal analysis software suite that supports various\ndevice types (such as logic analyzers, oscilloscopes, multimeters, and more).\n\nSmuView is a Qt-based source measurement unit GUI for sigrok.\n\n%prep\n%autosetup -n %{name}-%{name}-%{version}\n\n%build\n%cmake .\n%make_build\nmake manual-html\n\n%install\n%make_install\n\n%files\n%{!?_licensedir:%global license %%doc}\n%license COPYING\n%doc README INSTALL stuff\n%{_docdir}/%{name}/images/sv_with_load.png\n%{_docdir}/%{name}/manual.html\n%{_bindir}/smuview\n%{_mandir}/man1/%{name}.*\n%{_datadir}/applications/org.sigrok.SmuView.desktop\n%{_datadir}/metainfo/org.sigrok.SmuView.appdata.xml\n%{_datadir}/icons/hicolor/48x48/apps/smuview.png\n%{_datadir}/icons/hicolor/scalable/apps/smuview.svg\n"
  },
  {
    "path": "contrib/smuview_cross.nsi.in",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2013-2014 Uwe Hermann <uwe@hermann-uwe.de>\n## Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 3 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\n#\n# This file is used to create the Smuiew Windows installer via NSIS.\n# It is meant for use in a cross-compile setup (not for native builds).\n# See the 'sigrok-cross-mingw-smuview' script in the sigrok-util repo for details.\n#\n# NSIS documentation:\n# http://nsis.sourceforge.net/Docs/\n# http://nsis.sourceforge.net/Docs/Modern%20UI%202/Readme.html\n#\n\n# Include the \"Modern UI\" header, which gives us the usual Windows look-n-feel.\n!include \"MUI2.nsh\"\n\n\n# --- Global stuff ------------------------------------------------------------\n\n# Installer/product name.\nName \"SmuView\"\n\n# Filename of the installer executable.\n!if \"$%TARGET%\" != \"\"\n    !define TARGET \"-$%TARGET%\"\n!else\n    !define TARGET \"\"\n!endif\nOutFile \"SmuView-@SV_VERSION_STRING@${TARGET}-installer.exe\"\n\n# Where to install the application.\n!ifdef PE64\n\tInstallDir \"$PROGRAMFILES64\\sigrok\\SmuView\"\n!else\n\tInstallDir \"$PROGRAMFILES\\sigrok\\SmuView\"\n!endif\n\n# Request admin privileges for Windows Vista and Windows 7.\n# http://nsis.sourceforge.net/Docs/Chapter4.html\nRequestExecutionLevel admin\n\n# Local helper definitions.\n!define REGSTR \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SmuView\"\n\n\n# --- MUI interface configuration ---------------------------------------------\n\n# Use the following icon for the installer EXE file.\n!define MUI_ICON \"@PROJECT_SOURCE_DIR@/icons/smuview.ico\"\n\n# Show a nice image at the top of each installer page.\n!define MUI_HEADERIMAGE\n\n# Don't automatically go to the Finish page so the user can check the log.\n!define MUI_FINISHPAGE_NOAUTOCLOSE\n\n# Upon \"cancel\", ask the user if he really wants to abort the installer.\n!define MUI_ABORTWARNING\n\n# Don't force the user to accept the license, just show it.\n# Details: http://trac.videolan.org/vlc/ticket/3124\n!define MUI_LICENSEPAGE_BUTTON $(^NextBtn)\n!define MUI_LICENSEPAGE_TEXT_BOTTOM \"Click Next to continue.\"\n\n# Path where the cross-compiled sigrok tools and libraries are located.\n# Change this to where-ever you installed libsigrok.a and so on.\n!define CROSS \"@CMAKE_INSTALL_PREFIX@\"\n\n# Defines for WinAPI SHChangeNotify call.\n!define SHCNE_ASSOCCHANGED 0x8000000\n!define SHCNF_IDLIST 0\n\n\n# --- Functions/Macros --------------------------------------------------------\n\n# Inspired by http://nsis.sourceforge.net/Create_Internet_Shorcuts_during_installation\n!Macro \"CreateURL\" \"URLFile\" \"URLSite\" \"URLDesc\"\n\tWriteINIStr \"$INSTDIR\\${URLFile}.URL\" \"InternetShortcut\" \"URL\" \"${URLSite}\"\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\${URLFile}.lnk\" \"$INSTDIR\\${URLFile}.url\" \"\" \\\n\t\t\"$INSTDIR\\smuview.exe\" 0 \"SW_SHOWNORMAL\" \"\" \"${URLDesc}\"\n!MacroEnd\n\n\n# --- MUI pages ---------------------------------------------------------------\n\n# Show a nice \"Welcome to the ... Setup Wizard\" page.\n!insertmacro MUI_PAGE_WELCOME\n\n# Show the license of the project.\n!insertmacro MUI_PAGE_LICENSE \"@PROJECT_SOURCE_DIR@/COPYING\"\n\n# Show a screen which allows the user to select which components to install.\n!insertmacro MUI_PAGE_COMPONENTS\n\n# Allow the user to select a different install directory.\n!insertmacro MUI_PAGE_DIRECTORY\n\n# Perform the actual installation, i.e. install the files.\n!insertmacro MUI_PAGE_INSTFILES\n\n# Show a final \"We're done, click Finish to close this wizard\" message.\n!insertmacro MUI_PAGE_FINISH\n\n# Pages used for the uninstaller.\n!insertmacro MUI_UNPAGE_WELCOME\n!insertmacro MUI_UNPAGE_CONFIRM\n!insertmacro MUI_UNPAGE_INSTFILES\n!insertmacro MUI_UNPAGE_FINISH\n\n\n# --- MUI language files ------------------------------------------------------\n\n# Select an installer language (required!).\n!insertmacro MUI_LANGUAGE \"English\"\n\n\n# --- Default section ---------------------------------------------------------\n\nSection \"SmuView (required)\" Section1\n\t# This section is gray (can't be disabled) in the component list.\n\tSectionIn RO\n\n\t# Install the file(s) specified below into the specified directory.\n\tSetOutPath \"$INSTDIR\"\n\n\t# License file.\n\tFile \"@PROJECT_SOURCE_DIR@/COPYING\"\n\n\t# SmuView (statically linked, includes all libs).\n\tFile \"${CROSS}/bin/smuview.exe\"\n\n\t# Zadig (used for installing WinUSB drivers).\n\tFile \"${CROSS}/zadig.exe\"\n\tFile \"${CROSS}/zadig_xp.exe\"\n\n\t# Python\n\tFile \"${CROSS}/python34.dll\"\n\tFile \"${CROSS}/python34.zip\"\n\n\tSetOutPath \"$INSTDIR\\share\"\n\n\t# Generate the uninstaller executable.\n\tWriteUninstaller \"$INSTDIR\\Uninstall.exe\"\n\n\t# Create a sub-directory in the start menu.\n\tCreateDirectory \"$SMPROGRAMS\\sigrok\"\n\tCreateDirectory \"$SMPROGRAMS\\sigrok\\SmuView\"\n\n\t# Create a shortcut for the SmuView application.\n\tSetOutPath \"$INSTDIR\"\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView.lnk\" \\\n\t\t\"$INSTDIR\\smuview.exe\" \"\" \"$INSTDIR\\smuview.exe\" \\\n\t\t0 SW_SHOWNORMAL \\\n\t\t\"\" \"Open-source, portable sigrok GUI\"\n\n\t# Create a shortcut for the SmuView application running in debug mode.\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView (Debug).lnk\" \\\n\t\t\"$INSTDIR\\smuview.exe\" \"-l 5\" \"$INSTDIR\\smuview.exe\" \\\n\t\t0 SW_SHOWNORMAL \\\n\t\t\"\" \"Open-source, portable sigrok GUI (debug log level)\"\n\n\t# Create a shortcut for the uninstaller.\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\Uninstall SmuView.lnk\" \\\n\t\t\"$INSTDIR\\Uninstall.exe\" \"\" \"$INSTDIR\\Uninstall.exe\" 0 \\\n\t\tSW_SHOWNORMAL \"\" \"Uninstall SmuView\"\n\n\t# Create a shortcut for the Zadig executable.\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\Zadig (SmuView).lnk\" \\\n\t\t\"$INSTDIR\\zadig.exe\" \"\" \"$INSTDIR\\zadig.exe\" 0 \\\n\t\tSW_SHOWNORMAL \"\" \"Zadig (SmuView)\"\n\n\t# Create a shortcut for the Zadig executable (for Win XP).\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\Zadig (SmuView, Win XP).lnk\" \\\n\t\t\"$INSTDIR\\zadig_xp.exe\" \"\" \"$INSTDIR\\zadig_xp.exe\" 0 \\\n\t\tSW_SHOWNORMAL \"\" \"Zadig (SmuView, Win XP)\"\n\n\t# Create shortcuts to the HTML and PDF manuals, respectively.\n\t!InsertMacro \"CreateURL\" \"SmuView HTML manual\" \"https://knarfs.github.io/doc/smuview/@SV_MANUAL_VERSION@/manual.html\" \"SmuView HTML manual\"\n\t!InsertMacro \"CreateURL\" \"SmuView PDF manual\" \"https://knarfs.github.io/doc/smuview/@SV_MANUAL_VERSION@/manual.pdf\" \"SmuView PDF manual\"\n\t!InsertMacro \"CreateURL\" \"SmuView Python Bindings API\" \"https://knarfs.github.io/doc/smuview/@SV_MANUAL_VERSION@/python_bindings_api.html\" \"SmuView Python Bindings API\"\n\n\t# Create registry keys for \"Add/remove programs\" in the control panel.\n\tWriteRegStr HKLM \"${REGSTR}\" \"DisplayName\" \"SmuView\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"UninstallString\" \\\n\t\t\"$\\\"$INSTDIR\\Uninstall.exe$\\\"\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"InstallLocation\" \"$\\\"$INSTDIR$\\\"\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"DisplayIcon\" \\\n\t\t\"$\\\"$INSTDIR\\smuview.ico$\\\"\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"Publisher\" \"sigrok\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"HelpLink\" \\\n\t\t\"http://sigrok.org/wiki/SmuView\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"URLUpdateInfo\" \\\n\t\t\"https://github.com/knarfS/smuview/releases\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"URLInfoAbout\" \"https://github.com/knarfS/smuview\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"DisplayVersion\" \"@SV_VERSION_STRING@\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"Contact\" \\\n\t\t\"sigrok-devel@lists.sourceforge.org\"\n\tWriteRegStr HKLM \"${REGSTR}\" \"Comments\" \\\n\t\t\"This is a Qt based sigrok GUI.\"\n\n\t# Display \"Remove\" instead of \"Modify/Remove\" in the control panel.\n\tWriteRegDWORD HKLM \"${REGSTR}\" \"NoModify\" 1\n\tWriteRegDWORD HKLM \"${REGSTR}\" \"NoRepair\" 1\nSectionEnd\n\nSection \"Example scripts\" Section2\n\t# Example smuscript *.py files.\n\tSetOutPath \"$INSTDIR\\examples\"\n\n\tFile \"${CROSS}/share/smuscript/example_characterize_battery.py\"\n\tFile \"${CROSS}/share/smuscript/example_characterize_psu.py\"\n\tFile \"${CROSS}/share/smuscript/example_characterize_psu_2.py\"\n\tFile \"${CROSS}/share/smuscript/example_device_properties.py\"\n\tFile \"${CROSS}/share/smuscript/example_ui.py\"\n\tFile \"${CROSS}/share/smuscript/example_user_channel.py\"\n\tFile \"${CROSS}/share/smuscript/generate_documentation.py\"\n\tFile \"${CROSS}/share/smuscript/python_version.py\"\n\n\t# Create a shortcut for the example scripts folder.\n\tCreateShortCut \"$SMPROGRAMS\\sigrok\\SmuView\\Examples (SmuScript).lnk\" \\\n\t\t\"$INSTDIR\\examples\" \"\" \"$INSTDIR\\examples\" 0 \\\n\t\tSW_SHOWNORMAL \"\" \"\"\nSectionEnd\n\n\n# --- Uninstaller section -----------------------------------------------------\n\nSection \"Uninstall\"\n\t# Always delete the uninstaller first (yes, this really works).\n\tDelete \"$INSTDIR\\Uninstall.exe\"\n\n\t# Delete the application, the application data, and related libs.\n\tDelete \"$INSTDIR\\COPYING\"\n\tDelete \"$INSTDIR\\smuview.exe\"\n\tDelete \"$INSTDIR\\zadig.exe\"\n\tDelete \"$INSTDIR\\zadig_xp.exe\"\n\tDelete \"$INSTDIR\\python34.dll\"\n\tDelete \"$INSTDIR\\python34.zip\"\n\n\t# Delete the URL files for the manual.\n\t#Delete \"$INSTDIR\\SmuView HTML manual.url\"\n\t#Delete \"$INSTDIR\\SmuView PDF manual.url\"\n\n\t# Delete the example *.py files.\n\tRMDir /r \"$INSTDIR\\examples\\*\"\n\n\t# Delete the install directory and its sub-directories.\n\tRMDir \"$INSTDIR\\share\"\n\tRMDir \"$INSTDIR\\examples\"\n\tRMDir \"$INSTDIR\"\n\n\t# Delete the links from the start menu.\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView.lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView (Debug).lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\Uninstall SmuView.lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\Zadig (SmuView).lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\Zadig (SmuView, Win XP).lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\Examples (SmuScript).lnk\"\n\n\t# Delete the links to the manual.\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView HTML manual.lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView PDF manual.lnk\"\n\tDelete \"$SMPROGRAMS\\sigrok\\SmuView\\SmuView Python Bindings API.lnk\"\n\n\t# Delete the sub-directory in the start menu.\n\tRMDir \"$SMPROGRAMS\\sigrok\\SmuView\"\n\tRMDir \"$SMPROGRAMS\\sigrok\"\n\n\t# Delete the registry key(s).\n\tDeleteRegKey HKLM \"${REGSTR}\"\nSectionEnd\n\n\n# --- Component selection section descriptions --------------------------------\n\nLangString DESC_Section1 ${LANG_ENGLISH} \"This installs the SmuView sigrok GUI and all required libraries.\"\nLangString DESC_Section2 ${LANG_ENGLISH} \"This installs some example script files (SmuScript) that you can use to try out the features SmuView has to offer.\"\n\n!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN\n\t!insertmacro MUI_DESCRIPTION_TEXT ${Section1} $(DESC_Section1)\n\t!insertmacro MUI_DESCRIPTION_TEXT ${Section2} $(DESC_Section2)\n!insertmacro MUI_FUNCTION_DESCRIPTION_END\n"
  },
  {
    "path": "cppcheck-suppressions.xml",
    "content": "<?xml version=\"1.0\"?>\n<suppressions>\n\n\t<!-- Exclude Paths -->\n\t<suppress>\n\t\t<id>*</id>\n\t\t<fileName>*/build/*</fileName>\n\t</suppress>\n\t<suppress>\n\t\t<id>*</id>\n\t\t<fileName>*/external/pybind11_2.11_dev1/*</fileName>\n\t</suppress>\n\t<suppress>\n\t\t<id>*</id>\n\t\t<fileName>*/external/pybind11_2.9.2/*</fileName>\n\t</suppress>\n\t<suppress>\n\t\t<id>*</id>\n\t\t<fileName>*/external/QCodeEditor/*</fileName>\n\t</suppress>\n\t<suppress>\n\t\t<id>*</id>\n\t\t<fileName>*/external/QtFindReplaceDialog/*</fileName>\n\t</suppress>\n\n\t<!-- False positives, maybe because of forward declaration. -->\n\t<suppress>\n\t\t<id>unsafeClassCanLeak</id>\n\t</suppress>\n\n\t<!-- False positive? -->\n\t<suppress>\n\t\t<id>nullPointer</id>\n\t\t<fileName>*/devices/configurable.hpp</fileName>\n\t\t<symbolName>configurable</symbolName>\n\t</suppress>\n\n\t<!-- There are many functions in SmuView that are not used yet. -->\n\t<suppress>\n\t\t<id>unusedFunction</id>\n\t</suppress>\n\n\t<!-- Maybe add this checks later: -->\n\t<suppress>\n\t\t<id>useStlAlgorithm</id>\n\t</suppress>\n\t<suppress>\n\t\t<id>useInitializationList</id>\n\t</suppress>\n\t<suppress>\n\t\t<id>uninitMemberVar</id>\n\t</suppress>\n\n</suppressions>\n"
  },
  {
    "path": "doc/smuview.1",
    "content": ".TH SMUVIEW 1 \"Januray 6, 2021\"\n.SH \"NAME\"\nSmuView \\- Qt-based source measure unit GUI for sigrok\n.SH \"SYNOPSIS\"\n.B smuview \\fR[\\fBOPTIONS\\fR]\n.SH \"DESCRIPTION\"\n.B SmuView\nis a cross-platform Qt-based GUI for the\n.B sigrok\nsoftware suite for test and measurement equipment such as power supplies,\nelectronic loads, multimeters and more.\n.SH \"OPTIONS\"\n.B SmuView\nhas very few command line options, as most configuration elements are\navailable from the GUI itself.\n.TP\n.BR \"\\-l, \\-\\-loglevel \" <level>\nSet the libsigrok loglevel. The higher the number, the more debug output will\nbe printed. The dafault loglevel is 2 (Warnings), valid loglevels are:\n.sp\n\\fB0\\fP   None\n.br\n\\fB1\\fP   Error\n.br\n\\fB2\\fP   Warnings\n.br\n\\fB3\\fP   Informational\n.br\n\\fB4\\fP   Debug\n.br\n\\fB5\\fP   Spew\n.TP\n.B \"\\-h, \\-?, \\-\\-help\"\nShow a help text and exit.\n.TP\n.B \"\\-V, \\-\\-version\"\nShow version information and exit.\n.TP\n.BR \"\\-d, \\-\\-driver \" <drivername>\nSpecify the capture device to connect to.\n.TP\n.BR \"\\-D, \\-\\-dont\\-scan \"\nUsually SmuView automatically scans all drivers to find suitable\ndevices during program startup. This option disables the auto-scan.\n.TP\n.B \"\\-c, \\-\\-clean\"\nDon't restore previous settings (like views, position and size) on startup.\n.TP\n.B \\-\\-driver\nUsers can either specify the\noption to pick a device at startup, or interactively scan for devices\nafter SmuView has finished starting up.\n.TP\n.BR \"\\-s, \\-\\-script \" <path_to_smuscript>\nSpecify the SmuScript to load and execute.\n.SH \"EXIT STATUS\"\n.B SmuView\nexits with 0 on success, 1 on most failures.\n.SH \"SEE ALSO\"\n\\fBsigrok\\-cli\\fP(1)\n.SH \"BUGS\"\nPlease report any bugs via Github\n.RB \"(\" https://github.com/knarfS/smuview/issues \")\"\nor on the sigrok\\-devel mailing list\n.RB \"(\" sigrok\\-devel@lists.souceforge.net \").\"\n.SH \"LICENSE\"\n.B SmuView\nis covered by the GNU General Public License (GPL), version 3 or later.\n.SH \"AUTHORS\"\nPlease see the individual source code files.\n.PP\nThis manual page was written by Frank Stettner <frank\\-stettner@gmx.net>.\nIt is licensed under the terms of the GNU GPL (version 3 or later).\n"
  },
  {
    "path": "doc/smuview_python_bindings.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1\" />\n<meta name=\"generator\" content=\"pdoc 0.9.3.dev7+g49b7773\" />\n<title>smuview API documentation</title>\n<meta name=\"description\" content=\"The SmuView 0.0.5-git-64e7b9d Python bindings …\" />\n<link rel=\"preload stylesheet\" as=\"style\" href=\"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css\" integrity=\"sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=\" crossorigin>\n<link rel=\"preload stylesheet\" as=\"style\" href=\"https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css\" integrity=\"sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=\" crossorigin>\n<link rel=\"stylesheet preload\" as=\"style\" href=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css\" crossorigin>\n<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^=\"header-\"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>\n<style media=\"screen and (min-width: 700px)\">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>\n<style media=\"print\">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:\" (\" attr(href) \")\";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:\" (\" attr(title) \")\"}.ir a:after,a[href^=\"javascript:\"]:after,a[href^=\"#\"]:after{content:\"\"}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>\n<script defer src=\"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js\" integrity=\"sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=\" crossorigin></script>\n<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>\n</head>\n<body>\n<main>\n<article id=\"content\">\n<header>\n<h1 class=\"title\">Module <code>smuview</code></h1>\n</header>\n<section id=\"section-intro\">\n<p>The SmuView 0.0.5-git-64e7b9d Python bindings.</p>\n<p>The Python bindings are a scripting extension for SmuView to automate, setup and control complex or repetitive measurements, to process the incoming data and to create a standardized user interface for those measurements.</p>\n<p>The smuview module offers two default object instances: <code><a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a></code> and <code><a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a></code>.\nThe <code><a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a></code> object gives access to already connected devices or connects new devices. The returned device object can then be used to read data from the device or control the device.\nThe <code><a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a></code> object instance is used to modify the user interface, for example adding tabs or views.</p>\n<p>Here is a short example that connects the HP 3378A DMM via GPIB, reads a sample and creates the default tab for the device:</p>\n<pre><code>import smuview\nimport time\n\n# Connect device.\ndmm_dev = Session.connect_device(&quot;hp-3478a:conn=libgpib/hp3478a&quot;)[0]\n# Sleep 1s to give the devices the chance to create signals.\ntime.sleep(1)\n# Get last sample from channel P1.\nsample = dmm_dev.channels()[&quot;P1&quot;].actual_signal().get_last_sample(True)\nprint(sample)\n\n# Add default tab for the DMM device.\nUiProxy.add_device_tab(dmm_dev)\n</code></pre>\n<p>For more example scripts, please have a look into the <code>smuscript</code> folder.</p>\n</section>\n<section>\n</section>\n<section>\n</section>\n<section>\n</section>\n<section>\n<h2 class=\"section-title\" id=\"header-classes\">Classes</h2>\n<dl>\n<dt id=\"smuview.AnalogSampleSignal\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">AnalogSampleSignal</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>A signal with key-value pairs.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.AnalogSampleSignal.get_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_sample</span></span>(<span>self: <a title=\"smuview.AnalogSampleSignal\" href=\"#smuview.AnalogSampleSignal\">AnalogSampleSignal</a>, pos: int) ‑> Tuple[int, float]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the sample for the given position.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>pos</code></strong> :&ensp;<code>int</code></dt>\n<dd>The position/number of the sample.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Tuple[int, float]</code></dt>\n<dd>The sample with 1. the key and 2. the sample value.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.AnalogSampleSignal.push_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">push_sample</span></span>(<span>self: <a title=\"smuview.AnalogSampleSignal\" href=\"#smuview.AnalogSampleSignal\">AnalogSampleSignal</a>, sample: None, pos: int, unit_size: int, digits: int, decimal_places: int)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Push a new sample to the signal.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>sample</code></strong> :&ensp;<code>float</code> or <code>double</code></dt>\n<dd>The sample value.</dd>\n<dt><strong><code>pos</code></strong> :&ensp;<code>int</code></dt>\n<dd>The key (position) of the new sample.</dd>\n<dt><strong><code>unit_size</code></strong> :&ensp;<code>int</code></dt>\n<dd>The size of the floating point data type (float=4, double=8) for the <code>sample</code> argument.</dd>\n<dt><strong><code>digits</code></strong> :&ensp;<code>int</code></dt>\n<dd>The total number of digits.</dd>\n<dt><strong><code>decimal_places</code></strong> :&ensp;<code>int</code></dt>\n<dd>The number of decimal places.</dd>\n</dl></div>\n</dd>\n</dl>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseSignal.name\" href=\"#smuview.BaseSignal.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.sample_count\" href=\"#smuview.BaseSignal.sample_count\">sample_count</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.set_name\" href=\"#smuview.BaseSignal.set_name\">set_name</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n<dt id=\"smuview.AnalogTimeSignal\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">AnalogTimeSignal</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>A signal with time-value pairs.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.AnalogTimeSignal.get_last_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_last_sample</span></span>(<span>self: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>, relative_time: bool) ‑> Tuple[float, float]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the last sample of the signal.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>relative_time</code></strong> :&ensp;<code>bool</code></dt>\n<dd>When <code>True</code>, the returned timestamp is relative to the start of the SmuView session.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Tuple[float, float]</code></dt>\n<dd>The sample with 1. timestamp in milliseconds and 2. the sample value.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.AnalogTimeSignal.get_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_sample</span></span>(<span>self: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>, pos: int, relative_time: bool) ‑> Tuple[float, float]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the sample at the given position.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>pos</code></strong> :&ensp;<code>int</code></dt>\n<dd>The position/number of the sample.</dd>\n<dt><strong><code>relative_time</code></strong> :&ensp;<code>bool</code></dt>\n<dd>When <code>True</code>, the returned timestamp is relative to the start of the SmuView session.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Tuple[float, float]</code></dt>\n<dd>The sample with 1. timestamp in milliseconds and 2. the sample value.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.AnalogTimeSignal.push_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">push_sample</span></span>(<span>self: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>, sample: None, timestamp: float, unit_size: int, digits: int, decimal_places: int)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Push a new sample to the signal.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>sample</code></strong> :&ensp;<code>float</code> or <code>double</code></dt>\n<dd>The sample value.</dd>\n<dt><strong><code>timestamp</code></strong> :&ensp;<code>float</code></dt>\n<dd>The absolute timestamp in milliseconds.</dd>\n<dt><strong><code>unit_size</code></strong> :&ensp;<code>int</code></dt>\n<dd>The size of the floating point data type (float=4, double=8) for the <code>sample</code> argument.</dd>\n<dt><strong><code>digits</code></strong> :&ensp;<code>int</code></dt>\n<dd>The total number of digits.</dd>\n<dt><strong><code>decimal_places</code></strong> :&ensp;<code>int</code></dt>\n<dd>The number of decimal places.</dd>\n</dl></div>\n</dd>\n</dl>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseSignal.name\" href=\"#smuview.BaseSignal.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.sample_count\" href=\"#smuview.BaseSignal.sample_count\">sample_count</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.set_name\" href=\"#smuview.BaseSignal.set_name\">set_name</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n<dt id=\"smuview.BaseChannel\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">BaseChannel</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>The base class for all channel types.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Subclasses</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.HardwareChannel\" href=\"#smuview.HardwareChannel\">HardwareChannel</a></li>\n<li><a title=\"smuview.UserChannel\" href=\"#smuview.UserChannel\">UserChannel</a></li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.BaseChannel.actual_signal\"><code class=\"name flex\">\n<span>def <span class=\"ident\">actual_signal</span></span>(<span>self: <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>) ‑> <a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the actual signal of the channel.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></code></dt>\n<dd>The actual signal object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseChannel.add_signal\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_signal</span></span>(<span>self: <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>, quantity: <a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a>, quantity_flags: Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>], unit: <a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a>, custom_name: str = '') ‑> <a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a new signal to the channel.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>quantity</code></strong> :&ensp;<code><a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a></code></dt>\n<dd>The <code><a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a></code> of the new signal.</dd>\n<dt><strong><code>quantity_flags</code></strong> :&ensp;<code>Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>]</code></dt>\n<dd>The <code><a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a></code>s of the new signal.</dd>\n<dt><strong><code>unit</code></strong> :&ensp;<code><a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a></code></dt>\n<dd>The <code><a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a></code> of the new signal.</dd>\n<dt><strong><code>custom_name</code></strong> :&ensp;<code>str</code></dt>\n<dd>A custom name for the new signal. If empty (default), the signal name will be automatically generated.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></code></dt>\n<dd>The new signal object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseChannel.name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">name</span></span>(<span>self: <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the name of the channel.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The name of the channel.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseChannel.signals\"><code class=\"name flex\">\n<span>def <span class=\"ident\">signals</span></span>(<span>self: <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>) ‑> List[<a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all signals of the channel.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>List[<a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a>]</code></dt>\n<dd>All signals of the channel.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.BaseDevice\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">BaseDevice</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>The base class for all device types.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Subclasses</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.HardwareDevice\" href=\"#smuview.HardwareDevice\">HardwareDevice</a></li>\n<li><a title=\"smuview.UserDevice\" href=\"#smuview.UserDevice\">UserDevice</a></li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.BaseDevice.add_user_channel\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_user_channel</span></span>(<span>self: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>, channel_name: str, channel_group_name: str) ‑> <a title=\"smuview.UserChannel\" href=\"#smuview.UserChannel\">UserChannel</a></span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a new user channel to the device.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>channel_name</code></strong> :&ensp;<code>str</code></dt>\n<dd>The name of the new user channel.</dd>\n<dt><strong><code>channel_group_name</code></strong> :&ensp;<code>str</code></dt>\n<dd>The name of the channel group where to create the user channel. Can be empty.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code><a title=\"smuview.UserChannel\" href=\"#smuview.UserChannel\">UserChannel</a></code></dt>\n<dd>The new user channel object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseDevice.channels\"><code class=\"name flex\">\n<span>def <span class=\"ident\">channels</span></span>(<span>self: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>) ‑> Dict[str, <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all channels of the device.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Dict[str, <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>]</code></dt>\n<dd>A Dict where the key is the id of the channel and the value is the channel object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseDevice.configurables\"><code class=\"name flex\">\n<span>def <span class=\"ident\">configurables</span></span>(<span>self: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>) ‑> Dict[str, <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all configurables of the device.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Dict[str, <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>]</code></dt>\n<dd>A Dict where the key is the id of the <code><a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a></code> and the value is the <code><a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a></code> object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseDevice.id\"><code class=\"name flex\">\n<span>def <span class=\"ident\">id</span></span>(<span>self: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the unique id of the device.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the device.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseDevice.name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">name</span></span>(<span>self: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the name of the device.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The name of the device.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.BaseSignal\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">BaseSignal</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>The base class for all signal types.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Subclasses</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.AnalogSampleSignal\" href=\"#smuview.AnalogSampleSignal\">AnalogSampleSignal</a></li>\n<li><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.BaseSignal.name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">name</span></span>(<span>self: <a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the name of the signal.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The name of the signal.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseSignal.sample_count\"><code class=\"name flex\">\n<span>def <span class=\"ident\">sample_count</span></span>(<span>self: <a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a>) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the number of samples of the signal.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>int</code></dt>\n<dd>The number of samples.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.BaseSignal.set_name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">set_name</span></span>(<span>self: <a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a>, arg0: str)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Set a custom name for the signal.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>custom_name</code></strong> :&ensp;<code>str</code></dt>\n<dd>A custom name for the signal. If empty, the signal name will be automatically generated.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.ConfigKey\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">ConfigKey</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all available config keys for controlling a device.</p>\n<p><strong>init</strong>(self: smuview.ConfigKey, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.ConfigKey.ADCPowerlineCycles\"><code class=\"name\">var <span class=\"ident\">ADCPowerlineCycles</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Number of powerline cycles for ADC integration time.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Amplitude\"><code class=\"name\">var <span class=\"ident\">Amplitude</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Amplitude of a source without strictly-defined <code><a title=\"smuview.ConfigKey.MeasuredQuantity\" href=\"#smuview.ConfigKey.MeasuredQuantity\">ConfigKey.MeasuredQuantity</a></code>.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Averaging\"><code class=\"name\">var <span class=\"ident\">Averaging</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Averaging.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.AvgSamples\"><code class=\"name\">var <span class=\"ident\">AvgSamples</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The number of samples to be averaged over.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.BufferSize\"><code class=\"name\">var <span class=\"ident\">BufferSize</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Buffer size.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.CaptureFile\"><code class=\"name\">var <span class=\"ident\">CaptureFile</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The capturefile to inject.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.CaptureRatio\"><code class=\"name\">var <span class=\"ident\">CaptureRatio</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The pre/post-trigger capture ratio.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.CaptureUnitSize\"><code class=\"name\">var <span class=\"ident\">CaptureUnitSize</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The capturefile unit size.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.CenterFrequency\"><code class=\"name\">var <span class=\"ident\">CenterFrequency</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Center frequency.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.ChannelConfig\"><code class=\"name\">var <span class=\"ident\">ChannelConfig</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Channel configuration.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.ClockEdge\"><code class=\"name\">var <span class=\"ident\">ClockEdge</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Choice of clock edge for external clock (<code>r</code> or <code>f</code>).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Coupling\"><code class=\"name\">var <span class=\"ident\">Coupling</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Coupling.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Current\"><code class=\"name\">var <span class=\"ident\">Current</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Current current.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.CurrentLimit\"><code class=\"name\">var <span class=\"ident\">CurrentLimit</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Current limit.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.DataLog\"><code class=\"name\">var <span class=\"ident\">DataLog</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The device has internal storage, into which data is logged.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.DataSource\"><code class=\"name\">var <span class=\"ident\">DataSource</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Data source for acquisition.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.DeviceMode\"><code class=\"name\">var <span class=\"ident\">DeviceMode</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device mode for multi-function devices.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Digits\"><code class=\"name\">var <span class=\"ident\">Digits</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The number of digits (e.g. for a DMM).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Enabled\"><code class=\"name\">var <span class=\"ident\">Enabled</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Enabling/disabling a channel (group).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.EquivCircuitModel\"><code class=\"name\">var <span class=\"ident\">EquivCircuitModel</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Equivalent circuit model.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.ExternalClock\"><code class=\"name\">var <span class=\"ident\">ExternalClock</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Using an external clock.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.ExternalClockSource\"><code class=\"name\">var <span class=\"ident\">ExternalClockSource</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Which external clock source to use if the device supports multiple external clock channels.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Filter\"><code class=\"name\">var <span class=\"ident\">Filter</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Filter.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.HighResolution\"><code class=\"name\">var <span class=\"ident\">HighResolution</span></code></dt>\n<dd>\n<div class=\"desc\"><p>High resolution mode.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.HoldMax\"><code class=\"name\">var <span class=\"ident\">HoldMax</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Max hold mode.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.HoldMin\"><code class=\"name\">var <span class=\"ident\">HoldMin</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Min hold mode.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.HorizTriggerPos\"><code class=\"name\">var <span class=\"ident\">HorizTriggerPos</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Horizontal trigger position.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.LogicThreshold\"><code class=\"name\">var <span class=\"ident\">LogicThreshold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Logic threshold: predefined levels (<code>TTL</code>, <code>ECL</code>, <code>CMOS</code>, etc).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.LogicThresholdCustom\"><code class=\"name\">var <span class=\"ident\">LogicThresholdCustom</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Logic threshold: custom numerical value.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.MeasuredQuantity\"><code class=\"name\">var <span class=\"ident\">MeasuredQuantity</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Measured quantity.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.NumAnalogChannels\"><code class=\"name\">var <span class=\"ident\">NumAnalogChannels</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The number of analog channels.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.NumHDiv\"><code class=\"name\">var <span class=\"ident\">NumHDiv</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Number of horizontal divisions, as related to <code><a title=\"smuview.ConfigKey.TimeBase\" href=\"#smuview.ConfigKey.TimeBase\">ConfigKey.TimeBase</a></code>.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.NumLogicChannels\"><code class=\"name\">var <span class=\"ident\">NumLogicChannels</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The number of logic channels.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.NumVDiv\"><code class=\"name\">var <span class=\"ident\">NumVDiv</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Number of vertical divisions, as related to <code><a title=\"smuview.ConfigKey.VDiv\" href=\"#smuview.ConfigKey.VDiv\">ConfigKey.VDiv</a></code>.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Offset\"><code class=\"name\">var <span class=\"ident\">Offset</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Offset of a source without strictly-defined <code><a title=\"smuview.ConfigKey.MeasuredQuantity\" href=\"#smuview.ConfigKey.MeasuredQuantity\">ConfigKey.MeasuredQuantity</a></code>.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OutputFrequency\"><code class=\"name\">var <span class=\"ident\">OutputFrequency</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Output frequency in Hz.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OutputFrequencyTarget\"><code class=\"name\">var <span class=\"ident\">OutputFrequencyTarget</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Output frequency target in Hz.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverCurrentProtectionActive\"><code class=\"name\">var <span class=\"ident\">OverCurrentProtectionActive</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Status of over current protection (OCP).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverCurrentProtectionEnabled\"><code class=\"name\">var <span class=\"ident\">OverCurrentProtectionEnabled</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Enabling/disable\nover current protection (OCP) feature.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverCurrentProtectionThreshold\"><code class=\"name\">var <span class=\"ident\">OverCurrentProtectionThreshold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Over current protection (OCP) threshold.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverTemperatureProtectionActive\"><code class=\"name\">var <span class=\"ident\">OverTemperatureProtectionActive</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Status of over temperature protection (OTP).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverTemperatureProtectionEnabled\"><code class=\"name\">var <span class=\"ident\">OverTemperatureProtectionEnabled</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Enabling/disable over temperature protection (OTP) feature.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverVoltageProtectionActive\"><code class=\"name\">var <span class=\"ident\">OverVoltageProtectionActive</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Status of over voltage protection (OVP).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverVoltageProtectionEnabled\"><code class=\"name\">var <span class=\"ident\">OverVoltageProtectionEnabled</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Enabling/disable over voltage protection (OVP) feature.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.OverVoltageProtectionThreshold\"><code class=\"name\">var <span class=\"ident\">OverVoltageProtectionThreshold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Over voltage protection (OVP) threshold.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.PatternMode\"><code class=\"name\">var <span class=\"ident\">PatternMode</span></code></dt>\n<dd>\n<div class=\"desc\"><p>A pattern (pattern generator mode).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.PeakDetection\"><code class=\"name\">var <span class=\"ident\">PeakDetection</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Peak detection.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.PowerOff\"><code class=\"name\">var <span class=\"ident\">PowerOff</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Power off the device.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.ProbeFactor\"><code class=\"name\">var <span class=\"ident\">ProbeFactor</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The probe factor.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.RLE\"><code class=\"name\">var <span class=\"ident\">RLE</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Run-length encoding (RLE).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Range\"><code class=\"name\">var <span class=\"ident\">Range</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The measurement range of a DMM or the output range of a power supply.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Regulation\"><code class=\"name\">var <span class=\"ident\">Regulation</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Channel regulation. <code>CV</code>, <code>CC</code> or <code>UR</code>, denoting constant voltage, constant current or unregulated. <code>CC-</code> denotes a power supply in current sink mode (e.g. HP 66xxB). An empty string is used when there is no regulation, e.g. the output is disabled.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.SampleInterval\"><code class=\"name\">var <span class=\"ident\">SampleInterval</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The sample interval, in ms.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Samplerate\"><code class=\"name\">var <span class=\"ident\">Samplerate</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The samplerate, in Hz.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.SessionFile\"><code class=\"name\">var <span class=\"ident\">SessionFile</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Session filename.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.SplMeasurementRange\"><code class=\"name\">var <span class=\"ident\">SplMeasurementRange</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level measurement range.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.SplWeightFreq\"><code class=\"name\">var <span class=\"ident\">SplWeightFreq</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level frequency weighting.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.SplWeightTime\"><code class=\"name\">var <span class=\"ident\">SplWeightTime</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level time weighting.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Swap\"><code class=\"name\">var <span class=\"ident\">Swap</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Swapping channels.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TestMode\"><code class=\"name\">var <span class=\"ident\">TestMode</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Self test mode.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TimeBase\"><code class=\"name\">var <span class=\"ident\">TimeBase</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Time base.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TriggerLevel\"><code class=\"name\">var <span class=\"ident\">TriggerLevel</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Trigger level.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TriggerMatch\"><code class=\"name\">var <span class=\"ident\">TriggerMatch</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Trigger matches.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TriggerPattern\"><code class=\"name\">var <span class=\"ident\">TriggerPattern</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The pattern for the logic trigger.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TriggerSlope\"><code class=\"name\">var <span class=\"ident\">TriggerSlope</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The trigger slope.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.TriggerSource\"><code class=\"name\">var <span class=\"ident\">TriggerSource</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Trigger source.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.UnderVoltageConditionActive\"><code class=\"name\">var <span class=\"ident\">UnderVoltageConditionActive</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Status of under voltage condition (UVC).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.UnderVoltageConditionEnabled\"><code class=\"name\">var <span class=\"ident\">UnderVoltageConditionEnabled</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Enabling/disable under voltage condition (UVC) feature.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.UnderVoltageConditionThreshold\"><code class=\"name\">var <span class=\"ident\">UnderVoltageConditionThreshold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Under voltage condition threshold (UVC).</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Unknown\"><code class=\"name\">var <span class=\"ident\">Unknown</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unknown config key.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.VDiv\"><code class=\"name\">var <span class=\"ident\">VDiv</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Volts/div.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.Voltage\"><code class=\"name\">var <span class=\"ident\">Voltage</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Current voltage.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.VoltageTarget\"><code class=\"name\">var <span class=\"ident\">VoltageTarget</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Maximum target voltage.</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.VoltageThreshold\"><code class=\"name\">var <span class=\"ident\">VoltageThreshold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Logic low-high threshold range.</p></div>\n</dd>\n</dl>\n<h3>Static methods</h3>\n<dl>\n<dt id=\"smuview.ConfigKey.get_data_type\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_data_type</span></span>(<span>config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> <a title=\"smuview.DataType\" href=\"#smuview.DataType\">DataType</a></span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Helper function to get the data type for a config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The config key.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code><a title=\"smuview.DataType\" href=\"#smuview.DataType\">DataType</a></code></dt>\n<dd>The data type of the config key.</dd>\n</dl></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.ConfigKey.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.ConfigKey.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.ConfigKey) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.Configurable\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">Configurable</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>A configurable for controlling a device with config keys.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.Configurable.get_bool_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_bool_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return a boolean value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>bool</code></dt>\n<dd>The bool value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.get_double_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_double_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> float</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return a double value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>float</code></dt>\n<dd>The float value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.get_int_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_int_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return an integer value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>int</code></dt>\n<dd>The int value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.get_measured_quantity_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_measured_quantity_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> Tuple[<a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a>, Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>]]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return a measured quantity value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Tuple[<a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a>, Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>]]</code></dt>\n<dd>The measured quantity value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.get_string_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_string_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return a string value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The string value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.get_uint_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">get_uint_config</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>, config_key: <a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return an unsigned integer value from the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to get.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>int</code></dt>\n<dd>The (unsigned) int value of the config key.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.getable_configs\"><code class=\"name flex\">\n<span>def <span class=\"ident\">getable_configs</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>) ‑> Set[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all getable config keys.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>List[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</code></dt>\n<dd>All getable config keys.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.listable_configs\"><code class=\"name flex\">\n<span>def <span class=\"ident\">listable_configs</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>) ‑> Set[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all listable config keys.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>List[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</code></dt>\n<dd>All listable config keys.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">name</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return the name of the configurable.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The name of the configurable.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.set_config\"><code class=\"name flex\">\n<span>def <span class=\"ident\">set_config</span></span>(<span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Overloaded function.</p>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: bool) -&gt; None</li>\n</ol>\n<p>Set a boolean value to the given config key.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>bool</code></dt>\n<dd>The bool value to set.</dd>\n</dl>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: int) -&gt; None</li>\n</ol>\n<p>Set an integer value to the given config key.</p>\n<h2 id=\"parameters_1\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>int</code></dt>\n<dd>The int value to set.</dd>\n</dl>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: int) -&gt; None</li>\n</ol>\n<p>Set an unsigned integer value to the given config key.</p>\n<h2 id=\"parameters_2\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>int</code></dt>\n<dd>The (unsigned) int value to set.</dd>\n</dl>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: float) -&gt; None</li>\n</ol>\n<p>Set a double value to the given config key.</p>\n<h2 id=\"parameters_3\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>float</code></dt>\n<dd>The float value to set.</dd>\n</dl>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: str) -&gt; None</li>\n</ol>\n<p>Set a string value to the given config key.</p>\n<h2 id=\"parameters_4\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>str</code></dt>\n<dd>The string value to set.</dd>\n</dl>\n<ol>\n<li>set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: Tuple[smuview.Quantity, Set[smuview.QuantityFlag]]) -&gt; None</li>\n</ol>\n<p>Set a measured quantity value to the given config key.</p>\n<h2 id=\"parameters_5\">Parameters</h2>\n<dl>\n<dt><strong><code>config_key</code></strong> :&ensp;<code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></dt>\n<dd>The <code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code> to set.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>Tuple[<a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a>, Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>]]</code></dt>\n<dd>The measured quantity value to set.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Configurable.setable_configs\"><code class=\"name flex\">\n<span>def <span class=\"ident\">setable_configs</span></span>(<span>self: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>) ‑> Set[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all setable config keys.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>List[<a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a>]</code></dt>\n<dd>All setable config keys.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.DataType\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">DataType</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all available data types.</p>\n<p><strong>init</strong>(self: smuview.DataType, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.DataType.Bool\"><code class=\"name\">var <span class=\"ident\">Bool</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Bool</p></div>\n</dd>\n<dt id=\"smuview.DataType.Double\"><code class=\"name\">var <span class=\"ident\">Double</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Double</p></div>\n</dd>\n<dt id=\"smuview.DataType.DoubleRange\"><code class=\"name\">var <span class=\"ident\">DoubleRange</span></code></dt>\n<dd>\n<div class=\"desc\"><p>DoubleRange</p></div>\n</dd>\n<dt id=\"smuview.DataType.Int32\"><code class=\"name\">var <span class=\"ident\">Int32</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Int32</p></div>\n</dd>\n<dt id=\"smuview.DataType.KeyValue\"><code class=\"name\">var <span class=\"ident\">KeyValue</span></code></dt>\n<dd>\n<div class=\"desc\"><p>KeyValue</p></div>\n</dd>\n<dt id=\"smuview.DataType.MQ\"><code class=\"name\">var <span class=\"ident\">MQ</span></code></dt>\n<dd>\n<div class=\"desc\"><p>MQ</p></div>\n</dd>\n<dt id=\"smuview.DataType.RationalPeriod\"><code class=\"name\">var <span class=\"ident\">RationalPeriod</span></code></dt>\n<dd>\n<div class=\"desc\"><p>RationalPeriod</p></div>\n</dd>\n<dt id=\"smuview.DataType.RationalVolt\"><code class=\"name\">var <span class=\"ident\">RationalVolt</span></code></dt>\n<dd>\n<div class=\"desc\"><p>RationalVolt</p></div>\n</dd>\n<dt id=\"smuview.DataType.String\"><code class=\"name\">var <span class=\"ident\">String</span></code></dt>\n<dd>\n<div class=\"desc\"><p>String</p></div>\n</dd>\n<dt id=\"smuview.DataType.UInt64\"><code class=\"name\">var <span class=\"ident\">UInt64</span></code></dt>\n<dd>\n<div class=\"desc\"><p>UInt64</p></div>\n</dd>\n<dt id=\"smuview.DataType.UInt64Range\"><code class=\"name\">var <span class=\"ident\">UInt64Range</span></code></dt>\n<dd>\n<div class=\"desc\"><p>UInt64Range</p></div>\n</dd>\n<dt id=\"smuview.DataType.Unknown\"><code class=\"name\">var <span class=\"ident\">Unknown</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unknown</p></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.DataType.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.DataType.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.DataType) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.DockArea\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">DockArea</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all possible docking locations for a view.</p>\n<p><strong>init</strong>(self: smuview.DockArea, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.DockArea.BottomDockArea\"><code class=\"name\">var <span class=\"ident\">BottomDockArea</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Dock to the bottom dock area.</p></div>\n</dd>\n<dt id=\"smuview.DockArea.LeftDocktArea\"><code class=\"name\">var <span class=\"ident\">LeftDocktArea</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Dock to the left dock area.</p></div>\n</dd>\n<dt id=\"smuview.DockArea.RightDockArea\"><code class=\"name\">var <span class=\"ident\">RightDockArea</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Dock to the right dock area.</p></div>\n</dd>\n<dt id=\"smuview.DockArea.TopDockArea\"><code class=\"name\">var <span class=\"ident\">TopDockArea</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Dock to the top dock area.</p></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.DockArea.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.DockArea.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.DockArea) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.HardwareChannel\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">HardwareChannel</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>An actual hardware channel</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseChannel.actual_signal\" href=\"#smuview.BaseChannel.actual_signal\">actual_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.add_signal\" href=\"#smuview.BaseChannel.add_signal\">add_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.name\" href=\"#smuview.BaseChannel.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.signals\" href=\"#smuview.BaseChannel.signals\">signals</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n<dt id=\"smuview.HardwareDevice\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">HardwareDevice</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>An actual hardware device.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseDevice.add_user_channel\" href=\"#smuview.BaseDevice.add_user_channel\">add_user_channel</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.channels\" href=\"#smuview.BaseDevice.channels\">channels</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.configurables\" href=\"#smuview.BaseDevice.configurables\">configurables</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.id\" href=\"#smuview.BaseDevice.id\">id</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.name\" href=\"#smuview.BaseDevice.name\">name</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n<dt id=\"smuview.PyStreamBuf\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">PyStreamBuf</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Redirect all Python output to a SmuView console. This class is for internal SmuView use only!</p>\n<p><strong>init</strong>(self: smuview.PyStreamBuf, arg0: str, arg1: str) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.PyStreamBuf.closed\"><code class=\"name\">var <span class=\"ident\">closed</span></code></dt>\n<dd>\n<div class=\"desc\"><p><code>True</code> if the stream is closed.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.encoding\"><code class=\"name\">var <span class=\"ident\">encoding</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The name of the encoding that is used.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.errors\"><code class=\"name\">var <span class=\"ident\">errors</span></code></dt>\n<dd>\n<div class=\"desc\"><p>The error setting of the decoder or encoder.</p></div>\n</dd>\n</dl>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.PyStreamBuf.close\"><code class=\"name flex\">\n<span>def <span class=\"ident\">close</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Flush and close this stream.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.fileno\"><code class=\"name flex\">\n<span>def <span class=\"ident\">fileno</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> doesn't use a file descriptor.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.flush\"><code class=\"name flex\">\n<span>def <span class=\"ident\">flush</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Flush the write buffers of the stream.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.isatty\"><code class=\"name flex\">\n<span>def <span class=\"ident\">isatty</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Always returns <code>False</code>.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.read\"><code class=\"name flex\">\n<span>def <span class=\"ident\">read</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, size: int) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is write only.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.readable\"><code class=\"name flex\">\n<span>def <span class=\"ident\">readable</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Always returns <code>False</code>.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.readline\"><code class=\"name flex\">\n<span>def <span class=\"ident\">readline</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, size: int) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is write only.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.readlines\"><code class=\"name flex\">\n<span>def <span class=\"ident\">readlines</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, hint: int) ‑> List[str]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is write only.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.seek\"><code class=\"name flex\">\n<span>def <span class=\"ident\">seek</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, offset: int, whence: int) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is not seekable.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.seekable\"><code class=\"name flex\">\n<span>def <span class=\"ident\">seekable</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Always returns <code>False</code>. <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is not seekable atm.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.tell\"><code class=\"name flex\">\n<span>def <span class=\"ident\">tell</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is not seekable.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.truncate\"><code class=\"name flex\">\n<span>def <span class=\"ident\">truncate</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, size: int) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Raises an <code>OSError</code>, because <code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code> is not seekable.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.writable\"><code class=\"name flex\">\n<span>def <span class=\"ident\">writable</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Always return <code>True</code>.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.write\"><code class=\"name flex\">\n<span>def <span class=\"ident\">write</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, s: str) ‑> int</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Write the string <code>s</code> to the stream and return the number of characters written.</p></div>\n</dd>\n<dt id=\"smuview.PyStreamBuf.writelines\"><code class=\"name flex\">\n<span>def <span class=\"ident\">writelines</span></span>(<span>self: <a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a>, lines: List[str])</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Write a list of lines to the stream.</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.Quantity\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">Quantity</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all available quantities.</p>\n<p><strong>init</strong>(self: smuview.Quantity, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.Quantity.ApparentPower\"><code class=\"name\">var <span class=\"ident\">ApparentPower</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Apparent power</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Capacitance\"><code class=\"name\">var <span class=\"ident\">Capacitance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Capacitance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.CarbonMonoxide\"><code class=\"name\">var <span class=\"ident\">CarbonMonoxide</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Carbon monoxide</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Conductance\"><code class=\"name\">var <span class=\"ident\">Conductance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Conductance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Continuity\"><code class=\"name\">var <span class=\"ident\">Continuity</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Continuity</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Count\"><code class=\"name\">var <span class=\"ident\">Count</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Count</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Current\"><code class=\"name\">var <span class=\"ident\">Current</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Current</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Difference\"><code class=\"name\">var <span class=\"ident\">Difference</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Difference from reference value.</p></div>\n</dd>\n<dt id=\"smuview.Quantity.DissipationFactor\"><code class=\"name\">var <span class=\"ident\">DissipationFactor</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Dissipation factor</p></div>\n</dd>\n<dt id=\"smuview.Quantity.DutyCyle\"><code class=\"name\">var <span class=\"ident\">DutyCyle</span></code></dt>\n<dd>\n<div class=\"desc\"><p>DutyCyle</p></div>\n</dd>\n<dt id=\"smuview.Quantity.ElectricCharge\"><code class=\"name\">var <span class=\"ident\">ElectricCharge</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Electric charge</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Energy\"><code class=\"name\">var <span class=\"ident\">Energy</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Energy (also Work)</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Frequency\"><code class=\"name\">var <span class=\"ident\">Frequency</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Frequency</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Gain\"><code class=\"name\">var <span class=\"ident\">Gain</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Gain (a transistor's gain, or hFE, for example).</p></div>\n</dd>\n<dt id=\"smuview.Quantity.HarmonicRatio\"><code class=\"name\">var <span class=\"ident\">HarmonicRatio</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Harmonic ratio</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Mass\"><code class=\"name\">var <span class=\"ident\">Mass</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Mass</p></div>\n</dd>\n<dt id=\"smuview.Quantity.ParallelCapacitance\"><code class=\"name\">var <span class=\"ident\">ParallelCapacitance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Parallel capacitance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.ParallelInductance\"><code class=\"name\">var <span class=\"ident\">ParallelInductance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Parallel inductance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.ParallelResistance\"><code class=\"name\">var <span class=\"ident\">ParallelResistance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Parallel resistance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.PhaseAngle\"><code class=\"name\">var <span class=\"ident\">PhaseAngle</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Phase angle</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Power\"><code class=\"name\">var <span class=\"ident\">Power</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Electrical power, usually in W, or dBm.</p></div>\n</dd>\n<dt id=\"smuview.Quantity.PowerFactor\"><code class=\"name\">var <span class=\"ident\">PowerFactor</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Power factor</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Pressure\"><code class=\"name\">var <span class=\"ident\">Pressure</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Pressure</p></div>\n</dd>\n<dt id=\"smuview.Quantity.PulseWidth\"><code class=\"name\">var <span class=\"ident\">PulseWidth</span></code></dt>\n<dd>\n<div class=\"desc\"><p>PulseWidth</p></div>\n</dd>\n<dt id=\"smuview.Quantity.QualityFactor\"><code class=\"name\">var <span class=\"ident\">QualityFactor</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Quality factor</p></div>\n</dd>\n<dt id=\"smuview.Quantity.RelativeHumidity\"><code class=\"name\">var <span class=\"ident\">RelativeHumidity</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Relative humidity</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Resistance\"><code class=\"name\">var <span class=\"ident\">Resistance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Resistance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.SeriesCapacitance\"><code class=\"name\">var <span class=\"ident\">SeriesCapacitance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Series capacitance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.SeriesInductance\"><code class=\"name\">var <span class=\"ident\">SeriesInductance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Series inductance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.SeriesResistance\"><code class=\"name\">var <span class=\"ident\">SeriesResistance</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Series resistance</p></div>\n</dd>\n<dt id=\"smuview.Quantity.SoundPressureLevel\"><code class=\"name\">var <span class=\"ident\">SoundPressureLevel</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Logarithmic representation of sound pressure relative to a reference value.</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Temperature\"><code class=\"name\">var <span class=\"ident\">Temperature</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Temperature</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Time\"><code class=\"name\">var <span class=\"ident\">Time</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Time</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Unknown\"><code class=\"name\">var <span class=\"ident\">Unknown</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unknown</p></div>\n</dd>\n<dt id=\"smuview.Quantity.Voltage\"><code class=\"name\">var <span class=\"ident\">Voltage</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Voltage</p></div>\n</dd>\n<dt id=\"smuview.Quantity.WindSpeed\"><code class=\"name\">var <span class=\"ident\">WindSpeed</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Wind speed</p></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.Quantity.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.Quantity.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.Quantity) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.QuantityFlag\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">QuantityFlag</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all available quantity flags.</p>\n<p><strong>init</strong>(self: smuview.QuantityFlag, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.QuantityFlag.AC\"><code class=\"name\">var <span class=\"ident\">AC</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Alternating current.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Autorange\"><code class=\"name\">var <span class=\"ident\">Autorange</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in autoranging mode.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Avg\"><code class=\"name\">var <span class=\"ident\">Avg</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in average mode, averaging upon each new value.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.DC\"><code class=\"name\">var <span class=\"ident\">DC</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Direct current.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Diode\"><code class=\"name\">var <span class=\"ident\">Diode</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Value is voltage drop across a diode, or NAN.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Duration\"><code class=\"name\">var <span class=\"ident\">Duration</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Time is duration (as opposed to epoch, &hellip;).</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.FourWire\"><code class=\"name\">var <span class=\"ident\">FourWire</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in 4-wire mode.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Hold\"><code class=\"name\">var <span class=\"ident\">Hold</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in hold mode (repeating the last measurement).</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Max\"><code class=\"name\">var <span class=\"ident\">Max</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in max mode, only updating upon a new max value.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Min\"><code class=\"name\">var <span class=\"ident\">Min</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in min mode, only updating upon a new min value.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.RMS\"><code class=\"name\">var <span class=\"ident\">RMS</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Root mean square (RMS).</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Reference\"><code class=\"name\">var <span class=\"ident\">Reference</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Reference value shown.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Relative\"><code class=\"name\">var <span class=\"ident\">Relative</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Device is in relative mode.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplFreqWeightA\"><code class=\"name\">var <span class=\"ident\">SplFreqWeightA</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level is A-weighted in the frequency domain, according to IEC 61672:2003.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplFreqWeightC\"><code class=\"name\">var <span class=\"ident\">SplFreqWeightC</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level is C-weighted in the frequency domain, according to IEC 61672:2003.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplFreqWeightFlat\"><code class=\"name\">var <span class=\"ident\">SplFreqWeightFlat</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level is not weighted in the frequency domain, albeit without standards-defined low and high frequency limits.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplFreqWeightZ\"><code class=\"name\">var <span class=\"ident\">SplFreqWeightZ</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level is Z-weighted.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplLAT\"><code class=\"name\">var <span class=\"ident\">SplLAT</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level is time-averaged (LAT), also known as Equivalent Continuous A-weighted Sound Level (LEQ).</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplPctOverAlarm\"><code class=\"name\">var <span class=\"ident\">SplPctOverAlarm</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level represented as a percentage of measurements that were over a preset alarm level.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplTimeWeightF\"><code class=\"name\">var <span class=\"ident\">SplTimeWeightF</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level measurement is F-weighted (125ms) in the time domain.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.SplTimeWeightS\"><code class=\"name\">var <span class=\"ident\">SplTimeWeightS</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Sound pressure level measurement is S-weighted (1s) in the time domain.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Unknown\"><code class=\"name\">var <span class=\"ident\">Unknown</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unknown quantity flag.</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.Unstable\"><code class=\"name\">var <span class=\"ident\">Unstable</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unstable value (hasn't settled yet).</p></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.QuantityFlag.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.QuantityFlag.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.QuantityFlag) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.Session\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">Session</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>The SmuView <code><a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a></code> class for accessing the actual state of the application.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.Session.add_user_device\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_user_device</span></span>(<span>self: <a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a>) ‑> <a title=\"smuview.UserDevice\" href=\"#smuview.UserDevice\">UserDevice</a></span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Create a new user device.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code><a title=\"smuview.UserDevice\" href=\"#smuview.UserDevice\">UserDevice</a></code></dt>\n<dd>The created user device object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Session.connect_device\"><code class=\"name flex\">\n<span>def <span class=\"ident\">connect_device</span></span>(<span>self: <a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a>, conn_str: str) ‑> List[<a title=\"smuview.HardwareDevice\" href=\"#smuview.HardwareDevice\">HardwareDevice</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Connect a new device. For some devices (like DMMs) you may want to wait a fixed time, until the first sample has arrived and an <code>AnalogSignal</code> object has been created. Example:</p>\n<pre><code>import smuview\nimport time\n\n# Connect device.\ndmm_dev = Session.connect_device(&quot;hp-3478a:conn=libgpib/hp3478a&quot;)[0]\n# Sleep 1s to give the devices the chance to create signals.\ntime.sleep(1)\n</code></pre>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>conn_str</code></strong> :&ensp;<code>str</code></dt>\n<dd>The connection string. See <a href=\"https://sigrok.org/wiki/Connection_parameters\">https://sigrok.org/wiki/Connection_parameters</a></dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>List[<a title=\"smuview.HardwareDevice\" href=\"#smuview.HardwareDevice\">HardwareDevice</a>]</code></dt>\n<dd>A List with the newly connected device objects.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.Session.devices\"><code class=\"name flex\">\n<span>def <span class=\"ident\">devices</span></span>(<span>self: <a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a>) ‑> Dict[str, <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>]</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Return all connected devices.</p>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>Dict[str, <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>]</code></dt>\n<dd>A Dict where the key is the device id and the value is the device object.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.UiProxy\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">UiProxy</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Helper class for accessing the UI.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.UiProxy.add_control_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_control_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, area: <a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a>, configurable: <a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a control view for a configurable to the given tab.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n<dt><strong><code>configurable</code></strong> :&ensp;<code><a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a></code></dt>\n<dd>The <code><a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a></code> object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_curve_to_time_plot_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_curve_to_time_plot_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a signal to the given time plot view.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the time plot view.</dd>\n<dt><strong><code>signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The signal object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new curve or empty if the curve couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_curve_to_xy_plot_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_curve_to_xy_plot_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, x_signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>, y_signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add x/y signals to the given x/y plot view.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the x/y plot view.</dd>\n<dt><strong><code>x_signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The x signal object.</dd>\n<dt><strong><code>y_signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The y signal object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new curve or empty if the curve couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_data_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_data_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, area: <a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a>, signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a data view for a signal to the given tab.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n<dt><strong><code>signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The signal object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_device_tab\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_device_tab</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, device: <a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a device tab with standard view for a device to the UI.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>device</code></strong> :&ensp;<code><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></code></dt>\n<dd>The device object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new tab or empty if the tab couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_power_panel_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_power_panel_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, area: <a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a>, voltage_signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>, current_signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a power panel view for a voltage and a current signal to the given tab.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n<dt><strong><code>voltage_signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The voltage signal object.</dd>\n<dt><strong><code>current_signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The current signal object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_signal_to_data_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_signal_to_data_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, signal: <a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a>)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a signal to the given data view.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the data view.</dd>\n<dt><strong><code>signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The signal object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_time_plot_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_time_plot_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, area: <a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a time plot view to the given tab. Use <a href=\"UiProxy.set_channel_to_time_plot_view\"><code>UiProxy.set_channel_to_time_plot_view()</code></a> to set a channel to the plot view or use <a href=\"UiProxy.add_curve_to_time_plot_view\"><code>UiProxy.add_curve_to_time_plot_view()</code></a> to set a signal to the plot view.\nWhen you have set a channel to the plot, new curves will be automatically created, when the channel changes (e.g. for multimeters when switching functions).</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_value_panel_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_value_panel_view</span></span>(<span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Overloaded function.</p>\n<ol>\n<li>add_value_panel_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, channel: smuview.BaseChannel) -&gt; str</li>\n</ol>\n<p>Add a value panel view for a channel to the given tab.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n<dt><strong><code>channel</code></strong> :&ensp;<code><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></code></dt>\n<dd>The channel object.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n<dt><code>2. add_value_panel_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, signal: smuview.AnalogTimeSignal) -&gt; str</code></dt>\n<dd>&nbsp;</dd>\n</dl>\n<p>Add a value panel view for a signal to the given tab.</p>\n<h2 id=\"parameters_1\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n<dt><strong><code>signal</code></strong> :&ensp;<code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></dt>\n<dd>The signal object.</dd>\n</dl>\n<h2 id=\"returns_1\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.add_xy_plot_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">add_xy_plot_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, area: <a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a>) ‑> str</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Add a x/y plot view for two signals to the given tab. Use <a href=\"UiProxy.add_curve_to_xy_plot_view\"><code>UiProxy.add_curve_to_xy_plot_view()</code></a> to add a new curve (a set of two signals) to the plot view.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>area</code></strong> :&ensp;<code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></dt>\n<dd>Where to put the new view.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code></dt>\n<dd>The id of the new view or empty if the view couldn't be added.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.set_channel_to_time_plot_view\"><code class=\"name flex\">\n<span>def <span class=\"ident\">set_channel_to_time_plot_view</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, channel: <a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a>)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Set a channel to the given time plot view. New curves will be automatically created, when the channel changes (e.g. for multimeters when switching functions).</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the time plot view.</dd>\n<dt><strong><code>channel</code></strong> :&ensp;<code><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></code></dt>\n<dd>The channel object.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.set_curve_color\"><code class=\"name flex\">\n<span>def <span class=\"ident\">set_curve_color</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, curve_id: str, color: Tuple[int, int, int])</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Set the color of the given curve.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the plot view.</dd>\n<dt><strong><code>curve_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the curve.</dd>\n<dt><strong><code>color</code></strong> :&ensp;<code>Tuple[int, int, int]</code></dt>\n<dd>The color for the curve as a Tuple with the RGB values.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.set_curve_name\"><code class=\"name flex\">\n<span>def <span class=\"ident\">set_curve_name</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, tab_id: str, view_id: str, curve_id: str, name: str)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Set the name of the given curve.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>tab_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the tab.</dd>\n<dt><strong><code>view_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the plot view.</dd>\n<dt><strong><code>curve_id</code></strong> :&ensp;<code>str</code></dt>\n<dd>The id of the curve.</dd>\n<dt><strong><code>name</code></strong> :&ensp;<code>str</code></dt>\n<dd>The name for the curve.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.show_double_input_dialog\"><code class=\"name flex\">\n<span>def <span class=\"ident\">show_double_input_dialog</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, title: str, label: str, value: float = 0.0, decimals: int = 1, step: float = 0.1, min: float = 2.2250738585072014e-308, max: float = 1.7976931348623157e+308) ‑> object</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Show a dialog window to get a float value from the user. It returns the entered float value or <code>None</code> if the Cancel button was pressed.</p>\n<p>Only has effect if the used Qt version is equal or greater than 5.10!</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>title</code></strong> :&ensp;<code>str</code></dt>\n<dd>The window title of the input dialog.</dd>\n<dt><strong><code>label</code></strong> :&ensp;<code>str</code></dt>\n<dd>The label to display in the input dialog.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>float</code></dt>\n<dd>The default value of the float.</dd>\n<dt><strong><code>decimals</code></strong> :&ensp;<code>int</code></dt>\n<dd>The maximum number of decimal places the number may have. Default is 1.</dd>\n<dt><strong><code>step</code></strong> :&ensp;<code>float</code></dt>\n<dd>The amount by which the value can be incremented or decremented by the user.\nDefault is 0.1.\nOnly has effect for Qt versions &gt;= 5.10!</dd>\n<dt><strong><code>min</code></strong> :&ensp;<code>float</code></dt>\n<dd>The minimum value the user may choose.</dd>\n<dt><strong><code>max</code></strong> :&ensp;<code>float</code></dt>\n<dd>The maximum value the user may choose.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>float</code> or <code>None</code></dt>\n<dd>The user entered float value or <code>None</code> when the Cancel button was pressed.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.show_int_input_dialog\"><code class=\"name flex\">\n<span>def <span class=\"ident\">show_int_input_dialog</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, title: str, label: str, value: int = 0, step: int = 1, min: int = -2147483648, max: int = 2147483647) ‑> object</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Show a dialog window to get an integer value from the user. It returns the entered float value or <code>None</code> if the Cancel button was pressed.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>title</code></strong> :&ensp;<code>str</code></dt>\n<dd>The window title of the input dialog.</dd>\n<dt><strong><code>label</code></strong> :&ensp;<code>str</code></dt>\n<dd>The label to display in the input dialog.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>int</code></dt>\n<dd>The default value of the integer.</dd>\n<dt><strong><code>step</code></strong> :&ensp;<code>int</code></dt>\n<dd>The amount by which the value can be incremented or decremented by the user. Default is 1.</dd>\n<dt><strong><code>min</code></strong> :&ensp;<code>int</code></dt>\n<dd>The minimum value the user may choose.</dd>\n<dt><strong><code>max</code></strong> :&ensp;<code>int</code></dt>\n<dd>The maximum value the user may choose.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>int</code> or <code>None</code></dt>\n<dd>The user entered integer value or <code>None</code> when the Cancel button was pressed.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.show_message_box\"><code class=\"name flex\">\n<span>def <span class=\"ident\">show_message_box</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, title: str, text: str) ‑> bool</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Show a (info) message box with the given window title and text. Returns <code>True</code> when the Ok button was pressed.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>title</code></strong> :&ensp;<code>str</code></dt>\n<dd>The window title of the message box.</dd>\n<dt><strong><code>text</code></strong> :&ensp;<code>str</code></dt>\n<dd>The text to display in the message box.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>bool</code></dt>\n<dd><code>True</code> when the Ok button was pressed, else <code>False</code>.</dd>\n</dl></div>\n</dd>\n<dt id=\"smuview.UiProxy.show_string_input_dialog\"><code class=\"name flex\">\n<span>def <span class=\"ident\">show_string_input_dialog</span></span>(<span>self: <a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a>, title: str, label: str, value: str = '') ‑> object</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Show a dialog window to get a string value from the user. It returns the entered string value or <code>None</code> if the Cancel button was pressed.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>title</code></strong> :&ensp;<code>str</code></dt>\n<dd>The window title of the input dialog.</dd>\n<dt><strong><code>label</code></strong> :&ensp;<code>str</code></dt>\n<dd>The label to display in the input dialog.</dd>\n<dt><strong><code>value</code></strong> :&ensp;<code>str</code></dt>\n<dd>The default value of the string.</dd>\n</dl>\n<h2 id=\"returns\">Returns</h2>\n<dl>\n<dt><code>str</code> or <code>None</code></dt>\n<dd>The user entered string value or <code>None</code> when the Cancel button was pressed.</dd>\n</dl></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.Unit\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">Unit</span></span>\n<span>(</span><span>...)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Enum of all available units.</p>\n<p><strong>init</strong>(self: smuview.Unit, value: int) -&gt; None</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Class variables</h3>\n<dl>\n<dt id=\"smuview.Unit.Ampere\"><code class=\"name\">var <span class=\"ident\">Ampere</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Ampere</p></div>\n</dd>\n<dt id=\"smuview.Unit.AmpereHour\"><code class=\"name\">var <span class=\"ident\">AmpereHour</span></code></dt>\n<dd>\n<div class=\"desc\"><p>AmpereHour (Ah)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Boolean\"><code class=\"name\">var <span class=\"ident\">Boolean</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Boolean</p></div>\n</dd>\n<dt id=\"smuview.Unit.Carat\"><code class=\"name\">var <span class=\"ident\">Carat</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in carat.</p></div>\n</dd>\n<dt id=\"smuview.Unit.Celsius\"><code class=\"name\">var <span class=\"ident\">Celsius</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Celsius</p></div>\n</dd>\n<dt id=\"smuview.Unit.Concentration\"><code class=\"name\">var <span class=\"ident\">Concentration</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Concentration</p></div>\n</dd>\n<dt id=\"smuview.Unit.Coulomb\"><code class=\"name\">var <span class=\"ident\">Coulomb</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Coulomb</p></div>\n</dd>\n<dt id=\"smuview.Unit.DecibelMW\"><code class=\"name\">var <span class=\"ident\">DecibelMW</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Decibel milliWatt (dBm)</p></div>\n</dd>\n<dt id=\"smuview.Unit.DecibelSpl\"><code class=\"name\">var <span class=\"ident\">DecibelSpl</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Decibel sound pressure level</p></div>\n</dd>\n<dt id=\"smuview.Unit.DecibelVolt\"><code class=\"name\">var <span class=\"ident\">DecibelVolt</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Decibel Volt (dBV)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Degree\"><code class=\"name\">var <span class=\"ident\">Degree</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Degree</p></div>\n</dd>\n<dt id=\"smuview.Unit.Fahrenheit\"><code class=\"name\">var <span class=\"ident\">Fahrenheit</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Fahrenheit</p></div>\n</dd>\n<dt id=\"smuview.Unit.Farad\"><code class=\"name\">var <span class=\"ident\">Farad</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Farad</p></div>\n</dd>\n<dt id=\"smuview.Unit.Grain\"><code class=\"name\">var <span class=\"ident\">Grain</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in grain.</p></div>\n</dd>\n<dt id=\"smuview.Unit.Gram\"><code class=\"name\">var <span class=\"ident\">Gram</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in gram (g).</p></div>\n</dd>\n<dt id=\"smuview.Unit.HectoPascal\"><code class=\"name\">var <span class=\"ident\">HectoPascal</span></code></dt>\n<dd>\n<div class=\"desc\"><p>HectoPascal (hPa)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Henry\"><code class=\"name\">var <span class=\"ident\">Henry</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Henry</p></div>\n</dd>\n<dt id=\"smuview.Unit.Hertz\"><code class=\"name\">var <span class=\"ident\">Hertz</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Hertz</p></div>\n</dd>\n<dt id=\"smuview.Unit.Humidity293K\"><code class=\"name\">var <span class=\"ident\">Humidity293K</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Humidity at 293K</p></div>\n</dd>\n<dt id=\"smuview.Unit.Joule\"><code class=\"name\">var <span class=\"ident\">Joule</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Joule</p></div>\n</dd>\n<dt id=\"smuview.Unit.Kelvin\"><code class=\"name\">var <span class=\"ident\">Kelvin</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Kelvin</p></div>\n</dd>\n<dt id=\"smuview.Unit.MeterPerSecond\"><code class=\"name\">var <span class=\"ident\">MeterPerSecond</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Meter per second (m/s)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Momme\"><code class=\"name\">var <span class=\"ident\">Momme</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in momme.</p></div>\n</dd>\n<dt id=\"smuview.Unit.Ohm\"><code class=\"name\">var <span class=\"ident\">Ohm</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Ohm</p></div>\n</dd>\n<dt id=\"smuview.Unit.Ounce\"><code class=\"name\">var <span class=\"ident\">Ounce</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in avoirdupois ounce (oz).</p></div>\n</dd>\n<dt id=\"smuview.Unit.Pennyweight\"><code class=\"name\">var <span class=\"ident\">Pennyweight</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in pennyweight.</p></div>\n</dd>\n<dt id=\"smuview.Unit.Percentage\"><code class=\"name\">var <span class=\"ident\">Percentage</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Percentage</p></div>\n</dd>\n<dt id=\"smuview.Unit.Piece\"><code class=\"name\">var <span class=\"ident\">Piece</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Piece</p></div>\n</dd>\n<dt id=\"smuview.Unit.Pound\"><code class=\"name\">var <span class=\"ident\">Pound</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in avoirdupois pound (lb).</p></div>\n</dd>\n<dt id=\"smuview.Unit.RevolutionsPerMinute\"><code class=\"name\">var <span class=\"ident\">RevolutionsPerMinute</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Revolutions per minute (RPM)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Second\"><code class=\"name\">var <span class=\"ident\">Second</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Second</p></div>\n</dd>\n<dt id=\"smuview.Unit.Siemens\"><code class=\"name\">var <span class=\"ident\">Siemens</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Siemens</p></div>\n</dd>\n<dt id=\"smuview.Unit.Tael\"><code class=\"name\">var <span class=\"ident\">Tael</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in tael.</p></div>\n</dd>\n<dt id=\"smuview.Unit.Tola\"><code class=\"name\">var <span class=\"ident\">Tola</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in tola.</p></div>\n</dd>\n<dt id=\"smuview.Unit.TroyOunce\"><code class=\"name\">var <span class=\"ident\">TroyOunce</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Weight in troy ounce (oz t).</p></div>\n</dd>\n<dt id=\"smuview.Unit.Unitless\"><code class=\"name\">var <span class=\"ident\">Unitless</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unitless</p></div>\n</dd>\n<dt id=\"smuview.Unit.Unknown\"><code class=\"name\">var <span class=\"ident\">Unknown</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Unknown</p></div>\n</dd>\n<dt id=\"smuview.Unit.Volt\"><code class=\"name\">var <span class=\"ident\">Volt</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Volt</p></div>\n</dd>\n<dt id=\"smuview.Unit.VoltAmpere\"><code class=\"name\">var <span class=\"ident\">VoltAmpere</span></code></dt>\n<dd>\n<div class=\"desc\"><p>VoltAmpere (VA)</p></div>\n</dd>\n<dt id=\"smuview.Unit.Watt\"><code class=\"name\">var <span class=\"ident\">Watt</span></code></dt>\n<dd>\n<div class=\"desc\"><p>Watt</p></div>\n</dd>\n<dt id=\"smuview.Unit.WattHour\"><code class=\"name\">var <span class=\"ident\">WattHour</span></code></dt>\n<dd>\n<div class=\"desc\"><p>WattHour (Wh)</p></div>\n</dd>\n</dl>\n<h3>Instance variables</h3>\n<dl>\n<dt id=\"smuview.Unit.name\"><code class=\"name\">var <span class=\"ident\">name</span></code></dt>\n<dd>\n<div class=\"desc\"><p>name(self: handle) -&gt; str</p></div>\n</dd>\n<dt id=\"smuview.Unit.value\"><code class=\"name\">var <span class=\"ident\">value</span></code></dt>\n<dd>\n<div class=\"desc\"><p>(arg0: smuview.Unit) -&gt; int</p></div>\n</dd>\n</dl>\n</dd>\n<dt id=\"smuview.UserChannel\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">UserChannel</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>An user generated channel for storing custom data.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Methods</h3>\n<dl>\n<dt id=\"smuview.UserChannel.push_sample\"><code class=\"name flex\">\n<span>def <span class=\"ident\">push_sample</span></span>(<span>self: <a title=\"smuview.UserChannel\" href=\"#smuview.UserChannel\">UserChannel</a>, sample: float, timestamp: float, quantity: <a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a>, quantity_flags: Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>], unit: <a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a>, digits: int, decimal_places: int)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>Push a single sample to the channel.</p>\n<h2 id=\"parameters\">Parameters</h2>\n<dl>\n<dt><strong><code>sample</code></strong> :&ensp;<code>float</code></dt>\n<dd>The sample value.</dd>\n<dt><strong><code>timestamp</code></strong> :&ensp;<code>float</code></dt>\n<dd>The absolute timestamp in milliseconds.</dd>\n<dt><strong><code>quantity</code></strong> :&ensp;<code><a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a></code></dt>\n<dd>The <code><a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a></code> of the new signal.</dd>\n<dt><strong><code>quantity_flags</code></strong> :&ensp;<code>Set[<a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a>]</code></dt>\n<dd>The <code><a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a></code>s of the new signal.</dd>\n<dt><strong><code>unit</code></strong> :&ensp;<code><a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a></code></dt>\n<dd>The <code><a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a></code> of the new signal.</dd>\n<dt><strong><code>digits</code></strong> :&ensp;<code>int</code></dt>\n<dd>The total number of digits.</dd>\n<dt><strong><code>decimal_places</code></strong> :&ensp;<code>int</code></dt>\n<dd>The number of decimal places.</dd>\n</dl></div>\n</dd>\n</dl>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseChannel.actual_signal\" href=\"#smuview.BaseChannel.actual_signal\">actual_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.add_signal\" href=\"#smuview.BaseChannel.add_signal\">add_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.name\" href=\"#smuview.BaseChannel.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.signals\" href=\"#smuview.BaseChannel.signals\">signals</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n<dt id=\"smuview.UserDevice\"><code class=\"flex name class\">\n<span>class <span class=\"ident\">UserDevice</span></span>\n<span>(</span><span>*args, **kwargs)</span>\n</code></dt>\n<dd>\n<div class=\"desc\"><p>An user generated (virtual) device for storing custom data and showing a custom tab.</p></div>\n<h3>Ancestors</h3>\n<ul class=\"hlist\">\n<li><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></li>\n<li>pybind11_builtins.pybind11_object</li>\n</ul>\n<h3>Inherited members</h3>\n<ul class=\"hlist\">\n<li><code><b><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></b></code>:\n<ul class=\"hlist\">\n<li><code><a title=\"smuview.BaseDevice.add_user_channel\" href=\"#smuview.BaseDevice.add_user_channel\">add_user_channel</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.channels\" href=\"#smuview.BaseDevice.channels\">channels</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.configurables\" href=\"#smuview.BaseDevice.configurables\">configurables</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.id\" href=\"#smuview.BaseDevice.id\">id</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.name\" href=\"#smuview.BaseDevice.name\">name</a></code></li>\n</ul>\n</li>\n</ul>\n</dd>\n</dl>\n</section>\n</article>\n<nav id=\"sidebar\">\n<h1>Index</h1>\n<div class=\"toc\">\n<ul></ul>\n</div>\n<ul id=\"index\">\n<li><h3><a href=\"#header-classes\">Classes</a></h3>\n<ul>\n<li>\n<h4><code><a title=\"smuview.AnalogSampleSignal\" href=\"#smuview.AnalogSampleSignal\">AnalogSampleSignal</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.AnalogSampleSignal.get_sample\" href=\"#smuview.AnalogSampleSignal.get_sample\">get_sample</a></code></li>\n<li><code><a title=\"smuview.AnalogSampleSignal.push_sample\" href=\"#smuview.AnalogSampleSignal.push_sample\">push_sample</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.AnalogTimeSignal\" href=\"#smuview.AnalogTimeSignal\">AnalogTimeSignal</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.AnalogTimeSignal.get_last_sample\" href=\"#smuview.AnalogTimeSignal.get_last_sample\">get_last_sample</a></code></li>\n<li><code><a title=\"smuview.AnalogTimeSignal.get_sample\" href=\"#smuview.AnalogTimeSignal.get_sample\">get_sample</a></code></li>\n<li><code><a title=\"smuview.AnalogTimeSignal.push_sample\" href=\"#smuview.AnalogTimeSignal.push_sample\">push_sample</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.BaseChannel\" href=\"#smuview.BaseChannel\">BaseChannel</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.BaseChannel.actual_signal\" href=\"#smuview.BaseChannel.actual_signal\">actual_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.add_signal\" href=\"#smuview.BaseChannel.add_signal\">add_signal</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.name\" href=\"#smuview.BaseChannel.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseChannel.signals\" href=\"#smuview.BaseChannel.signals\">signals</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.BaseDevice\" href=\"#smuview.BaseDevice\">BaseDevice</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.BaseDevice.add_user_channel\" href=\"#smuview.BaseDevice.add_user_channel\">add_user_channel</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.channels\" href=\"#smuview.BaseDevice.channels\">channels</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.configurables\" href=\"#smuview.BaseDevice.configurables\">configurables</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.id\" href=\"#smuview.BaseDevice.id\">id</a></code></li>\n<li><code><a title=\"smuview.BaseDevice.name\" href=\"#smuview.BaseDevice.name\">name</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.BaseSignal\" href=\"#smuview.BaseSignal\">BaseSignal</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.BaseSignal.name\" href=\"#smuview.BaseSignal.name\">name</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.sample_count\" href=\"#smuview.BaseSignal.sample_count\">sample_count</a></code></li>\n<li><code><a title=\"smuview.BaseSignal.set_name\" href=\"#smuview.BaseSignal.set_name\">set_name</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.ConfigKey\" href=\"#smuview.ConfigKey\">ConfigKey</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.ConfigKey.ADCPowerlineCycles\" href=\"#smuview.ConfigKey.ADCPowerlineCycles\">ADCPowerlineCycles</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Amplitude\" href=\"#smuview.ConfigKey.Amplitude\">Amplitude</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Averaging\" href=\"#smuview.ConfigKey.Averaging\">Averaging</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.AvgSamples\" href=\"#smuview.ConfigKey.AvgSamples\">AvgSamples</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.BufferSize\" href=\"#smuview.ConfigKey.BufferSize\">BufferSize</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.CaptureFile\" href=\"#smuview.ConfigKey.CaptureFile\">CaptureFile</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.CaptureRatio\" href=\"#smuview.ConfigKey.CaptureRatio\">CaptureRatio</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.CaptureUnitSize\" href=\"#smuview.ConfigKey.CaptureUnitSize\">CaptureUnitSize</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.CenterFrequency\" href=\"#smuview.ConfigKey.CenterFrequency\">CenterFrequency</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.ChannelConfig\" href=\"#smuview.ConfigKey.ChannelConfig\">ChannelConfig</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.ClockEdge\" href=\"#smuview.ConfigKey.ClockEdge\">ClockEdge</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Coupling\" href=\"#smuview.ConfigKey.Coupling\">Coupling</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Current\" href=\"#smuview.ConfigKey.Current\">Current</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.CurrentLimit\" href=\"#smuview.ConfigKey.CurrentLimit\">CurrentLimit</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.DataLog\" href=\"#smuview.ConfigKey.DataLog\">DataLog</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.DataSource\" href=\"#smuview.ConfigKey.DataSource\">DataSource</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.DeviceMode\" href=\"#smuview.ConfigKey.DeviceMode\">DeviceMode</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Digits\" href=\"#smuview.ConfigKey.Digits\">Digits</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Enabled\" href=\"#smuview.ConfigKey.Enabled\">Enabled</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.EquivCircuitModel\" href=\"#smuview.ConfigKey.EquivCircuitModel\">EquivCircuitModel</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.ExternalClock\" href=\"#smuview.ConfigKey.ExternalClock\">ExternalClock</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.ExternalClockSource\" href=\"#smuview.ConfigKey.ExternalClockSource\">ExternalClockSource</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Filter\" href=\"#smuview.ConfigKey.Filter\">Filter</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.HighResolution\" href=\"#smuview.ConfigKey.HighResolution\">HighResolution</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.HoldMax\" href=\"#smuview.ConfigKey.HoldMax\">HoldMax</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.HoldMin\" href=\"#smuview.ConfigKey.HoldMin\">HoldMin</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.HorizTriggerPos\" href=\"#smuview.ConfigKey.HorizTriggerPos\">HorizTriggerPos</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.LogicThreshold\" href=\"#smuview.ConfigKey.LogicThreshold\">LogicThreshold</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.LogicThresholdCustom\" href=\"#smuview.ConfigKey.LogicThresholdCustom\">LogicThresholdCustom</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.MeasuredQuantity\" href=\"#smuview.ConfigKey.MeasuredQuantity\">MeasuredQuantity</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.NumAnalogChannels\" href=\"#smuview.ConfigKey.NumAnalogChannels\">NumAnalogChannels</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.NumHDiv\" href=\"#smuview.ConfigKey.NumHDiv\">NumHDiv</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.NumLogicChannels\" href=\"#smuview.ConfigKey.NumLogicChannels\">NumLogicChannels</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.NumVDiv\" href=\"#smuview.ConfigKey.NumVDiv\">NumVDiv</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Offset\" href=\"#smuview.ConfigKey.Offset\">Offset</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OutputFrequency\" href=\"#smuview.ConfigKey.OutputFrequency\">OutputFrequency</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OutputFrequencyTarget\" href=\"#smuview.ConfigKey.OutputFrequencyTarget\">OutputFrequencyTarget</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverCurrentProtectionActive\" href=\"#smuview.ConfigKey.OverCurrentProtectionActive\">OverCurrentProtectionActive</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverCurrentProtectionEnabled\" href=\"#smuview.ConfigKey.OverCurrentProtectionEnabled\">OverCurrentProtectionEnabled</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverCurrentProtectionThreshold\" href=\"#smuview.ConfigKey.OverCurrentProtectionThreshold\">OverCurrentProtectionThreshold</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverTemperatureProtectionActive\" href=\"#smuview.ConfigKey.OverTemperatureProtectionActive\">OverTemperatureProtectionActive</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverTemperatureProtectionEnabled\" href=\"#smuview.ConfigKey.OverTemperatureProtectionEnabled\">OverTemperatureProtectionEnabled</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverVoltageProtectionActive\" href=\"#smuview.ConfigKey.OverVoltageProtectionActive\">OverVoltageProtectionActive</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverVoltageProtectionEnabled\" href=\"#smuview.ConfigKey.OverVoltageProtectionEnabled\">OverVoltageProtectionEnabled</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.OverVoltageProtectionThreshold\" href=\"#smuview.ConfigKey.OverVoltageProtectionThreshold\">OverVoltageProtectionThreshold</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.PatternMode\" href=\"#smuview.ConfigKey.PatternMode\">PatternMode</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.PeakDetection\" href=\"#smuview.ConfigKey.PeakDetection\">PeakDetection</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.PowerOff\" href=\"#smuview.ConfigKey.PowerOff\">PowerOff</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.ProbeFactor\" href=\"#smuview.ConfigKey.ProbeFactor\">ProbeFactor</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.RLE\" href=\"#smuview.ConfigKey.RLE\">RLE</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Range\" href=\"#smuview.ConfigKey.Range\">Range</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Regulation\" href=\"#smuview.ConfigKey.Regulation\">Regulation</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.SampleInterval\" href=\"#smuview.ConfigKey.SampleInterval\">SampleInterval</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Samplerate\" href=\"#smuview.ConfigKey.Samplerate\">Samplerate</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.SessionFile\" href=\"#smuview.ConfigKey.SessionFile\">SessionFile</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.SplMeasurementRange\" href=\"#smuview.ConfigKey.SplMeasurementRange\">SplMeasurementRange</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.SplWeightFreq\" href=\"#smuview.ConfigKey.SplWeightFreq\">SplWeightFreq</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.SplWeightTime\" href=\"#smuview.ConfigKey.SplWeightTime\">SplWeightTime</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Swap\" href=\"#smuview.ConfigKey.Swap\">Swap</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TestMode\" href=\"#smuview.ConfigKey.TestMode\">TestMode</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TimeBase\" href=\"#smuview.ConfigKey.TimeBase\">TimeBase</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TriggerLevel\" href=\"#smuview.ConfigKey.TriggerLevel\">TriggerLevel</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TriggerMatch\" href=\"#smuview.ConfigKey.TriggerMatch\">TriggerMatch</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TriggerPattern\" href=\"#smuview.ConfigKey.TriggerPattern\">TriggerPattern</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TriggerSlope\" href=\"#smuview.ConfigKey.TriggerSlope\">TriggerSlope</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.TriggerSource\" href=\"#smuview.ConfigKey.TriggerSource\">TriggerSource</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.UnderVoltageConditionActive\" href=\"#smuview.ConfigKey.UnderVoltageConditionActive\">UnderVoltageConditionActive</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.UnderVoltageConditionEnabled\" href=\"#smuview.ConfigKey.UnderVoltageConditionEnabled\">UnderVoltageConditionEnabled</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.UnderVoltageConditionThreshold\" href=\"#smuview.ConfigKey.UnderVoltageConditionThreshold\">UnderVoltageConditionThreshold</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Unknown\" href=\"#smuview.ConfigKey.Unknown\">Unknown</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.VDiv\" href=\"#smuview.ConfigKey.VDiv\">VDiv</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.Voltage\" href=\"#smuview.ConfigKey.Voltage\">Voltage</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.VoltageTarget\" href=\"#smuview.ConfigKey.VoltageTarget\">VoltageTarget</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.VoltageThreshold\" href=\"#smuview.ConfigKey.VoltageThreshold\">VoltageThreshold</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.get_data_type\" href=\"#smuview.ConfigKey.get_data_type\">get_data_type</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.name\" href=\"#smuview.ConfigKey.name\">name</a></code></li>\n<li><code><a title=\"smuview.ConfigKey.value\" href=\"#smuview.ConfigKey.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.Configurable\" href=\"#smuview.Configurable\">Configurable</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.Configurable.get_bool_config\" href=\"#smuview.Configurable.get_bool_config\">get_bool_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.get_double_config\" href=\"#smuview.Configurable.get_double_config\">get_double_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.get_int_config\" href=\"#smuview.Configurable.get_int_config\">get_int_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.get_measured_quantity_config\" href=\"#smuview.Configurable.get_measured_quantity_config\">get_measured_quantity_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.get_string_config\" href=\"#smuview.Configurable.get_string_config\">get_string_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.get_uint_config\" href=\"#smuview.Configurable.get_uint_config\">get_uint_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.getable_configs\" href=\"#smuview.Configurable.getable_configs\">getable_configs</a></code></li>\n<li><code><a title=\"smuview.Configurable.listable_configs\" href=\"#smuview.Configurable.listable_configs\">listable_configs</a></code></li>\n<li><code><a title=\"smuview.Configurable.name\" href=\"#smuview.Configurable.name\">name</a></code></li>\n<li><code><a title=\"smuview.Configurable.set_config\" href=\"#smuview.Configurable.set_config\">set_config</a></code></li>\n<li><code><a title=\"smuview.Configurable.setable_configs\" href=\"#smuview.Configurable.setable_configs\">setable_configs</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.DataType\" href=\"#smuview.DataType\">DataType</a></code></h4>\n<ul class=\"two-column\">\n<li><code><a title=\"smuview.DataType.Bool\" href=\"#smuview.DataType.Bool\">Bool</a></code></li>\n<li><code><a title=\"smuview.DataType.Double\" href=\"#smuview.DataType.Double\">Double</a></code></li>\n<li><code><a title=\"smuview.DataType.DoubleRange\" href=\"#smuview.DataType.DoubleRange\">DoubleRange</a></code></li>\n<li><code><a title=\"smuview.DataType.Int32\" href=\"#smuview.DataType.Int32\">Int32</a></code></li>\n<li><code><a title=\"smuview.DataType.KeyValue\" href=\"#smuview.DataType.KeyValue\">KeyValue</a></code></li>\n<li><code><a title=\"smuview.DataType.MQ\" href=\"#smuview.DataType.MQ\">MQ</a></code></li>\n<li><code><a title=\"smuview.DataType.RationalPeriod\" href=\"#smuview.DataType.RationalPeriod\">RationalPeriod</a></code></li>\n<li><code><a title=\"smuview.DataType.RationalVolt\" href=\"#smuview.DataType.RationalVolt\">RationalVolt</a></code></li>\n<li><code><a title=\"smuview.DataType.String\" href=\"#smuview.DataType.String\">String</a></code></li>\n<li><code><a title=\"smuview.DataType.UInt64\" href=\"#smuview.DataType.UInt64\">UInt64</a></code></li>\n<li><code><a title=\"smuview.DataType.UInt64Range\" href=\"#smuview.DataType.UInt64Range\">UInt64Range</a></code></li>\n<li><code><a title=\"smuview.DataType.Unknown\" href=\"#smuview.DataType.Unknown\">Unknown</a></code></li>\n<li><code><a title=\"smuview.DataType.name\" href=\"#smuview.DataType.name\">name</a></code></li>\n<li><code><a title=\"smuview.DataType.value\" href=\"#smuview.DataType.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.DockArea\" href=\"#smuview.DockArea\">DockArea</a></code></h4>\n<ul class=\"two-column\">\n<li><code><a title=\"smuview.DockArea.BottomDockArea\" href=\"#smuview.DockArea.BottomDockArea\">BottomDockArea</a></code></li>\n<li><code><a title=\"smuview.DockArea.LeftDocktArea\" href=\"#smuview.DockArea.LeftDocktArea\">LeftDocktArea</a></code></li>\n<li><code><a title=\"smuview.DockArea.RightDockArea\" href=\"#smuview.DockArea.RightDockArea\">RightDockArea</a></code></li>\n<li><code><a title=\"smuview.DockArea.TopDockArea\" href=\"#smuview.DockArea.TopDockArea\">TopDockArea</a></code></li>\n<li><code><a title=\"smuview.DockArea.name\" href=\"#smuview.DockArea.name\">name</a></code></li>\n<li><code><a title=\"smuview.DockArea.value\" href=\"#smuview.DockArea.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.HardwareChannel\" href=\"#smuview.HardwareChannel\">HardwareChannel</a></code></h4>\n</li>\n<li>\n<h4><code><a title=\"smuview.HardwareDevice\" href=\"#smuview.HardwareDevice\">HardwareDevice</a></code></h4>\n</li>\n<li>\n<h4><code><a title=\"smuview.PyStreamBuf\" href=\"#smuview.PyStreamBuf\">PyStreamBuf</a></code></h4>\n<ul class=\"two-column\">\n<li><code><a title=\"smuview.PyStreamBuf.close\" href=\"#smuview.PyStreamBuf.close\">close</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.closed\" href=\"#smuview.PyStreamBuf.closed\">closed</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.encoding\" href=\"#smuview.PyStreamBuf.encoding\">encoding</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.errors\" href=\"#smuview.PyStreamBuf.errors\">errors</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.fileno\" href=\"#smuview.PyStreamBuf.fileno\">fileno</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.flush\" href=\"#smuview.PyStreamBuf.flush\">flush</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.isatty\" href=\"#smuview.PyStreamBuf.isatty\">isatty</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.read\" href=\"#smuview.PyStreamBuf.read\">read</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.readable\" href=\"#smuview.PyStreamBuf.readable\">readable</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.readline\" href=\"#smuview.PyStreamBuf.readline\">readline</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.readlines\" href=\"#smuview.PyStreamBuf.readlines\">readlines</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.seek\" href=\"#smuview.PyStreamBuf.seek\">seek</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.seekable\" href=\"#smuview.PyStreamBuf.seekable\">seekable</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.tell\" href=\"#smuview.PyStreamBuf.tell\">tell</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.truncate\" href=\"#smuview.PyStreamBuf.truncate\">truncate</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.writable\" href=\"#smuview.PyStreamBuf.writable\">writable</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.write\" href=\"#smuview.PyStreamBuf.write\">write</a></code></li>\n<li><code><a title=\"smuview.PyStreamBuf.writelines\" href=\"#smuview.PyStreamBuf.writelines\">writelines</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.Quantity\" href=\"#smuview.Quantity\">Quantity</a></code></h4>\n<ul class=\"two-column\">\n<li><code><a title=\"smuview.Quantity.ApparentPower\" href=\"#smuview.Quantity.ApparentPower\">ApparentPower</a></code></li>\n<li><code><a title=\"smuview.Quantity.Capacitance\" href=\"#smuview.Quantity.Capacitance\">Capacitance</a></code></li>\n<li><code><a title=\"smuview.Quantity.CarbonMonoxide\" href=\"#smuview.Quantity.CarbonMonoxide\">CarbonMonoxide</a></code></li>\n<li><code><a title=\"smuview.Quantity.Conductance\" href=\"#smuview.Quantity.Conductance\">Conductance</a></code></li>\n<li><code><a title=\"smuview.Quantity.Continuity\" href=\"#smuview.Quantity.Continuity\">Continuity</a></code></li>\n<li><code><a title=\"smuview.Quantity.Count\" href=\"#smuview.Quantity.Count\">Count</a></code></li>\n<li><code><a title=\"smuview.Quantity.Current\" href=\"#smuview.Quantity.Current\">Current</a></code></li>\n<li><code><a title=\"smuview.Quantity.Difference\" href=\"#smuview.Quantity.Difference\">Difference</a></code></li>\n<li><code><a title=\"smuview.Quantity.DissipationFactor\" href=\"#smuview.Quantity.DissipationFactor\">DissipationFactor</a></code></li>\n<li><code><a title=\"smuview.Quantity.DutyCyle\" href=\"#smuview.Quantity.DutyCyle\">DutyCyle</a></code></li>\n<li><code><a title=\"smuview.Quantity.ElectricCharge\" href=\"#smuview.Quantity.ElectricCharge\">ElectricCharge</a></code></li>\n<li><code><a title=\"smuview.Quantity.Energy\" href=\"#smuview.Quantity.Energy\">Energy</a></code></li>\n<li><code><a title=\"smuview.Quantity.Frequency\" href=\"#smuview.Quantity.Frequency\">Frequency</a></code></li>\n<li><code><a title=\"smuview.Quantity.Gain\" href=\"#smuview.Quantity.Gain\">Gain</a></code></li>\n<li><code><a title=\"smuview.Quantity.HarmonicRatio\" href=\"#smuview.Quantity.HarmonicRatio\">HarmonicRatio</a></code></li>\n<li><code><a title=\"smuview.Quantity.Mass\" href=\"#smuview.Quantity.Mass\">Mass</a></code></li>\n<li><code><a title=\"smuview.Quantity.ParallelCapacitance\" href=\"#smuview.Quantity.ParallelCapacitance\">ParallelCapacitance</a></code></li>\n<li><code><a title=\"smuview.Quantity.ParallelInductance\" href=\"#smuview.Quantity.ParallelInductance\">ParallelInductance</a></code></li>\n<li><code><a title=\"smuview.Quantity.ParallelResistance\" href=\"#smuview.Quantity.ParallelResistance\">ParallelResistance</a></code></li>\n<li><code><a title=\"smuview.Quantity.PhaseAngle\" href=\"#smuview.Quantity.PhaseAngle\">PhaseAngle</a></code></li>\n<li><code><a title=\"smuview.Quantity.Power\" href=\"#smuview.Quantity.Power\">Power</a></code></li>\n<li><code><a title=\"smuview.Quantity.PowerFactor\" href=\"#smuview.Quantity.PowerFactor\">PowerFactor</a></code></li>\n<li><code><a title=\"smuview.Quantity.Pressure\" href=\"#smuview.Quantity.Pressure\">Pressure</a></code></li>\n<li><code><a title=\"smuview.Quantity.PulseWidth\" href=\"#smuview.Quantity.PulseWidth\">PulseWidth</a></code></li>\n<li><code><a title=\"smuview.Quantity.QualityFactor\" href=\"#smuview.Quantity.QualityFactor\">QualityFactor</a></code></li>\n<li><code><a title=\"smuview.Quantity.RelativeHumidity\" href=\"#smuview.Quantity.RelativeHumidity\">RelativeHumidity</a></code></li>\n<li><code><a title=\"smuview.Quantity.Resistance\" href=\"#smuview.Quantity.Resistance\">Resistance</a></code></li>\n<li><code><a title=\"smuview.Quantity.SeriesCapacitance\" href=\"#smuview.Quantity.SeriesCapacitance\">SeriesCapacitance</a></code></li>\n<li><code><a title=\"smuview.Quantity.SeriesInductance\" href=\"#smuview.Quantity.SeriesInductance\">SeriesInductance</a></code></li>\n<li><code><a title=\"smuview.Quantity.SeriesResistance\" href=\"#smuview.Quantity.SeriesResistance\">SeriesResistance</a></code></li>\n<li><code><a title=\"smuview.Quantity.SoundPressureLevel\" href=\"#smuview.Quantity.SoundPressureLevel\">SoundPressureLevel</a></code></li>\n<li><code><a title=\"smuview.Quantity.Temperature\" href=\"#smuview.Quantity.Temperature\">Temperature</a></code></li>\n<li><code><a title=\"smuview.Quantity.Time\" href=\"#smuview.Quantity.Time\">Time</a></code></li>\n<li><code><a title=\"smuview.Quantity.Unknown\" href=\"#smuview.Quantity.Unknown\">Unknown</a></code></li>\n<li><code><a title=\"smuview.Quantity.Voltage\" href=\"#smuview.Quantity.Voltage\">Voltage</a></code></li>\n<li><code><a title=\"smuview.Quantity.WindSpeed\" href=\"#smuview.Quantity.WindSpeed\">WindSpeed</a></code></li>\n<li><code><a title=\"smuview.Quantity.name\" href=\"#smuview.Quantity.name\">name</a></code></li>\n<li><code><a title=\"smuview.Quantity.value\" href=\"#smuview.Quantity.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.QuantityFlag\" href=\"#smuview.QuantityFlag\">QuantityFlag</a></code></h4>\n<ul class=\"two-column\">\n<li><code><a title=\"smuview.QuantityFlag.AC\" href=\"#smuview.QuantityFlag.AC\">AC</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Autorange\" href=\"#smuview.QuantityFlag.Autorange\">Autorange</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Avg\" href=\"#smuview.QuantityFlag.Avg\">Avg</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.DC\" href=\"#smuview.QuantityFlag.DC\">DC</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Diode\" href=\"#smuview.QuantityFlag.Diode\">Diode</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Duration\" href=\"#smuview.QuantityFlag.Duration\">Duration</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.FourWire\" href=\"#smuview.QuantityFlag.FourWire\">FourWire</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Hold\" href=\"#smuview.QuantityFlag.Hold\">Hold</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Max\" href=\"#smuview.QuantityFlag.Max\">Max</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Min\" href=\"#smuview.QuantityFlag.Min\">Min</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.RMS\" href=\"#smuview.QuantityFlag.RMS\">RMS</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Reference\" href=\"#smuview.QuantityFlag.Reference\">Reference</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Relative\" href=\"#smuview.QuantityFlag.Relative\">Relative</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplFreqWeightA\" href=\"#smuview.QuantityFlag.SplFreqWeightA\">SplFreqWeightA</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplFreqWeightC\" href=\"#smuview.QuantityFlag.SplFreqWeightC\">SplFreqWeightC</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplFreqWeightFlat\" href=\"#smuview.QuantityFlag.SplFreqWeightFlat\">SplFreqWeightFlat</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplFreqWeightZ\" href=\"#smuview.QuantityFlag.SplFreqWeightZ\">SplFreqWeightZ</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplLAT\" href=\"#smuview.QuantityFlag.SplLAT\">SplLAT</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplPctOverAlarm\" href=\"#smuview.QuantityFlag.SplPctOverAlarm\">SplPctOverAlarm</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplTimeWeightF\" href=\"#smuview.QuantityFlag.SplTimeWeightF\">SplTimeWeightF</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.SplTimeWeightS\" href=\"#smuview.QuantityFlag.SplTimeWeightS\">SplTimeWeightS</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Unknown\" href=\"#smuview.QuantityFlag.Unknown\">Unknown</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.Unstable\" href=\"#smuview.QuantityFlag.Unstable\">Unstable</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.name\" href=\"#smuview.QuantityFlag.name\">name</a></code></li>\n<li><code><a title=\"smuview.QuantityFlag.value\" href=\"#smuview.QuantityFlag.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.Session\" href=\"#smuview.Session\">Session</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.Session.add_user_device\" href=\"#smuview.Session.add_user_device\">add_user_device</a></code></li>\n<li><code><a title=\"smuview.Session.connect_device\" href=\"#smuview.Session.connect_device\">connect_device</a></code></li>\n<li><code><a title=\"smuview.Session.devices\" href=\"#smuview.Session.devices\">devices</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.UiProxy\" href=\"#smuview.UiProxy\">UiProxy</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.UiProxy.add_control_view\" href=\"#smuview.UiProxy.add_control_view\">add_control_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_curve_to_time_plot_view\" href=\"#smuview.UiProxy.add_curve_to_time_plot_view\">add_curve_to_time_plot_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_curve_to_xy_plot_view\" href=\"#smuview.UiProxy.add_curve_to_xy_plot_view\">add_curve_to_xy_plot_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_data_view\" href=\"#smuview.UiProxy.add_data_view\">add_data_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_device_tab\" href=\"#smuview.UiProxy.add_device_tab\">add_device_tab</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_power_panel_view\" href=\"#smuview.UiProxy.add_power_panel_view\">add_power_panel_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_signal_to_data_view\" href=\"#smuview.UiProxy.add_signal_to_data_view\">add_signal_to_data_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_time_plot_view\" href=\"#smuview.UiProxy.add_time_plot_view\">add_time_plot_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_value_panel_view\" href=\"#smuview.UiProxy.add_value_panel_view\">add_value_panel_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.add_xy_plot_view\" href=\"#smuview.UiProxy.add_xy_plot_view\">add_xy_plot_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.set_channel_to_time_plot_view\" href=\"#smuview.UiProxy.set_channel_to_time_plot_view\">set_channel_to_time_plot_view</a></code></li>\n<li><code><a title=\"smuview.UiProxy.set_curve_color\" href=\"#smuview.UiProxy.set_curve_color\">set_curve_color</a></code></li>\n<li><code><a title=\"smuview.UiProxy.set_curve_name\" href=\"#smuview.UiProxy.set_curve_name\">set_curve_name</a></code></li>\n<li><code><a title=\"smuview.UiProxy.show_double_input_dialog\" href=\"#smuview.UiProxy.show_double_input_dialog\">show_double_input_dialog</a></code></li>\n<li><code><a title=\"smuview.UiProxy.show_int_input_dialog\" href=\"#smuview.UiProxy.show_int_input_dialog\">show_int_input_dialog</a></code></li>\n<li><code><a title=\"smuview.UiProxy.show_message_box\" href=\"#smuview.UiProxy.show_message_box\">show_message_box</a></code></li>\n<li><code><a title=\"smuview.UiProxy.show_string_input_dialog\" href=\"#smuview.UiProxy.show_string_input_dialog\">show_string_input_dialog</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.Unit\" href=\"#smuview.Unit\">Unit</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.Unit.Ampere\" href=\"#smuview.Unit.Ampere\">Ampere</a></code></li>\n<li><code><a title=\"smuview.Unit.AmpereHour\" href=\"#smuview.Unit.AmpereHour\">AmpereHour</a></code></li>\n<li><code><a title=\"smuview.Unit.Boolean\" href=\"#smuview.Unit.Boolean\">Boolean</a></code></li>\n<li><code><a title=\"smuview.Unit.Carat\" href=\"#smuview.Unit.Carat\">Carat</a></code></li>\n<li><code><a title=\"smuview.Unit.Celsius\" href=\"#smuview.Unit.Celsius\">Celsius</a></code></li>\n<li><code><a title=\"smuview.Unit.Concentration\" href=\"#smuview.Unit.Concentration\">Concentration</a></code></li>\n<li><code><a title=\"smuview.Unit.Coulomb\" href=\"#smuview.Unit.Coulomb\">Coulomb</a></code></li>\n<li><code><a title=\"smuview.Unit.DecibelMW\" href=\"#smuview.Unit.DecibelMW\">DecibelMW</a></code></li>\n<li><code><a title=\"smuview.Unit.DecibelSpl\" href=\"#smuview.Unit.DecibelSpl\">DecibelSpl</a></code></li>\n<li><code><a title=\"smuview.Unit.DecibelVolt\" href=\"#smuview.Unit.DecibelVolt\">DecibelVolt</a></code></li>\n<li><code><a title=\"smuview.Unit.Degree\" href=\"#smuview.Unit.Degree\">Degree</a></code></li>\n<li><code><a title=\"smuview.Unit.Fahrenheit\" href=\"#smuview.Unit.Fahrenheit\">Fahrenheit</a></code></li>\n<li><code><a title=\"smuview.Unit.Farad\" href=\"#smuview.Unit.Farad\">Farad</a></code></li>\n<li><code><a title=\"smuview.Unit.Grain\" href=\"#smuview.Unit.Grain\">Grain</a></code></li>\n<li><code><a title=\"smuview.Unit.Gram\" href=\"#smuview.Unit.Gram\">Gram</a></code></li>\n<li><code><a title=\"smuview.Unit.HectoPascal\" href=\"#smuview.Unit.HectoPascal\">HectoPascal</a></code></li>\n<li><code><a title=\"smuview.Unit.Henry\" href=\"#smuview.Unit.Henry\">Henry</a></code></li>\n<li><code><a title=\"smuview.Unit.Hertz\" href=\"#smuview.Unit.Hertz\">Hertz</a></code></li>\n<li><code><a title=\"smuview.Unit.Humidity293K\" href=\"#smuview.Unit.Humidity293K\">Humidity293K</a></code></li>\n<li><code><a title=\"smuview.Unit.Joule\" href=\"#smuview.Unit.Joule\">Joule</a></code></li>\n<li><code><a title=\"smuview.Unit.Kelvin\" href=\"#smuview.Unit.Kelvin\">Kelvin</a></code></li>\n<li><code><a title=\"smuview.Unit.MeterPerSecond\" href=\"#smuview.Unit.MeterPerSecond\">MeterPerSecond</a></code></li>\n<li><code><a title=\"smuview.Unit.Momme\" href=\"#smuview.Unit.Momme\">Momme</a></code></li>\n<li><code><a title=\"smuview.Unit.Ohm\" href=\"#smuview.Unit.Ohm\">Ohm</a></code></li>\n<li><code><a title=\"smuview.Unit.Ounce\" href=\"#smuview.Unit.Ounce\">Ounce</a></code></li>\n<li><code><a title=\"smuview.Unit.Pennyweight\" href=\"#smuview.Unit.Pennyweight\">Pennyweight</a></code></li>\n<li><code><a title=\"smuview.Unit.Percentage\" href=\"#smuview.Unit.Percentage\">Percentage</a></code></li>\n<li><code><a title=\"smuview.Unit.Piece\" href=\"#smuview.Unit.Piece\">Piece</a></code></li>\n<li><code><a title=\"smuview.Unit.Pound\" href=\"#smuview.Unit.Pound\">Pound</a></code></li>\n<li><code><a title=\"smuview.Unit.RevolutionsPerMinute\" href=\"#smuview.Unit.RevolutionsPerMinute\">RevolutionsPerMinute</a></code></li>\n<li><code><a title=\"smuview.Unit.Second\" href=\"#smuview.Unit.Second\">Second</a></code></li>\n<li><code><a title=\"smuview.Unit.Siemens\" href=\"#smuview.Unit.Siemens\">Siemens</a></code></li>\n<li><code><a title=\"smuview.Unit.Tael\" href=\"#smuview.Unit.Tael\">Tael</a></code></li>\n<li><code><a title=\"smuview.Unit.Tola\" href=\"#smuview.Unit.Tola\">Tola</a></code></li>\n<li><code><a title=\"smuview.Unit.TroyOunce\" href=\"#smuview.Unit.TroyOunce\">TroyOunce</a></code></li>\n<li><code><a title=\"smuview.Unit.Unitless\" href=\"#smuview.Unit.Unitless\">Unitless</a></code></li>\n<li><code><a title=\"smuview.Unit.Unknown\" href=\"#smuview.Unit.Unknown\">Unknown</a></code></li>\n<li><code><a title=\"smuview.Unit.Volt\" href=\"#smuview.Unit.Volt\">Volt</a></code></li>\n<li><code><a title=\"smuview.Unit.VoltAmpere\" href=\"#smuview.Unit.VoltAmpere\">VoltAmpere</a></code></li>\n<li><code><a title=\"smuview.Unit.Watt\" href=\"#smuview.Unit.Watt\">Watt</a></code></li>\n<li><code><a title=\"smuview.Unit.WattHour\" href=\"#smuview.Unit.WattHour\">WattHour</a></code></li>\n<li><code><a title=\"smuview.Unit.name\" href=\"#smuview.Unit.name\">name</a></code></li>\n<li><code><a title=\"smuview.Unit.value\" href=\"#smuview.Unit.value\">value</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.UserChannel\" href=\"#smuview.UserChannel\">UserChannel</a></code></h4>\n<ul class=\"\">\n<li><code><a title=\"smuview.UserChannel.push_sample\" href=\"#smuview.UserChannel.push_sample\">push_sample</a></code></li>\n</ul>\n</li>\n<li>\n<h4><code><a title=\"smuview.UserDevice\" href=\"#smuview.UserDevice\">UserDevice</a></code></h4>\n</li>\n</ul>\n</li>\n</ul>\n</nav>\n</main>\n<footer id=\"footer\">\n<p>Generated by <a href=\"https://pdoc3.github.io/pdoc\"><cite>pdoc</cite> 0.9.3.dev7+g49b7773</a>.</p>\n</footer>\n</body>\n</html>\n"
  },
  {
    "path": "doc/smuview_python_bindings.txt",
    "content": "Help on built-in module smuview:\n\nNAME\n    smuview - The SmuView 0.0.5-git-64e7b9d Python bindings.\n\nDESCRIPTION\n    The Python bindings are a scripting extension for SmuView to automate, setup and control complex or repetitive measurements, to process the incoming data and to create a standardized user interface for those measurements.\n    \n    The smuview module offers two default object instances: `Session` and `UiProxy`.\n    The `Session` object gives access to already connected devices or connects new devices. The returned device object can then be used to read data from the device or control the device.\n    The `UiProxy` object instance is used to modify the user interface, for example adding tabs or views.\n    \n    Here is a short example that connects the HP 3378A DMM via GPIB, reads a sample and creates the default tab for the device:\n    ```\n    import smuview\n    import time\n    \n    # Connect device.\n    dmm_dev = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\n    # Sleep 1s to give the devices the chance to create signals.\n    time.sleep(1)\n    # Get last sample from channel P1.\n    sample = dmm_dev.channels()[\"P1\"].actual_signal().get_last_sample(True)\n    print(sample)\n    \n    # Add default tab for the DMM device.\n    UiProxy.add_device_tab(dmm_dev)\n    ```\n    \n    For more example scripts, please have a look into the `smuscript` folder.\n\nCLASSES\n    pybind11_builtins.pybind11_object(builtins.object)\n        BaseChannel\n            HardwareChannel\n            UserChannel\n        BaseDevice\n            HardwareDevice\n            UserDevice\n        BaseSignal\n            AnalogSampleSignal\n            AnalogTimeSignal\n        ConfigKey\n        Configurable\n        DataType\n        DockArea\n        PyStreamBuf\n        Quantity\n        QuantityFlag\n        Session\n        UiProxy\n        Unit\n    \n    class AnalogSampleSignal(BaseSignal)\n     |  A signal with key-value pairs.\n     |  \n     |  Method resolution order:\n     |      AnalogSampleSignal\n     |      BaseSignal\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  get_sample(...)\n     |      get_sample(self: smuview.AnalogSampleSignal, pos: int) -> Tuple[int, float]\n     |      \n     |      Return the sample for the given position.\n     |      \n     |      Parameters\n     |      ----------\n     |      pos : int\n     |          The position/number of the sample.\n     |      \n     |      Returns\n     |      -------\n     |      Tuple[int, float]\n     |          The sample with 1. the key and 2. the sample value.\n     |  \n     |  push_sample(...)\n     |      push_sample(self: smuview.AnalogSampleSignal, sample: capsule, pos: int, unit_size: int, digits: int, decimal_places: int) -> None\n     |      \n     |      Push a new sample to the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      sample : float or double\n     |          The sample value.\n     |      pos : int\n     |          The key (position) of the new sample.\n     |      unit_size : int\n     |          The size of the floating point data type (float=4, double=8) for the `sample` argument.\n     |      digits : int\n     |          The total number of digits.\n     |      decimal_places : int\n     |          The number of decimal places.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseSignal:\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseSignal) -> str\n     |      \n     |      Return the name of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the signal.\n     |  \n     |  sample_count(...)\n     |      sample_count(self: smuview.BaseSignal) -> int\n     |      \n     |      Return the number of samples of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      int\n     |          The number of samples.\n     |  \n     |  set_name(...)\n     |      set_name(self: smuview.BaseSignal, arg0: str) -> None\n     |      \n     |      Set a custom name for the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      custom_name : str\n     |          A custom name for the signal. If empty, the signal name will be automatically generated.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class AnalogTimeSignal(BaseSignal)\n     |  A signal with time-value pairs.\n     |  \n     |  Method resolution order:\n     |      AnalogTimeSignal\n     |      BaseSignal\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  get_last_sample(...)\n     |      get_last_sample(self: smuview.AnalogTimeSignal, relative_time: bool) -> Tuple[float, float]\n     |      \n     |      Return the last sample of the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      relative_time : bool\n     |          When `True`, the returned timestamp is relative to the start of the SmuView session.\n     |      \n     |      Returns\n     |      -------\n     |      Tuple[float, float]\n     |          The sample with 1. timestamp in milliseconds and 2. the sample value.\n     |  \n     |  get_sample(...)\n     |      get_sample(self: smuview.AnalogTimeSignal, pos: int, relative_time: bool) -> Tuple[float, float]\n     |      \n     |      Return the sample at the given position.\n     |      \n     |      Parameters\n     |      ----------\n     |      pos : int\n     |          The position/number of the sample.\n     |      relative_time : bool\n     |          When `True`, the returned timestamp is relative to the start of the SmuView session.\n     |      \n     |      Returns\n     |      -------\n     |      Tuple[float, float]\n     |          The sample with 1. timestamp in milliseconds and 2. the sample value.\n     |  \n     |  push_sample(...)\n     |      push_sample(self: smuview.AnalogTimeSignal, sample: capsule, timestamp: float, unit_size: int, digits: int, decimal_places: int) -> None\n     |      \n     |      Push a new sample to the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      sample : float or double\n     |          The sample value.\n     |      timestamp : float\n     |          The absolute timestamp in milliseconds.\n     |      unit_size : int\n     |          The size of the floating point data type (float=4, double=8) for the `sample` argument.\n     |      digits : int\n     |          The total number of digits.\n     |      decimal_places : int\n     |          The number of decimal places.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseSignal:\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseSignal) -> str\n     |      \n     |      Return the name of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the signal.\n     |  \n     |  sample_count(...)\n     |      sample_count(self: smuview.BaseSignal) -> int\n     |      \n     |      Return the number of samples of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      int\n     |          The number of samples.\n     |  \n     |  set_name(...)\n     |      set_name(self: smuview.BaseSignal, arg0: str) -> None\n     |      \n     |      Set a custom name for the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      custom_name : str\n     |          A custom name for the signal. If empty, the signal name will be automatically generated.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class BaseChannel(pybind11_builtins.pybind11_object)\n     |  The base class for all channel types.\n     |  \n     |  Method resolution order:\n     |      BaseChannel\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  actual_signal(...)\n     |      actual_signal(self: smuview.BaseChannel) -> smuview.BaseSignal\n     |      \n     |      Return the actual signal of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The actual signal object.\n     |  \n     |  add_signal(...)\n     |      add_signal(self: smuview.BaseChannel, quantity: smuview.Quantity, quantity_flags: Set[smuview.QuantityFlag], unit: smuview.Unit, custom_name: str = '') -> smuview.BaseSignal\n     |      \n     |      Add a new signal to the channel.\n     |      \n     |      Parameters\n     |      ----------\n     |      quantity : Quantity\n     |          The `Quantity` of the new signal.\n     |      quantity_flags : Set[QuantityFlag]\n     |          The `QuantityFlag`s of the new signal.\n     |      unit : Unit\n     |          The `Unit` of the new signal.\n     |      custom_name: str\n     |          A custom name for the new signal. If empty (default), the signal name will be automatically generated.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The new signal object.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseChannel) -> str\n     |      \n     |      Return the name of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the channel.\n     |  \n     |  signals(...)\n     |      signals(self: smuview.BaseChannel) -> List[smuview.BaseSignal]\n     |      \n     |      Return all signals of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      List[BaseSignal]\n     |          All signals of the channel.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class BaseDevice(pybind11_builtins.pybind11_object)\n     |  The base class for all device types.\n     |  \n     |  Method resolution order:\n     |      BaseDevice\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  add_user_channel(...)\n     |      add_user_channel(self: smuview.BaseDevice, channel_name: str, channel_group_name: str) -> smuview.UserChannel\n     |      \n     |      Add a new user channel to the device.\n     |      \n     |      Parameters\n     |      ----------\n     |      channel_name : str\n     |          The name of the new user channel.\n     |      channel_group_name : str\n     |          The name of the channel group where to create the user channel. Can be empty.\n     |      \n     |      Returns\n     |      -------\n     |      UserChannel\n     |          The new user channel object.\n     |  \n     |  channels(...)\n     |      channels(self: smuview.BaseDevice) -> Dict[str, smuview.BaseChannel]\n     |      \n     |      Return all channels of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, BaseChannel]\n     |          A Dict where the key is the id of the channel and the value is the channel object.\n     |  \n     |  configurables(...)\n     |      configurables(self: smuview.BaseDevice) -> Dict[str, smuview.Configurable]\n     |      \n     |      Return all configurables of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, Configurable]\n     |          A Dict where the key is the id of the `Configurable` and the value is the `Configurable` object.\n     |  \n     |  id(...)\n     |      id(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the unique id of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the device.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the name of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the device.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class BaseSignal(pybind11_builtins.pybind11_object)\n     |  The base class for all signal types.\n     |  \n     |  Method resolution order:\n     |      BaseSignal\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseSignal) -> str\n     |      \n     |      Return the name of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the signal.\n     |  \n     |  sample_count(...)\n     |      sample_count(self: smuview.BaseSignal) -> int\n     |      \n     |      Return the number of samples of the signal.\n     |      \n     |      Returns\n     |      -------\n     |      int\n     |          The number of samples.\n     |  \n     |  set_name(...)\n     |      set_name(self: smuview.BaseSignal, arg0: str) -> None\n     |      \n     |      Set a custom name for the signal.\n     |      \n     |      Parameters\n     |      ----------\n     |      custom_name : str\n     |          A custom name for the signal. If empty, the signal name will be automatically generated.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class ConfigKey(pybind11_builtins.pybind11_object)\n     |  Enum of all available config keys for controlling a device.\n     |  \n     |  Method resolution order:\n     |      ConfigKey\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.ConfigKey) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.ConfigKey, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.ConfigKey) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.ConfigKey, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods defined here:\n     |  \n     |  get_data_type(...) from builtins.PyCapsule\n     |      get_data_type(config_key: smuview.ConfigKey) -> smuview.DataType\n     |      \n     |      Helper function to get the data type for a config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The config key.\n     |      \n     |      Returns\n     |      -------\n     |      DataType\n     |          The data type of the config key.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  ADCPowerlineCycles = <ConfigKey.ADCPowerlineCycles: 69>\n     |  \n     |  Amplitude = <ConfigKey.Amplitude: 47>\n     |  \n     |  Averaging = <ConfigKey.Averaging: 5>\n     |  \n     |  AvgSamples = <ConfigKey.AvgSamples: 6>\n     |  \n     |  BufferSize = <ConfigKey.BufferSize: 9>\n     |  \n     |  CaptureFile = <ConfigKey.CaptureFile: 64>\n     |  \n     |  CaptureRatio = <ConfigKey.CaptureRatio: 1>\n     |  \n     |  CaptureUnitSize = <ConfigKey.CaptureUnitSize: 65>\n     |  \n     |  CenterFrequency = <ConfigKey.CenterFrequency: 26>\n     |  \n     |  ChannelConfig = <ConfigKey.ChannelConfig: 34>\n     |  \n     |  ClockEdge = <ConfigKey.ClockEdge: 46>\n     |  \n     |  Coupling = <ConfigKey.Coupling: 13>\n     |  \n     |  Current = <ConfigKey.Current: 31>\n     |  \n     |  CurrentLimit = <ConfigKey.CurrentLimit: 32>\n     |  \n     |  DataLog = <ConfigKey.DataLog: 70>\n     |  \n     |  DataSource = <ConfigKey.DataSource: 67>\n     |  \n     |  DeviceMode = <ConfigKey.DeviceMode: 71>\n     |  \n     |  Digits = <ConfigKey.Digits: 62>\n     |  \n     |  Enabled = <ConfigKey.Enabled: 33>\n     |  \n     |  EquivCircuitModel = <ConfigKey.EquivCircuitModel: 52>\n     |  \n     |  ExternalClock = <ConfigKey.ExternalClock: 24>\n     |  \n     |  ExternalClockSource = <ConfigKey.ExternalClockSource: 54>\n     |  \n     |  Filter = <ConfigKey.Filter: 11>\n     |  \n     |  HighResolution = <ConfigKey.HighResolution: 57>\n     |  \n     |  HoldMax = <ConfigKey.HoldMax: 21>\n     |  \n     |  HoldMin = <ConfigKey.HoldMin: 22>\n     |  \n     |  HorizTriggerPos = <ConfigKey.HorizTriggerPos: 8>\n     |  \n     |  LogicThreshold = <ConfigKey.LogicThreshold: 59>\n     |  \n     |  LogicThresholdCustom = <ConfigKey.LogicThresholdCustom: 60>\n     |  \n     |  MeasuredQuantity = <ConfigKey.MeasuredQuantity: 51>\n     |  \n     |  NumAnalogChannels = <ConfigKey.NumAnalogChannels: 28>\n     |  \n     |  NumHDiv = <ConfigKey.NumHDiv: 16>\n     |  \n     |  NumLogicChannels = <ConfigKey.NumLogicChannels: 27>\n     |  \n     |  NumVDiv = <ConfigKey.NumVDiv: 17>\n     |  \n     |  Offset = <ConfigKey.Offset: 55>\n     |  \n     |  OutputFrequency = <ConfigKey.OutputFrequency: 49>\n     |  \n     |  OutputFrequencyTarget = <ConfigKey.OutputFrequencyTarget: 50>\n     |  \n     |  OverCurrentProtectionActive = <ConfigKey.OverCurrentProtectionActive: ...\n     |  \n     |  OverCurrentProtectionEnabled = <ConfigKey.OverCurrentProtectionEnabled...\n     |  \n     |  OverCurrentProtectionThreshold = <ConfigKey.OverCurrentProtectionThres...\n     |  \n     |  OverTemperatureProtectionActive = <ConfigKey.OverTemperatureProtection...\n     |  \n     |  OverTemperatureProtectionEnabled = <ConfigKey.OverTemperatureProtectio...\n     |  \n     |  OverVoltageProtectionActive = <ConfigKey.OverVoltageProtectionActive: ...\n     |  \n     |  OverVoltageProtectionEnabled = <ConfigKey.OverVoltageProtectionEnabled...\n     |  \n     |  OverVoltageProtectionThreshold = <ConfigKey.OverVoltageProtectionThres...\n     |  \n     |  PatternMode = <ConfigKey.PatternMode: 2>\n     |  \n     |  PeakDetection = <ConfigKey.PeakDetection: 58>\n     |  \n     |  PowerOff = <ConfigKey.PowerOff: 66>\n     |  \n     |  ProbeFactor = <ConfigKey.ProbeFactor: 68>\n     |  \n     |  RLE = <ConfigKey.RLE: 3>\n     |  \n     |  Range = <ConfigKey.Range: 61>\n     |  \n     |  Regulation = <ConfigKey.Regulation: 48>\n     |  \n     |  SampleInterval = <ConfigKey.SampleInterval: 15>\n     |  \n     |  Samplerate = <ConfigKey.Samplerate: 0>\n     |  \n     |  SessionFile = <ConfigKey.SessionFile: 63>\n     |  \n     |  SplMeasurementRange = <ConfigKey.SplMeasurementRange: 20>\n     |  \n     |  SplWeightFreq = <ConfigKey.SplWeightFreq: 18>\n     |  \n     |  SplWeightTime = <ConfigKey.SplWeightTime: 19>\n     |  \n     |  Swap = <ConfigKey.Swap: 25>\n     |  \n     |  TestMode = <ConfigKey.TestMode: 72>\n     |  \n     |  TimeBase = <ConfigKey.TimeBase: 10>\n     |  \n     |  TriggerLevel = <ConfigKey.TriggerLevel: 53>\n     |  \n     |  TriggerMatch = <ConfigKey.TriggerMatch: 14>\n     |  \n     |  TriggerPattern = <ConfigKey.TriggerPattern: 56>\n     |  \n     |  TriggerSlope = <ConfigKey.TriggerSlope: 4>\n     |  \n     |  TriggerSource = <ConfigKey.TriggerSource: 7>\n     |  \n     |  UnderVoltageConditionActive = <ConfigKey.UnderVoltageConditionActive: ...\n     |  \n     |  UnderVoltageConditionEnabled = <ConfigKey.UnderVoltageConditionEnabled...\n     |  \n     |  UnderVoltageConditionThreshold = <ConfigKey.UnderVoltageConditionThres...\n     |  \n     |  Unknown = <ConfigKey.Unknown: 73>\n     |  \n     |  VDiv = <ConfigKey.VDiv: 12>\n     |  \n     |  Voltage = <ConfigKey.Voltage: 29>\n     |  \n     |  VoltageTarget = <ConfigKey.VoltageTarget: 30>\n     |  \n     |  VoltageThreshold = <ConfigKey.VoltageThreshold: 23>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class Configurable(pybind11_builtins.pybind11_object)\n     |  A configurable for controlling a device with config keys.\n     |  \n     |  Method resolution order:\n     |      Configurable\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  get_bool_config(...)\n     |      get_bool_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> bool\n     |      \n     |      Return a boolean value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      bool\n     |          The bool value of the config key.\n     |  \n     |  get_double_config(...)\n     |      get_double_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> float\n     |      \n     |      Return a double value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      float\n     |          The float value of the config key.\n     |  \n     |  get_int_config(...)\n     |      get_int_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> int\n     |      \n     |      Return an integer value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      int\n     |          The int value of the config key.\n     |  \n     |  get_measured_quantity_config(...)\n     |      get_measured_quantity_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> Tuple[smuview.Quantity, Set[smuview.QuantityFlag]]\n     |      \n     |      Return a measured quantity value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      Tuple[Quantity, Set[QuantityFlag]]\n     |          The measured quantity value of the config key.\n     |  \n     |  get_string_config(...)\n     |      get_string_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> str\n     |      \n     |      Return a string value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The string value of the config key.\n     |  \n     |  get_uint_config(...)\n     |      get_uint_config(self: smuview.Configurable, config_key: smuview.ConfigKey) -> int\n     |      \n     |      Return an unsigned integer value from the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to get.\n     |      \n     |      Returns\n     |      -------\n     |      int\n     |          The (unsigned) int value of the config key.\n     |  \n     |  getable_configs(...)\n     |      getable_configs(self: smuview.Configurable) -> Set[smuview.ConfigKey]\n     |      \n     |      Return all getable config keys.\n     |      \n     |      Returns\n     |      -------\n     |      List[ConfigKey]\n     |          All getable config keys.\n     |  \n     |  listable_configs(...)\n     |      listable_configs(self: smuview.Configurable) -> Set[smuview.ConfigKey]\n     |      \n     |      Return all listable config keys.\n     |      \n     |      Returns\n     |      -------\n     |      List[ConfigKey]\n     |          All listable config keys.\n     |  \n     |  name(...)\n     |      name(self: smuview.Configurable) -> str\n     |      \n     |      Return the name of the configurable.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the configurable.\n     |  \n     |  set_config(...)\n     |      set_config(*args, **kwargs)\n     |      Overloaded function.\n     |      \n     |      1. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: bool) -> None\n     |      \n     |      Set a boolean value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : bool\n     |          The bool value to set.\n     |      \n     |      2. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: int) -> None\n     |      \n     |      Set an integer value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : int\n     |          The int value to set.\n     |      \n     |      3. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: int) -> None\n     |      \n     |      Set an unsigned integer value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : int\n     |          The (unsigned) int value to set.\n     |      \n     |      4. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: float) -> None\n     |      \n     |      Set a double value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : float\n     |          The float value to set.\n     |      \n     |      5. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: str) -> None\n     |      \n     |      Set a string value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : str\n     |          The string value to set.\n     |      \n     |      6. set_config(self: smuview.Configurable, config_key: smuview.ConfigKey, value: Tuple[smuview.Quantity, Set[smuview.QuantityFlag]]) -> None\n     |      \n     |      Set a measured quantity value to the given config key.\n     |      \n     |      Parameters\n     |      ----------\n     |      config_key : ConfigKey\n     |          The `ConfigKey` to set.\n     |      value : Tuple[Quantity, Set[QuantityFlag]]\n     |          The measured quantity value to set.\n     |  \n     |  setable_configs(...)\n     |      setable_configs(self: smuview.Configurable) -> Set[smuview.ConfigKey]\n     |      \n     |      Return all setable config keys.\n     |      \n     |      Returns\n     |      -------\n     |      List[ConfigKey]\n     |          All setable config keys.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class DataType(pybind11_builtins.pybind11_object)\n     |  Enum of all available data types.\n     |  \n     |  Method resolution order:\n     |      DataType\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.DataType) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.DataType, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.DataType) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.DataType, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  Bool = <DataType.Bool: 2>\n     |  \n     |  Double = <DataType.Double: 3>\n     |  \n     |  DoubleRange = <DataType.DoubleRange: 8>\n     |  \n     |  Int32 = <DataType.Int32: 9>\n     |  \n     |  KeyValue = <DataType.KeyValue: 6>\n     |  \n     |  MQ = <DataType.MQ: 10>\n     |  \n     |  RationalPeriod = <DataType.RationalPeriod: 4>\n     |  \n     |  RationalVolt = <DataType.RationalVolt: 5>\n     |  \n     |  String = <DataType.String: 1>\n     |  \n     |  UInt64 = <DataType.UInt64: 0>\n     |  \n     |  UInt64Range = <DataType.UInt64Range: 7>\n     |  \n     |  Unknown = <DataType.Unknown: 11>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class DockArea(pybind11_builtins.pybind11_object)\n     |  Enum of all possible docking locations for a view.\n     |  \n     |  Method resolution order:\n     |      DockArea\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.DockArea) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.DockArea, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.DockArea) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.DockArea, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  BottomDockArea = <DockArea.BottomDockArea: 8>\n     |  \n     |  LeftDocktArea = <DockArea.LeftDocktArea: 1>\n     |  \n     |  RightDockArea = <DockArea.RightDockArea: 2>\n     |  \n     |  TopDockArea = <DockArea.TopDockArea: 4>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class HardwareChannel(BaseChannel)\n     |  An actual hardware channel\n     |  \n     |  Method resolution order:\n     |      HardwareChannel\n     |      BaseChannel\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseChannel:\n     |  \n     |  actual_signal(...)\n     |      actual_signal(self: smuview.BaseChannel) -> smuview.BaseSignal\n     |      \n     |      Return the actual signal of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The actual signal object.\n     |  \n     |  add_signal(...)\n     |      add_signal(self: smuview.BaseChannel, quantity: smuview.Quantity, quantity_flags: Set[smuview.QuantityFlag], unit: smuview.Unit, custom_name: str = '') -> smuview.BaseSignal\n     |      \n     |      Add a new signal to the channel.\n     |      \n     |      Parameters\n     |      ----------\n     |      quantity : Quantity\n     |          The `Quantity` of the new signal.\n     |      quantity_flags : Set[QuantityFlag]\n     |          The `QuantityFlag`s of the new signal.\n     |      unit : Unit\n     |          The `Unit` of the new signal.\n     |      custom_name: str\n     |          A custom name for the new signal. If empty (default), the signal name will be automatically generated.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The new signal object.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseChannel) -> str\n     |      \n     |      Return the name of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the channel.\n     |  \n     |  signals(...)\n     |      signals(self: smuview.BaseChannel) -> List[smuview.BaseSignal]\n     |      \n     |      Return all signals of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      List[BaseSignal]\n     |          All signals of the channel.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class HardwareDevice(BaseDevice)\n     |  An actual hardware device.\n     |  \n     |  Method resolution order:\n     |      HardwareDevice\n     |      BaseDevice\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseDevice:\n     |  \n     |  add_user_channel(...)\n     |      add_user_channel(self: smuview.BaseDevice, channel_name: str, channel_group_name: str) -> smuview.UserChannel\n     |      \n     |      Add a new user channel to the device.\n     |      \n     |      Parameters\n     |      ----------\n     |      channel_name : str\n     |          The name of the new user channel.\n     |      channel_group_name : str\n     |          The name of the channel group where to create the user channel. Can be empty.\n     |      \n     |      Returns\n     |      -------\n     |      UserChannel\n     |          The new user channel object.\n     |  \n     |  channels(...)\n     |      channels(self: smuview.BaseDevice) -> Dict[str, smuview.BaseChannel]\n     |      \n     |      Return all channels of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, BaseChannel]\n     |          A Dict where the key is the id of the channel and the value is the channel object.\n     |  \n     |  configurables(...)\n     |      configurables(self: smuview.BaseDevice) -> Dict[str, smuview.Configurable]\n     |      \n     |      Return all configurables of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, Configurable]\n     |          A Dict where the key is the id of the `Configurable` and the value is the `Configurable` object.\n     |  \n     |  id(...)\n     |      id(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the unique id of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the device.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the name of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the device.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class PyStreamBuf(pybind11_builtins.pybind11_object)\n     |  Redirect all Python output to a SmuView console. This class is for internal SmuView use only!\n     |  \n     |  Method resolution order:\n     |      PyStreamBuf\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __del__(...)\n     |      __del__(self: smuview.PyStreamBuf) -> None\n     |      \n     |      Prepare for object destruction.\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.PyStreamBuf, arg0: str, arg1: str) -> None\n     |  \n     |  close(...)\n     |      close(self: smuview.PyStreamBuf) -> None\n     |      \n     |      Flush and close this stream.\n     |  \n     |  fileno(...)\n     |      fileno(self: smuview.PyStreamBuf) -> int\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` doesn't use a file descriptor.\n     |  \n     |  flush(...)\n     |      flush(self: smuview.PyStreamBuf) -> None\n     |      \n     |      Flush the write buffers of the stream.\n     |  \n     |  isatty(...)\n     |      isatty(self: smuview.PyStreamBuf) -> bool\n     |      \n     |      Always returns `False`.\n     |  \n     |  read(...)\n     |      read(self: smuview.PyStreamBuf, size: int) -> str\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is write only.\n     |  \n     |  readable(...)\n     |      readable(self: smuview.PyStreamBuf) -> bool\n     |      \n     |      Always returns `False`.\n     |  \n     |  readline(...)\n     |      readline(self: smuview.PyStreamBuf, size: int) -> str\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is write only.\n     |  \n     |  readlines(...)\n     |      readlines(self: smuview.PyStreamBuf, hint: int) -> List[str]\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is write only.\n     |  \n     |  seek(...)\n     |      seek(self: smuview.PyStreamBuf, offset: int, whence: int) -> int\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is not seekable.\n     |  \n     |  seekable(...)\n     |      seekable(self: smuview.PyStreamBuf) -> bool\n     |      \n     |      Always returns `False`. `PyStreamBuf` is not seekable atm.\n     |  \n     |  tell(...)\n     |      tell(self: smuview.PyStreamBuf) -> int\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is not seekable.\n     |  \n     |  truncate(...)\n     |      truncate(self: smuview.PyStreamBuf, size: int) -> int\n     |      \n     |      Raises an `OSError`, because `PyStreamBuf` is not seekable.\n     |  \n     |  writable(...)\n     |      writable(self: smuview.PyStreamBuf) -> bool\n     |      \n     |      Always return `True`.\n     |  \n     |  write(...)\n     |      write(self: smuview.PyStreamBuf, s: str) -> int\n     |      \n     |      Write the string `s` to the stream and return the number of characters written.\n     |  \n     |  writelines(...)\n     |      writelines(self: smuview.PyStreamBuf, lines: List[str]) -> None\n     |      \n     |      Write a list of lines to the stream.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  closed\n     |      `True` if the stream is closed.\n     |  \n     |  encoding\n     |      The name of the encoding that is used.\n     |  \n     |  errors\n     |      The error setting of the decoder or encoder.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class Quantity(pybind11_builtins.pybind11_object)\n     |  Enum of all available quantities.\n     |  \n     |  Method resolution order:\n     |      Quantity\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.Quantity) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.Quantity, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.Quantity) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.Quantity, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  ApparentPower = <Quantity.ApparentPower: 31>\n     |  \n     |  Capacitance = <Quantity.Capacitance: 3>\n     |  \n     |  CarbonMonoxide = <Quantity.CarbonMonoxide: 14>\n     |  \n     |  Conductance = <Quantity.Conductance: 9>\n     |  \n     |  Continuity = <Quantity.Continuity: 7>\n     |  \n     |  Count = <Quantity.Count: 29>\n     |  \n     |  Current = <Quantity.Current: 1>\n     |  \n     |  Difference = <Quantity.Difference: 28>\n     |  \n     |  DissipationFactor = <Quantity.DissipationFactor: 25>\n     |  \n     |  DutyCyle = <Quantity.DutyCyle: 6>\n     |  \n     |  ElectricCharge = <Quantity.ElectricCharge: 11>\n     |  \n     |  Energy = <Quantity.Energy: 34>\n     |  \n     |  Frequency = <Quantity.Frequency: 5>\n     |  \n     |  Gain = <Quantity.Gain: 12>\n     |  \n     |  HarmonicRatio = <Quantity.HarmonicRatio: 33>\n     |  \n     |  Mass = <Quantity.Mass: 32>\n     |  \n     |  ParallelCapacitance = <Quantity.ParallelCapacitance: 20>\n     |  \n     |  ParallelInductance = <Quantity.ParallelInductance: 19>\n     |  \n     |  ParallelResistance = <Quantity.ParallelResistance: 21>\n     |  \n     |  PhaseAngle = <Quantity.PhaseAngle: 27>\n     |  \n     |  Power = <Quantity.Power: 10>\n     |  \n     |  PowerFactor = <Quantity.PowerFactor: 30>\n     |  \n     |  Pressure = <Quantity.Pressure: 18>\n     |  \n     |  PulseWidth = <Quantity.PulseWidth: 8>\n     |  \n     |  QualityFactor = <Quantity.QualityFactor: 26>\n     |  \n     |  RelativeHumidity = <Quantity.RelativeHumidity: 15>\n     |  \n     |  Resistance = <Quantity.Resistance: 2>\n     |  \n     |  SeriesCapacitance = <Quantity.SeriesCapacitance: 23>\n     |  \n     |  SeriesInductance = <Quantity.SeriesInductance: 22>\n     |  \n     |  SeriesResistance = <Quantity.SeriesResistance: 24>\n     |  \n     |  SoundPressureLevel = <Quantity.SoundPressureLevel: 13>\n     |  \n     |  Temperature = <Quantity.Temperature: 4>\n     |  \n     |  Time = <Quantity.Time: 16>\n     |  \n     |  Unknown = <Quantity.Unknown: 35>\n     |  \n     |  Voltage = <Quantity.Voltage: 0>\n     |  \n     |  WindSpeed = <Quantity.WindSpeed: 17>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class QuantityFlag(pybind11_builtins.pybind11_object)\n     |  Enum of all available quantity flags.\n     |  \n     |  Method resolution order:\n     |      QuantityFlag\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.QuantityFlag) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.QuantityFlag, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.QuantityFlag) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.QuantityFlag, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  AC = <QuantityFlag.AC: 0>\n     |  \n     |  Autorange = <QuantityFlag.Autorange: 7>\n     |  \n     |  Avg = <QuantityFlag.Avg: 18>\n     |  \n     |  DC = <QuantityFlag.DC: 1>\n     |  \n     |  Diode = <QuantityFlag.Diode: 3>\n     |  \n     |  Duration = <QuantityFlag.Duration: 17>\n     |  \n     |  FourWire = <QuantityFlag.FourWire: 21>\n     |  \n     |  Hold = <QuantityFlag.Hold: 4>\n     |  \n     |  Max = <QuantityFlag.Max: 5>\n     |  \n     |  Min = <QuantityFlag.Min: 6>\n     |  \n     |  RMS = <QuantityFlag.RMS: 2>\n     |  \n     |  Reference = <QuantityFlag.Reference: 19>\n     |  \n     |  Relative = <QuantityFlag.Relative: 8>\n     |  \n     |  SplFreqWeightA = <QuantityFlag.SplFreqWeightA: 9>\n     |  \n     |  SplFreqWeightC = <QuantityFlag.SplFreqWeightC: 10>\n     |  \n     |  SplFreqWeightFlat = <QuantityFlag.SplFreqWeightFlat: 12>\n     |  \n     |  SplFreqWeightZ = <QuantityFlag.SplFreqWeightZ: 11>\n     |  \n     |  SplLAT = <QuantityFlag.SplLAT: 15>\n     |  \n     |  SplPctOverAlarm = <QuantityFlag.SplPctOverAlarm: 16>\n     |  \n     |  SplTimeWeightF = <QuantityFlag.SplTimeWeightF: 14>\n     |  \n     |  SplTimeWeightS = <QuantityFlag.SplTimeWeightS: 13>\n     |  \n     |  Unknown = <QuantityFlag.Unknown: 22>\n     |  \n     |  Unstable = <QuantityFlag.Unstable: 20>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class Session(pybind11_builtins.pybind11_object)\n     |  The SmuView `Session` class for accessing the actual state of the application.\n     |  \n     |  Method resolution order:\n     |      Session\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  add_user_device(...)\n     |      add_user_device(self: smuview.Session) -> smuview.UserDevice\n     |      \n     |      Create a new user device.\n     |      \n     |      Returns\n     |      -------\n     |      UserDevice\n     |          The created user device object.\n     |  \n     |  connect_device(...)\n     |      connect_device(self: smuview.Session, conn_str: str) -> List[smuview.HardwareDevice]\n     |      \n     |      Connect a new device. For some devices (like DMMs) you may want to wait a fixed time, until the first sample has arrived and an `AnalogSignal` object has been created. Example:\n     |      ```\n     |      import smuview\n     |      import time\n     |      \n     |      # Connect device.\n     |      dmm_dev = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\n     |      # Sleep 1s to give the devices the chance to create signals.\n     |      time.sleep(1)\n     |      ```\n     |      \n     |      Parameters\n     |      ----------\n     |      conn_str : str\n     |          The connection string. See https://sigrok.org/wiki/Connection_parameters\n     |      \n     |      Returns\n     |      -------\n     |      List[HardwareDevice]\n     |          A List with the newly connected device objects.\n     |  \n     |  devices(...)\n     |      devices(self: smuview.Session) -> Dict[str, smuview.BaseDevice]\n     |      \n     |      Return all connected devices.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, BaseDevice]\n     |          A Dict where the key is the device id and the value is the device object.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class UiProxy(pybind11_builtins.pybind11_object)\n     |  Helper class for accessing the UI.\n     |  \n     |  Method resolution order:\n     |      UiProxy\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  add_control_view(...)\n     |      add_control_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, configurable: smuview.Configurable) -> str\n     |      \n     |      Add a control view for a configurable to the given tab.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      configurable : Configurable\n     |          The `Configurable` object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  add_curve_to_time_plot_view(...)\n     |      add_curve_to_time_plot_view(self: smuview.UiProxy, tab_id: str, view_id: str, signal: smuview.AnalogTimeSignal) -> str\n     |      \n     |      Add a signal to the given time plot view.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the time plot view.\n     |      signal : AnalogTimeSignal\n     |          The signal object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new curve or empty if the curve couldn't be added.\n     |  \n     |  add_curve_to_xy_plot_view(...)\n     |      add_curve_to_xy_plot_view(self: smuview.UiProxy, tab_id: str, view_id: str, x_signal: smuview.AnalogTimeSignal, y_signal: smuview.AnalogTimeSignal) -> str\n     |      \n     |      Add x/y signals to the given x/y plot view.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the x/y plot view.\n     |      x_signal : AnalogTimeSignal\n     |          The x signal object.\n     |      y_signal : AnalogTimeSignal\n     |          The y signal object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new curve or empty if the curve couldn't be added.\n     |  \n     |  add_data_view(...)\n     |      add_data_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, signal: smuview.AnalogTimeSignal) -> str\n     |      \n     |      Add a data view for a signal to the given tab.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      signal : AnalogTimeSignal\n     |          The signal object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  add_device_tab(...)\n     |      add_device_tab(self: smuview.UiProxy, device: smuview.BaseDevice) -> str\n     |      \n     |      Add a device tab with standard view for a device to the UI.\n     |      \n     |      Parameters\n     |      ----------\n     |      device : BaseDevice\n     |          The device object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new tab or empty if the tab couldn't be added.\n     |  \n     |  add_power_panel_view(...)\n     |      add_power_panel_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, voltage_signal: smuview.AnalogTimeSignal, current_signal: smuview.AnalogTimeSignal) -> str\n     |      \n     |      Add a power panel view for a voltage and a current signal to the given tab.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      voltage_signal : AnalogTimeSignal\n     |          The voltage signal object.\n     |      current_signal : AnalogTimeSignal\n     |          The current signal object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  add_signal_to_data_view(...)\n     |      add_signal_to_data_view(self: smuview.UiProxy, tab_id: str, view_id: str, signal: smuview.AnalogTimeSignal) -> None\n     |      \n     |      Add a signal to the given data view.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the data view.\n     |      signal : AnalogTimeSignal\n     |          The signal object.\n     |  \n     |  add_time_plot_view(...)\n     |      add_time_plot_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea) -> str\n     |      \n     |      Add a time plot view to the given tab. Use [`UiProxy.set_channel_to_time_plot_view()`](UiProxy.set_channel_to_time_plot_view) to set a channel to the plot view or use [`UiProxy.add_curve_to_time_plot_view()`](UiProxy.add_curve_to_time_plot_view) to set a signal to the plot view.\n     |      When you have set a channel to the plot, new curves will be automatically created, when the channel changes (e.g. for multimeters when switching functions).\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  add_value_panel_view(...)\n     |      add_value_panel_view(*args, **kwargs)\n     |      Overloaded function.\n     |      \n     |      1. add_value_panel_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, channel: smuview.BaseChannel) -> str\n     |      \n     |      Add a value panel view for a channel to the given tab.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      channel : BaseChannel\n     |          The channel object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |      \n     |      2. add_value_panel_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea, signal: smuview.AnalogTimeSignal) -> str\n     |      \n     |      Add a value panel view for a signal to the given tab.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      signal : AnalogTimeSignal\n     |          The signal object.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  add_xy_plot_view(...)\n     |      add_xy_plot_view(self: smuview.UiProxy, tab_id: str, area: smuview.DockArea) -> str\n     |      \n     |      Add a x/y plot view for two signals to the given tab. Use [`UiProxy.add_curve_to_xy_plot_view()`](UiProxy.add_curve_to_xy_plot_view) to add a new curve (a set of two signals) to the plot view.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      area : DockArea\n     |          Where to put the new view.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the new view or empty if the view couldn't be added.\n     |  \n     |  set_channel_to_time_plot_view(...)\n     |      set_channel_to_time_plot_view(self: smuview.UiProxy, tab_id: str, view_id: str, channel: smuview.BaseChannel) -> None\n     |      \n     |      Set a channel to the given time plot view. New curves will be automatically created, when the channel changes (e.g. for multimeters when switching functions).\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the time plot view.\n     |      channel : BaseChannel\n     |          The channel object.\n     |  \n     |  set_curve_color(...)\n     |      set_curve_color(self: smuview.UiProxy, tab_id: str, view_id: str, curve_id: str, color: Tuple[int, int, int]) -> None\n     |      \n     |      Set the color of the given curve.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the plot view.\n     |      curve_id : str\n     |          The id of the curve.\n     |      color : Tuple[int, int, int]\n     |          The color for the curve as a Tuple with the RGB values.\n     |  \n     |  set_curve_name(...)\n     |      set_curve_name(self: smuview.UiProxy, tab_id: str, view_id: str, curve_id: str, name: str) -> None\n     |      \n     |      Set the name of the given curve.\n     |      \n     |      Parameters\n     |      ----------\n     |      tab_id : str\n     |          The id of the tab.\n     |      view_id : str\n     |          The id of the plot view.\n     |      curve_id : str\n     |          The id of the curve.\n     |      name : str\n     |          The name for the curve.\n     |  \n     |  show_double_input_dialog(...)\n     |      show_double_input_dialog(self: smuview.UiProxy, title: str, label: str, value: float = 0.0, decimals: int = 1, step: float = 0.1, min: float = 2.2250738585072014e-308, max: float = 1.7976931348623157e+308) -> object\n     |      \n     |      Show a dialog window to get a float value from the user. It returns the entered float value or `None` if the Cancel button was pressed.\n     |      \n     |      Only has effect if the used Qt version is equal or greater than 5.10!\n     |      \n     |      Parameters\n     |      ----------\n     |      title : str\n     |          The window title of the input dialog.\n     |      label : str\n     |          The label to display in the input dialog.\n     |      value : float\n     |          The default value of the float.\n     |      decimals : int\n     |          The maximum number of decimal places the number may have. Default is 1.\n     |      step : float\n     |          The amount by which the value can be incremented or decremented by the user.    Default is 0.1.\n     |          Only has effect for Qt versions >= 5.10!\n     |      min : float\n     |          The minimum value the user may choose.\n     |      max : float\n     |          The maximum value the user may choose.\n     |      \n     |      Returns\n     |      -------\n     |      float or None\n     |          The user entered float value or `None` when the Cancel button was pressed.\n     |  \n     |  show_int_input_dialog(...)\n     |      show_int_input_dialog(self: smuview.UiProxy, title: str, label: str, value: int = 0, step: int = 1, min: int = -2147483648, max: int = 2147483647) -> object\n     |      \n     |      Show a dialog window to get an integer value from the user. It returns the entered float value or `None` if the Cancel button was pressed.\n     |      \n     |      Parameters\n     |      ----------\n     |      title : str\n     |          The window title of the input dialog.\n     |      label : str\n     |          The label to display in the input dialog.\n     |      value : int\n     |          The default value of the integer.\n     |      step : int\n     |          The amount by which the value can be incremented or decremented by the user. Default is 1.\n     |      min : int\n     |          The minimum value the user may choose.\n     |      max : int\n     |          The maximum value the user may choose.\n     |      \n     |      Returns\n     |      -------\n     |      int or None\n     |          The user entered integer value or `None` when the Cancel button was pressed.\n     |  \n     |  show_message_box(...)\n     |      show_message_box(self: smuview.UiProxy, title: str, text: str) -> bool\n     |      \n     |      Show a (info) message box with the given window title and text. Returns `True` when the Ok button was pressed.\n     |      \n     |      Parameters\n     |      ----------\n     |      title : str\n     |          The window title of the message box.\n     |      text : str\n     |          The text to display in the message box.\n     |      \n     |      Returns\n     |      -------\n     |      bool\n     |          `True` when the Ok button was pressed, else `False`.\n     |  \n     |  show_string_input_dialog(...)\n     |      show_string_input_dialog(self: smuview.UiProxy, title: str, label: str, value: str = '') -> object\n     |      \n     |      Show a dialog window to get a string value from the user. It returns the entered string value or `None` if the Cancel button was pressed.\n     |      \n     |      Parameters\n     |      ----------\n     |      title : str\n     |          The window title of the input dialog.\n     |      label : str\n     |          The label to display in the input dialog.\n     |      value : str\n     |          The default value of the string.\n     |      \n     |      Returns\n     |      -------\n     |      str or None\n     |          The user entered string value or `None` when the Cancel button was pressed.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class Unit(pybind11_builtins.pybind11_object)\n     |  Enum of all available units.\n     |  \n     |  Method resolution order:\n     |      Unit\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __eq__(...)\n     |      __eq__(self: object, other: object) -> bool\n     |  \n     |  __getstate__(...)\n     |      __getstate__(self: object) -> int\n     |  \n     |  __hash__(...)\n     |      __hash__(self: object) -> int\n     |  \n     |  __index__(...)\n     |      __index__(self: smuview.Unit) -> int\n     |  \n     |  __init__(...)\n     |      __init__(self: smuview.Unit, value: int) -> None\n     |  \n     |  __int__(...)\n     |      __int__(self: smuview.Unit) -> int\n     |  \n     |  __ne__(...)\n     |      __ne__(self: object, other: object) -> bool\n     |  \n     |  __repr__(...)\n     |      __repr__(self: object) -> str\n     |  \n     |  __setstate__(...)\n     |      __setstate__(self: smuview.Unit, state: int) -> None\n     |  \n     |  __str__ = name(...)\n     |      name(self: handle) -> str\n     |  \n     |  ----------------------------------------------------------------------\n     |  Readonly properties defined here:\n     |  \n     |  __members__\n     |  \n     |  name\n     |      name(self: handle) -> str\n     |  \n     |  value\n     |  \n     |  ----------------------------------------------------------------------\n     |  Data and other attributes defined here:\n     |  \n     |  Ampere = <Unit.Ampere: 1>\n     |  \n     |  AmpereHour = <Unit.AmpereHour: 22>\n     |  \n     |  Boolean = <Unit.Boolean: 9>\n     |  \n     |  Carat = <Unit.Carat: 30>\n     |  \n     |  Celsius = <Unit.Celsius: 5>\n     |  \n     |  Concentration = <Unit.Concentration: 16>\n     |  \n     |  Coulomb = <Unit.Coulomb: 23>\n     |  \n     |  DecibelMW = <Unit.DecibelMW: 12>\n     |  \n     |  DecibelSpl = <Unit.DecibelSpl: 15>\n     |  \n     |  DecibelVolt = <Unit.DecibelVolt: 13>\n     |  \n     |  Degree = <Unit.Degree: 27>\n     |  \n     |  Fahrenheit = <Unit.Fahrenheit: 6>\n     |  \n     |  Farad = <Unit.Farad: 3>\n     |  \n     |  Grain = <Unit.Grain: 35>\n     |  \n     |  Gram = <Unit.Gram: 29>\n     |  \n     |  HectoPascal = <Unit.HectoPascal: 25>\n     |  \n     |  Henry = <Unit.Henry: 28>\n     |  \n     |  Hertz = <Unit.Hertz: 7>\n     |  \n     |  Humidity293K = <Unit.Humidity293K: 26>\n     |  \n     |  Joule = <Unit.Joule: 21>\n     |  \n     |  Kelvin = <Unit.Kelvin: 4>\n     |  \n     |  MeterPerSecond = <Unit.MeterPerSecond: 24>\n     |  \n     |  Momme = <Unit.Momme: 37>\n     |  \n     |  Ohm = <Unit.Ohm: 2>\n     |  \n     |  Ounce = <Unit.Ounce: 31>\n     |  \n     |  Pennyweight = <Unit.Pennyweight: 34>\n     |  \n     |  Percentage = <Unit.Percentage: 8>\n     |  \n     |  Piece = <Unit.Piece: 39>\n     |  \n     |  Pound = <Unit.Pound: 33>\n     |  \n     |  RevolutionsPerMinute = <Unit.RevolutionsPerMinute: 17>\n     |  \n     |  Second = <Unit.Second: 10>\n     |  \n     |  Siemens = <Unit.Siemens: 11>\n     |  \n     |  Tael = <Unit.Tael: 36>\n     |  \n     |  Tola = <Unit.Tola: 38>\n     |  \n     |  TroyOunce = <Unit.TroyOunce: 32>\n     |  \n     |  Unitless = <Unit.Unitless: 14>\n     |  \n     |  Unknown = <Unit.Unknown: 40>\n     |  \n     |  Volt = <Unit.Volt: 0>\n     |  \n     |  VoltAmpere = <Unit.VoltAmpere: 18>\n     |  \n     |  Watt = <Unit.Watt: 19>\n     |  \n     |  WattHour = <Unit.WattHour: 20>\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class UserChannel(BaseChannel)\n     |  An user generated channel for storing custom data.\n     |  \n     |  Method resolution order:\n     |      UserChannel\n     |      BaseChannel\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  push_sample(...)\n     |      push_sample(self: smuview.UserChannel, sample: float, timestamp: float, quantity: smuview.Quantity, quantity_flags: Set[smuview.QuantityFlag], unit: smuview.Unit, digits: int, decimal_places: int) -> None\n     |      \n     |      Push a single sample to the channel.\n     |      \n     |      Parameters\n     |      ----------\n     |      sample : float\n     |          The sample value.\n     |      timestamp : float\n     |          The absolute timestamp in milliseconds.\n     |      quantity : Quantity\n     |          The `Quantity` of the new signal.\n     |      quantity_flags : Set[QuantityFlag]\n     |          The `QuantityFlag`s of the new signal.\n     |      unit : Unit\n     |          The `Unit` of the new signal.\n     |      digits : int\n     |          The total number of digits.\n     |      decimal_places : int\n     |          The number of decimal places.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseChannel:\n     |  \n     |  actual_signal(...)\n     |      actual_signal(self: smuview.BaseChannel) -> smuview.BaseSignal\n     |      \n     |      Return the actual signal of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The actual signal object.\n     |  \n     |  add_signal(...)\n     |      add_signal(self: smuview.BaseChannel, quantity: smuview.Quantity, quantity_flags: Set[smuview.QuantityFlag], unit: smuview.Unit, custom_name: str = '') -> smuview.BaseSignal\n     |      \n     |      Add a new signal to the channel.\n     |      \n     |      Parameters\n     |      ----------\n     |      quantity : Quantity\n     |          The `Quantity` of the new signal.\n     |      quantity_flags : Set[QuantityFlag]\n     |          The `QuantityFlag`s of the new signal.\n     |      unit : Unit\n     |          The `Unit` of the new signal.\n     |      custom_name: str\n     |          A custom name for the new signal. If empty (default), the signal name will be automatically generated.\n     |      \n     |      Returns\n     |      -------\n     |      BaseSignal\n     |          The new signal object.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseChannel) -> str\n     |      \n     |      Return the name of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the channel.\n     |  \n     |  signals(...)\n     |      signals(self: smuview.BaseChannel) -> List[smuview.BaseSignal]\n     |      \n     |      Return all signals of the channel.\n     |      \n     |      Returns\n     |      -------\n     |      List[BaseSignal]\n     |          All signals of the channel.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n    \n    class UserDevice(BaseDevice)\n     |  An user generated (virtual) device for storing custom data and showing a custom tab.\n     |  \n     |  Method resolution order:\n     |      UserDevice\n     |      BaseDevice\n     |      pybind11_builtins.pybind11_object\n     |      builtins.object\n     |  \n     |  Methods defined here:\n     |  \n     |  __init__(self, /, *args, **kwargs)\n     |      Initialize self.  See help(type(self)) for accurate signature.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Methods inherited from BaseDevice:\n     |  \n     |  add_user_channel(...)\n     |      add_user_channel(self: smuview.BaseDevice, channel_name: str, channel_group_name: str) -> smuview.UserChannel\n     |      \n     |      Add a new user channel to the device.\n     |      \n     |      Parameters\n     |      ----------\n     |      channel_name : str\n     |          The name of the new user channel.\n     |      channel_group_name : str\n     |          The name of the channel group where to create the user channel. Can be empty.\n     |      \n     |      Returns\n     |      -------\n     |      UserChannel\n     |          The new user channel object.\n     |  \n     |  channels(...)\n     |      channels(self: smuview.BaseDevice) -> Dict[str, smuview.BaseChannel]\n     |      \n     |      Return all channels of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, BaseChannel]\n     |          A Dict where the key is the id of the channel and the value is the channel object.\n     |  \n     |  configurables(...)\n     |      configurables(self: smuview.BaseDevice) -> Dict[str, smuview.Configurable]\n     |      \n     |      Return all configurables of the device.\n     |      \n     |      Returns\n     |      -------\n     |      Dict[str, Configurable]\n     |          A Dict where the key is the id of the `Configurable` and the value is the `Configurable` object.\n     |  \n     |  id(...)\n     |      id(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the unique id of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The id of the device.\n     |  \n     |  name(...)\n     |      name(self: smuview.BaseDevice) -> str\n     |      \n     |      Return the name of the device.\n     |      \n     |      Returns\n     |      -------\n     |      str\n     |          The name of the device.\n     |  \n     |  ----------------------------------------------------------------------\n     |  Static methods inherited from pybind11_builtins.pybind11_object:\n     |  \n     |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n     |      Create and return a new object.  See help(type) for accurate signature.\n\nDATA\n    __pdoc__ = {'ConfigKey.ADCPowerlineCycles': 'Number of powerline cycle...\n\nFILE\n    (built-in)\n\n\n"
  },
  {
    "path": "extdef.h",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SMUVIEW_EXTDEF_H\n#define SMUVIEW_EXTDEF_H\n\n#define countof(x) (sizeof(x) / sizeof(x[0]))\n\n#define begin_element(x) (&x[0])\n#define end_element(x) (&x[countof(x)])\n\n#endif // SMUVIEW_EXTDEF_H\n"
  },
  {
    "path": "external/.clang-tidy",
    "content": "---\nChecks: 'nocheck-*'\nWarningsAsErrors: ''\nHeaderFilterRegex: ''\n...\n"
  },
  {
    "path": "external/QCodeEditor/.clang-format",
    "content": "---\nLanguage:        Cpp\n# BasedOnStyle:  Microsoft\nAccessModifierOffset: -2\nAlignAfterOpenBracket: Align\nAlignConsecutiveMacros: false\nAlignConsecutiveAssignments: false\nAlignConsecutiveDeclarations: false\nAlignEscapedNewlines: Right\nAlignOperands:   true\nAlignTrailingComments: true\nAllowAllArgumentsOnNextLine: true\nAllowAllConstructorInitializersOnNextLine: true\nAllowAllParametersOfDeclarationOnNextLine: true\nAllowShortBlocksOnASingleLine: false\nAllowShortCaseLabelsOnASingleLine: false\nAllowShortFunctionsOnASingleLine: None\nAllowShortLambdasOnASingleLine: All\nAllowShortIfStatementsOnASingleLine: Never\nAllowShortLoopsOnASingleLine: false\nAlwaysBreakAfterDefinitionReturnType: None\nAlwaysBreakAfterReturnType: None\nAlwaysBreakBeforeMultilineStrings: false\nAlwaysBreakTemplateDeclarations: MultiLine\nBinPackArguments: true\nBinPackParameters: true\nBraceWrapping:\n  AfterCaseLabel:  false\n  AfterClass:      true\n  AfterControlStatement: true\n  AfterEnum:       true\n  AfterFunction:   true\n  AfterNamespace:  true\n  AfterObjCDeclaration: true\n  AfterStruct:     true\n  AfterUnion:      false\n  AfterExternBlock: true\n  BeforeCatch:     true\n  BeforeElse:      true\n  IndentBraces:    false\n  SplitEmptyFunction: true\n  SplitEmptyRecord: true\n  SplitEmptyNamespace: true\nBreakBeforeBinaryOperators: None\nBreakBeforeBraces: Custom\nBreakBeforeInheritanceComma: false\nBreakInheritanceList: BeforeColon\nBreakBeforeTernaryOperators: true\nBreakConstructorInitializersBeforeComma: false\nBreakConstructorInitializers: BeforeColon\nBreakAfterJavaFieldAnnotations: false\nBreakStringLiterals: true\nColumnLimit:     120\nCommentPragmas:  '^ IWYU pragma:'\nCompactNamespaces: false\nConstructorInitializerAllOnOneLineOrOnePerLine: false\nConstructorInitializerIndentWidth: 4\nContinuationIndentWidth: 4\nCpp11BracedListStyle: true\nDerivePointerAlignment: false\nDisableFormat:   false\nExperimentalAutoDetectBinPacking: false\nFixNamespaceComments: true\nForEachMacros:\n  - foreach\n  - Q_FOREACH\n  - BOOST_FOREACH\nIncludeBlocks:   Preserve\nIncludeCategories:\n  - Regex:           '^\"(llvm|llvm-c|clang|clang-c)/'\n    Priority:        2\n  - Regex:           '^(<|\"(gtest|gmock|isl|json)/)'\n    Priority:        3\n  - Regex:           '.*'\n    Priority:        1\nIncludeIsMainRegex: '(Test)?$'\nIndentCaseLabels: false\nIndentPPDirectives: None\nIndentWidth:     4\nIndentWrappedFunctionNames: false\nJavaScriptQuotes: Leave\nJavaScriptWrapImports: true\nKeepEmptyLinesAtTheStartOfBlocks: true\nMacroBlockBegin: ''\nMacroBlockEnd:   ''\nMaxEmptyLinesToKeep: 1\nNamespaceIndentation: None\nObjCBinPackProtocolList: Auto\nObjCBlockIndentWidth: 2\nObjCSpaceAfterProperty: false\nObjCSpaceBeforeProtocolList: true\nPenaltyBreakAssignment: 2\nPenaltyBreakBeforeFirstCallParameter: 19\nPenaltyBreakComment: 300\nPenaltyBreakFirstLessLess: 120\nPenaltyBreakString: 1000\nPenaltyBreakTemplateDeclaration: 10\nPenaltyExcessCharacter: 1000000\nPenaltyReturnTypeOnItsOwnLine: 1000\nPointerAlignment: Right\nReflowComments:  true\nSortIncludes:    true\nSortUsingDeclarations: true\nSpaceAfterCStyleCast: false\nSpaceAfterLogicalNot: false\nSpaceAfterTemplateKeyword: true\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeCpp11BracedList: false\nSpaceBeforeCtorInitializerColon: true\nSpaceBeforeInheritanceColon: true\nSpaceBeforeParens: ControlStatements\nSpaceBeforeRangeBasedForLoopColon: true\nSpaceInEmptyParentheses: false\nSpacesBeforeTrailingComments: 1\nSpacesInAngles:  false\nSpacesInContainerLiterals: true\nSpacesInCStyleCastParentheses: false\nSpacesInParentheses: false\nSpacesInSquareBrackets: false\nStandard:        Cpp11\nStatementMacros:\n  - Q_UNUSED\n  - QT_REQUIRE_VERSION\nTabWidth:        4\nUseTab:          Never\n...\n\n"
  },
  {
    "path": "external/QCodeEditor/.editorconfig",
    "content": "# EditorConfig file (https://editorconfig.org) for the QCodeEditor project\n\nroot = true\n\n[*]\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n# QCodeEditor C++ files\n[**.cpp]\nindent_style = space\nindent_size = 4\n[**.hpp]\nindent_style = space\nindent_size = 2\n\n# QCodeEditor XML files\n[**.xml]\nindent_style = space\nindent_size = 4\n[**.qrc]\nindent_style = space\nindent_size = 4\n\n# QCodeEditor CMake files\n[CMakeLists.txt]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": "external/QCodeEditor/.gitignore",
    "content": "build/\ncmake-build-debug/\ncmake-build-release/\n.idea/\n.kdev4/\nQCodeEditor.kdev4\n*~\n"
  },
  {
    "path": "external/QCodeEditor/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.6)\nproject(QCodeEditor)\n\nset(CMAKE_CXX_STANDARD 17)\n\noption(BUILD_EXAMPLE \"Example building required\" Off)\n\nif (${BUILD_EXAMPLE})\n    message(STATUS \"QCodeEditor example will be built.\")\n    add_subdirectory(example)\nendif()\n\nset(RESOURCES_FILE\n    resources/qcodeeditor_resources.qrc\n)\n\nset(INCLUDE_FILES\n    include/QHighlightRule\n    include/QHighlightBlockRule\n    include/QCodeEditor\n    include/QCXXHighlighter\n    include/QLineNumberArea\n    include/QStyleSyntaxHighlighter\n    include/QSyntaxStyle\n    include/QGLSLCompleter\n    include/QGLSLHighlighter\n    include/QJavaHighlighter\n    include/QJSHighlighter\n    include/QLanguage\n    include/QXMLHighlighter\n    include/QJSONHighlighter\n    include/QLuaCompleter\n    include/QLuaHighlighter\n    include/QPythonHighlighter\n    include/internal/QHighlightRule.hpp\n    include/internal/QHighlightBlockRule.hpp\n    include/internal/QCodeEditor.hpp\n    include/internal/QCXXHighlighter.hpp\n    include/internal/QJavaHighlighter.hpp\n    include/internal/QJSHighlighter.hpp\n    include/internal/QLineNumberArea.hpp\n    include/internal/QStyleSyntaxHighlighter.hpp\n    include/internal/QSyntaxStyle.hpp\n    include/internal/QGLSLCompleter.hpp\n    include/internal/QGLSLHighlighter.hpp\n    include/internal/QLanguage.hpp\n    include/internal/QXMLHighlighter.hpp\n    include/internal/QJSONHighlighter.hpp\n    include/internal/QLuaCompleter.hpp\n    include/internal/QLuaHighlighter.hpp\n    include/internal/QPythonCompleter.hpp\n    include/internal/QPythonHighlighter.hpp\n)\n\nset(SOURCE_FILES\n    src/internal/QCodeEditor.cpp\n    src/internal/QLineNumberArea.cpp\n    src/internal/QCXXHighlighter.cpp\n    src/internal/QSyntaxStyle.cpp\n    src/internal/QStyleSyntaxHighlighter.cpp\n    src/internal/QGLSLCompleter.cpp\n    src/internal/QGLSLHighlighter.cpp\n    src/internal/QJavaHighlighter.cpp\n    src/internal/QJSHighlighter.cpp\n    src/internal/QLanguage.cpp\n    src/internal/QXMLHighlighter.cpp\n    src/internal/QJSONHighlighter.cpp\n    src/internal/QLuaCompleter.cpp\n    src/internal/QLuaHighlighter.cpp\n    src/internal/QPythonCompleter.cpp\n    src/internal/QPythonHighlighter.cpp\n)\n\n# Create code for QObjects\nset(CMAKE_AUTOMOC On)\n\n# Create code from resource files\nset(CMAKE_AUTORCC ON)\n\n# Generate compile_commands.json in build/ for analyzers like clang-tidy.\nset(CMAKE_EXPORT_COMPILE_COMMANDS ON)\n\n# Find includes in corresponding build directories\nfind_package(Qt5Core    CONFIG REQUIRED)\nfind_package(Qt5Widgets CONFIG REQUIRED)\nfind_package(Qt5Gui     CONFIG REQUIRED)\n\nadd_library(QCodeEditor STATIC\n    ${RESOURCES_FILE}\n    ${SOURCE_FILES}\n    ${INCLUDE_FILES}\n)\n\ntarget_include_directories(QCodeEditor PUBLIC\n    include\n)\n\nif(CMAKE_COMPILER_IS_GNUCXX)\n    target_compile_options(QCodeEditor\n        PRIVATE\n        -pedantic\n        -Wall\n        -Wextra\n        -Weffc++\n        -Woverloaded-virtual\n        -Winit-self\n        -Wunreachable-code\n    )\nendif(CMAKE_COMPILER_IS_GNUCXX)\n\ntarget_link_libraries(QCodeEditor\n    Qt5::Core\n    Qt5::Widgets\n    Qt5::Gui\n)\n"
  },
  {
    "path": "external/QCodeEditor/LICENSE.MIT",
    "content": "MIT License\n\nCopyright (c) 2013-2019 Megaxela\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "external/QCodeEditor/README.md",
    "content": "# Qt Code Editor Widget\n\n[![GitHub Workflow Status](https://github.com/cpeditor/QCodeEditor/workflows/CI:%20Build%20Test/badge.svg?event=push)](https://github.com/cpeditor/QCodeEditor/actions?query=event%3Apush)\n\nIt's a widget for editing/viewing code.\n\nThis project uses a resource named `qcodeeditor_resources.qrc`. The main application\nmust not use a resource file with the same name.\n\n(It's not a project from a Qt example.)\n\n## Requirements\n0. C++11 featured compiler.\n0. Qt 5.\n\n## Abilities\n1. Auto parentheses.\n1. Different highlight rules.\n1. Auto indentation.\n1. Replace tabs with spaces.\n1. GLSL completion rules.\n1. GLSL highlight rules.\n1. C++ highlight rules.\n1. XML highlight rules.\n1. JSON highligh rules.\n1. Java highligh rules.\n1. JavaScript highligh rules.\n1. Frame selection.\n1. Qt Creator styles.\n\n## Build\nIt's a CMake-based library, so it can be used as a submodule (see the example).\nBut here are the steps to build it as a static library (for external use for example).\n\n1. Clone the repository: `git clone https://github.com/Megaxela/QCodeEditor`\n1. Go into the repository: `cd QCodeEditor`\n1. Create a build folder: `mkdir build`\n1. Go into the build folder: `cd build`\n1. Generate a build file for your compiler: `cmake ..`\n    1. If you need to build the example, specify `-DBUILD_EXAMPLE=On` on this step.\n1. Build the library: `cmake --build .`\n\n## Example\n\nBy default, `QCodeEditor` uses the standard QtCreator theme. But you may specify\nyour own by parsing it with `QSyntaxStyle`. The example uses [Dracula](https://draculatheme.com) theme.\n(See the example for more.) \n\n<img src=\"https://github.com/Megaxela/QCodeEditor/blob/master/example/image/preview.png\">\n\n## LICENSE\n\n<img align=\"right\" src=\"http://opensource.org/trademarks/opensource/OSI-Approved-License-100x137.png\">\n\nLibrary is licensed under the [MIT License](https://opensource.org/licenses/MIT)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "external/QCodeEditor/include/QCXXHighlighter",
    "content": "#pragma once\n\n#include <internal/QCXXHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QCodeEditor",
    "content": "#pragma once\n\n#include <internal/QCodeEditor.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QGLSLCompleter",
    "content": "#pragma once\n\n#include <internal/QGLSLCompleter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QGLSLHighlighter",
    "content": "#pragma once\n\n#include <internal/QGLSLHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QHighlightBlockRule",
    "content": "#pragma once\n\n#include <internal/QHighlightBlockRule.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QHighlightRule",
    "content": "#pragma once\n\n#include <internal/QHighlightRule.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QJSHighlighter",
    "content": "#pragma once\n\n#include <internal/QJSHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QJSONHighlighter",
    "content": "#pragma once\n\n#include <internal/QJSONHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QJavaHighlighter",
    "content": "#pragma once\n\n#include <internal/QJavaHighlighter.hpp>\n"
  },
  {
    "path": "external/QCodeEditor/include/QLanguage",
    "content": "#pragma once\n\n#include <internal/QLanguage.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QLineNumberArea",
    "content": "#pragma once\n\n#include <internal/QLineNumberArea.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QLuaCompleter",
    "content": "#pragma once\n\n#include <internal/QLuaCompleter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QLuaHighlighter",
    "content": "#pragma once\n\n#include <internal/QLuaHighlighter.hpp>\n"
  },
  {
    "path": "external/QCodeEditor/include/QPythonCompleter",
    "content": "#pragma once\n\n#include <internal/QPythonCompleter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QPythonHighlighter",
    "content": "#pragma once\n\n#include <internal/QPythonHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QStyleSyntaxHighlighter",
    "content": "#pragma once\n\n#include <internal/QStyleSyntaxHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QSyntaxStyle",
    "content": "#pragma once\n\n#include <internal/QSyntaxStyle.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/QXMLHighlighter",
    "content": "#pragma once\n\n#include <internal/QXMLHighlighter.hpp>"
  },
  {
    "path": "external/QCodeEditor/include/internal/QCXXHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that describes C++ code\n * highlighter.\n */\nclass QCXXHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QCXXHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n\n    QRegularExpression m_includePattern;\n    QRegularExpression m_functionPattern;\n    QRegularExpression m_defTypePattern;\n\n    QRegularExpression m_commentStartPattern;\n    QRegularExpression m_commentEndPattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QCodeEditor.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QTextEdit> // Required for inheritance\n\nclass QCompleter;\nclass QLineNumberArea;\nclass QSyntaxStyle;\nclass QStyleSyntaxHighlighter;\nclass QFramedTextAttribute;\n\n/**\n * @brief Class, that describes code editor.\n */\nclass QCodeEditor : public QTextEdit\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief The SeverityLevel enum\n     * @note the order should be: the bigger the more important\n     */\n    enum class SeverityLevel\n    {\n        Hint,\n        Information,\n        Warning,\n        Error\n    };\n\n    struct Parenthesis\n    {\n        QChar left, right;\n        bool autoComplete, autoRemove, tabJumpOut;\n\n        Parenthesis(QChar l = '(', QChar r = ')', bool complete = true, bool remove = true, bool jumpout = true)\n            : left(l), right(r), autoComplete(complete), autoRemove(remove), tabJumpOut(jumpout)\n        {\n        }\n    };\n\n    /**\n     * @brief Constructor.\n     * @param widget Pointer to parent widget.\n     */\n    explicit QCodeEditor(QWidget *widget = nullptr);\n\n    // Disable copying\n    QCodeEditor(const QCodeEditor &) = delete;\n    QCodeEditor &operator=(const QCodeEditor &) = delete;\n\n    /**\n     * @brief Method for getting first visible block\n     * index.\n     * @return Index.\n     */\n    int getFirstVisibleBlock();\n\n    /**\n     * @brief Method for setting highlighter.\n     * @param highlighter Pointer to syntax highlighter.\n     */\n    void setHighlighter(QStyleSyntaxHighlighter *highlighter);\n\n    /**\n     * @brief Method for setting syntax sty.e.\n     * @param style Pointer to syntax style.\n     */\n    void setSyntaxStyle(QSyntaxStyle *style);\n\n    /**\n     * @brief Method for setting tab replacing\n     * enabled.\n     */\n    void setTabReplace(bool enabled);\n\n    /**\n     * @brief Method for getting is tab replacing enabled.\n     * Default value: true\n     */\n    bool tabReplace() const;\n\n    /**\n     * @brief Method for setting amount of spaces, that will\n     * replace tab.\n     * @param val Number of spaces.\n     */\n    void setTabReplaceSize(int val);\n\n    /**\n     * @brief Method for getting number of spaces, that will\n     * replace tab if `tabReplace` is true.\n     * Default: 4\n     */\n    int tabReplaceSize() const;\n\n    /**\n     * @brief Method for setting auto indentation enabled.\n     */\n    void setAutoIndentation(bool enabled);\n\n    /**\n     * @brief Method for setting the parentheses.\n     */\n    void setParentheses(const QVector<Parenthesis> &parentheses);\n\n    /**\n     * @brief Method for setting extra bottom margin enabled.\n     */\n    void setExtraBottomMargin(bool enabled);\n\n    /**\n     * @brief Method for getting is auto indentation enabled.\n     * Default: true\n     */\n    bool autoIndentation() const;\n\n    /**\n     * @brief Method for setting completer.\n     * @param completer Pointer to completer object.\n     */\n    void setCompleter(QCompleter *completer);\n\n    /**\n     * @brief Method for getting completer.\n     * @return Pointer to completer.\n     */\n    QCompleter *completer() const;\n\n    /**\n     * @brief squiggle Puts a underline squiggle under text ranges in Editor\n     * @param level defines the color of the underline depending upon the severity\n     * @param tooltipMessage The tooltip hover message to show when over selection.\n     * @note QPair<int, int>: first -> Line number in 1-based indexing\n     *                        second -> Character number in 0-based indexing\n     */\n    void squiggle(SeverityLevel level, QPair<int, int>, QPair<int, int>, const QString &tooltipMessage);\n\n    /**\n     * @brief clearSquiggle, Clears complete squiggle from editor\n     */\n    void clearSquiggle();\n\n  Q_SIGNALS:\n    /**\n     * @brief Signal, the font is changed by the wheel event.\n     */\n    void fontChanged(const QFont &newFont);\n\n  public Q_SLOTS:\n\n    /**\n     * @brief Slot, that performs insertion of\n     * completion info into code.\n     * @param s Data.\n     */\n    void insertCompletion(const QString &s);\n\n    /**\n     * @brief Slot, that performs update of\n     * internal editor viewport based on line\n     * number area width.\n     */\n    void updateLineNumberAreaWidth(int);\n\n    /**\n     * @brief Slot, that performs update of some\n     * part of line number area.\n     * @param rect Area that has to be updated.\n     */\n    void updateLineNumberArea(QRect rect);\n\n    /**\n     * @brief Slot, that will proceed extra selection\n     * for current cursor position.\n     */\n    void updateExtraSelection1();\n    void updateExtraSelection2();\n\n    /**\n     * @brief Slot, that will update editor style.\n     */\n    void updateStyle();\n\n    /**\n     * @brief Slot, that indent the selected lines.\n     */\n    void indent();\n\n    /**\n     * @brief Slot, that unindent the selected lines.\n     */\n    void unindent();\n\n    /**\n     * @brief Slot, that swap the selected lines up.\n     */\n    void swapLineUp();\n\n    /**\n     * @brief Slot, that swap the selected lines down.\n     */\n    void swapLineDown();\n\n    /**\n     * @brief Slot, that delete the selected lines.\n     */\n    void deleteLine();\n\n    /**\n     * @brief Slot, that duplicate the current line or the selection.\n     */\n    void duplicate();\n\n    /**\n     * @brief Slot, that toggle single line comment of the\n     * selected lines.\n     */\n    void toggleComment();\n\n    /**\n     * @brief Slot, that toggle block comment of the selection.\n     */\n    void toggleBlockComment();\n\n  protected:\n    /**\n     * @brief Method, that's called on any text insertion of\n     * mimedata into editor. If it's text - it inserts text\n     * as plain text.\n     */\n    void insertFromMimeData(const QMimeData *source) override;\n\n    /**\n     * @brief Method, that's called on editor painting. This\n     * method if overloaded for line number area redraw.\n     */\n    void paintEvent(QPaintEvent *e) override;\n\n    /**\n     * @brief Method, that's called on any widget resize.\n     * This method if overloaded for line number area\n     * resizing.\n     */\n    void resizeEvent(QResizeEvent *e) override;\n\n    /**\n     * @brief Method, update the bottom margin when the font changes.\n     */\n    void changeEvent(QEvent *e) override;\n\n    /**\n     * @brief Method, update the font size when the wheel is rotated with Ctrl pressed\n     */\n    void wheelEvent(QWheelEvent *e) override;\n\n    /**\n     * @brief Method, that's called on any key press, posted\n     * into code editor widget. This method is overloaded for:\n     *\n     * 1. Completion\n     * 2. Tab to spaces\n     * 3. Low indentation\n     * 4. Auto parenthesis\n     */\n    void keyPressEvent(QKeyEvent *e) override;\n\n    /**\n     * @brief Method, that's called on focus into widget.\n     * It's required for setting this widget to set\n     * completer.\n     */\n    void focusInEvent(QFocusEvent *e) override;\n\n    /**\n     * @brief Method for tooltip generation\n     */\n    bool event(QEvent *e) override;\n\n  private Q_SLOTS:\n    /**\n     * @brief Slot, that updates the bottom margin.\n     */\n    void updateBottomMargin();\n\n  private:\n    /**\n     * @brief Method for initializing default\n     * monospace font.\n     */\n    void initFont();\n\n    /**\n     * @brief Method for performing connection\n     * of objects.\n     */\n    void performConnections();\n\n    /**\n     * @brief Method for updating geometry of line number area.\n     */\n    void updateLineGeometry();\n\n    /**\n     * @brief Method, that performs completer processing.\n     * Returns true if event has to be dropped.\n     * @param e Pointer to key event.\n     * @return Shall event be dropped.\n     */\n    bool proceedCompleterBegin(QKeyEvent *e);\n    void proceedCompleterEnd(QKeyEvent *e);\n\n    /**\n     * @brief Method for getting character under\n     * cursor.\n     * @param offset Offset to cursor.\n     */\n    QChar charUnderCursor(int offset = 0) const;\n\n    /**\n     * @brief Method for getting word under\n     * cursor.\n     * @return Word under cursor.\n     */\n    QString wordUnderCursor() const;\n\n    /**\n     * @brief Method, that adds highlighting of\n     * currently selected line to extra selection list.\n     */\n    void highlightCurrentLine();\n\n    /**\n     * @brief Method, that adds highlighting of\n     * parenthesis if available.\n     */\n    void highlightParenthesis();\n\n    void highlightOccurrences();\n\n    /**\n     * @brief Method for remove the first group of regex\n     * in each line of the selection.\n     * @param regex remove its first group\n     * @param force if true, remove regardless of whether\n     * all lines are begun with regex; if false remove\n     * only when all lines are begun with regex.\n     * @return if regex is removed\n     */\n    bool removeInEachLineOfSelection(const QRegularExpression &regex, bool force);\n\n    /**\n     * @brief Method for add the str at the begin of regex\n     * in each line of the selection.\n     * @param regex add at the begin of its match\n     * @param str string to add\n     */\n    void addInEachLineOfSelection(const QRegularExpression &regex, const QString &str);\n\n    /**\n     * @brief The SquiggleInformation struct, Line number will be index of vector+1;\n     */\n    struct SquiggleInformation\n    {\n        SquiggleInformation() = default;\n\n        SquiggleInformation(QPair<int, int> start, QPair<int, int> stop, const QString &text)\n            : m_startPos(start), m_stopPos(stop), m_tooltipText(text)\n        {\n        }\n\n        QPair<int, int> m_startPos;\n        QPair<int, int> m_stopPos;\n        QString m_tooltipText;\n    };\n\n    QStyleSyntaxHighlighter *m_highlighter;\n    QSyntaxStyle *m_syntaxStyle;\n    QLineNumberArea *m_lineNumberArea;\n    QCompleter *m_completer;\n\n    bool m_autoIndentation;\n    bool m_replaceTab;\n    bool m_extraBottomMargin;\n    QString m_tabReplace;\n\n    QList<QTextEdit::ExtraSelection> extra1, extra2, extra_squiggles;\n\n    QVector<SquiggleInformation> m_squiggler;\n\n    QVector<Parenthesis> m_parentheses;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QGLSLCompleter.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QCompleter> // Required for inheritance\n\n/**\n * @brief Class, that describes completer with\n * glsl specific types and functions.\n */\nclass QGLSLCompleter : public QCompleter\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QObject.\n     */\n    explicit QGLSLCompleter(QObject *parent = nullptr);\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QGLSLHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that describes Glsl code\n * highlighter.\n */\nclass QGLSLHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QGLSLHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n\n    QRegularExpression m_includePattern;\n    QRegularExpression m_functionPattern;\n    QRegularExpression m_defTypePattern;\n\n    QRegularExpression m_commentStartPattern;\n    QRegularExpression m_commentEndPattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QHighlightBlockRule.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QRegularExpression>\n#include <QString>\n\nstruct QHighlightBlockRule\n{\n    QHighlightBlockRule() : startPattern(), endPattern(), formatName()\n    {\n    }\n\n    QHighlightBlockRule(QRegularExpression start, QRegularExpression end, QString format)\n        : startPattern(std::move(start)), endPattern(std::move(end)), formatName(std::move(format))\n    {\n    }\n\n    QRegularExpression startPattern;\n    QRegularExpression endPattern;\n    QString formatName;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QHighlightRule.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QRegularExpression>\n#include <QString>\n\nstruct QHighlightRule\n{\n    QHighlightRule() : pattern(), formatName()\n    {\n    }\n\n    QHighlightRule(QRegularExpression p, QString f) : pattern(std::move(p)), formatName(std::move(f))\n    {\n    }\n\n    QRegularExpression pattern;\n    QString formatName;\n};"
  },
  {
    "path": "external/QCodeEditor/include/internal/QJSHighlighter.hpp",
    "content": "#pragma once\n\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Derived to implement highlighting of JavaScript code.\n */\nclass QJSHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructs a new instance of a JavaScript highlighter.\n     * @param document The text document to be highlighted.\n     * This may be a null pointer.\n     */\n    explicit QJSHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n\n    QRegularExpression m_commentStartPattern;\n    QRegularExpression m_commentEndPattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QJSONHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QVector>\n\n/**\n * @brief Class, that describes JSON code\n * highlighter.\n */\nclass QJSONHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QJSONHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n    QRegularExpression m_keyRegex;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QJavaHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Derived to implement highlighting of Java code.\n */\nclass QJavaHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructs a new instance of a Java highlighter.\n     * @param document The text document to be highlighted.\n     * This may be a null pointer.\n     */\n    explicit QJavaHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    /**\n     * @brief Derived to highlight blocks of Java code.\n     * @param text The block of text containing Java code.\n     */\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n\n    QRegularExpression m_commentStartPattern;\n    QRegularExpression m_commentEndPattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QLanguage.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QMap>\n#include <QObject> // Required for inheritance\n#include <QString>\n\nclass QIODevice;\n\n/**\n * Class, that describes object for parsing\n * language file.\n */\nclass QLanguage : public QObject\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QObject.\n     */\n    explicit QLanguage(QIODevice *device = nullptr, QObject *parent = nullptr);\n\n    /**\n     * @brief Method for parsing.\n     * @param device Pointer to device.\n     * @return Success.\n     */\n    bool load(QIODevice *device);\n\n    /**\n     * @brief Method for getting available keys.\n     */\n    QStringList keys();\n\n    /**\n     * @brief Method for getting names\n     * from key.\n     * @param name\n     * @return\n     */\n    QStringList names(const QString &key);\n\n    /**\n     * @brief Method for getting is object loaded.\n     */\n    bool isLoaded() const;\n\n  private:\n    bool m_loaded;\n\n    QMap<QString, QStringList> m_list;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QLineNumberArea.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QWidget> // Required for inheritance\n\n#include <QCodeEditor>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that describes line number area widget.\n */\nclass QLineNumberArea : public QWidget\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QTextEdit widget.\n     */\n    explicit QLineNumberArea(QCodeEditor *parent = nullptr);\n\n    // Disable copying\n    QLineNumberArea(const QLineNumberArea &) = delete;\n    QLineNumberArea &operator=(const QLineNumberArea &) = delete;\n\n    /**\n     * @brief Overridden method for getting line number area\n     * size.\n     */\n    QSize sizeHint() const override;\n\n    /**\n     * @brief Method for setting syntax style object.\n     * @param style Pointer to syntax style.\n     */\n    void setSyntaxStyle(QSyntaxStyle *style);\n\n    /**\n     * @brief Method for getting syntax style.\n     * @return Pointer to syntax style.\n     */\n    QSyntaxStyle *syntaxStyle() const;\n\n    void lint(QCodeEditor::SeverityLevel level, int from, int to);\n\n    void clearLint();\n\n  protected:\n    void paintEvent(QPaintEvent *event) override;\n\n  private:\n    QSyntaxStyle *m_syntaxStyle;\n\n    QCodeEditor *m_codeEditParent;\n\n    QMap<int, QCodeEditor::SeverityLevel> m_squiggles;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QLuaCompleter.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QCompleter> // Required for inheritance\n\n/**\n * @brief Class, that describes completer with\n * glsl specific types and functions.\n */\nclass QLuaCompleter : public QCompleter\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QObject.\n     */\n    explicit QLuaCompleter(QObject *parent = nullptr);\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QLuaHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightBlockRule>\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QMap>\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that describes C++ code\n * highlighter.\n */\nclass QLuaHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QLuaHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n    QVector<QHighlightBlockRule> m_highlightBlockRules;\n\n    QRegularExpression m_requirePattern;\n    QRegularExpression m_functionPattern;\n    QRegularExpression m_defTypePattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QPythonCompleter.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QCompleter> // Required for inheritance\n\n/**\n * @brief Class, that describes completer with\n * glsl specific types and functions.\n */\nclass QPythonCompleter : public QCompleter\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QObject.\n     */\n    explicit QPythonCompleter(QObject *parent = nullptr);\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QPythonHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QHighlightBlockRule>\n#include <QHighlightRule>\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that describes Glsl code\n * highlighter.\n */\nclass QPythonHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QPythonHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    QVector<QHighlightRule> m_highlightRules;\n    QVector<QHighlightBlockRule> m_highlightBlockRules;\n\n    QRegularExpression m_includePattern;\n    QRegularExpression m_functionPattern;\n    QRegularExpression m_defTypePattern;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QStyleSyntaxHighlighter.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QSyntaxHighlighter> // Required for inheritance\n\nclass QSyntaxStyle;\n\n/**\n * @brief Class, that descrubes highlighter with\n * syntax style.\n */\nclass QStyleSyntaxHighlighter : public QSyntaxHighlighter\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to text document.\n     */\n    explicit QStyleSyntaxHighlighter(QTextDocument *document = nullptr);\n\n    // Disable copying\n    QStyleSyntaxHighlighter(const QStyleSyntaxHighlighter &) = delete;\n    QStyleSyntaxHighlighter &operator=(const QStyleSyntaxHighlighter &) = delete;\n\n    /**\n     * @brief Method for setting syntax style.\n     * @param style Pointer to syntax style.\n     */\n    void setSyntaxStyle(QSyntaxStyle *style);\n\n    /**\n     * @brief Method for getting syntax style.\n     * @return Pointer to syntax style. May be nullptr.\n     */\n    QSyntaxStyle *syntaxStyle() const;\n\n    /**\n     * @brief Method for getting a sequence that marks a comment line.\n     * @return QString containing a sequence that marks a comment line.\n     * @details Returned value can be empty meaning that this language doesn't\n     * support single-line comments\n     */\n    QString commentLineSequence() const;\n\n    /**\n     * @brief Method to set a sequence that marks a comment line.\n     * @param commentLineSequence a sequence that marks a comment line. Can be empty.\n     */\n    void setCommentLineSequence(const QString &commentLineSequence);\n\n    /**\n     * @brief Method for getting a sequence that marks a start of a multi line comment block.\n     * @return QString containing a sequence that marks a multi line comment block.\n     * @details Returned value can be empty meaning that this language doesn't\n     * support multi line comments\n     */\n    QString startCommentBlockSequence() const;\n\n    /**\n     * @brief Method to set a sequence that marks a start of a multi line comment block.\n     * @param commentLineSequence a sequence that marks a start of a multi line comment block. Can be empty.\n     */\n    void setStartCommentBlockSequence(const QString &startCommentBlockSequence);\n\n    /**\n     * @brief Method for getting a sequence that marks a end of a multi line comment block.\n     * @return QString containing a sequence that marks an end multi line comment block.\n     * @details Returned value can be empty meaning that this language doesn't\n     * support multi line comments.\n     */\n    QString endCommentBlockSequence() const;\n\n    /**\n     * @brief Method to set a sequence that marks an end of a multi line comment block.\n     * @param commentLineSequence a sequence that marks an end of a multi line comment block. Can be empty.\n     */\n    void setEndCommentBlockSequence(const QString &endCommentBlockSequence);\n\n  private:\n    QSyntaxStyle *m_syntaxStyle;\n\n  protected:\n    QString m_commentLineSequence;\n    QString m_startCommentBlockSequence;\n    QString m_endCommentBlockSequence;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QSyntaxStyle.hpp",
    "content": "#pragma once\n\n// Qt\n#include <QMap>\n#include <QObject> // Required for inheritance\n#include <QString>\n#include <QTextCharFormat>\n\n/**\n * @brief Class, that describes Qt style\n * parser for QCodeEditor.\n */\nclass QSyntaxStyle : public QObject\n{\n    Q_OBJECT\n\n  public:\n    /**\n     * @brief Constructor.\n     * @param parent Pointer to parent QObject\n     */\n    explicit QSyntaxStyle(QObject *parent = nullptr);\n\n    /**\n     * @brief Method for loading and parsing\n     * style.\n     * @param fl Style.\n     * @return Success.\n     */\n    bool load(const QString &fl);\n\n    /**\n     * @brief Method for getting style name.\n     * @return Name.\n     */\n    QString name() const;\n\n    /**\n     * @brief Method for checking is syntax style loaded.\n     * @return Is loaded.\n     */\n    bool isLoaded() const;\n\n    /**\n     * @brief Method for getting format for property\n     * name.\n     * @param name Property name.\n     * @return Text char format.\n     */\n    QTextCharFormat getFormat(const QString &name) const;\n\n    /**\n     * @brief Static method for getting default style.\n     * @return Pointer to default style.\n     */\n    static QSyntaxStyle *defaultStyle();\n\n  private:\n    QString m_name;\n\n    QMap<QString, QTextCharFormat> m_data;\n\n    bool m_loaded;\n};\n"
  },
  {
    "path": "external/QCodeEditor/include/internal/QXMLHighlighter.hpp",
    "content": "#pragma once\n\n// QCodeEditor\n#include <QStyleSyntaxHighlighter> // Required for inheritance\n\n// Qt\n#include <QRegularExpression>\n#include <QVector>\n\n/**\n * @brief Class, that describes XML code\n * highlighter.\n */\nclass QXMLHighlighter : public QStyleSyntaxHighlighter\n{\n    Q_OBJECT\n  public:\n    /**\n     * @brief Constructor.\n     * @param document Pointer to document.\n     */\n    explicit QXMLHighlighter(QTextDocument *document = nullptr);\n\n  protected:\n    void highlightBlock(const QString &text) override;\n\n  private:\n    void highlightByRegex(const QTextCharFormat &format, const QRegularExpression &regex, const QString &text);\n\n    QVector<QRegularExpression> m_xmlKeywordRegexes;\n    QRegularExpression m_xmlElementRegex;\n    QRegularExpression m_xmlAttributeRegex;\n    QRegularExpression m_xmlValueRegex;\n    QRegularExpression m_xmlCommentBeginRegex;\n    QRegularExpression m_xmlCommentEndRegex;\n};\n"
  },
  {
    "path": "external/QCodeEditor/resources/default_style.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<style-scheme version=\"1.0\" name=\"Default\">\n    <style name=\"Text\" foreground=\"#000000\" background=\"#ffffff\"/>\n    <style name=\"Link\" foreground=\"#0000ff\"/>\n    <style name=\"Selection\" foreground=\"#eff0f1\" background=\"#3daee9\"/>\n    <style name=\"LineNumber\" foreground=\"#6272a4\"/>\n    <style name=\"SearchResult\" background=\"#ffef0b\"/>\n    <style name=\"SearchScope\" background=\"#2d5c76\"/>\n    <style name=\"Parentheses\" foreground=\"#ff0000\" background=\"#b4eeb4\"/>\n    <style name=\"ParenthesesMismatch\" background=\"#ff00ff\"/>\n    <style name=\"AutoComplete\" foreground=\"#000080\" background=\"#c0c0ff\"/>\n    <style name=\"CurrentLine\" background=\"#eeeeee\"/>\n    <style name=\"CurrentLineNumber\" foreground=\"#808080\" bold=\"true\"/>\n    <style name=\"Occurrences\" background=\"#b4b4b4\"/>\n    <style name=\"Occurrences.Unused\" underlineColor=\"#808000\" underlineStyle=\"SingleUnderline\"/>\n    <style name=\"Occurrences.Rename\" background=\"#ff6464\"/>\n    <style name=\"Number\" foreground=\"#000080\"/>\n    <style name=\"String\" foreground=\"#008000\"/>\n    <style name=\"Type\" foreground=\"#800080\"/>\n    <style name=\"Local\" foreground=\"#092e64\"/>\n    <style name=\"Global\" foreground=\"#ce5c00\"/>\n    <style name=\"Field\" foreground=\"#800000\"/>\n    <style name=\"Static\" foreground=\"#800080\"/>\n    <style name=\"VirtualMethod\" foreground=\"#00677c\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"Function\" foreground=\"#00677c\" background=\"#ffffff\"/>\n    <style name=\"Keyword\" foreground=\"#808000\"/>\n    <style name=\"PrimitiveType\" foreground=\"#808000\"/>\n    <style name=\"Operator\"/>\n    <style name=\"Overloaded Operator\"/>\n    <style name=\"Preprocessor\" foreground=\"#000080\"/>\n    <style name=\"Label\" foreground=\"#800000\"/>\n    <style name=\"Comment\" foreground=\"#008000\"/>\n    <style name=\"Doxygen.Comment\" foreground=\"#000080\"/>\n    <style name=\"Doxygen.Tag\" foreground=\"#0000ff\"/>\n    <style name=\"VisualWhitespace\" foreground=\"#c0c0c0\"/>\n    <style name=\"QmlLocalId\" foreground=\"#000000\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"QmlExternalId\" foreground=\"#000080\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"QmlTypeId\" foreground=\"#800080\"/>\n    <style name=\"QmlRootObjectProperty\" foreground=\"#000000\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"QmlScopeObjectProperty\" foreground=\"#000000\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"QmlExternalObjectProperty\" foreground=\"#000080\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"JsScopeVar\" foreground=\"#2985c7\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"JsImportVar\" foreground=\"#0055af\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"JsGlobalVar\" foreground=\"#0055af\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"QmlStateName\" foreground=\"#000000\" background=\"#ffffff\" italic=\"true\"/>\n    <style name=\"Binding\" foreground=\"#800000\"/>\n    <style name=\"DisabledCode\" background=\"#efefef\"/>\n    <style name=\"AddedLine\" foreground=\"#00aa00\"/>\n    <style name=\"RemovedLine\" foreground=\"#ff0000\"/>\n    <style name=\"DiffFile\" foreground=\"#000080\"/>\n    <style name=\"DiffLocation\" foreground=\"#0000ff\"/>\n    <style name=\"DiffFileLine\" background=\"#ffff00\"/>\n    <style name=\"DiffContextLine\" background=\"#afd7e7\"/>\n    <style name=\"DiffSourceLine\" background=\"#ffdfdf\"/>\n    <style name=\"DiffSourceChar\" background=\"#ffafaf\"/>\n    <style name=\"DiffDestLine\" background=\"#dfffdf\"/>\n    <style name=\"DiffDestChar\" background=\"#afffaf\"/>\n    <style name=\"LogChangeLine\" foreground=\"#c00000\"/>\n    <style name=\"Warning\" underlineColor=\"#ffbe00\" underlineStyle=\"SingleUnderline\"/>\n    <style name=\"WarningContext\" underlineColor=\"#ffbe00\" underlineStyle=\"DotLine\"/>\n    <style name=\"Error\" underlineColor=\"#ff0000\" underlineStyle=\"SingleUnderline\"/>\n    <style name=\"ErrorContext\" underlineColor=\"#ff0000\" underlineStyle=\"DotLine\"/>\n    <style name=\"Declaration\" bold=\"true\"/>\n    <style name=\"FunctionDefinition\"/>\n    <style name=\"OutputArgument\" italic=\"true\"/>\n</style-scheme>\n"
  },
  {
    "path": "external/QCodeEditor/resources/languages/cpp.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>alignas</name>\n        <name>alignof</name>\n        <name>and</name>\n        <name>and_eq</name>\n        <name>asm</name>\n        <name>atomic_cancel</name>\n        <name>atomic_commit</name>\n        <name>atomic_noexcept</name>\n        <name>auto</name>\n        <name>bitand</name>\n        <name>bitor</name>\n        <name>break</name>\n        <name>case</name>\n        <name>catch</name>\n        <name>class</name>\n        <name>compl</name>\n        <name>concept</name>\n        <name>const</name>\n        <name>constexpr</name>\n        <name>const_cast</name>\n        <name>continue</name>\n        <name>co_await</name>\n        <name>co_return</name>\n        <name>co_yield</name>\n        <name>decltype</name>\n        <name>default</name>\n        <name>delete</name>\n        <name>do</name>\n        <name>dynamic_cast</name>\n        <name>else</name>\n        <name>enum</name>\n        <name>explicit</name>\n        <name>export</name>\n        <name>extern</name>\n        <name>false</name>\n        <name>for</name>\n        <name>friend</name>\n        <name>goto</name>\n        <name>if</name>\n        <name>import</name>\n        <name>inline</name>\n        <name>module</name>\n        <name>mutable</name>\n        <name>namespace</name>\n        <name>new</name>\n        <name>noexcept</name>\n        <name>not</name>\n        <name>not_eq</name>\n        <name>nullptr</name>\n        <name>operator</name>\n        <name>or</name>\n        <name>or_eq</name>\n        <name>private</name>\n        <name>protected</name>\n        <name>public</name>\n        <name>reflexpr</name>\n        <name>register(2)</name>\n        <name>reinterpret_cast</name>\n        <name>requires</name>\n        <name>return</name>\n        <name>sizeof</name>\n        <name>static</name>\n        <name>static_assert</name>\n        <name>static_cast</name>\n        <name>struct</name>\n        <name>switch</name>\n        <name>synchronized</name>\n        <name>template</name>\n        <name>this</name>\n        <name>thread_local</name>\n        <name>throw</name>\n        <name>true</name>\n        <name>try</name>\n        <name>typedef</name>\n        <name>typeid</name>\n        <name>typename</name>\n        <name>union</name>\n        <name>using</name>\n        <name>virtual</name>\n        <name>volatile</name>\n        <name>while</name>\n        <name>xor</name>\n        <name>xor_eq</name>\n    </section>\n    <section name=\"PrimitiveType\">\n        <name>bool</name>\n        <name>char</name>\n        <name>char16_t</name>\n        <name>char32_t</name>\n        <name>double</name>\n        <name>float</name>\n        <name>int</name>\n        <name>long</name>\n        <name>short</name>\n        <name>signed</name>\n        <name>unsigned</name>\n        <name>void</name>\n        <name>wchar_t</name>\n    </section>\n</root>"
  },
  {
    "path": "external/QCodeEditor/resources/languages/glsl.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>attribute</name>\n        <name>const</name>\n        <name>uniform</name>\n        <name>varying</name>\n        <name>buffer</name>\n        <name>shared</name>\n        <name>coherent</name>\n        <name>volatile</name>\n        <name>restrict</name>\n        <name>readonly</name>\n        <name>writeonly</name>\n        <name>layout</name>\n        <name>centroid</name>\n        <name>flat</name>\n        <name>smooth</name>\n        <name>noperspective</name>\n        <name>patch</name>\n        <name>sample</name>\n        <name>break</name>\n        <name>continue</name>\n        <name>do</name>\n        <name>for</name>\n        <name>while</name>\n        <name>switch</name>\n        <name>case</name>\n        <name>default</name>\n        <name>if</name>\n        <name>else</name>\n        <name>subroutine</name>\n        <name>in</name>\n        <name>out</name>\n        <name>inout</name>\n        <name>invariant</name>\n        <name>precise</name>\n        <name>discard</name>\n        <name>return</name>\n        <name>lowp</name>\n        <name>mediump</name>\n        <name>highp</name>\n        <name>precision</name>\n        <name>struct</name>\n    </section>\n    <section name=\"Function\">\n        <name>radians</name>\n        <name>degrees</name>\n        <name>sin</name>\n        <name>cos</name>\n        <name>tan</name>\n        <name>asin</name>\n        <name>acos</name>\n        <name>atan</name>\n        <name>sinh</name>\n        <name>cosh</name>\n        <name>tanh</name>\n        <name>asinh</name>\n        <name>acosh</name>\n        <name>atanh</name>\n        <name>pow</name>\n        <name>exp</name>\n        <name>log</name>\n        <name>exp2</name>\n        <name>log2</name>\n        <name>sqrt</name>\n        <name>inversesqrt</name>\n        <name>abs</name>\n        <name>sign</name>\n        <name>floor</name>\n        <name>trunc</name>\n        <name>round</name>\n        <name>roundEven</name>\n        <name>ceil</name>\n        <name>fract</name>\n        <name>mod</name>\n        <name>modf</name>\n        <name>min</name>\n        <name>max</name>\n        <name>clamp</name>\n        <name>mix</name>\n        <name>step</name>\n        <name>smoothstep</name>\n        <name>isnan</name>\n        <name>isinf</name>\n        <name>floatBitsToInt</name>\n        <name>floatBitsToUint</name>\n        <name>intBitsToFloat</name>\n        <name>uintBitsToFloat</name>\n        <name>fma</name>\n        <name>frexp</name>\n        <name>ldexp</name>\n        <name>packUnorm2x16</name>\n        <name>packSnorm2x16</name>\n        <name>packUnorm4x8</name>\n        <name>packSnorm4x8</name>\n        <name>unpackUnorm2x16</name>\n        <name>unpackSnorm2x16</name>\n        <name>unpackUnorm4x8</name>\n        <name>unpackSnorm4x8</name>\n        <name>packDouble2x32</name>\n        <name>unpackDouble2x32</name>\n        <name>packHalf2x16</name>\n        <name>unpackHalf2x16</name>\n        <name>length</name>\n        <name>distance</name>\n        <name>dot</name>\n        <name>cross</name>\n        <name>normalize</name>\n        <name>ftransform</name>\n        <name>faceforward</name>\n        <name>reflect</name>\n        <name>refract</name>\n        <name>matrixCompMult</name>\n        <name>outerProduct</name>\n        <name>transpose</name>\n        <name>determinant</name>\n        <name>inverse</name>\n        <name>lessThan</name>\n        <name>lessThanEqual</name>\n        <name>greaterThan</name>\n        <name>greaterThanEqual</name>\n        <name>equal</name>\n        <name>notEqual</name>\n        <name>any</name>\n        <name>all</name>\n        <name>not</name>\n        <name>uaddCarry</name>\n        <name>usubBorrow</name>\n        <name>umulExtended</name>\n        <name>imulExtended</name>\n        <name>bitfieldExtract</name>\n        <name>bitfieldInsert</name>\n        <name>bitfieldReverse</name>\n        <name>bitCount</name>\n        <name>findLSB</name>\n        <name>findMSB</name>\n        <name>textureSize</name>\n        <name>textureQueryLod</name>\n        <name>textureQueryLevels</name>\n        <name>textureSamples</name>\n        <name>texture</name>\n        <name>textureProj</name>\n        <name>textureLod</name>\n        <name>textureOffset</name>\n        <name>texelFetch</name>\n        <name>texelFetchOffset</name>\n        <name>textureProjOffset</name>\n        <name>textureLodOffset</name>\n        <name>textureProjLod</name>\n        <name>textureProjLodOffset</name>\n        <name>textureGrad</name>\n        <name>textureGradOffset</name>\n        <name>textureProjGrad</name>\n        <name>textureProjGradOffset</name>\n        <name>textureGather</name>\n        <name>textureGatherOffset</name>\n        <name>textureGatherOffsets</name>\n        <name>texture1D</name>\n        <name>texture1DProj</name>\n        <name>texture1DLod</name>\n        <name>texture1DProjLod</name>\n        <name>texture2D</name>\n        <name>texture2DProj</name>\n        <name>texture2DLod</name>\n        <name>texture2DProjLod</name>\n        <name>texture3D</name>\n        <name>texture3DProj</name>\n        <name>texture3DLod</name>\n        <name>texture3DProjLod</name>\n        <name>textureCube</name>\n        <name>textureCubeLod</name>\n        <name>shadow1D</name>\n        <name>shadow2D</name>\n        <name>shadow1DProj</name>\n        <name>shadow2DProj</name>\n        <name>shadow1DLod</name>\n        <name>shadow2DLod</name>\n        <name>shadow1DProjLod</name>\n        <name>shadow2DProjLod</name>\n        <name>atomicCounterIncrement</name>\n        <name>atomicCounterDecrement</name>\n        <name>atomicCounter</name>\n        <name>atomicAdd</name>\n        <name>atomicMin</name>\n        <name>atomicMax</name>\n        <name>atomicAnd</name>\n        <name>atomicOr</name>\n        <name>atomicXor</name>\n        <name>atomicExchange</name>\n        <name>atomicCompSwap</name>\n        <name>imageSize</name>\n        <name>imageSamples</name>\n        <name>imageLoad</name>\n        <name>imageStore</name>\n        <name>imageAtomicAdd</name>\n        <name>imageAtomicMin</name>\n        <name>imageAtomicMax</name>\n        <name>imageAtomicAnd</name>\n        <name>imageAtomicOr</name>\n        <name>imageAtomicXor</name>\n        <name>imageAtomicExchange</name>\n        <name>imageAtomicCompSwap</name>\n        <name>dFdx</name>\n        <name>dFdy</name>\n        <name>dFdxFine</name>\n        <name>dFdyFine</name>\n        <name>dFdxCoarse</name>\n        <name>dFdyCoarse</name>\n        <name>fwidth</name>\n        <name>fwidthFine</name>\n        <name>fwidthCoarse</name>\n        <name>interpolateAtCentroid</name>\n        <name>interpolateAtSample</name>\n        <name>interpolateAtOffset</name>\n        <name>noise1</name>\n        <name>noise2</name>\n        <name>noise3</name>\n        <name>noise4</name>\n        <name>EmitStreamVertex</name>\n        <name>EndStreamPrimitive</name>\n        <name>EndStreamPrimitive</name>\n        <name>EndStreamPrimitive</name>\n        <name>memoryBarrier</name>\n        <name>memoryBarrierAtomicCounter</name>\n        <name>memoryBarrierBuffer</name>\n        <name>memoryBarrierShared</name>\n        <name>memoryBarrierImage</name>\n        <name>groupMemoryBarrier</name>\n    </section>\n    <section name=\"PrimitiveType\">\n        <name>float</name>\n        <name>atomic_uint</name>\n        <name>double</name>\n        <name>int</name>\n        <name>void</name>\n        <name>bool</name>\n        <name>true</name>\n        <name>false</name>\n        <name>mat2</name>\n        <name>mat3</name>\n        <name>mat4</name>\n        <name>dmat2</name>\n        <name>dmat3</name>\n        <name>dmat4</name>\n        <name>mat2x2</name>\n        <name>mat2x3</name>\n        <name>mat2x4</name>\n        <name>dmat2x2</name>\n        <name>dmat2x3</name>\n        <name>dmat2x4</name>\n        <name>mat3x2</name>\n        <name>mat3x3</name>\n        <name>mat3x4</name>\n        <name>dmat3x2</name>\n        <name>dmat3x3</name>\n        <name>dmat3x4</name>\n        <name>mat4x2</name>\n        <name>mat4x3</name>\n        <name>mat4x4</name>\n        <name>dmat4x2</name>\n        <name>dmat4x3</name>\n        <name>dmat4x4</name>\n        <name>vec2</name>\n        <name>vec3</name>\n        <name>vec4</name>\n        <name>ivec2</name>\n        <name>ivec3</name>\n        <name>ivec4</name>\n        <name>bvec2</name>\n        <name>bvec3</name>\n        <name>bvec4</name>\n        <name>dvec2</name>\n        <name>dvec3</name>\n        <name>dvec4</name>\n        <name>uint</name>\n        <name>uvec2</name>\n        <name>uvec3</name>\n        <name>uvec4</name>\n        <name>sampler1D</name>\n        <name>sampler2D</name>\n        <name>sampler3D</name>\n        <name>samplerCube</name>\n        <name>sampler1DShadow</name>\n        <name>sampler2DShadow</name>\n        <name>samplerCubeShadow</name>\n        <name>sampler1DArray</name>\n        <name>sampler2DArray</name>\n        <name>sampler1DArrayShadow</name>\n        <name>sampler2DArrayShadow</name>\n        <name>sampler1D</name>\n        <name>isampler2D</name>\n        <name>isampler3D</name>\n        <name>isamplerCube</name>\n        <name>isampler1DArray</name>\n        <name>isampler2DArray</name>\n        <name>usampler1D</name>\n        <name>usampler2D</name>\n        <name>usampler3D</name>\n        <name>usamplerCube</name>\n        <name>usampler1DArray</name>\n        <name>usampler2DArray</name>\n        <name>sampler2DRect</name>\n        <name>sampler2DRectShadow</name>\n        <name>isampler2DRect</name>\n        <name>usampler2DRect</name>\n        <name>samplerBuffer</name>\n        <name>isamplerBuffer</name>\n        <name>usamplerBuffer</name>\n        <name>sampler2DMS</name>\n        <name>isampler2DMS</name>\n        <name>usampler2DMS</name>\n        <name>sampler2DMSArray</name>\n        <name>isampler2DMSArray</name>\n        <name>usampler2DMSArray</name>\n        <name>samplerCubeArray</name>\n        <name>samplerCubeArrayShadow</name>\n        <name>isamplerCubeArray</name>\n        <name>usamplerCubeArray</name>\n        <name>image1D</name>\n        <name>iimage1D</name>\n        <name>uimage1D</name>\n        <name>image2D</name>\n        <name>iimage2D</name>\n        <name>uimage2D</name>\n        <name>image3D</name>\n        <name>iimage3D</name>\n        <name>uimage3D</name>\n        <name>image2DRect</name>\n        <name>iimage2DRect</name>\n        <name>uimage2DRect</name>\n        <name>imageCube</name>\n        <name>iimageCube</name>\n        <name>uimageCube</name>\n        <name>imageBuffer</name>\n        <name>iimageBuffer</name>\n        <name>uimageBuffer</name>\n        <name>image1DArray</name>\n        <name>iimage1DArray</name>\n        <name>uimage1DArray</name>\n        <name>image2DArray</name>\n        <name>iimage2DArray</name>\n        <name>uimage2DArray</name>\n        <name>imageCubeArray</name>\n        <name>iimageCubeArray</name>\n        <name>uimageCubeArray</name>\n        <name>image2DMS</name>\n        <name>iimage2DMS</name>\n        <name>uimage2DMS</name>\n        <name>image2DMSArray</name>\n        <name>iimage2DMSArray</name>\n        <name>uimage2DMSArray</name>\n    </section>\n</root>\n"
  },
  {
    "path": "external/QCodeEditor/resources/languages/java.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>abstract</name>\n        <name>assert</name>\n        <name>break</name>\n        <name>case</name>\n        <name>catch</name>\n        <name>const</name>\n        <name>continue</name>\n        <name>default</name>\n        <name>do</name>\n        <name>else</name>\n        <name>extends</name>\n        <name>final</name>\n        <name>finally</name>\n        <name>for</name>\n        <name>if</name>\n        <name>goto</name>\n        <name>implements</name>\n        <name>import</name>\n        <name>instanceof</name>\n        <name>native</name>\n        <name>new</name>\n        <name>package</name>\n        <name>private</name>\n        <name>protected</name>\n        <name>public</name>\n        <name>return</name>\n        <name>static</name>\n        <name>strictfp</name>\n        <name>super</name>\n        <name>switch</name>\n        <name>synchronized</name>\n        <name>this</name>\n        <name>throw</name>\n        <name>throws</name>\n        <name>transient</name>\n        <name>try</name>\n        <name>volatile</name>\n        <name>while</name>\n\n        <name>true</name>\n        <name>false</name>\n        <name>null</name>\n\n    </section>\n    <section name=\"PrimitiveType\">\n        <name>boolean</name>\n        <name>byte</name>\n        <name>char</name>\n        <name>class</name>\n        <name>double</name>\n        <name>enum</name>\n        <name>float</name>\n        <name>int</name>\n        <name>interface</name>\n        <name>long</name>\n        <name>short</name>\n        <name>void</name>\n    </section>\n</root>\n"
  },
  {
    "path": "external/QCodeEditor/resources/languages/js.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>break</name>\n        <name>case</name>\n        <name>class</name>\n        <name>catch</name>\n        <name>const</name>\n        <name>continue</name>\n        <name>debugger</name>\n        <name>default</name>\n        <name>delete</name>\n        <name>do</name>\n        <name>else</name>\n        <name>export</name>\n        <name>extends</name>\n        <name>finally</name>\n        <name>for</name>\n        <name>function</name>\n        <name>if</name>\n        <name>import</name>\n        <name>in</name>\n        <name>instanceof</name>\n        <name>let</name>\n        <name>new</name>\n        <name>return</name>\n        <name>super</name>\n        <name>switch</name>\n        <name>this</name>\n        <name>throw</name>\n        <name>try</name>\n        <name>typeof</name>\n        <name>var</name>\n        <name>void</name>\n        <name>while</name>\n        <name>with</name>\n        <name>yield</name>\n    </section>\n</root>"
  },
  {
    "path": "external/QCodeEditor/resources/languages/lua.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>break</name>\n        <name>do</name>\n        <name>else</name>\n        <name>elseif</name>\n        <name>end</name>\n        <name>false</name>\n        <name>for</name>\n        <name>function</name>\n        <name>if</name>\n        <name>in</name>\n        <name>repeat</name>\n        <name>return</name>\n        <name>then</name>\n        <name>until</name>\n        <name>while</name>\n    </section>\n    <section name=\"Type\">\n        <name>local</name>\n        <name>nil</name>\n        <name>boolean</name>\n        <name>number</name>\n        <name>string</name>\n        <name>function</name>\n        <name>userdata</name>\n        <name>thread</name>\n        <name>table</name>\n    </section>\n    <section name=\"Operator\">\n        <name>\\+</name>\n        <name>\\-</name>\n        <name>\\*</name>\n        <name>\\/</name>\n        <name>\\%</name>\n        <name>\\^</name>\n        <name>==</name>\n        <name>~=</name>\n        <name>&gt;</name>\n        <name>&lt;</name>\n        <name>&gt;=</name>\n        <name>&lt;=</name>\n        <name>and</name>\n        <name>or</name>\n        <name>not</name>\n        <name>\\.\\.</name>\n        <name>\\#</name>\n    </section>\n</root>\n"
  },
  {
    "path": "external/QCodeEditor/resources/languages/python.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<root>\n    <section name=\"Keyword\">\n        <name>break</name>\n        <name>continue</name>\n        <name>do</name>\n        <name>for</name>\n        <name>while</name>\n        <name>if</name>\n        <name>else</name>\n        <name>def</name>\n        <name>import</name>\n        <name>return</name>\n        <name>class</name>\n        <name>in</name>\n        <name>is</name>\n        <name>not</name>\n        <name>or</name>\n        <name>and</name>\n        <name>enumerate</name>\n    </section>\n    <section name=\"Function\">\n        <name>min</name>\n        <name>max</name>\n        <name>len</name>\n    </section>\n    <section name=\"PrimitiveType\">\n        <name>float</name>\n        <name>int</name>\n        <name>bool</name>\n        <name>True</name>\n        <name>False</name>\n        <name>str</name>\n        <name>unicode</name>\n        <name>byte</name>\n        <name>set</name>\n        <name>dict</name>\n    </section>\n</root>\n"
  },
  {
    "path": "external/QCodeEditor/resources/qcodeeditor_resources.qrc",
    "content": "<RCC>\n    <qresource prefix=\"/\">\n        <file>default_style.xml</file>\n        <file>languages/glsl.xml</file>\n        <file>languages/cpp.xml</file>\n        <file>languages/java.xml</file>\n        <file>languages/lua.xml</file>\n        <file>languages/python.xml</file>\n        <file>languages/js.xml</file>\n    </qresource>\n</RCC>\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QCXXHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QCXXHighlighter>\n#include <QLanguage>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QFile>\n\nQCXXHighlighter::QCXXHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(),\n      m_includePattern(QRegularExpression(R\"(^\\s*#\\s*include\\s*([<\"][^:?\"<>\\|]+[\">]))\")),\n      m_functionPattern(QRegularExpression(\n          R\"(\\b([_a-zA-Z][_a-zA-Z0-9]*\\s+)?((?:[_a-zA-Z][_a-zA-Z0-9]*\\s*::\\s*)*[_a-zA-Z][_a-zA-Z0-9]*)(?=\\s*\\())\")),\n      m_defTypePattern(QRegularExpression(R\"(\\b([_a-zA-Z][_a-zA-Z0-9]*)\\s+[_a-zA-Z][_a-zA-Z0-9]*\\s*[;=])\")),\n      m_commentStartPattern(QRegularExpression(R\"(/\\*)\")), m_commentEndPattern(QRegularExpression(R\"(\\*/)\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/cpp.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(name)), key});\n        }\n    }\n\n    // Numbers\n    m_highlightRules.append(\n        {QRegularExpression(\n             R\"((?<=\\b|\\s|^)(?i)(?:(?:(?:(?:(?:\\d+(?:'\\d+)*)?\\.(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)\\.(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)?\\.(?:[0-9a-f]+(?:'[0-9a-f]+)*)(?:p[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)\\.?(?:p[+-]?(?:\\d+(?:'\\d+)*))))[lf]?)|(?:(?:(?:[1-9]\\d*(?:'\\d+)*)|(?:0[0-7]*(?:'[0-7]+)*)|(?:0x[0-9a-f]+(?:'[0-9a-f]+)*)|(?:0b[01]+(?:'[01]+)*))(?:u?l{0,2}|l{0,2}u?)))(?=\\b|\\s|$))\"),\n         \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"(\"[^\\n\"]*\")\"), \"String\"});\n\n    // Define\n    m_highlightRules.append({QRegularExpression(R\"(#[a-zA-Z_]+)\"), \"Preprocessor\"});\n\n    // Single line\n    m_highlightRules.append({QRegularExpression(R\"(//[^\\n]*)\"), \"Comment\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"//\";\n    m_startCommentBlockSequence = \"/*\";\n    m_endCommentBlockSequence = \"*/\";\n}\n\nvoid QCXXHighlighter::highlightBlock(const QString &text)\n{\n    // Checking for include\n    {\n        auto matchIterator = m_includePattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Preprocessor\"));\n\n            setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"String\"));\n        }\n    }\n    // Checking for function\n    {\n        auto matchIterator = m_functionPattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Type\"));\n\n            setFormat(match.capturedStart(2), match.capturedLength(2), syntaxStyle()->getFormat(\"Function\"));\n        }\n    }\n    {\n        auto matchIterator = m_defTypePattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"Type\"));\n        }\n    }\n\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n\n    int startIndex = 0;\n    if (previousBlockState() != 1)\n    {\n        startIndex = text.indexOf(m_commentStartPattern);\n    }\n\n    while (startIndex >= 0)\n    {\n        auto match = m_commentEndPattern.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int commentLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(1);\n            commentLength = text.length() - startIndex;\n        }\n        else\n        {\n            commentLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, commentLength, syntaxStyle()->getFormat(\"Comment\"));\n        startIndex = text.indexOf(m_commentStartPattern, startIndex + commentLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QCodeEditor.cpp",
    "content": "// QCodeEditor\n#include <QCXXHighlighter>\n#include <QCodeEditor>\n#include <QJSHighlighter>\n#include <QJavaHighlighter>\n#include <QLineNumberArea>\n#include <QPythonHighlighter>\n#include <QStyleSyntaxHighlighter>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QAbstractItemView>\n#include <QAbstractTextDocumentLayout>\n#include <QCompleter>\n#include <QCursor>\n#include <QDebug>\n#include <QFontDatabase>\n#include <QMimeData>\n#include <QPaintEvent>\n#include <QScrollBar>\n#include <QShortcut>\n#include <QTextBlock>\n#include <QTextCharFormat>\n#include <QTextStream>\n#include <QToolTip>\n\nQCodeEditor::QCodeEditor(QWidget *widget)\n    : QTextEdit(widget), m_highlighter(nullptr), m_syntaxStyle(nullptr), m_lineNumberArea(new QLineNumberArea(this)),\n      m_completer(nullptr), m_autoIndentation(true), m_replaceTab(true), m_extraBottomMargin(true),\n      m_tabReplace(QString(4, ' ')), extra1(), extra2(), extra_squiggles(), m_squiggler(),\n      m_parentheses({{'(', ')'}, {'{', '}'}, {'[', ']'}, {'\\\"', '\\\"'}, {'\\'', '\\''}})\n{\n    initFont();\n    performConnections();\n    setMouseTracking(true);\n\n    setSyntaxStyle(QSyntaxStyle::defaultStyle());\n}\n\nvoid QCodeEditor::initFont()\n{\n    auto fnt = QFontDatabase::systemFont(QFontDatabase::FixedFont);\n    fnt.setFixedPitch(true);\n    fnt.setPointSize(10);\n\n    setFont(fnt);\n}\n\nvoid QCodeEditor::performConnections()\n{\n    connect(document(), &QTextDocument::blockCountChanged, this, &QCodeEditor::updateLineNumberAreaWidth);\n    connect(document(), &QTextDocument::blockCountChanged, this, &QCodeEditor::updateBottomMargin);\n\n    connect(verticalScrollBar(), &QScrollBar::valueChanged, this, [this](int) { m_lineNumberArea->update(); });\n\n    connect(this, &QTextEdit::cursorPositionChanged, this, &QCodeEditor::updateExtraSelection1);\n    connect(this, &QTextEdit::selectionChanged, this, &QCodeEditor::updateExtraSelection2);\n}\n\nvoid QCodeEditor::setHighlighter(QStyleSyntaxHighlighter *highlighter)\n{\n    if (m_highlighter)\n    {\n        m_highlighter->setDocument(nullptr);\n    }\n\n    m_highlighter = highlighter;\n\n    if (m_highlighter)\n    {\n        m_highlighter->setSyntaxStyle(m_syntaxStyle);\n        m_highlighter->setDocument(document());\n    }\n}\n\nvoid QCodeEditor::setSyntaxStyle(QSyntaxStyle *style)\n{\n    m_syntaxStyle = style;\n\n    m_lineNumberArea->setSyntaxStyle(m_syntaxStyle);\n\n    if (m_highlighter)\n    {\n        m_highlighter->setSyntaxStyle(m_syntaxStyle);\n    }\n\n    updateStyle();\n}\n\nvoid QCodeEditor::updateStyle()\n{\n    if (m_highlighter)\n    {\n        m_highlighter->rehighlight();\n    }\n\n    if (m_syntaxStyle)\n    {\n        QString backgroundColor = m_syntaxStyle->getFormat(\"Text\").background().color().name();\n        QString textColor = m_syntaxStyle->getFormat(\"Text\").foreground().color().name();\n        QString selectionBackground = m_syntaxStyle->getFormat(\"Selection\").background().color().name();\n\n        setStyleSheet(QString(\"QTextEdit { background-color: %1; selection-background-color: %2; color: %3; }\")\n                          .arg(backgroundColor, selectionBackground, textColor));\n    }\n\n    updateExtraSelection1();\n    updateExtraSelection2();\n}\n\nvoid QCodeEditor::resizeEvent(QResizeEvent *e)\n{\n    QTextEdit::resizeEvent(e);\n\n    updateLineGeometry();\n    updateBottomMargin();\n}\n\nvoid QCodeEditor::changeEvent(QEvent *e)\n{\n    QTextEdit::changeEvent(e);\n    if (e->type() == QEvent::FontChange)\n        updateBottomMargin();\n}\n\nvoid QCodeEditor::wheelEvent(QWheelEvent *e)\n{\n    if (e->modifiers() == Qt::ControlModifier)\n    {\n        const auto sizes = QFontDatabase::standardSizes();\n        if (sizes.isEmpty())\n        {\n            qDebug() << \"QFontDatabase::standardSizes() is empty\";\n            return;\n        }\n        int newSize = font().pointSize();\n        if (e->angleDelta().y() > 0)\n            newSize = qMin(newSize + 1, sizes.last());\n        else if (e->angleDelta().y() < 0)\n            newSize = qMax(newSize - 1, sizes.first());\n        if (newSize != font().pointSize())\n        {\n            QFont newFont = font();\n            newFont.setPointSize(newSize);\n            setFont(newFont);\n            Q_EMIT fontChanged(newFont);\n        }\n    }\n    else\n        QTextEdit::wheelEvent(e);\n}\n\nvoid QCodeEditor::updateLineGeometry()\n{\n    QRect cr = contentsRect();\n    m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), m_lineNumberArea->sizeHint().width(), cr.height()));\n}\n\nvoid QCodeEditor::updateBottomMargin()\n{\n    auto doc = document();\n    if (doc->blockCount() > 1)\n    {\n        // calling QTextFrame::setFrameFormat with an empty document makes the application crash\n        auto rf = doc->rootFrame();\n        auto format = rf->frameFormat();\n        int documentMargin = doc->documentMargin();\n        int bottomMargin = m_extraBottomMargin\n                               ? qMax(documentMargin, viewport()->height() - fontMetrics().height()) - documentMargin\n                               : documentMargin;\n        if (format.bottomMargin() != bottomMargin)\n        {\n            format.setBottomMargin(bottomMargin);\n            rf->setFrameFormat(format);\n        }\n    }\n}\n\nvoid QCodeEditor::updateLineNumberAreaWidth(int)\n{\n    setViewportMargins(m_lineNumberArea->sizeHint().width(), 0, 0, 0);\n}\n\nvoid QCodeEditor::updateLineNumberArea(QRect rect)\n{\n    m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->sizeHint().width(), rect.height());\n    updateLineGeometry();\n\n    if (rect.contains(viewport()->rect()))\n    {\n        updateLineNumberAreaWidth(0);\n    }\n}\n\nvoid QCodeEditor::updateExtraSelection1()\n{\n    extra1.clear();\n\n    highlightCurrentLine();\n    highlightParenthesis();\n\n    setExtraSelections(extra1 + extra2 + extra_squiggles);\n}\n\nvoid QCodeEditor::updateExtraSelection2()\n{\n    extra2.clear();\n\n    highlightOccurrences();\n\n    setExtraSelections(extra1 + extra2 + extra_squiggles);\n}\n\nvoid QCodeEditor::indent()\n{\n    addInEachLineOfSelection(QRegularExpression(\"^\"), m_replaceTab ? m_tabReplace : \"\\t\");\n}\n\nvoid QCodeEditor::unindent()\n{\n    removeInEachLineOfSelection(QRegularExpression(\"^(\\t| {1,\" + QString::number(tabReplaceSize()) + \"})\"), true);\n}\n\nvoid QCodeEditor::swapLineUp()\n{\n    auto cursor = textCursor();\n    auto lines = toPlainText().remove('\\r').split('\\n');\n    int selectionStart = cursor.selectionStart();\n    int selectionEnd = cursor.selectionEnd();\n    bool cursorAtEnd = cursor.position() == selectionEnd;\n    cursor.setPosition(selectionStart);\n    int lineStart = cursor.blockNumber();\n    cursor.setPosition(selectionEnd);\n    int lineEnd = cursor.blockNumber();\n\n    if (lineStart == 0)\n        return;\n    selectionStart -= lines[lineStart - 1].length() + 1;\n    selectionEnd -= lines[lineStart - 1].length() + 1;\n    lines.move(lineStart - 1, lineEnd);\n\n    cursor.select(QTextCursor::Document);\n    cursor.insertText(lines.join('\\n'));\n\n    if (cursorAtEnd)\n    {\n        cursor.setPosition(selectionStart);\n        cursor.setPosition(selectionEnd, QTextCursor::KeepAnchor);\n    }\n    else\n    {\n        cursor.setPosition(selectionEnd);\n        cursor.setPosition(selectionStart, QTextCursor::KeepAnchor);\n    }\n\n    setTextCursor(cursor);\n}\n\nvoid QCodeEditor::swapLineDown()\n{\n    auto cursor = textCursor();\n    auto lines = toPlainText().remove('\\r').split('\\n');\n    int selectionStart = cursor.selectionStart();\n    int selectionEnd = cursor.selectionEnd();\n    bool cursorAtEnd = cursor.position() == selectionEnd;\n    cursor.setPosition(selectionStart);\n    int lineStart = cursor.blockNumber();\n    cursor.setPosition(selectionEnd);\n    int lineEnd = cursor.blockNumber();\n\n    if (lineEnd == document()->blockCount() - 1)\n        return;\n    selectionStart += lines[lineEnd + 1].length() + 1;\n    selectionEnd += lines[lineEnd + 1].length() + 1;\n    lines.move(lineEnd + 1, lineStart);\n\n    cursor.select(QTextCursor::Document);\n    cursor.insertText(lines.join('\\n'));\n\n    if (cursorAtEnd)\n    {\n        cursor.setPosition(selectionStart);\n        cursor.setPosition(selectionEnd, QTextCursor::KeepAnchor);\n    }\n    else\n    {\n        cursor.setPosition(selectionEnd);\n        cursor.setPosition(selectionStart, QTextCursor::KeepAnchor);\n    }\n\n    setTextCursor(cursor);\n}\n\nvoid QCodeEditor::deleteLine()\n{\n    auto cursor = textCursor();\n    int selectionStart = cursor.selectionStart();\n    int selectionEnd = cursor.selectionEnd();\n    cursor.setPosition(selectionStart);\n    int lineStart = cursor.blockNumber();\n    cursor.setPosition(selectionEnd);\n    int lineEnd = cursor.blockNumber();\n    int columnNumber = textCursor().columnNumber();\n    cursor.movePosition(QTextCursor::Start);\n    if (lineEnd == document()->blockCount() - 1)\n    {\n        if (lineStart == 0)\n        {\n            cursor.select(QTextCursor::Document);\n        }\n        else\n        {\n            cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineStart - 1);\n            cursor.movePosition(QTextCursor::EndOfBlock);\n            cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);\n        }\n    }\n    else\n    {\n        cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineStart);\n        cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, lineEnd - lineStart + 1);\n    }\n    cursor.removeSelectedText();\n    cursor.movePosition(QTextCursor::StartOfBlock);\n    cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor,\n                        qMin(columnNumber, cursor.block().text().length()));\n    setTextCursor(cursor);\n}\n\nvoid QCodeEditor::duplicate()\n{\n    auto cursor = textCursor();\n    if (cursor.hasSelection()) // duplicate the selection\n    {\n        auto text = cursor.selectedText();\n        bool cursorAtEnd = cursor.selectionEnd() == cursor.position();\n        cursor.insertText(text + text);\n        if (cursorAtEnd)\n        {\n            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::MoveAnchor, text.length());\n            cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, text.length());\n        }\n        else\n        {\n            cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor, text.length());\n        }\n    }\n    else // duplicate the current line\n    {\n        int column = cursor.columnNumber();\n        cursor.movePosition(QTextCursor::StartOfBlock);\n        cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);\n        auto text = cursor.selectedText();\n        cursor.insertText(text + \"\\n\" + text);\n        cursor.movePosition(QTextCursor::StartOfBlock);\n        cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, column);\n    }\n    setTextCursor(cursor);\n}\n\nvoid QCodeEditor::toggleComment()\n{\n    if (m_highlighter == nullptr)\n        return;\n    QString comment = m_highlighter->commentLineSequence();\n    if (comment.isEmpty())\n        return;\n\n    if (!removeInEachLineOfSelection(QRegularExpression(\"^\\\\s*(\" + comment + \" ?)\"), false))\n    {\n        addInEachLineOfSelection(QRegularExpression(\"\\\\S|^\\\\s*$\"), comment + \" \");\n    }\n}\n\nvoid QCodeEditor::toggleBlockComment()\n{\n    if (m_highlighter == nullptr)\n        return;\n    QString commentStart = m_highlighter->startCommentBlockSequence();\n    QString commentEnd = m_highlighter->endCommentBlockSequence();\n\n    if (commentStart.isEmpty() || commentEnd.isEmpty())\n        return;\n\n    auto cursor = textCursor();\n    int startPos = cursor.selectionStart();\n    int endPos = cursor.selectionEnd();\n    bool cursorAtEnd = cursor.position() == endPos;\n    auto text = cursor.selectedText();\n    int pos1, pos2;\n    if (text.indexOf(commentStart) == 0 && text.length() >= commentStart.length() + commentEnd.length() &&\n        text.lastIndexOf(commentEnd) + commentEnd.length() == text.length())\n    {\n        insertPlainText(text.mid(commentStart.length(), text.length() - commentStart.length() - commentEnd.length()));\n        pos1 = startPos;\n        pos2 = endPos - commentStart.length() - commentEnd.length();\n    }\n    else\n    {\n        insertPlainText(commentStart + text + commentEnd);\n        pos1 = startPos;\n        pos2 = endPos + commentStart.length() + commentEnd.length();\n    }\n    if (cursorAtEnd)\n    {\n        cursor.setPosition(pos1);\n        cursor.setPosition(pos2, QTextCursor::KeepAnchor);\n    }\n    else\n    {\n        cursor.setPosition(pos2);\n        cursor.setPosition(pos1, QTextCursor::KeepAnchor);\n    }\n    setTextCursor(cursor);\n}\n\nvoid QCodeEditor::highlightParenthesis()\n{\n    auto currentSymbol = charUnderCursor();\n    auto prevSymbol = charUnderCursor(-1);\n\n    for (auto &p : m_parentheses)\n    {\n        int direction;\n\n        QChar counterSymbol;\n        QChar activeSymbol;\n        auto position = textCursor().position();\n\n        if (p.left == currentSymbol)\n        {\n            direction = 1;\n            counterSymbol = p.right;\n            activeSymbol = currentSymbol;\n        }\n        else if (p.right == prevSymbol)\n        {\n            direction = -1;\n            counterSymbol = p.left;\n            activeSymbol = prevSymbol;\n            position--;\n        }\n        else\n        {\n            continue;\n        }\n\n        auto counter = 1;\n\n        while (counter != 0 && position > 0 && position < (document()->characterCount() - 1))\n        {\n            // Moving position\n            position += direction;\n\n            auto character = document()->characterAt(position);\n            // Checking symbol under position\n            if (character == activeSymbol)\n            {\n                ++counter;\n            }\n            else if (character == counterSymbol)\n            {\n                --counter;\n            }\n        }\n\n        auto format = m_syntaxStyle->getFormat(\"Parentheses\");\n\n        // Found\n        if (counter == 0)\n        {\n            ExtraSelection selection{};\n\n            auto directionEnum = direction < 0 ? QTextCursor::MoveOperation::Left : QTextCursor::MoveOperation::Right;\n\n            selection.format = format;\n            selection.cursor = textCursor();\n            selection.cursor.clearSelection();\n            selection.cursor.movePosition(directionEnum, QTextCursor::MoveMode::MoveAnchor,\n                                          qAbs(textCursor().position() - position));\n\n            selection.cursor.movePosition(QTextCursor::MoveOperation::Right, QTextCursor::MoveMode::KeepAnchor, 1);\n\n            extra1.append(selection);\n\n            selection.cursor = textCursor();\n            selection.cursor.clearSelection();\n            selection.cursor.movePosition(directionEnum, QTextCursor::MoveMode::KeepAnchor, 1);\n\n            extra1.append(selection);\n        }\n\n        break;\n    }\n}\n\nvoid QCodeEditor::highlightCurrentLine()\n{\n    if (!isReadOnly())\n    {\n        QTextEdit::ExtraSelection selection{};\n\n        selection.format = m_syntaxStyle->getFormat(\"CurrentLine\");\n        selection.format.setForeground(QBrush());\n        selection.format.setProperty(QTextFormat::FullWidthSelection, true);\n        selection.cursor = textCursor();\n        selection.cursor.clearSelection();\n\n        extra1.append(selection);\n    }\n}\n\nvoid QCodeEditor::highlightOccurrences()\n{\n    auto cursor = textCursor();\n    if (cursor.hasSelection())\n    {\n        auto text = cursor.selectedText();\n        if (QRegularExpression(\n                R\"((?:[_a-zA-Z][_a-zA-Z0-9]*)|(?<=\\b|\\s|^)(?i)(?:(?:(?:(?:(?:\\d+(?:'\\d+)*)?\\.(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)\\.(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)?\\.(?:[0-9a-f]+(?:'[0-9a-f]+)*)(?:p[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)\\.?(?:p[+-]?(?:\\d+(?:'\\d+)*))))[lf]?)|(?:(?:(?:[1-9]\\d*(?:'\\d+)*)|(?:0[0-7]*(?:'[0-7]+)*)|(?:0x[0-9a-f]+(?:'[0-9a-f]+)*)|(?:0b[01]+(?:'[01]+)*))(?:u?l{0,2}|l{0,2}u?)))(?=\\b|\\s|$))\")\n                .match(text)\n                .captured() == text)\n        {\n            auto doc = document();\n            cursor = doc->find(text, 0, QTextDocument::FindWholeWords | QTextDocument::FindCaseSensitively);\n            while (!cursor.isNull())\n            {\n                if (cursor != textCursor())\n                {\n                    QTextEdit::ExtraSelection e;\n                    e.cursor = cursor;\n                    e.format.setBackground(m_syntaxStyle->getFormat(\"Selection\").background());\n                    extra2.push_back(e);\n                }\n                cursor = doc->find(text, cursor, QTextDocument::FindWholeWords | QTextDocument::FindCaseSensitively);\n            }\n        }\n    }\n}\n\nvoid QCodeEditor::paintEvent(QPaintEvent *e)\n{\n    updateLineNumberArea(e->rect());\n    QTextEdit::paintEvent(e);\n}\n\nint QCodeEditor::getFirstVisibleBlock()\n{\n    // Detect the first block for which bounding rect - once translated\n    // in absolute coordinated - is contained by the editor's text area\n\n    // Costly way of doing but since \"blockBoundingGeometry(...)\" doesn't\n    // exists for \"QTextEdit\"...\n\n    QTextCursor curs = QTextCursor(document());\n    curs.movePosition(QTextCursor::Start);\n    for (int i = 0; i < document()->blockCount(); ++i)\n    {\n        QTextBlock block = curs.block();\n\n        QRect r1 = viewport()->geometry();\n        QRect r2 = document()\n                       ->documentLayout()\n                       ->blockBoundingRect(block)\n                       .translated(viewport()->geometry().x(),\n                                   viewport()->geometry().y() - verticalScrollBar()->sliderPosition())\n                       .toRect();\n\n        if (r1.intersects(r2))\n        {\n            return i;\n        }\n\n        curs.movePosition(QTextCursor::NextBlock);\n    }\n\n    return 0;\n}\n\nbool QCodeEditor::proceedCompleterBegin(QKeyEvent *e)\n{\n    if (m_completer && m_completer->popup()->isVisible())\n    {\n        switch (e->key())\n        {\n        case Qt::Key_Enter:\n        case Qt::Key_Return:\n        case Qt::Key_Escape:\n        case Qt::Key_Tab:\n        case Qt::Key_Backtab:\n            e->ignore();\n            return true; // let the completer do default behavior\n        default:\n            break;\n        }\n    }\n\n    // todo: Replace with modifiable QShortcut\n    auto isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space);\n\n    return !(!m_completer || !isShortcut);\n}\n\nvoid QCodeEditor::proceedCompleterEnd(QKeyEvent *e)\n{\n    auto ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);\n\n    if (!m_completer || (ctrlOrShift && e->text().isEmpty()) || e->key() == Qt::Key_Delete)\n    {\n        return;\n    }\n\n    static QString eow(R\"(~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-=)\");\n\n    auto isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_Space);\n    auto completionPrefix = wordUnderCursor();\n\n    if (!isShortcut && (e->text().isEmpty() || completionPrefix.length() < 2 || eow.contains(e->text().right(1))))\n    {\n        m_completer->popup()->hide();\n        return;\n    }\n\n    if (completionPrefix != m_completer->completionPrefix())\n    {\n        m_completer->setCompletionPrefix(completionPrefix);\n        m_completer->popup()->setCurrentIndex(m_completer->completionModel()->index(0, 0));\n    }\n\n    auto cursRect = cursorRect();\n    cursRect.setWidth(m_completer->popup()->sizeHintForColumn(0) +\n                      m_completer->popup()->verticalScrollBar()->sizeHint().width());\n\n    m_completer->complete(cursRect);\n}\n\nvoid QCodeEditor::keyPressEvent(QKeyEvent *e)\n{\n    auto completerSkip = proceedCompleterBegin(e);\n\n    if (!completerSkip)\n    {\n        if ((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && e->modifiers() != Qt::NoModifier)\n        {\n            QKeyEvent pureEnter(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);\n            if (e->modifiers() == Qt::ControlModifier)\n            {\n                moveCursor(QTextCursor::EndOfBlock);\n                keyPressEvent(&pureEnter);\n                return;\n            }\n            else if (e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))\n            {\n                if (textCursor().blockNumber() == 0)\n                {\n                    moveCursor(QTextCursor::StartOfBlock);\n                    insertPlainText(\"\\n\");\n                    moveCursor(QTextCursor::PreviousBlock);\n                    moveCursor(QTextCursor::EndOfBlock);\n                }\n                else\n                {\n                    moveCursor(QTextCursor::PreviousBlock);\n                    moveCursor(QTextCursor::EndOfBlock);\n                    keyPressEvent(&pureEnter);\n                }\n                return;\n            }\n            else if (e->modifiers() == Qt::ShiftModifier)\n            {\n                keyPressEvent(&pureEnter);\n                return;\n            }\n        }\n\n        if (e->key() == Qt::Key_Tab && e->modifiers() == Qt::NoModifier)\n        {\n            if (textCursor().hasSelection())\n            {\n                indent();\n                return;\n            }\n\n            auto c = charUnderCursor();\n            for (auto p : qAsConst(m_parentheses))\n            {\n                if (p.tabJumpOut && c == p.right)\n                {\n                    moveCursor(QTextCursor::NextCharacter);\n                    return;\n                }\n            }\n\n            if (m_replaceTab)\n            {\n                insertPlainText(m_tabReplace);\n                return;\n            }\n        }\n\n        if (e->key() == Qt::Key_Backtab && e->modifiers() == Qt::ShiftModifier)\n        {\n            unindent();\n            return;\n        }\n\n        if (e->key() == Qt::Key_Delete && e->modifiers() == Qt::ShiftModifier)\n        {\n            deleteLine();\n            return;\n        }\n\n        // Auto indentation\n\n        QString indentationSpaces = QRegularExpression(\"^\\\\s*\")\n                                        .match(document()->findBlockByNumber(textCursor().blockNumber()).text())\n                                        .captured();\n\n        // Have Qt Edior like behaviour, if {|} and enter is pressed indent the two\n        // parenthesis\n        if (m_autoIndentation && (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) &&\n            e->modifiers() == Qt::NoModifier && charUnderCursor(-1) == '{' && charUnderCursor() == '}')\n        {\n            insertPlainText(\"\\n\" + indentationSpaces + (m_replaceTab ? m_tabReplace : \"\\t\") + \"\\n\" + indentationSpaces);\n\n            for (int i = 0; i <= indentationSpaces.length(); ++i)\n                moveCursor(QTextCursor::MoveOperation::Left);\n\n            return;\n        }\n\n        // Auto-indent for single \"{\" without \"}\"\n        if (m_autoIndentation && (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) &&\n            e->modifiers() == Qt::NoModifier && charUnderCursor(-1) == '{')\n        {\n            insertPlainText(\"\\n\" + indentationSpaces + (m_replaceTab ? m_tabReplace : \"\\t\"));\n            setTextCursor(textCursor()); // scroll to the cursor\n            return;\n        }\n\n        if (e->key() == Qt::Key_Backspace && e->modifiers() == Qt::NoModifier && !textCursor().hasSelection())\n        {\n            auto pre = charUnderCursor(-1);\n            auto nxt = charUnderCursor();\n            for (auto p : qAsConst(m_parentheses))\n            {\n                if (p.autoRemove && p.left == pre && p.right == nxt)\n                {\n                    auto cursor = textCursor();\n                    cursor.movePosition(QTextCursor::Left, QTextCursor::MoveAnchor);\n                    cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, 2);\n                    cursor.removeSelectedText();\n                    setTextCursor(textCursor()); // scroll to the cursor\n                    return;\n                }\n            }\n\n            if (textCursor().columnNumber() <= indentationSpaces.length() && textCursor().columnNumber() >= 1 &&\n                !m_tabReplace.isEmpty())\n            {\n                auto cursor = textCursor();\n                int realColumn = 0, newIndentLength = 0;\n                for (int i = 0; i < cursor.columnNumber(); ++i)\n                {\n                    if (indentationSpaces[i] != '\\t')\n                        ++realColumn;\n                    else\n                    {\n                        realColumn =\n                            (realColumn + m_tabReplace.length()) / m_tabReplace.length() * m_tabReplace.length();\n                    }\n                    if (realColumn % m_tabReplace.length() == 0 && i < cursor.columnNumber() - 1)\n                    {\n                        newIndentLength = i + 1;\n                    }\n                }\n                cursor.movePosition(QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor,\n                                    cursor.columnNumber() - newIndentLength);\n                cursor.removeSelectedText();\n                setTextCursor(textCursor()); // scroll to the cursor\n                return;\n            }\n        }\n\n        for (auto p : qAsConst(m_parentheses))\n        {\n            if (p.autoComplete)\n            {\n                auto cursor = textCursor();\n                if (cursor.hasSelection())\n                {\n                    if (p.left == e->text())\n                    {\n                        // Add parentheses for selection\n                        int startPos = cursor.selectionStart();\n                        int endPos = cursor.selectionEnd();\n                        bool cursorAtEnd = cursor.position() == endPos;\n                        auto text = p.left + cursor.selectedText() + p.right;\n                        insertPlainText(text);\n                        if (cursorAtEnd)\n                        {\n                            cursor.setPosition(startPos + 1);\n                            cursor.setPosition(endPos + 1, QTextCursor::KeepAnchor);\n                        }\n                        else\n                        {\n                            cursor.setPosition(endPos + 1);\n                            cursor.setPosition(startPos + 1, QTextCursor::KeepAnchor);\n                        }\n                        setTextCursor(cursor);\n                        return;\n                    }\n                }\n                else\n                {\n                    if (p.right == e->text())\n                    {\n                        auto symbol = charUnderCursor();\n\n                        if (symbol == p.right)\n                        {\n                            moveCursor(QTextCursor::NextCharacter);\n                            return;\n                        }\n                    }\n\n                    if (p.left == e->text())\n                    {\n                        insertPlainText(QString(p.left) + p.right);\n                        moveCursor(QTextCursor::PreviousCharacter);\n                        return;\n                    }\n                }\n            }\n        }\n\n        if ((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && e->modifiers() == Qt::NoModifier)\n        {\n            insertPlainText(\"\\n\" + indentationSpaces.left(textCursor().columnNumber()));\n            setTextCursor(textCursor()); // scroll to the cursor\n            return;\n        }\n\n        if (e->key() == Qt::Key_Escape && textCursor().hasSelection())\n        {\n            auto cursor = textCursor();\n            cursor.clearSelection();\n            setTextCursor(cursor);\n        }\n\n        QTextEdit::keyPressEvent(e);\n    }\n\n    proceedCompleterEnd(e);\n}\n\nvoid QCodeEditor::setAutoIndentation(bool enabled)\n{\n    m_autoIndentation = enabled;\n}\n\nvoid QCodeEditor::setParentheses(const QVector<Parenthesis> &parentheses)\n{\n    m_parentheses = parentheses;\n}\n\nvoid QCodeEditor::setExtraBottomMargin(bool enabled)\n{\n    m_extraBottomMargin = enabled;\n    updateBottomMargin();\n}\n\nbool QCodeEditor::autoIndentation() const\n{\n    return m_autoIndentation;\n}\n\nvoid QCodeEditor::setTabReplace(bool enabled)\n{\n    m_replaceTab = enabled;\n}\n\nbool QCodeEditor::tabReplace() const\n{\n    return m_replaceTab;\n}\n\nvoid QCodeEditor::setTabReplaceSize(int val)\n{\n    m_tabReplace.fill(' ', val);\n#if QT_VERSION >= 0x050B00\n    setTabStopDistance(fontMetrics().horizontalAdvance(QString(val * 1000, ' ')) / 1000.0);\n#elif QT_VERSION == 0x050A00\n    setTabStopDistance(fontMetrics().width(QString(val * 1000, ' ')) / 1000.0);\n#else\n    setTabStopWidth(fontMetrics().width(QString(val * 1000, ' ')) / 1000.0);\n#endif\n}\n\nint QCodeEditor::tabReplaceSize() const\n{\n    return m_tabReplace.size();\n}\n\nvoid QCodeEditor::setCompleter(QCompleter *completer)\n{\n    if (m_completer)\n    {\n        disconnect(m_completer, nullptr, this, nullptr);\n    }\n\n    m_completer = completer;\n\n    if (!m_completer)\n    {\n        return;\n    }\n\n    m_completer->setWidget(this);\n    m_completer->setCompletionMode(QCompleter::CompletionMode::PopupCompletion);\n\n    connect(m_completer, QOverload<const QString &>::of(&QCompleter::activated), this, &QCodeEditor::insertCompletion);\n}\n\nvoid QCodeEditor::focusInEvent(QFocusEvent *e)\n{\n    if (m_completer)\n    {\n        m_completer->setWidget(this);\n    }\n\n    QTextEdit::focusInEvent(e);\n}\n\nbool QCodeEditor::event(QEvent *event)\n{\n    if (event->type() == QEvent::ToolTip)\n    {\n        auto *helpEvent = dynamic_cast<QHelpEvent *>(event);\n        auto point = helpEvent->pos();\n        point.setX(point.x() - m_lineNumberArea->geometry().right());\n        QTextCursor cursor = cursorForPosition(point);\n\n        auto lineNumber = cursor.blockNumber() + 1;\n\n        QTextCursor copyCursor(cursor);\n        copyCursor.movePosition(QTextCursor::StartOfBlock);\n\n        auto blockPositionStart = cursor.positionInBlock() - copyCursor.positionInBlock();\n        QPair<int, int> positionOfTooltip{lineNumber, blockPositionStart};\n\n        QString text;\n        for (auto const &e : qAsConst(m_squiggler))\n        {\n            if (e.m_startPos <= positionOfTooltip && e.m_stopPos >= positionOfTooltip)\n            {\n                if (text.isEmpty())\n                    text = e.m_tooltipText;\n                else\n                    text += \"; \" + e.m_tooltipText;\n            }\n        }\n\n        if (text.isEmpty())\n            QToolTip::hideText();\n        else\n            QToolTip::showText(helpEvent->globalPos(), text);\n\n        return true;\n    }\n    return QTextEdit::event(event);\n}\n\nvoid QCodeEditor::insertCompletion(const QString &s)\n{\n    if (m_completer->widget() != this)\n    {\n        return;\n    }\n\n    auto tc = textCursor();\n    tc.select(QTextCursor::SelectionType::WordUnderCursor);\n    tc.insertText(s);\n    setTextCursor(tc);\n}\n\nQCompleter *QCodeEditor::completer() const\n{\n    return m_completer;\n}\n\nvoid QCodeEditor::squiggle(SeverityLevel level, QPair<int, int> start, QPair<int, int> stop,\n                           const QString &tooltipMessage)\n{\n    if (stop < start)\n        return;\n\n    SquiggleInformation info(start, stop, tooltipMessage);\n    m_squiggler.push_back(info);\n\n    auto cursor = textCursor();\n\n    cursor.movePosition(QTextCursor::Start);\n    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, start.first - 1);\n    cursor.movePosition(QTextCursor::StartOfBlock);\n    cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, start.second);\n\n    if (stop.first > start.first)\n        cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, stop.first - start.first);\n\n    cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::KeepAnchor);\n    cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, stop.second);\n\n    QTextCharFormat newcharfmt = currentCharFormat();\n    newcharfmt.setFontUnderline(true);\n\n    switch (level)\n    {\n    case SeverityLevel::Error:\n        newcharfmt.setUnderlineColor(m_syntaxStyle->getFormat(\"Error\").underlineColor());\n        newcharfmt.setUnderlineStyle(m_syntaxStyle->getFormat(\"Error\").underlineStyle());\n        break;\n    case SeverityLevel::Warning:\n        newcharfmt.setUnderlineColor(m_syntaxStyle->getFormat(\"Warning\").underlineColor());\n        newcharfmt.setUnderlineStyle(m_syntaxStyle->getFormat(\"Warning\").underlineStyle());\n        break;\n    case SeverityLevel::Information:\n        newcharfmt.setUnderlineColor(m_syntaxStyle->getFormat(\"Warning\").underlineColor());\n        newcharfmt.setUnderlineStyle(QTextCharFormat::DotLine);\n        break;\n    case SeverityLevel::Hint:\n        newcharfmt.setUnderlineColor(m_syntaxStyle->getFormat(\"Text\").foreground().color());\n        newcharfmt.setUnderlineStyle(QTextCharFormat::DotLine);\n    }\n\n    extra_squiggles.push_back({cursor, newcharfmt});\n\n    m_lineNumberArea->lint(level, start.first, stop.first);\n\n    setExtraSelections(extra1 + extra2 + extra_squiggles);\n}\n\nvoid QCodeEditor::clearSquiggle()\n{\n    if (m_squiggler.empty())\n        return;\n\n    m_squiggler.clear();\n    extra_squiggles.clear();\n\n    m_lineNumberArea->clearLint();\n\n    setExtraSelections(extra1 + extra2);\n}\n\nQChar QCodeEditor::charUnderCursor(int offset) const\n{\n    auto block = textCursor().blockNumber();\n    auto index = textCursor().positionInBlock();\n    auto text = document()->findBlockByNumber(block).text();\n\n    index += offset;\n\n    if (index < 0 || index >= text.size())\n    {\n        return {};\n    }\n\n    return text[index];\n}\n\nQString QCodeEditor::wordUnderCursor() const\n{\n    auto tc = textCursor();\n    tc.select(QTextCursor::WordUnderCursor);\n    return tc.selectedText();\n}\n\nvoid QCodeEditor::insertFromMimeData(const QMimeData *source)\n{\n    insertPlainText(source->text());\n}\n\nbool QCodeEditor::removeInEachLineOfSelection(const QRegularExpression &regex, bool force)\n{\n    auto cursor = textCursor();\n    auto lines = toPlainText().remove('\\r').split('\\n');\n    int selectionStart = cursor.selectionStart();\n    int selectionEnd = cursor.selectionEnd();\n    bool cursorAtEnd = cursor.position() == selectionEnd;\n    cursor.setPosition(selectionStart);\n    int lineStart = cursor.blockNumber();\n    cursor.setPosition(selectionEnd);\n    int lineEnd = cursor.blockNumber();\n    QString newText;\n    QTextStream stream(&newText);\n    int deleteTotal = 0, deleteFirst = 0;\n    for (int i = lineStart; i <= lineEnd; ++i)\n    {\n        auto line = lines[i];\n        auto match = regex.match(line).captured(1);\n        int len = match.length();\n        if (len == 0 && !force)\n            return false;\n        if (i == lineStart)\n            deleteFirst = len;\n        deleteTotal += len;\n        stream << line.remove(line.indexOf(match), len);\n        if (i != lineEnd)\n#if QT_VERSION >= 0x50E00\n            stream << Qt::endl;\n#else\n            stream << endl;\n#endif\n    }\n    cursor.movePosition(QTextCursor::Start);\n    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineStart);\n    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, lineEnd - lineStart);\n    cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);\n    cursor.insertText(newText);\n    cursor.setPosition(qMax(0, selectionStart - deleteFirst));\n    if (cursor.blockNumber() < lineStart)\n    {\n        cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineStart - cursor.blockNumber());\n        cursor.movePosition(QTextCursor::StartOfBlock);\n    }\n    int pos = cursor.position();\n    cursor.setPosition(selectionEnd - deleteTotal);\n    if (cursor.blockNumber() < lineEnd)\n    {\n        cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineEnd - cursor.blockNumber());\n        cursor.movePosition(QTextCursor::StartOfBlock);\n    }\n    int pos2 = cursor.position();\n    if (cursorAtEnd)\n    {\n        cursor.setPosition(pos);\n        cursor.setPosition(pos2, QTextCursor::KeepAnchor);\n    }\n    else\n    {\n        cursor.setPosition(pos2);\n        cursor.setPosition(pos, QTextCursor::KeepAnchor);\n    }\n    setTextCursor(cursor);\n    return true;\n}\n\nvoid QCodeEditor::addInEachLineOfSelection(const QRegularExpression &regex, const QString &str)\n{\n    auto cursor = textCursor();\n    auto lines = toPlainText().remove('\\r').split('\\n');\n    int selectionStart = cursor.selectionStart();\n    int selectionEnd = cursor.selectionEnd();\n    bool cursorAtEnd = cursor.position() == selectionEnd;\n    cursor.setPosition(selectionStart);\n    int lineStart = cursor.blockNumber();\n    cursor.setPosition(selectionEnd);\n    int lineEnd = cursor.blockNumber();\n    QString newText;\n    QTextStream stream(&newText);\n    for (int i = lineStart; i <= lineEnd; ++i)\n    {\n        auto line = lines[i];\n        stream << line.insert(line.indexOf(regex), str);\n        if (i != lineEnd)\n#if QT_VERSION >= 0x50E00\n            stream << Qt::endl;\n#else\n            stream << endl;\n#endif\n    }\n    cursor.movePosition(QTextCursor::Start);\n    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, lineStart);\n    cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, lineEnd - lineStart);\n    cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);\n    cursor.insertText(newText);\n    int pos = selectionStart + str.length();\n    int pos2 = selectionEnd + str.length() * (lineEnd - lineStart + 1);\n    if (cursorAtEnd)\n    {\n        cursor.setPosition(pos);\n        cursor.setPosition(pos2, QTextCursor::KeepAnchor);\n    }\n    else\n    {\n        cursor.setPosition(pos2);\n        cursor.setPosition(pos, QTextCursor::KeepAnchor);\n    }\n    setTextCursor(cursor);\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QGLSLCompleter.cpp",
    "content": "// QCodeEditor\n#include <QGLSLCompleter>\n#include <QLanguage>\n\n// Qt\n#include <QFile>\n#include <QStringListModel>\n\nQGLSLCompleter::QGLSLCompleter(QObject *parent) : QCompleter(parent)\n{\n    // Setting up GLSL types\n    QStringList list;\n\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/glsl.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        list.append(names);\n    }\n\n    setModel(new QStringListModel(list, this));\n    setCompletionColumn(0);\n    setModelSorting(QCompleter::CaseInsensitivelySortedModel);\n    setCaseSensitivity(Qt::CaseSensitive);\n    setWrapAround(true);\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QGLSLHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QGLSLHighlighter>\n#include <QLanguage>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QDebug>\n#include <QFile>\n\nQGLSLHighlighter::QGLSLHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(),\n      m_includePattern(QRegularExpression(R\"(#include\\s+([<\"][a-zA-Z0-9*._]+[\">]))\")),\n      m_functionPattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+(?:\\s+|::))*([A-Za-z0-9_]+)(?=\\())\")),\n      m_defTypePattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+)\\s+[A-Za-z]{1}[A-Za-z0-9_]+\\s*[;=])\")),\n      m_commentStartPattern(QRegularExpression(R\"(/\\*)\")), m_commentEndPattern(QRegularExpression(R\"(\\*/)\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/glsl.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(name)), key});\n        }\n    }\n\n    // Following rules has higher priority to display\n    // than language specific keys\n    // So they must be applied at last.\n    // Numbers\n    m_highlightRules.append({QRegularExpression(R\"(\\b(0b|0x){0,1}[\\d.']+\\b)\"), \"Number\"});\n\n    // Define\n    m_highlightRules.append({QRegularExpression(R\"(#[a-zA-Z_]+)\"), \"Preprocessor\"});\n\n    // Single line\n    m_highlightRules.append({QRegularExpression(\"//[^\\n]*\"), \"Comment\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"//\";\n    m_startCommentBlockSequence = \"/*\";\n    m_endCommentBlockSequence = \"*/\";\n}\n\nvoid QGLSLHighlighter::highlightBlock(const QString &text)\n{\n\n    {\n        auto matchIterator = m_includePattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Preprocessor\"));\n\n            setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"String\"));\n        }\n    }\n    // Checking for function\n    {\n        auto matchIterator = m_functionPattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Type\"));\n\n            setFormat(match.capturedStart(2), match.capturedLength(2), syntaxStyle()->getFormat(\"Function\"));\n        }\n    }\n\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n\n    int startIndex = 0;\n    if (previousBlockState() != 1)\n    {\n        startIndex = text.indexOf(m_commentStartPattern);\n    }\n\n    while (startIndex >= 0)\n    {\n        auto match = m_commentEndPattern.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int commentLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(1);\n            commentLength = text.length() - startIndex;\n        }\n        else\n        {\n            commentLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, commentLength, syntaxStyle()->getFormat(\"Comment\"));\n        startIndex = text.indexOf(m_commentStartPattern, startIndex + commentLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QJSHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QJSHighlighter>\n#include <QLanguage>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QFile>\n\nQJSHighlighter::QJSHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(), m_commentStartPattern(QRegularExpression(R\"(/\\*)\")),\n      m_commentEndPattern(QRegularExpression(R\"(\\*/)\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/js.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(name)), key});\n        }\n    }\n\n    // Numbers\n    m_highlightRules.append(\n        {QRegularExpression(\n             R\"((?<=\\b|\\s|^)(?i)(?:(?:(?:(?:(?:\\d+(?:'\\d+)*)?\\.(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)\\.(?:e[+-]?(?:\\d+(?:'\\d+)*))?)|(?:(?:\\d+(?:'\\d+)*)(?:e[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)?\\.(?:[0-9a-f]+(?:'[0-9a-f]+)*)(?:p[+-]?(?:\\d+(?:'\\d+)*)))|(?:0x(?:[0-9a-f]+(?:'[0-9a-f]+)*)\\.?(?:p[+-]?(?:\\d+(?:'\\d+)*))))[lf]?)|(?:(?:(?:[1-9]\\d*(?:'\\d+)*)|(?:0[0-7]*(?:'[0-7]+)*)|(?:0x[0-9a-f]+(?:'[0-9a-f]+)*)|(?:0b[01]+(?:'[01]+)*))(?:u?l{0,2}|l{0,2}u?)))(?=\\b|\\s|$))\"),\n         \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"(\"[^\\n\"]*\")\"), \"String\"});\n\n    // Single line\n    m_highlightRules.append({QRegularExpression(R\"(//[^\\n]*)\"), \"Comment\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"//\";\n    m_startCommentBlockSequence = \"/*\";\n    m_endCommentBlockSequence = \"*/\";\n}\n\nvoid QJSHighlighter::highlightBlock(const QString &text)\n{\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n\n    int startIndex = 0;\n    if (previousBlockState() != 1)\n    {\n        startIndex = text.indexOf(m_commentStartPattern);\n    }\n\n    while (startIndex >= 0)\n    {\n        auto match = m_commentEndPattern.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int commentLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(1);\n            commentLength = text.length() - startIndex;\n        }\n        else\n        {\n            commentLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, commentLength, syntaxStyle()->getFormat(\"Comment\"));\n        startIndex = text.indexOf(m_commentStartPattern, startIndex + commentLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QJSONHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QJSONHighlighter>\n#include <QSyntaxStyle>\n\nQJSONHighlighter::QJSONHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(), m_keyRegex(R\"((\"[^\\r\\n:]+?\")\\s*:)\")\n{\n    auto keywords = QStringList() << \"null\"\n                                  << \"true\"\n                                  << \"false\";\n\n    for (auto &&keyword : keywords)\n    {\n        m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(keyword)), \"Keyword\"});\n    }\n\n    // Numbers\n    m_highlightRules.append({QRegularExpression(R\"(\\b(0b|0x){0,1}[\\d.']+\\b)\"), \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"(\"[^\\n\"]*\")\"), \"String\"});\n}\n\nvoid QJSONHighlighter::highlightBlock(const QString &text)\n{\n    for (auto &&rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    // Special treatment for key regex\n    auto matchIterator = m_keyRegex.globalMatch(text);\n\n    while (matchIterator.hasNext())\n    {\n        auto match = matchIterator.next();\n\n        setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"Keyword\"));\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QJavaHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QJavaHighlighter>\n#include <QLanguage>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QFile>\n\nQJavaHighlighter::QJavaHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(), m_commentStartPattern(QRegularExpression(R\"(/\\*)\")),\n      m_commentEndPattern(QRegularExpression(R\"(\\*/)\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n\n    QFile fl(\":/languages/java.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(name)), key});\n        }\n    }\n\n    // Numbers\n    m_highlightRules.append(\n        {QRegularExpression(\n             R\"((?<=\\b|\\s|^)(?i)(?:(?:[0-9]+\\.[0-9]*(?:e[+-]?[0-9]+)?[fd]?)|(?:\\.[0-9]+(?:e[+-]?[0-9]+)?[fd]?)|(?:[0-9]+(?:e[+-]?[0-9]+)[fd]?)|(?:[0-9]+(?:e[+-]?[0-9]+)?[fd])|(?:(?:(?:0x[0-9a-f]+\\.?)|(?:0x[0-9a-f]*\\.[0-9a-f]+))p[+-]?[0-9]+[fd]?)|(?:0)|(?:[1-9][0-9]*)|(?:0x[0-9a-f]+)|(?:0[0-7]+))(?=\\b|\\s|$))\"),\n         \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"(\"[^\\n\"]*\")\"), \"String\"});\n\n    // Single line\n    m_highlightRules.append({QRegularExpression(R\"(//[^\\n]*)\"), \"Comment\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"//\";\n    m_startCommentBlockSequence = \"/*\";\n    m_endCommentBlockSequence = \"*/\";\n}\n\nvoid QJavaHighlighter::highlightBlock(const QString &text)\n{\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n\n    int startIndex = 0;\n    if (previousBlockState() != 1)\n    {\n        startIndex = text.indexOf(m_commentStartPattern);\n    }\n\n    while (startIndex >= 0)\n    {\n        auto match = m_commentEndPattern.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int commentLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(1);\n            commentLength = text.length() - startIndex;\n        }\n        else\n        {\n            commentLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, commentLength, syntaxStyle()->getFormat(\"Comment\"));\n        startIndex = text.indexOf(m_commentStartPattern, startIndex + commentLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QLanguage.cpp",
    "content": "// QCodeEditor\n#include <QLanguage>\n\n// Qt\n#include <QIODevice>\n#include <QXmlStreamReader>\n\nQLanguage::QLanguage(QIODevice *device, QObject *parent) : QObject(parent), m_loaded(false), m_list()\n{\n    load(device);\n}\n\nbool QLanguage::load(QIODevice *device)\n{\n    if (device == nullptr)\n    {\n        return false;\n    }\n\n    QXmlStreamReader reader(device);\n\n    QString name;\n    QStringList list;\n    bool readText = false;\n\n    while (!reader.atEnd() && !reader.hasError())\n    {\n        auto type = reader.readNext();\n\n        if (type == QXmlStreamReader::TokenType::StartElement)\n        {\n            if (reader.name() == \"section\")\n            {\n                if (!list.empty())\n                {\n                    m_list[name] = list;\n                    list.clear();\n                }\n\n                name = reader.attributes().value(\"name\").toString();\n            }\n            else if (reader.name() == \"name\")\n            {\n                readText = true;\n            }\n        }\n        else if (type == QXmlStreamReader::TokenType::Characters && readText)\n        {\n            list << reader.text().toString();\n            readText = false;\n        }\n    }\n\n    if (!list.empty())\n    {\n        m_list[name] = list;\n    }\n\n    m_loaded = !reader.hasError();\n\n    return m_loaded;\n}\n\nQStringList QLanguage::keys()\n{\n    return m_list.keys();\n}\n\nQStringList QLanguage::names(const QString &key)\n{\n    return m_list[key];\n}\n\nbool QLanguage::isLoaded() const\n{\n    return m_loaded;\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QLineNumberArea.cpp",
    "content": "// QCodeEditor\n#include <QCodeEditor>\n#include <QLineNumberArea>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QAbstractTextDocumentLayout>\n#include <QPaintEvent>\n#include <QPainter>\n#include <QScrollBar>\n#include <QTextBlock>\n#include <QTextEdit>\n\nQLineNumberArea::QLineNumberArea(QCodeEditor *parent)\n    : QWidget(parent), m_syntaxStyle(nullptr), m_codeEditParent(parent), m_squiggles()\n{\n}\n\nQSize QLineNumberArea::sizeHint() const\n{\n    if (m_codeEditParent == nullptr)\n    {\n        return QWidget::sizeHint();\n    }\n\n    const int digits = QString::number(m_codeEditParent->document()->blockCount()).length();\n    int space;\n\n#if QT_VERSION >= 0x050B00\n    space = 15 + m_codeEditParent->fontMetrics().horizontalAdvance(QLatin1Char('9')) * digits;\n#else\n    space = 15 + m_codeEditParent->fontMetrics().width(QLatin1Char('9')) * digits;\n#endif\n\n    return {space, 0};\n}\n\nvoid QLineNumberArea::setSyntaxStyle(QSyntaxStyle *style)\n{\n    m_syntaxStyle = style;\n}\n\nQSyntaxStyle *QLineNumberArea::syntaxStyle() const\n{\n    return m_syntaxStyle;\n}\n\nvoid QLineNumberArea::lint(QCodeEditor::SeverityLevel level, int from, int to)\n{\n    for (int i = from - 1; i < to; ++i)\n    {\n        m_squiggles[i] = qMax(m_squiggles[i], level);\n    }\n    update();\n}\n\nvoid QLineNumberArea::clearLint()\n{\n    m_squiggles.clear();\n    update();\n}\n\nvoid QLineNumberArea::paintEvent(QPaintEvent *event)\n{\n    QPainter painter(this);\n\n    // Clearing rect to update\n    painter.fillRect(event->rect(), m_syntaxStyle->getFormat(\"Text\").background().color());\n\n    auto blockNumber = m_codeEditParent->getFirstVisibleBlock();\n    auto block = m_codeEditParent->document()->findBlockByNumber(blockNumber);\n    auto top = (int)m_codeEditParent->document()\n                   ->documentLayout()\n                   ->blockBoundingRect(block)\n                   .translated(0, -m_codeEditParent->verticalScrollBar()->value())\n                   .top();\n    auto bottom = top + (int)m_codeEditParent->document()->documentLayout()->blockBoundingRect(block).height();\n\n    auto currentLine = m_syntaxStyle->getFormat(\"CurrentLineNumber\").foreground().color();\n    auto otherLines = m_syntaxStyle->getFormat(\"LineNumber\").foreground().color();\n\n    painter.setFont(m_codeEditParent->font());\n\n    while (block.isValid() && top <= event->rect().bottom())\n    {\n        if (block.isVisible() && bottom >= event->rect().top())\n        {\n            QString number = QString::number(blockNumber + 1);\n\n            if (m_squiggles.contains(blockNumber))\n            {\n                QColor squiggleColor;\n                switch (m_squiggles[blockNumber])\n                {\n                case QCodeEditor::SeverityLevel::Error:\n                    squiggleColor = m_syntaxStyle->getFormat(\"Error\").underlineColor();\n                    break;\n                case QCodeEditor::SeverityLevel::Warning:\n                    squiggleColor = m_syntaxStyle->getFormat(\"Warning\").underlineColor();\n                    break;\n                case QCodeEditor::SeverityLevel::Information:\n                    squiggleColor = m_syntaxStyle->getFormat(\"Warning\").underlineColor();\n                    break;\n                case QCodeEditor::SeverityLevel::Hint:\n                    squiggleColor = m_syntaxStyle->getFormat(\"Text\").foreground().color();\n                    break;\n                default:\n                    Q_UNREACHABLE();\n                    break;\n                }\n                painter.fillRect(0, top, 7, m_codeEditParent->fontMetrics().height(), squiggleColor);\n            }\n\n            auto isCurrentLine = m_codeEditParent->textCursor().blockNumber() == blockNumber;\n            painter.setPen(isCurrentLine ? currentLine : otherLines);\n\n            painter.drawText(-5, top, sizeHint().width(), m_codeEditParent->fontMetrics().height(), Qt::AlignRight,\n                             number);\n        }\n\n        block = block.next();\n        top = bottom;\n        bottom = top + (int)m_codeEditParent->document()->documentLayout()->blockBoundingRect(block).height();\n        ++blockNumber;\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QLuaCompleter.cpp",
    "content": "// QCodeEditor\n#include <QLanguage>\n#include <QLuaCompleter>\n\n// Qt\n#include <QFile>\n#include <QStringListModel>\n\nQLuaCompleter::QLuaCompleter(QObject *parent) : QCompleter(parent)\n{\n    // Setting up GLSL types\n    QStringList list;\n\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/lua.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        list.append(names);\n    }\n\n    setModel(new QStringListModel(list, this));\n    setCompletionColumn(0);\n    setModelSorting(QCompleter::CaseInsensitivelySortedModel);\n    setCaseSensitivity(Qt::CaseSensitive);\n    setWrapAround(true);\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QLuaHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QLanguage>\n#include <QLuaHighlighter>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QFile>\n\nQLuaHighlighter::QLuaHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(), m_highlightBlockRules(),\n      m_requirePattern(QRegularExpression(R\"(require\\s*([(\"'][a-zA-Z0-9*._]+['\")]))\")),\n      m_functionPattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+(?:\\s+|::))*([A-Za-z0-9_]+)(?=\\())\")),\n      m_defTypePattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+)\\s+[A-Za-z]{1}[A-Za-z0-9_]+\\s*[=])\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/lua.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b\\s{0,1}%1\\s{0,1}\\b)\").arg(name)), key});\n        }\n    }\n\n    // Numbers\n    m_highlightRules.append({QRegularExpression(R\"(\\b(0b|0x){0,1}[\\d.']+\\b)\"), \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"([\"'][^\\n\"]*[\"'])\"), \"String\"});\n\n    // Preprocessor\n    m_highlightRules.append({QRegularExpression(R\"(#\\![a-zA-Z_]+)\"), \"Preprocessor\"});\n\n    // Single line\n    m_highlightRules.append({QRegularExpression(R\"(--[^\\n]*)\"), \"Comment\"});\n\n    // Multiline comments\n    m_highlightBlockRules.append({QRegularExpression(R\"(--\\[\\[)\"), QRegularExpression(R\"(--\\]\\])\"), \"Comment\"});\n\n    // Multiline string\n    m_highlightBlockRules.append({QRegularExpression(R\"(\\[\\[)\"), QRegularExpression(R\"(\\]\\])\"), \"String\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"--\";\n    m_startCommentBlockSequence = \"--[[\";\n    m_endCommentBlockSequence = \"]]\";\n}\n\nvoid QLuaHighlighter::highlightBlock(const QString &text)\n{\n    { // Checking for require\n        auto matchIterator = m_requirePattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Preprocessor\"));\n\n            setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"String\"));\n        }\n    }\n    { // Checking for function\n        auto matchIterator = m_functionPattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Type\"));\n\n            setFormat(match.capturedStart(2), match.capturedLength(2), syntaxStyle()->getFormat(\"Function\"));\n        }\n    }\n    { // checking for type\n        auto matchIterator = m_defTypePattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(1), match.capturedLength(1), syntaxStyle()->getFormat(\"Type\"));\n        }\n    }\n\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n    int startIndex = 0;\n    int highlightRuleId = previousBlockState();\n    if (highlightRuleId < 1 || highlightRuleId > m_highlightBlockRules.size())\n    {\n        for (int i = 0; i < m_highlightBlockRules.size(); ++i)\n        {\n            startIndex = text.indexOf(m_highlightBlockRules.at(i).startPattern);\n            if (startIndex >= 0)\n            {\n                highlightRuleId = i + 1;\n                break;\n            }\n        }\n    }\n\n    while (startIndex >= 0)\n    {\n        const auto &blockRules = m_highlightBlockRules.at(highlightRuleId - 1);\n        auto match = blockRules.endPattern.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int matchLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(highlightRuleId);\n            matchLength = text.length() - startIndex;\n        }\n        else\n        {\n            matchLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, matchLength, syntaxStyle()->getFormat(blockRules.formatName));\n        startIndex = text.indexOf(blockRules.startPattern, startIndex + matchLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QPythonCompleter.cpp",
    "content": "// QCodeEditor\n#include <QLanguage>\n#include <QPythonCompleter>\n\n// Qt\n#include <QFile>\n#include <QStringListModel>\n\nQPythonCompleter::QPythonCompleter(QObject *parent) : QCompleter(parent)\n{\n    // Setting up Python types\n    QStringList list;\n\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/python.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        list.append(names);\n    }\n\n    setModel(new QStringListModel(list, this));\n    setCompletionColumn(0);\n    setModelSorting(QCompleter::CaseInsensitivelySortedModel);\n    setCaseSensitivity(Qt::CaseSensitive);\n    setWrapAround(true);\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QPythonHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QLanguage>\n#include <QPythonHighlighter>\n#include <QSyntaxStyle>\n\n// Qt\n#include <QDebug>\n#include <QFile>\n\nQPythonHighlighter::QPythonHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_highlightRules(), m_highlightBlockRules(),\n      m_includePattern(QRegularExpression(R\"(import \\w+)\")),\n      m_functionPattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+(?:\\.))*([A-Za-z0-9_]+)(?=\\())\")),\n      m_defTypePattern(QRegularExpression(R\"(\\b([A-Za-z0-9_]+)\\s+[A-Za-z]{1}[A-Za-z0-9_]+\\s*[;=])\"))\n{\n    Q_INIT_RESOURCE(qcodeeditor_resources);\n    QFile fl(\":/languages/python.xml\");\n\n    if (!fl.open(QIODevice::ReadOnly))\n    {\n        return;\n    }\n\n    QLanguage language(&fl);\n\n    if (!language.isLoaded())\n    {\n        return;\n    }\n\n    auto keys = language.keys();\n    for (auto &&key : keys)\n    {\n        auto names = language.names(key);\n        for (auto &&name : names)\n        {\n            m_highlightRules.append({QRegularExpression(QString(R\"(\\b%1\\b)\").arg(name)), key});\n        }\n    }\n\n    // Following rules has higher priority to display\n    // than language specific keys\n    // So they must be applied at last.\n    // Numbers\n    m_highlightRules.append({QRegularExpression(R\"(\\b(0b|0x){0,1}[\\d.']+\\b)\"), \"Number\"});\n\n    // Strings\n    m_highlightRules.append({QRegularExpression(R\"(\"[^\\n\"]*\")\"), \"String\"});\n    m_highlightRules.append({QRegularExpression(R\"('[^\\n\"]*')\"), \"String\"});\n\n    // Single line comment\n    m_highlightRules.append({QRegularExpression(\"#[^\\n]*\"), \"Comment\"});\n\n    // Multiline string\n    m_highlightBlockRules.append({QRegularExpression(\"(''')\"), QRegularExpression(\"(''')\"), \"String\"});\n    m_highlightBlockRules.append({QRegularExpression(\"(\\\"\\\"\\\")\"), QRegularExpression(\"(\\\"\\\"\\\")\"), \"String\"});\n\n    // Comment sequences for toggling support\n    m_commentLineSequence = \"#\";\n    m_startCommentBlockSequence = \"'''\";\n    m_endCommentBlockSequence = m_startCommentBlockSequence;\n}\n\nvoid QPythonHighlighter::highlightBlock(const QString &text)\n{\n    // Checking for function\n    {\n        auto matchIterator = m_functionPattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(\"Type\"));\n\n            setFormat(match.capturedStart(2), match.capturedLength(2), syntaxStyle()->getFormat(\"Function\"));\n        }\n    }\n\n    for (auto &rule : m_highlightRules)\n    {\n        auto matchIterator = rule.pattern.globalMatch(text);\n\n        while (matchIterator.hasNext())\n        {\n            auto match = matchIterator.next();\n\n            setFormat(match.capturedStart(), match.capturedLength(), syntaxStyle()->getFormat(rule.formatName));\n        }\n    }\n\n    setCurrentBlockState(0);\n    int startIndex = 0;\n    int highlightRuleId = previousBlockState();\n    if (highlightRuleId < 1 || highlightRuleId > m_highlightBlockRules.size())\n    {\n        for (int i = 0; i < m_highlightBlockRules.size(); ++i)\n        {\n            startIndex = text.indexOf(m_highlightBlockRules.at(i).startPattern);\n\n            if (startIndex >= 0)\n            {\n                highlightRuleId = i + 1;\n                break;\n            }\n        }\n    }\n\n    while (startIndex >= 0)\n    {\n        const auto &blockRules = m_highlightBlockRules.at(highlightRuleId - 1);\n        auto match = blockRules.endPattern.match(text, startIndex + 1); // Should be + length of start pattern\n\n        int endIndex = match.capturedStart();\n        int matchLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(highlightRuleId);\n            matchLength = text.length() - startIndex;\n        }\n        else\n        {\n            matchLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, matchLength, syntaxStyle()->getFormat(blockRules.formatName));\n        startIndex = text.indexOf(blockRules.startPattern, startIndex + matchLength);\n    }\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QStyleSyntaxHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QStyleSyntaxHighlighter>\n\nQStyleSyntaxHighlighter::QStyleSyntaxHighlighter(QTextDocument *document)\n    : QSyntaxHighlighter(document), m_syntaxStyle(nullptr), m_commentLineSequence(), m_startCommentBlockSequence(),\n      m_endCommentBlockSequence()\n{\n}\n\nvoid QStyleSyntaxHighlighter::setSyntaxStyle(QSyntaxStyle *style)\n{\n    m_syntaxStyle = style;\n}\n\nQSyntaxStyle *QStyleSyntaxHighlighter::syntaxStyle() const\n{\n    return m_syntaxStyle;\n}\n\nQString QStyleSyntaxHighlighter::commentLineSequence() const\n{\n    return m_commentLineSequence;\n}\n\nvoid QStyleSyntaxHighlighter::setCommentLineSequence(const QString &commentLineSequence)\n{\n    m_commentLineSequence = commentLineSequence;\n}\n\nQString QStyleSyntaxHighlighter::startCommentBlockSequence() const\n{\n    return m_startCommentBlockSequence;\n}\n\nvoid QStyleSyntaxHighlighter::setStartCommentBlockSequence(const QString &startCommentBlockSequence)\n{\n    m_startCommentBlockSequence = startCommentBlockSequence;\n}\n\nQString QStyleSyntaxHighlighter::endCommentBlockSequence() const\n{\n    return m_endCommentBlockSequence;\n}\n\nvoid QStyleSyntaxHighlighter::setEndCommentBlockSequence(const QString &endCommentBlockSequence)\n{\n    m_endCommentBlockSequence = endCommentBlockSequence;\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QSyntaxStyle.cpp",
    "content": "// QCodeEditor\n#include <QSyntaxStyle>\n\n// Qt\n#include <QDebug>\n#include <QFile>\n#include <QXmlStreamReader>\n\nQSyntaxStyle::QSyntaxStyle(QObject *parent) : QObject(parent), m_name(), m_data(), m_loaded(false)\n{\n}\n\nbool QSyntaxStyle::load(const QString &fl)\n{\n    QXmlStreamReader reader(fl);\n\n    while (!reader.atEnd() && !reader.hasError())\n    {\n        auto token = reader.readNext();\n\n        if (token == QXmlStreamReader::StartElement)\n        {\n            if (reader.name() == \"style-scheme\")\n            {\n                if (reader.attributes().hasAttribute(\"name\"))\n                {\n                    m_name = reader.attributes().value(\"name\").toString();\n                }\n            }\n            else if (reader.name() == \"style\")\n            {\n                auto attributes = reader.attributes();\n\n                auto name = attributes.value(\"name\");\n\n                QTextCharFormat format;\n\n                if (attributes.hasAttribute(\"background\"))\n                {\n                    format.setBackground(QColor(attributes.value(\"background\").toString()));\n                }\n\n                if (attributes.hasAttribute(\"foreground\"))\n                {\n                    format.setForeground(QColor(attributes.value(\"foreground\").toString()));\n                }\n\n                if (attributes.hasAttribute(\"bold\") && attributes.value(\"bold\") == \"true\")\n                {\n                    format.setFontWeight(QFont::Weight::Bold);\n                }\n\n                if (attributes.hasAttribute(\"italic\") && attributes.value(\"italic\") == \"true\")\n                {\n                    format.setFontItalic(true);\n                }\n\n                if (attributes.hasAttribute(\"underlineStyle\"))\n                {\n                    auto underline = attributes.value(\"underlineStyle\");\n\n                    auto s = QTextCharFormat::UnderlineStyle::NoUnderline;\n\n                    if (underline == \"SingleUnderline\")\n                    {\n                        s = QTextCharFormat::UnderlineStyle::SingleUnderline;\n                    }\n                    else if (underline == \"DashUnderline\")\n                    {\n                        s = QTextCharFormat::UnderlineStyle::DashUnderline;\n                    }\n                    else if (underline == \"DotLine\")\n                    {\n                        s = QTextCharFormat::UnderlineStyle::DotLine;\n                    }\n                    else if (underline == \"DashDotLine\")\n                    {\n                        s = QTextCharFormat::DashDotLine;\n                    }\n                    else if (underline == \"DashDotDotLine\")\n                    {\n                        s = QTextCharFormat::DashDotDotLine;\n                    }\n                    else if (underline == \"WaveUnderline\")\n                    {\n                        s = QTextCharFormat::WaveUnderline;\n                    }\n                    else if (underline == \"SpellCheckUnderline\")\n                    {\n                        s = QTextCharFormat::SpellCheckUnderline;\n                    }\n                    else\n                    {\n                        qDebug() << \"Unknown underline value \" << underline;\n                    }\n\n                    format.setUnderlineStyle(s);\n                }\n\n                if (attributes.hasAttribute(\"underlineColor\"))\n                {\n                    auto color = attributes.value(\"underlineColor\");\n\n                    format.setUnderlineColor(QColor(color.toString()));\n                }\n\n                m_data[name.toString()] = format;\n            }\n        }\n    }\n\n    m_loaded = !reader.hasError();\n\n    return m_loaded;\n}\n\nQString QSyntaxStyle::name() const\n{\n    return m_name;\n}\n\nQTextCharFormat QSyntaxStyle::getFormat(const QString &name) const\n{\n    auto result = m_data.find(name);\n\n    if (result == m_data.end())\n    {\n        return QTextCharFormat();\n    }\n\n    return result.value();\n}\n\nbool QSyntaxStyle::isLoaded() const\n{\n    return m_loaded;\n}\n\nQSyntaxStyle *QSyntaxStyle::defaultStyle()\n{\n    static QSyntaxStyle style;\n\n    if (!style.isLoaded())\n    {\n        Q_INIT_RESOURCE(qcodeeditor_resources);\n        QFile fl(\":/default_style.xml\");\n\n        if (!fl.open(QIODevice::ReadOnly))\n        {\n            return &style;\n        }\n\n        if (!style.load(fl.readAll()))\n        {\n            qDebug() << \"Can't load default style.\";\n        }\n    }\n\n    return &style;\n}\n"
  },
  {
    "path": "external/QCodeEditor/src/internal/QXMLHighlighter.cpp",
    "content": "// QCodeEditor\n#include <QSyntaxStyle>\n#include <QXMLHighlighter>\n\nQXMLHighlighter::QXMLHighlighter(QTextDocument *document)\n    : QStyleSyntaxHighlighter(document), m_xmlKeywordRegexes(),\n      m_xmlElementRegex(R\"(<[\\s]*[/]?[\\s]*([^\\n][a-zA-Z-_:]*)(?=[\\s/>]))\"), m_xmlAttributeRegex(R\"(\\w+(?=\\=))\"),\n      m_xmlValueRegex(R\"(\"[^\\n\"]+\"(?=\\??[\\s/>]))\"), m_xmlCommentBeginRegex(R\"(<!--)\"), m_xmlCommentEndRegex(R\"(-->)\")\n{\n    m_xmlKeywordRegexes << QRegularExpression(\"<\\\\?\") << QRegularExpression(\"/>\") << QRegularExpression(\">\")\n                        << QRegularExpression(\"<\") << QRegularExpression(\"</\") << QRegularExpression(\"\\\\?>\");\n\n    m_startCommentBlockSequence = \"<!--\";\n    m_endCommentBlockSequence = \"-->\";\n}\n\nvoid QXMLHighlighter::highlightBlock(const QString &text)\n{\n    // Special treatment for xml element regex as we use captured text to emulate lookbehind\n    auto matchIterator = m_xmlElementRegex.globalMatch(text);\n    while (matchIterator.hasNext())\n    {\n        auto match = matchIterator.next();\n\n        setFormat(match.capturedStart(), match.capturedLength(),\n                  syntaxStyle()->getFormat(\"Keyword\") // XML ELEMENT FORMAT\n        );\n    }\n\n    // Highlight xml keywords *after* xml elements to fix any occasional / captured into the enclosing element\n\n    for (auto &&regex : m_xmlKeywordRegexes)\n    {\n        highlightByRegex(syntaxStyle()->getFormat(\"Keyword\"), regex, text);\n    }\n\n    highlightByRegex(syntaxStyle()->getFormat(\"Text\"), m_xmlAttributeRegex, text);\n\n    setCurrentBlockState(0);\n\n    int startIndex = 0;\n    if (previousBlockState() != 1)\n    {\n        startIndex = text.indexOf(m_xmlCommentBeginRegex);\n    }\n\n    while (startIndex >= 0)\n    {\n        auto match = m_xmlCommentEndRegex.match(text, startIndex);\n\n        int endIndex = match.capturedStart();\n        int commentLength = 0;\n\n        if (endIndex == -1)\n        {\n            setCurrentBlockState(1);\n            commentLength = text.length() - startIndex;\n        }\n        else\n        {\n            commentLength = endIndex - startIndex + match.capturedLength();\n        }\n\n        setFormat(startIndex, commentLength, syntaxStyle()->getFormat(\"Comment\"));\n\n        startIndex = text.indexOf(m_xmlCommentBeginRegex, startIndex + commentLength);\n    }\n\n    highlightByRegex(syntaxStyle()->getFormat(\"String\"), m_xmlValueRegex, text);\n}\n\nvoid QXMLHighlighter::highlightByRegex(const QTextCharFormat &format, const QRegularExpression &regex,\n                                       const QString &text)\n{\n    auto matchIterator = regex.globalMatch(text);\n\n    while (matchIterator.hasNext())\n    {\n        auto match = matchIterator.next();\n\n        setFormat(match.capturedStart(), match.capturedLength(), format);\n    }\n}\n"
  },
  {
    "path": "external/QtFindReplaceDialog/.editorconfig",
    "content": "# EditorConfig file (https://editorconfig.org) for the QCodeEditor project\n\nroot = true\n\n[*]\nend_of_line = lf\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n# QtFindReplaceDialog C++ files\n[**.cpp]\nindent_style = space\nindent_size = 4\n[**.h]\nindent_style = space\nindent_size = 2\n\n# QtFindReplaceDialog CMake files\n[CMakeLists.txt]\nindent_style = tab\nindent_size = 4\n"
  },
  {
    "path": "external/QtFindReplaceDialog/.gitignore",
    "content": "*.pro.user*\n*~\nbuild*\n*.log\n*.tar.gz\n\n# KDEvelop\n.kdev4/\n"
  },
  {
    "path": "external/QtFindReplaceDialog/COPYING",
    "content": "                  GNU LESSER GENERAL PUBLIC LICENSE\n                       Version 2.1, February 1999\n\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n[This is the first released version of the Lesser GPL.  It also counts\n as the successor of the GNU Library Public License, version 2, hence\n the version number 2.1.]\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicenses are intended to guarantee your freedom to share and change\nfree software--to make sure the software is free for all its users.\n\n  This license, the Lesser General Public License, applies to some\nspecially designated software packages--typically libraries--of the\nFree Software Foundation and other authors who decide to use it.  You\ncan use it too, but we suggest you first think carefully about whether\nthis license or the ordinary General Public License is the better\nstrategy to use in any particular case, based on the explanations below.\n\n  When we speak of free software, we are referring to freedom of use,\nnot price.  Our General Public Licenses are designed to make sure that\nyou have the freedom to distribute copies of free software (and charge\nfor this service if you wish); that you receive source code or can get\nit if you want it; that you can change the software and use pieces of\nit in new free programs; and that you are informed that you can do\nthese things.\n\n  To protect your rights, we need to make restrictions that forbid\ndistributors to deny you these rights or to ask you to surrender these\nrights.  These restrictions translate to certain responsibilities for\nyou if you distribute copies of the library or if you modify it.\n\n  For example, if you distribute copies of the library, whether gratis\nor for a fee, you must give the recipients all the rights that we gave\nyou.  You must make sure that they, too, receive or can get the source\ncode.  If you link other code with the library, you must provide\ncomplete object files to the recipients, so that they can relink them\nwith the library after making changes to the library and recompiling\nit.  And you must show them these terms so they know their rights.\n\n  We protect your rights with a two-step method: (1) we copyright the\nlibrary, and (2) we offer you this license, which gives you legal\npermission to copy, distribute and/or modify the library.\n\n  To protect each distributor, we want to make it very clear that\nthere is no warranty for the free library.  Also, if the library is\nmodified by someone else and passed on, the recipients should know\nthat what they have is not the original version, so that the original\nauthor's reputation will not be affected by problems that might be\nintroduced by others.\n\f\n  Finally, software patents pose a constant threat to the existence of\nany free program.  We wish to make sure that a company cannot\neffectively restrict the users of a free program by obtaining a\nrestrictive license from a patent holder.  Therefore, we insist that\nany patent license obtained for a version of the library must be\nconsistent with the full freedom of use specified in this license.\n\n  Most GNU software, including some libraries, is covered by the\nordinary GNU General Public License.  This license, the GNU Lesser\nGeneral Public License, applies to certain designated libraries, and\nis quite different from the ordinary General Public License.  We use\nthis license for certain libraries in order to permit linking those\nlibraries into non-free programs.\n\n  When a program is linked with a library, whether statically or using\na shared library, the combination of the two is legally speaking a\ncombined work, a derivative of the original library.  The ordinary\nGeneral Public License therefore permits such linking only if the\nentire combination fits its criteria of freedom.  The Lesser General\nPublic License permits more lax criteria for linking other code with\nthe library.\n\n  We call this license the \"Lesser\" General Public License because it\ndoes Less to protect the user's freedom than the ordinary General\nPublic License.  It also provides other free software developers Less\nof an advantage over competing non-free programs.  These disadvantages\nare the reason we use the ordinary General Public License for many\nlibraries.  However, the Lesser license provides advantages in certain\nspecial circumstances.\n\n  For example, on rare occasions, there may be a special need to\nencourage the widest possible use of a certain library, so that it becomes\na de-facto standard.  To achieve this, non-free programs must be\nallowed to use the library.  A more frequent case is that a free\nlibrary does the same job as widely used non-free libraries.  In this\ncase, there is little to gain by limiting the free library to free\nsoftware only, so we use the Lesser General Public License.\n\n  In other cases, permission to use a particular library in non-free\nprograms enables a greater number of people to use a large body of\nfree software.  For example, permission to use the GNU C Library in\nnon-free programs enables many more people to use the whole GNU\noperating system, as well as its variant, the GNU/Linux operating\nsystem.\n\n  Although the Lesser General Public License is Less protective of the\nusers' freedom, it does ensure that the user of a program that is\nlinked with the Library has the freedom and the wherewithal to run\nthat program using a modified version of the Library.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.  Pay close attention to the difference between a\n\"work based on the library\" and a \"work that uses the library\".  The\nformer contains code derived from the library, whereas the latter must\nbe combined with the library in order to run.\n\f\n                  GNU LESSER GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control compilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n\n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\f\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\f\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\f\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) Verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\f\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\f\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply,\nand the section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License may add\nan explicit geographical distribution limitation excluding those countries,\nso that distribution is permitted only in or among countries not thus\nexcluded.  In such case, this License incorporates the limitation as if\nwritten in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\f\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\n                            NO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\f\n           How to Apply These Terms to Your New Libraries\n\n  If you develop a new library, and you want it to be of the greatest\npossible use to the public, we recommend making it free software that\neveryone can redistribute and change.  You can do so by permitting\nredistribution under these terms (or, alternatively, under the terms of the\nordinary General Public License).\n\n  To apply these terms, attach the following notices to the library.  It is\nsafest to attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the library's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This library is free software; you can redistribute it and/or\n    modify it under the terms of the GNU Lesser General Public\n    License as published by the Free Software Foundation; either\n    version 2.1 of the License, or (at your option) any later version.\n\n    This library is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n    Lesser General Public License for more details.\n\n    You should have received a copy of the GNU Lesser General Public\n    License along with this library; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the library, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the\n  library `Frob' (a library for tweaking knobs) written by James Random Hacker.\n\n  <signature of Ty Coon>, 1 April 1990\n  Ty Coon, President of Vice\n\nThat's all there is to it!\n"
  },
  {
    "path": "external/QtFindReplaceDialog/README.txt",
    "content": "QtFindReplaceDialog is an implementation of a Find/Replace Qt dialog\nto be used in qt text edit based applications.\nA simple Find (only) dialog is also provided.\n\nYou can use these dialogs in your applications either by copying\nthe files in the dialogs directory, or by building the dialogs as library.\n\nYou can build the library by using qmake and then make.\nFor instance, if you use a shadow build (which is reccomended),\nsimply create a build directory and enter there. Then run\n\n  qmake -recursive ../qtfindreplacedialog.pro\n  make\n\nA running example, using the find and find/replace dialogs,\ncan be found in the directory examples (this will be built also).\n\nYou can specify additional arguments for qmake, for instance,\nif you want to build the library statically use CONFIG+=static.\nThen, you can install it using make install, possibly by\nusing a specific installation root:\n\n  INSTALL_ROOT=$HOME/usr/local make install\n"
  },
  {
    "path": "external/QtFindReplaceDialog/TODO",
    "content": "history of searched text\n\nexample with embedding of the forms in a dock?\n\non-the-fly search (highlight all occurrences)\n\nusage documentation\n\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.1)\nset(CMAKE_CXX_STANDARD 17)\n\nset(CMAKE_INCLUDE_CURRENT_DIR ON)\n\n# ---------------------------------------------------------\n\nfind_package(Qt5 COMPONENTS Widgets REQUIRED)\n\nset(CMAKE_AUTOMOC ON)\nset(CMAKE_AUTOUIC ON)\nset(CMAKE_AUTORCC ON)\n\n# ---------------------------------------------------------\n\nset(QtFindReplaceDialog_SHARED_HEADERS\n\t\"finddialog.h\"\n\t\"findform.h\"\n\t\"findreplacedialog.h\"\n\t\"findreplaceform.h\"\n\t\"findreplace_global.h\"\n)\n\nset(QtFindReplaceDialog_SOURCES\n\t\"finddialog.cpp\"\n\t\"findform.cpp\"\n\t\"findreplacedialog.cpp\"\n\t\"findreplacedialog.ui\"\n\t\"findreplaceform.cpp\"\n\t\"findreplaceform.ui\"\n\t${QtFindReplaceDialog_SHARED_HEADERS}\n)\n\nif(MSVC)\n\tset(MY_COMPILE_OPTIONS \"/W3\")\nelse()\n\tset(MY_COMPILE_OPTIONS \"-Wall\")\nendif()\n\n# ---------------------------------------------------------\n\nadd_library(QtFindReplaceDialog STATIC ${QtFindReplaceDialog_SOURCES})\nset_target_properties(QtFindReplaceDialog PROPERTIES PUBLIC_HEADER \"${QtFindReplaceDialog_SHARED_HEADERS}\")\ntarget_compile_definitions(QtFindReplaceDialog PUBLIC \"-DFINDREPLACESHARED_EXPORT=\")\ntarget_compile_definitions(QtFindReplaceDialog PRIVATE \"-DFINDREPLACE_LIBRARY\")\ntarget_compile_options(QtFindReplaceDialog PUBLIC ${MY_COMPILE_OPTIONS})\ntarget_link_libraries(QtFindReplaceDialog PRIVATE Qt5::Widgets)\n\ntarget_include_directories(QtFindReplaceDialog SYSTEM INTERFACE\n\t$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>\n\t$<INSTALL_INTERFACE:QtFindReplaceDialog/include>  # <prefix>/QtFindReplaceDialog/include\n)\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/dialogs.pro",
    "content": "# -------------------------------------------------\r\n# Project created by QtCreator 2009-11-07T11:39:43\r\n# -------------------------------------------------\r\nQT *= core gui\r\ngreaterThan(QT_MAJOR_VERSION,4):QT*=widgets\r\nTARGET = qtfindreplacedialog\r\nTEMPLATE = lib\r\nDEFINES += FINDREPLACE_LIBRARY\r\nCONFIG *= QtFindReplaceDialog-buildlib\r\ninclude(../qtfindreplacedialog.pri)\r\nDESTDIR = ../lib\r\nDEPENDPATH += .\r\ntarget.path = /lib\r\nheaders.files = $$HEADERS\r\nheaders.path = /include\r\nINSTALLS += target \\\r\n    headers\r\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/finddialog.cpp",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#include \"finddialog.h\"\n#include \"ui_findreplacedialog.h\"\n\nFindDialog::FindDialog(QWidget *parent) :\n    FindReplaceDialog(parent)\n{\n    ui->findReplaceForm->hideReplaceWidgets();\n    setWindowTitle(tr(\"Find\", \"FindDialog\"));\n}\n\nFindDialog::~FindDialog()\n{\n}\n\nvoid FindDialog::writeSettings(QSettings &settings, const QString &prefix) {\n    FindReplaceDialog::writeSettings(settings, prefix);\n}\n\nvoid FindDialog::readSettings(QSettings &settings, const QString &prefix) {\n    FindReplaceDialog::readSettings(settings, prefix);\n}\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/finddialog.h",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#ifndef FINDDIALOG_H\n#define FINDDIALOG_H\n\n#include <QDialog>\n\n#include \"findreplace_global.h\"\n\n#include \"findreplacedialog.h\"\n\n/**\n  * A find dialog (it is basically the same\n  * as FindReplaceDialog without the replace related widgets).\n  */\nclass FINDREPLACESHARED_EXPORT FindDialog : public FindReplaceDialog {\n    Q_OBJECT\npublic:\n    FindDialog(QWidget *parent = 0);\n    ~FindDialog();\n\n    /**\n      * Writes the state of the form to the passed settings.\n      * @param settings\n      * @param prefix the prefix to insert in the settings\n      */\n    virtual void writeSettings(QSettings &settings, const QString &prefix = \"FindDialog\");\n\n    /**\n      * Reads the state of the form from the passed settings.\n      * @param settings\n      * @param prefix the prefix to look for in the settings\n      */\n    virtual void readSettings(QSettings &settings, const QString &prefix = \"FindDialog\");\n};\n\n#endif // FINDDIALOG_H\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findform.cpp",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#include <QtGui>\n#include <QTextEdit>\n#include <QRegExp>\n\n#include \"findform.h\"\n#include \"ui_findreplaceform.h\"\n\nFindForm::FindForm(QWidget *parent) :\n    FindReplaceForm(parent)\n{\n    hideReplaceWidgets();\n}\n\nFindForm::~FindForm()\n{\n\n}\n\nvoid FindForm::changeEvent(QEvent *e)\n{\n    QWidget::changeEvent(e);\n    switch (e->type()) {\n    case QEvent::LanguageChange:\n        ui->retranslateUi(this);\n        break;\n    default:\n        break;\n    }\n}\n\nvoid FindForm::writeSettings(QSettings &settings, const QString &prefix) {\n    FindReplaceForm::writeSettings(settings, prefix);\n}\n\nvoid FindForm::readSettings(QSettings &settings, const QString &prefix) {\n    FindReplaceForm::readSettings(settings, prefix);\n}\n\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findform.h",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#ifndef FINDFORM_H\n#define FINDFORM_H\n\n#include <QWidget>\n#include <QTextCursor>\n\n#include \"findreplace_global.h\"\n\n#include \"findreplaceform.h\"\n\n/**\n  * The form for the find dialog (it is basically the same\n  * as FindReplaceForm without the replace related widgets).\n  */\nclass FINDREPLACESHARED_EXPORT FindForm : public FindReplaceForm {\n    Q_OBJECT\npublic:\n    FindForm(QWidget *parent = 0);\n    ~FindForm();\n\n    /**\n      * Writes the state of the form to the passed settings.\n      * @param settings\n      * @param prefix the prefix to insert in the settings\n      */\n    virtual void writeSettings(QSettings &settings, const QString &prefix = \"FindDialog\");\n\n    /**\n      * Reads the state of the form from the passed settings.\n      * @param settings\n      * @param prefix the prefix to look for in the settings\n      */\n    virtual void readSettings(QSettings &settings, const QString &prefix = \"FindDialog\");\n\nprotected:\n    void changeEvent(QEvent *e);\n\n};\n\n#endif // FINDFORM_H\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplace_global.h",
    "content": "/*\r\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\r\n * See COPYING file that comes with this distribution\r\n */\r\n\r\n#ifndef FINDREPLACE_GLOBAL_H\r\n#define FINDREPLACE_GLOBAL_H\r\n\r\n#include <QtCore/qglobal.h>\r\n\r\n#ifndef FINDREPLACESHARED_EXPORT\r\n\r\n#if defined(FINDREPLACE_LIBRARY)\r\n#define FINDREPLACESHARED_EXPORT Q_DECL_EXPORT\r\n#else\r\n#define FINDREPLACESHARED_EXPORT Q_DECL_IMPORT\r\n#endif\r\n\r\n#endif\r\n\r\n#endif // FINDREPLACE_GLOBAL_H\r\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplacedialog.cpp",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#include \"findreplacedialog.h\"\n#include \"ui_findreplacedialog.h\"\n\nFindReplaceDialog::FindReplaceDialog(QWidget *parent)\n    : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), ui(new Ui::FindReplaceDialog)\n{\n    ui->setupUi(this);\n}\n\nFindReplaceDialog::~FindReplaceDialog()\n{\n    delete ui;\n}\n\nvoid FindReplaceDialog::changeEvent(QEvent *e)\n{\n    QDialog::changeEvent(e);\n    switch (e->type())\n    {\n    case QEvent::LanguageChange:\n        ui->retranslateUi(this);\n        break;\n    default:\n        break;\n    }\n}\n\nvoid FindReplaceDialog::setTextEdit(QTextEdit *textEdit)\n{\n    ui->findReplaceForm->setTextEdit(textEdit);\n}\n\nvoid FindReplaceDialog::writeSettings(QSettings &settings, const QString &prefix)\n{\n    ui->findReplaceForm->writeSettings(settings, prefix);\n}\n\nvoid FindReplaceDialog::readSettings(QSettings &settings, const QString &prefix)\n{\n    ui->findReplaceForm->readSettings(settings, prefix);\n}\n\nvoid FindReplaceDialog::setTextToFind(const QString &strText)\n{\n    ui->findReplaceForm->setTextToFind(strText);\n}\n\nvoid FindReplaceDialog::find()\n{\n    ui->findReplaceForm->find();\n}\n\nvoid FindReplaceDialog::findNext()\n{\n    ui->findReplaceForm->findNext();\n}\n\nvoid FindReplaceDialog::findPrev()\n{\n    ui->findReplaceForm->findPrev();\n}\n\nvoid FindReplaceDialog::showDialog(const QString &textToFind)\n{\n    show();\n    raise();\n    activateWindow();\n    ui->findReplaceForm->maybeSetTextToFind(textToFind);\n}\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplacedialog.h",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#ifndef FINDREPLACEDIALOG_H\n#define FINDREPLACEDIALOG_H\n\n#include <QDialog>\n\n#include \"findreplace_global.h\"\n\nnamespace Ui\n{\nclass FindReplaceDialog;\n}\n\nclass QTextEdit;\nclass QSettings;\n\n/**\n * A find/replace dialog.\n *\n * It relies on a FindReplaceForm object (see that class for the functionalities provided).\n */\nclass FINDREPLACESHARED_EXPORT FindReplaceDialog : public QDialog\n{\n    Q_OBJECT\n  public:\n    FindReplaceDialog(QWidget *parent = 0);\n    virtual ~FindReplaceDialog();\n\n    /**\n     * Associates the text editor where to perform the search\n     * @param textEdit\n     */\n    void setTextEdit(QTextEdit *textEdit);\n\n    /**\n     * Writes the state of the form to the passed settings.\n     * @param settings\n     * @param prefix the prefix to insert in the settings\n     */\n    virtual void writeSettings(QSettings &settings, const QString &prefix = \"FindReplaceDialog\");\n\n    /**\n     * Reads the state of the form from the passed settings.\n     * @param settings\n     * @param prefix the prefix to look for in the settings\n     */\n    virtual void readSettings(QSettings &settings, const QString &prefix = \"FindReplaceDialog\");\n\n  public Q_SLOTS:\n    /**\n     * Sets the current textToFind (used to set it from specialized current selection, etc)\n     */\n    void setTextToFind(const QString &strText);\n\n    /**\n     * Finds the next or previous occurrence:\n     */\n    void find();\n\n    /**\n     * Finds the next occurrence\n     */\n    void findNext();\n\n    /**\n     * Finds the previous occurrence\n     */\n    void findPrev();\n\n    /**\n     * Show dialog with text to find selected\n     */\n    void showDialog(const QString &textToFind = QString());\n\n  protected:\n    void changeEvent(QEvent *e);\n\n    Ui::FindReplaceDialog *ui;\n};\n\n#endif // FINDREPLACEDIALOG_H\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplacedialog.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <class>FindReplaceDialog</class>\r\n <widget class=\"QDialog\" name=\"FindReplaceDialog\">\r\n  <property name=\"geometry\">\r\n   <rect>\r\n    <x>0</x>\r\n    <y>0</y>\r\n    <width>342</width>\r\n    <height>140</height>\r\n   </rect>\r\n  </property>\r\n  <property name=\"windowTitle\">\r\n   <string>Find/Replace</string>\r\n  </property>\r\n  <layout class=\"QGridLayout\" name=\"gridLayout\">\r\n   <item row=\"0\" column=\"0\">\r\n    <widget class=\"FindReplaceForm\" name=\"findReplaceForm\" native=\"true\"/>\r\n   </item>\r\n  </layout>\r\n </widget>\r\n <customwidgets>\r\n  <customwidget>\r\n   <class>FindReplaceForm</class>\r\n   <extends>QWidget</extends>\r\n   <header location=\"global\">findreplaceform.h</header>\r\n   <container>1</container>\r\n  </customwidget>\r\n </customwidgets>\r\n <resources/>\r\n <connections/>\r\n</ui>\r\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplaceform.cpp",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#include <QCheckBox>\n#include <QLineEdit>\n#include <QPushButton>\n#include <QRegExp>\n#include <QSettings>\n#include <QShowEvent>\n#include <QTextEdit>\n#include <QtGui>\n\n#include \"findreplaceform.h\"\n#include \"ui_findreplaceform.h\"\n\n#define TEXT_TO_FIND \"textToFind\"\n#define TEXT_TO_REPLACE \"textToReplace\"\n#define DOWN_RADIO \"downRadio\"\n#define UP_RADIO \"upRadio\"\n#define CASE_CHECK \"caseCheck\"\n#define WHOLE_CHECK \"wholeCheck\"\n#define REGEXP_CHECK \"regexpCheck\"\n\n#define DEBUG_FIND 0 // Set to '1' to enable debugging of 'find'\n\nFindReplaceForm::FindReplaceForm(QWidget *parent) :\n    QWidget(parent),\n    ui(new Ui::FindReplaceForm),\n    textEdit(nullptr)\n{\n    ui->setupUi(this);\n\n    ui->findButton->setAutoDefault(false);\n    ui->replaceButton->setAutoDefault(false);\n    ui->replaceAllButton->setAutoDefault(false);\n\n    ui->errorLabel->setText(\"\");\n\n    connect(ui->textToFind, &QLineEdit::textChanged,\n        this, &FindReplaceForm::textToFindChanged);\n    connect(ui->textToFind, &QLineEdit::textChanged,\n        this, &FindReplaceForm::validateRegExp);\n\n    connect(ui->regexCheckBox, &QCheckBox::toggled,\n        this, &FindReplaceForm::regexpSelected);\n\n    connect(ui->findButton, &QPushButton::clicked,\n        this, QOverload<>::of(&FindReplaceForm::find));\n\n    connect(ui->replaceButton, &QPushButton::clicked,\n        this, &FindReplaceForm::replace);\n    connect(ui->replaceAllButton, &QPushButton::clicked,\n        this, &FindReplaceForm::replaceAll);\n\n    connect(ui->textToFind, &QLineEdit::returnPressed,\n        ui->findButton, &QPushButton::click);\n    connect(ui->textToReplace, &QLineEdit::returnPressed,\n        ui->replaceButton, &QPushButton::click);\n}\n\nFindReplaceForm::~FindReplaceForm()\n{\n    delete ui;\n}\n\nvoid FindReplaceForm::hideReplaceWidgets()\n{\n    ui->replaceLabel->setVisible(false);\n    ui->textToReplace->setVisible(false);\n    ui->replaceButton->setVisible(false);\n    ui->replaceAllButton->setVisible(false);\n}\n\nvoid FindReplaceForm::setTextEdit(QTextEdit *textEdit_)\n{\n    if (textEdit != textEdit_)\n    {\n        disconnect(selectionChangeConnection);\n        ui->replaceButton->setEnabled(false);\n        textEdit = textEdit_;\n        validateRegExp(ui->textToFind->text());\n        if (textEdit) {\n            selectionChangeConnection =\n                connect(textEdit, &QTextEdit::selectionChanged,\n                    this, &FindReplaceForm::onSelectionChanged);\n        }\n    }\n}\n\nvoid FindReplaceForm::changeEvent(QEvent *e)\n{\n    QWidget::changeEvent(e);\n    switch (e->type())\n    {\n    case QEvent::LanguageChange:\n        ui->retranslateUi(this);\n        break;\n    default:\n        break;\n    }\n}\n\nvoid FindReplaceForm::showEvent(QShowEvent *event)\n{\n    showError(QString());\n    showMessage(QString());\n    QWidget::showEvent(event);\n}\n\nvoid FindReplaceForm::textToFindChanged()\n{\n    ui->findButton->setEnabled(ui->textToFind->text().size() > 0);\n    ui->replaceButton->setEnabled(false);\n    ui->replaceAllButton->setEnabled(ui->textToFind->text().size() > 0);\n}\n\nvoid FindReplaceForm::regexpSelected(bool sel)\n{\n    if (sel)\n        validateRegExp(ui->textToFind->text());\n    else\n        validateRegExp(\"\");\n}\n\nvoid FindReplaceForm::onSelectionChanged()\n{\n    ui->replaceButton->setEnabled(false);\n}\n\nvoid FindReplaceForm::validateRegExp(const QString &text)\n{\n    if (!ui->regexCheckBox->isChecked() || text.size() == 0)\n    {\n        ui->errorLabel->setText(\"\");\n        return; // nothing to validate\n    }\n\n    QRegExp reg(text, (ui->caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive));\n\n    if (reg.isValid())\n    {\n        showError(\"\");\n    }\n    else\n    {\n        showError(reg.errorString());\n    }\n}\n\nvoid FindReplaceForm::showError(const QString &error)\n{\n    if (error.isEmpty())\n    {\n        ui->errorLabel->setText(\"\");\n    }\n    else\n    {\n        ui->errorLabel->setText(\"<span style=\\\" font-weight:600; color:#ff0000;\\\">\" + error + \"</span>\");\n    }\n}\n\nvoid FindReplaceForm::showMessage(const QString &message)\n{\n    if (message.isEmpty())\n    {\n        ui->errorLabel->setText(\"\");\n    }\n    else\n    {\n        ui->errorLabel->setText(\"<span style=\\\" font-weight:600; color:green;\\\">\" + message + \"</span>\");\n    }\n}\n\nvoid FindReplaceForm::setTextToFind(const QString &strText)\n{\n    ui->textToFind->selectAll();\n    ui->textToFind->insert(strText);\n}\n\nvoid FindReplaceForm::find()\n{\n    find(ui->downRadioButton->isChecked());\n}\n\nvoid FindReplaceForm::find(bool next)\n{\n    if (!textEdit)\n    {\n        showError(\"No active editor\");\n        return;\n    }\n\n    // backward search\n    bool back = !next;\n\n    const QString &toSearch = ui->textToFind->text();\n\n    bool result = false;\n\n    // Check the cursor for wrap:\n    textCursor = textEdit->textCursor();\n    if (!textCursor.hasSelection())\n    {\n        if (next && textCursor.atEnd())\n        {\n            textCursor.movePosition(QTextCursor::Start);\n        }\n        else if (back && textCursor.atStart())\n        {\n            textCursor.movePosition(QTextCursor::End);\n        }\n    }\n    textEdit->setTextCursor(textCursor);\n\n    QTextDocument::FindFlags flags;\n\n    if (back)\n        flags |= QTextDocument::FindBackward;\n    if (ui->caseCheckBox->isChecked())\n        flags |= QTextDocument::FindCaseSensitively;\n    if (ui->wholeCheckBox->isChecked())\n        flags |= QTextDocument::FindWholeWords;\n\n    if (ui->regexCheckBox->isChecked())\n    {\n        QRegExp reg(toSearch, (ui->caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive));\n\n#if (DEBUG_FIND)\n        qDebug() << \"searching for regexp: \" << reg.pattern();\n#endif\n\n        textCursor = textEdit->document()->find(reg, textCursor, flags);\n        if (!textCursor.isNull())\n            textEdit->setTextCursor(textCursor);\n        result = (!textCursor.isNull());\n    }\n    else\n    {\n#if (DEBUG_FIND)\n        qDebug() << \"searching for: \" << toSearch;\n#endif\n\n        result = textEdit->find(toSearch, flags);\n    }\n\n    if (result)\n    {\n        ui->replaceButton->setEnabled(true);\n        showError(\"\");\n    }\n    else\n    {\n        showError(tr(\"no match found\", \"FindDialog\"));\n        // move to the end of the document (if searching down)\n        //\tor the beginning of the document (if searching up)\n        //\tfor the next find.  The next find will wrap the\n        //\tcursor and this logic will work if the user switches\n        //\tthe direction of the search:\n        textCursor = textEdit->textCursor();\n        if (next)\n        {\n            textCursor.movePosition(QTextCursor::End);\n        }\n        else\n        {\n            textCursor.movePosition(QTextCursor::Start);\n        }\n        textEdit->setTextCursor(textCursor);\n    }\n}\n\nvoid FindReplaceForm::replace()\n{\n    if (!textEdit)\n    {\n        showError(\"No active editor\");\n        return;\n    }\n    if (textEdit->textCursor().hasSelection())\n    {\n        if (ui->regexCheckBox->isChecked())\n            textEdit->textCursor().insertText(textEdit->textCursor().selectedText().replace(\n                QRegularExpression(ui->textToFind->text()), ui->textToReplace->text()));\n        else\n            textEdit->textCursor().insertText(ui->textToReplace->text());\n    }\n    find();\n}\n\nvoid FindReplaceForm::replaceAll()\n{\n    if (!textEdit)\n    {\n        showError(\"No active editor\");\n        return;\n    }\n\n    if (ui->downRadioButton->isChecked())\n        textEdit->moveCursor(QTextCursor::Start);\n    else\n        textEdit->moveCursor(QTextCursor::End);\n\n    int cnt = 0;\n    find();\n    textEdit->textCursor().beginEditBlock();\n    while (ui->replaceButton->isEnabled())\n    {\n        replace();\n        ++cnt;\n    }\n    textEdit->textCursor().endEditBlock();\n\n    showMessage(tr(\"Replaced %1 occurrence(s)\", \"FindDialog\").arg(cnt));\n}\n\nvoid FindReplaceForm::maybeSetTextToFind(const QString &textToFind)\n{\n    if (!textToFind.isEmpty())\n        setTextToFind(textToFind);\n    ui->textToFind->setFocus();\n    ui->textToFind->selectAll();\n}\n\nvoid FindReplaceForm::writeSettings(QSettings &settings, const QString &prefix)\n{\n    settings.beginGroup(prefix);\n    settings.setValue(TEXT_TO_FIND, ui->textToFind->text());\n    settings.setValue(TEXT_TO_REPLACE, ui->textToReplace->text());\n    settings.setValue(DOWN_RADIO, ui->downRadioButton->isChecked());\n    settings.setValue(UP_RADIO, ui->upRadioButton->isChecked());\n    settings.setValue(CASE_CHECK, ui->caseCheckBox->isChecked());\n    settings.setValue(WHOLE_CHECK, ui->wholeCheckBox->isChecked());\n    settings.setValue(REGEXP_CHECK, ui->regexCheckBox->isChecked());\n    settings.endGroup();\n}\n\nvoid FindReplaceForm::readSettings(QSettings &settings, const QString &prefix)\n{\n    settings.beginGroup(prefix);\n    ui->textToFind->setText(settings.value(TEXT_TO_FIND, \"\").toString());\n    ui->textToReplace->setText(settings.value(TEXT_TO_REPLACE, \"\").toString());\n    ui->downRadioButton->setChecked(settings.value(DOWN_RADIO, true).toBool());\n    ui->upRadioButton->setChecked(settings.value(UP_RADIO, false).toBool());\n    ui->caseCheckBox->setChecked(settings.value(CASE_CHECK, false).toBool());\n    ui->wholeCheckBox->setChecked(settings.value(WHOLE_CHECK, false).toBool());\n    ui->regexCheckBox->setChecked(settings.value(REGEXP_CHECK, false).toBool());\n    settings.endGroup();\n}\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplaceform.h",
    "content": "/*\n * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>\n * See COPYING file that comes with this distribution\n */\n\n#ifndef FINDREPLACEFORM_H\n#define FINDREPLACEFORM_H\n\n#include <QTextCursor>\n#include <QWidget>\n\n#include \"findreplace_global.h\"\n\nnamespace Ui\n{\nclass FindReplaceForm;\n}\n\nclass QTextEdit;\nclass QSettings;\nclass QEvent;\nclass QShowEvent;\n\n/**\n * The form for the find/replace dialog.  The form presents the typical\n * widgets you find in standard find/replace dialogs, and it acts on a QTextEdit.\n *\n * \\image html Screenshot-FindReplace.png\n *\n * You need to set the QTextEdit explicitly, using the method setTextEdit(QTextEdit *textEdit).\n *\n * For instance\n * \\code\n * m_findReplaceDialog = new FindReplaceDialog(this);\n * m_findReplaceDialog->setModal(false);\n * m_findReplaceDialog->setTextEdit(ui->textEdit);\n * \\endcode\n *\n * The find functionalities is available even if the find dialog is not shown: if something\n * to search for was already specified, the application can call the methods findNext() and\n * findPrev() (e.g., by connecting them to menu items).\n *\n * In case a regular expression is used as the search term, the form also checks whether the\n * expression is a valid regular expression (You may want to take a look at the syntax of regular expressions:\n * http://doc.trolltech.com/qregexp.html).\n *\n * The form provides also functionalities to save and restore its state using a QSettings object (i.e.,\n * the last word searched for, the options of the form, etc.) via the methods writeSettings()\n * and readSettings().\n *\n * You can take a look at the \\ref examples page.\n */\nclass FINDREPLACESHARED_EXPORT FindReplaceForm : public QWidget\n{\n    Q_OBJECT\n  public:\n    FindReplaceForm(QWidget *parent = 0);\n    virtual ~FindReplaceForm();\n\n    /**\n     * Associates the text editor where to perform the search\n     * @param textEdit_\n     */\n    void setTextEdit(QTextEdit *textEdit_);\n\n    /// hides replace widgets from the form\n    void hideReplaceWidgets();\n\n    /**\n     * Writes the state of the form to the passed settings.\n     * @param settings\n     * @param prefix the prefix to insert in the settings\n     */\n    virtual void writeSettings(QSettings &settings, const QString &prefix = \"FindReplaceDialog\");\n\n    /**\n     * Reads the state of the form from the passed settings.\n     * @param settings\n     * @param prefix the prefix to look for in the settings\n     */\n    virtual void readSettings(QSettings &settings, const QString &prefix = \"FindReplaceDialog\");\n\n  public Q_SLOTS:\n    /**\n     * Sets the current textToFind (used to set it from specialized current selection, etc)\n     */\n    void setTextToFind(const QString &strText);\n\n    /**\n     * performs the find task\n     * @param next whether to find the next or the previous\n     * occurrence\n     */\n    void find(bool next);\n\n    /**\n     * Finds the next occurrence\n     */\n    void find();\n\n    /**\n     * Finds the next occurrence\n     */\n    void findNext()\n    {\n        find(true);\n    }\n\n    /**\n     * Finds the previous occurrence\n     */\n    void findPrev()\n    {\n        find(false);\n    }\n\n    /**\n     * Replaces the found occurrences and goes to the next occurrence\n     */\n    void replace();\n\n    /**\n     * Replaces all the found occurrences\n     */\n    void replaceAll();\n\n    /**\n     * Set text to find if not empty and select it\n     */\n    void maybeSetTextToFind(const QString &textToFind = QString());\n\n  protected:\n    void changeEvent(QEvent *e);\n    void showEvent(QShowEvent *event);\n\n    /// shows an error in the dialog\n    void showError(const QString &error);\n\n    /// shows a message in the dialog\n    void showMessage(const QString &message);\n\n  protected Q_SLOTS:\n    /// when the text edit contents changed\n    void textToFindChanged();\n\n    /// checks whether the passed text is a valid regexp\n    void validateRegExp(const QString &text);\n\n    /// the regexp checkbox was selected\n    void regexpSelected(bool sel);\n\n    // the selection of the textedit changed\n    void onSelectionChanged();\n\n  protected:\n    Ui::FindReplaceForm *ui;\n\n    /// for searching into the text\n    QTextCursor textCursor;\n\n    /// the text editor (possibly) associated with this form\n    QTextEdit *textEdit;\n\n    // connection to textedit selection change\n    QMetaObject::Connection selectionChangeConnection;\n};\n\n#endif // FINDREPLACEFORM_H\n"
  },
  {
    "path": "external/QtFindReplaceDialog/dialogs/findreplaceform.ui",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<ui version=\"4.0\">\r\n <class>FindReplaceForm</class>\r\n <widget class=\"QWidget\" name=\"FindReplaceForm\">\r\n  <property name=\"geometry\">\r\n   <rect>\r\n    <x>0</x>\r\n    <y>0</y>\r\n    <width>483</width>\r\n    <height>288</height>\r\n   </rect>\r\n  </property>\r\n  <property name=\"windowTitle\">\r\n   <string>Form</string>\r\n  </property>\r\n  <layout class=\"QGridLayout\" name=\"gridLayout\">\r\n   <item row=\"0\" column=\"0\">\r\n    <layout class=\"QVBoxLayout\" name=\"verticalLayout_5\">\r\n     <item>\r\n      <layout class=\"QVBoxLayout\" name=\"verticalLayout_2\">\r\n       <item>\r\n        <layout class=\"QGridLayout\" name=\"gridLayout_3\">\r\n         <item row=\"0\" column=\"0\">\r\n          <widget class=\"QLabel\" name=\"label\">\r\n           <property name=\"text\">\r\n            <string>Find:</string>\r\n           </property>\r\n           <property name=\"buddy\">\r\n            <cstring>textToFind</cstring>\r\n           </property>\r\n          </widget>\r\n         </item>\r\n         <item row=\"0\" column=\"1\">\r\n          <widget class=\"QLineEdit\" name=\"textToFind\"/>\r\n         </item>\r\n         <item row=\"1\" column=\"0\">\r\n          <widget class=\"QLabel\" name=\"replaceLabel\">\r\n           <property name=\"text\">\r\n            <string>Replace with:</string>\r\n           </property>\r\n           <property name=\"buddy\">\r\n            <cstring>textToReplace</cstring>\r\n           </property>\r\n          </widget>\r\n         </item>\r\n         <item row=\"1\" column=\"1\">\r\n          <widget class=\"QLineEdit\" name=\"textToReplace\"/>\r\n         </item>\r\n        </layout>\r\n       </item>\r\n      </layout>\r\n     </item>\r\n     <item>\r\n      <widget class=\"QLabel\" name=\"errorLabel\">\r\n       <property name=\"text\">\r\n        <string>errorLabel</string>\r\n       </property>\r\n      </widget>\r\n     </item>\r\n     <item>\r\n      <layout class=\"QHBoxLayout\" name=\"horizontalLayout\">\r\n       <item>\r\n        <widget class=\"QGroupBox\" name=\"groupBox\">\r\n         <property name=\"title\">\r\n          <string>Direction</string>\r\n         </property>\r\n         <layout class=\"QVBoxLayout\" name=\"verticalLayout_3\">\r\n          <item>\r\n           <widget class=\"QRadioButton\" name=\"upRadioButton\">\r\n            <property name=\"text\">\r\n             <string>Up</string>\r\n            </property>\r\n           </widget>\r\n          </item>\r\n          <item>\r\n           <widget class=\"QRadioButton\" name=\"downRadioButton\">\r\n            <property name=\"text\">\r\n             <string>Down</string>\r\n            </property>\r\n            <property name=\"checked\">\r\n             <bool>true</bool>\r\n            </property>\r\n           </widget>\r\n          </item>\r\n         </layout>\r\n        </widget>\r\n       </item>\r\n       <item>\r\n        <widget class=\"QGroupBox\" name=\"groupBox_2\">\r\n         <property name=\"title\">\r\n          <string>Options</string>\r\n         </property>\r\n         <layout class=\"QVBoxLayout\" name=\"verticalLayout_4\">\r\n          <item>\r\n           <widget class=\"QCheckBox\" name=\"caseCheckBox\">\r\n            <property name=\"text\">\r\n             <string>Case sensitive</string>\r\n            </property>\r\n           </widget>\r\n          </item>\r\n          <item>\r\n           <widget class=\"QCheckBox\" name=\"wholeCheckBox\">\r\n            <property name=\"text\">\r\n             <string>Whole words only</string>\r\n            </property>\r\n           </widget>\r\n          </item>\r\n          <item>\r\n           <widget class=\"QCheckBox\" name=\"regexCheckBox\">\r\n            <property name=\"toolTip\">\r\n             <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;\r\n&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;\r\np, li { white-space: pre-wrap; }\r\n&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;\r\n&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;whether the text to search should be interpreted as a regular expression.&lt;/p&gt;\r\n&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;\r\n&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You may want to take a look at the syntax of regular expressions:&lt;/p&gt;\r\n&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://doc.trolltech.com/qregexp.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://doc.trolltech.com/qregexp.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>\r\n            </property>\r\n            <property name=\"text\">\r\n             <string>Regular Expression</string>\r\n            </property>\r\n           </widget>\r\n          </item>\r\n         </layout>\r\n        </widget>\r\n       </item>\r\n      </layout>\r\n     </item>\r\n    </layout>\r\n   </item>\r\n   <item row=\"0\" column=\"1\">\r\n    <layout class=\"QVBoxLayout\" name=\"verticalLayout\">\r\n     <property name=\"leftMargin\">\r\n      <number>10</number>\r\n     </property>\r\n     <item>\r\n      <widget class=\"QPushButton\" name=\"findButton\">\r\n       <property name=\"enabled\">\r\n        <bool>false</bool>\r\n       </property>\r\n       <property name=\"text\">\r\n        <string>Find</string>\r\n       </property>\r\n      </widget>\r\n     </item>\r\n     <item>\r\n      <widget class=\"QPushButton\" name=\"replaceButton\">\r\n       <property name=\"enabled\">\r\n        <bool>false</bool>\r\n       </property>\r\n       <property name=\"text\">\r\n        <string>Replace</string>\r\n       </property>\r\n      </widget>\r\n     </item>\r\n     <item>\r\n      <widget class=\"QPushButton\" name=\"replaceAllButton\">\r\n       <property name=\"enabled\">\r\n        <bool>false</bool>\r\n       </property>\r\n       <property name=\"text\">\r\n        <string>Replace All</string>\r\n       </property>\r\n      </widget>\r\n     </item>\r\n     <item>\r\n      <spacer name=\"verticalSpacer\">\r\n       <property name=\"orientation\">\r\n        <enum>Qt::Vertical</enum>\r\n       </property>\r\n       <property name=\"sizeHint\" stdset=\"0\">\r\n        <size>\r\n         <width>20</width>\r\n         <height>40</height>\r\n        </size>\r\n       </property>\r\n      </spacer>\r\n     </item>\r\n    </layout>\r\n   </item>\r\n  </layout>\r\n </widget>\r\n <resources/>\r\n <connections/>\r\n</ui>\r\n"
  },
  {
    "path": "external/QtFindReplaceDialog/doc/.gitignore",
    "content": "*.pro.user\n*~\nbuild*\n*.log\noutput\n"
  },
  {
    "path": "external/QtFindReplaceDialog/doc/Doxyfile",
    "content": "# Doxyfile 1.5.8\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project\n#\n# All text after a hash (#) is considered a comment and will be ignored\n# The format is:\n#       TAG = value [value, ...]\n# For lists items can also be appended using:\n#       TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\" \")\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file \n# that follow. The default is UTF-8 which is also the encoding used for all \n# text before the first occurrence of this tag. Doxygen uses libiconv (or the \n# iconv built into libc) for the transcoding. See \n# http://www.gnu.org/software/libiconv for the list of possible encodings.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded \n# by quotes) that should identify the project.\n\nPROJECT_NAME           = \"QtFindReplaceDialog User's Guide\"\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. \n# This could be handy for archiving the generated documentation or \n# if some version control system is used.\n\nPROJECT_NUMBER         = 1.0\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) \n# base path where the generated documentation will be put. \n# If a relative path is entered, it will be relative to the location \n# where doxygen was started. If left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = ./output\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create \n# 4096 sub-directories (in 2 levels) under the output directory of each output \n# format and will distribute the generated files over these directories. \n# Enabling this option can be useful when feeding doxygen a huge amount of \n# source files, where putting all generated files in the same directory would \n# otherwise cause performance problems for the file system.\n\nCREATE_SUBDIRS         = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all \n# documentation generated by doxygen is written. Doxygen will use this \n# information to generate all constant output in the proper language. \n# The default language is English, other supported languages are: \n# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, \n# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, \n# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), \n# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, \n# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, \n# Spanish, Swedish, and Ukrainian.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will \n# include brief member descriptions after the members that are listed in \n# the file and class documentation (similar to JavaDoc). \n# Set to NO to disable this.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend \n# the brief description of a member or function before the detailed description. \n# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the \n# brief descriptions will be completely suppressed.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator \n# that is used to form the text in various listings. Each string \n# in this list, if found as the leading text of the brief description, will be \n# stripped from the text and the result after processing the whole list, is \n# used as the annotated text. Otherwise, the brief description is used as-is. \n# If left blank, the following values are used (\"$name\" is automatically \n# replaced with the name of the entity): \"The $name class\" \"The $name widget\" \n# \"The $name file\" \"is\" \"provides\" \"specifies\" \"contains\" \n# \"represents\" \"a\" \"an\" \"the\"\n\nABBREVIATE_BRIEF       = \n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then \n# Doxygen will generate a detailed section even if there is only a brief \n# description.\n\nALWAYS_DETAILED_SEC    = YES\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all \n# inherited members of a class in the documentation of that class as if those \n# members were ordinary class members. Constructors, destructors and assignment \n# operators of the base classes will not be shown.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full \n# path before files name in the file list and in the header files. If set \n# to NO the shortest path that makes the file name unique will be used.\n\nFULL_PATH_NAMES        = NO\n\n# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag \n# can be used to strip a user-defined part of the path. Stripping is \n# only done if one of the specified strings matches the left-hand part of \n# the path. The tag can be used to show relative paths in the file list. \n# If left blank the directory from which doxygen is run is used as the \n# path to strip.\n\nSTRIP_FROM_PATH        = \n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of \n# the path mentioned in the documentation of a class, which tells \n# the reader which header file to include in order to use a class. \n# If left blank only the name of the header file containing the class \n# definition is used. Otherwise one should specify the include paths that \n# are normally passed to the compiler using the -I flag.\n\nSTRIP_FROM_INC_PATH    = \n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter \n# (but less readable) file names. This can be useful is your file systems \n# doesn't support long names like on DOS, Mac, or CD-ROM.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen \n# will interpret the first line (until the first dot) of a JavaDoc-style \n# comment as the brief description. If set to NO, the JavaDoc \n# comments will behave just like regular Qt-style comments \n# (thus requiring an explicit @brief command for a brief description.)\n\nJAVADOC_AUTOBRIEF      = YES\n\n# If the QT_AUTOBRIEF tag is set to YES then Doxygen will \n# interpret the first line (until the first dot) of a Qt-style \n# comment as the brief description. If set to NO, the comments \n# will behave just like regular Qt-style comments (thus requiring \n# an explicit \\brief command for a brief description.)\n\nQT_AUTOBRIEF           = YES\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen \n# treat a multi-line C++ special comment block (i.e. a block of //! or /// \n# comments) as a brief description. This used to be the default behaviour. \n# The new default is to treat a multi-line C++ comment block as a detailed \n# description. Set this tag to YES if you prefer the old behaviour instead.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented \n# member inherits the documentation from any documented member that it \n# re-implements.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce \n# a new page for each member. If set to NO, the documentation of a member will \n# be part of the file/class/namespace that contains it.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. \n# Doxygen uses this value to replace tabs by spaces in code fragments.\n\nTAB_SIZE               = 2\n\n# This tag can be used to specify a number of aliases that acts \n# as commands in the documentation. An alias has the form \"name=value\". \n# For example adding \"sideeffect=\\par Side Effects:\\n\" will allow you to \n# put the command \\sideeffect (or @sideeffect) in the documentation, which \n# will result in a user-defined paragraph with heading \"Side Effects:\". \n# You can put \\n's in the value part of an alias to insert newlines.\n\nALIASES                = \n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C \n# sources only. Doxygen will then generate output that is more tailored for C. \n# For instance, some of the names that are used will be different. The list \n# of all members will be omitted, etc.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java \n# sources only. Doxygen will then generate output that is more tailored for \n# Java. For instance, namespaces will be presented as packages, qualified \n# scopes will look different, etc.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran \n# sources only. Doxygen will then generate output that is more tailored for \n# Fortran.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL \n# sources. Doxygen will then generate output that is tailored for \n# VHDL.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it parses. \n# With this tag you can assign which parser to use for a given extension. \n# Doxygen has a built-in mapping, but you can override or extend it using this tag. \n# The format is ext=language, where ext is a file extension, and language is one of \n# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, \n# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat \n# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), \n# use: inc=Fortran f=C\n\nEXTENSION_MAPPING      = \n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want \n# to include (a tag file for) the STL sources as input, then you should \n# set this tag to YES in order to let doxygen match functions declarations and \n# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. \n# func(std::string) {}). This also make the inheritance and collaboration \n# diagrams that involve STL classes more complete and accurate.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to \n# enable parsing support.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. \n# Doxygen will parse them like normal C++ but will assume all classes use public \n# instead of private inheritance when no explicit protection keyword is present.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate getter \n# and setter methods for a property. Setting this option to YES (the default) \n# will make doxygen to replace the get and set methods by a property in the \n# documentation. This will only work if the methods are indeed getting or \n# setting a simple type. If this is not the case, or you want to show the \n# methods anyway, you should set this option to NO.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC \n# tag is set to YES, then doxygen will reuse the documentation of the first \n# member in the group (if any) for the other members of the group. By default \n# all members of a group must be documented explicitly.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES (the default) to allow class member groups of \n# the same type (for instance a group of public functions) to be put as a \n# subgroup of that type (e.g. under the Public Functions section). Set it to \n# NO to prevent subgrouping. Alternatively, this can be done per class using \n# the \\nosubgrouping command.\n\nSUBGROUPING            = NO\n\n# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum \n# is documented as struct, union, or enum with the name of the typedef. So \n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct \n# with name TypeT. When disabled the typedef will appear as a member of a file, \n# namespace, or class. And the struct will be named TypeS. This can typically \n# be useful for C code in case the coding convention dictates that all compound \n# types are typedef'ed and only the typedef is referenced, never the tag name.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to \n# determine which symbols to keep in memory and which to flush to disk. \n# When the cache is full, less often used symbols will be written to disk. \n# For small to medium size projects (<1000 input files) the default value is \n# probably good enough. For larger projects a too small cache size can cause \n# doxygen to be busy swapping symbols to and from disk most of the time \n# causing a significant performance penality. \n# If the system has enough physical memory increasing the cache will improve the \n# performance by keeping more symbols in memory. Note that the value works on \n# a logarithmic scale so increasing the size by one will rougly double the \n# memory usage. The cache size is given by this formula: \n# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, \n# corresponding to a cache size of 2^16 = 65536 symbols\n\nSYMBOL_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in \n# documentation are documented, even if no documentation was available. \n# Private class members and static file members will be hidden unless \n# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class \n# will be included in the documentation.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file \n# will be included in the documentation.\n\nEXTRACT_STATIC         = YES\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) \n# defined locally in source files will be included in the documentation. \n# If set to NO only classes defined in header files are included.\n\nEXTRACT_LOCAL_CLASSES  = NO\n\n# This flag is only useful for Objective-C code. When set to YES local \n# methods, which are defined in the implementation section but not in \n# the interface are included in the documentation. \n# If set to NO (the default) only methods in the interface are included.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be \n# extracted and appear in the documentation as a namespace called \n# 'anonymous_namespace{file}', where file will be replaced with the base \n# name of the file that contains the anonymous namespace. By default \n# anonymous namespace are hidden.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all \n# undocumented members of documented classes, files or namespaces. \n# If set to NO (the default) these members will be included in the \n# various overviews, but no documentation section is generated. \n# This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all \n# undocumented classes that are normally visible in the class hierarchy. \n# If set to NO (the default) these classes will be included in the various \n# overviews. This option has no effect if EXTRACT_ALL is enabled.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all \n# friend (class|struct|union) declarations. \n# If set to NO (the default) these declarations will be included in the \n# documentation.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any \n# documentation blocks found inside the body of a function. \n# If set to NO (the default) these blocks will be appended to the \n# function's detailed documentation block.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation \n# that is typed after a \\internal command is included. If the tag is set \n# to NO (the default) then the documentation will be excluded. \n# Set it to YES to include the internal documentation.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate \n# file names in lower-case letters. If set to YES upper-case letters are also \n# allowed. This is useful if you have classes or files whose names only differ \n# in case and if your file system supports case sensitive file names. Windows \n# and Mac users are advised to set this option to NO.\n\nCASE_SENSE_NAMES       = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen \n# will show members with their full class and namespace scopes in the \n# documentation. If set to YES the scope will be hidden.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen \n# will put a list of the files that are included by a file in the documentation \n# of that file.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] \n# is inserted in the documentation for inline members.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen \n# will sort the (detailed) documentation of file and class members \n# alphabetically by member name. If set to NO the members will appear in \n# declaration order.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the \n# brief documentation of file, namespace and class members alphabetically \n# by member name. If set to NO (the default) the members will appear in \n# declaration order.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the \n# hierarchy of group names into alphabetical order. If set to NO (the default) \n# the group names will appear in their defined order.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be \n# sorted by fully-qualified names, including namespaces. If set to \n# NO (the default), the class list will be sorted only by class name, \n# not including the namespace part. \n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. \n# Note: This option applies only to the class list, not to the \n# alphabetical list.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# The GENERATE_TODOLIST tag can be used to enable (YES) or \n# disable (NO) the todo list. This list is created by putting \\todo \n# commands in the documentation.\n\nGENERATE_TODOLIST      = NO\n\n# The GENERATE_TESTLIST tag can be used to enable (YES) or \n# disable (NO) the test list. This list is created by putting \\test \n# commands in the documentation.\n\nGENERATE_TESTLIST      = NO\n\n# The GENERATE_BUGLIST tag can be used to enable (YES) or \n# disable (NO) the bug list. This list is created by putting \\bug \n# commands in the documentation.\n\nGENERATE_BUGLIST       = NO\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or \n# disable (NO) the deprecated list. This list is created by putting \n# \\deprecated commands in the documentation.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional \n# documentation sections, marked by \\if sectionname ... \\endif.\n\nENABLED_SECTIONS       = \n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines \n# the initial value of a variable or define consists of for it to appear in \n# the documentation. If the initializer consists of more lines than specified \n# here it will be hidden. Use a value of 0 to hide initializers completely. \n# The appearance of the initializer of individual variables and defines in the \n# documentation can be controlled using \\showinitializer or \\hideinitializer \n# command in the documentation regardless of this setting.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated \n# at the bottom of the documentation of classes and structs. If set to YES the \n# list will mention the files that were used to generate the documentation.\n\nSHOW_USED_FILES        = NO\n\n# If the sources in your project are distributed over multiple directories \n# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy \n# in the documentation. The default is NO.\n\nSHOW_DIRECTORIES       = NO\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. \n# This will remove the Files entry from the Quick Index and from the \n# Folder Tree View (if specified). The default is YES.\n\nSHOW_FILES             = NO\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the \n# Namespaces page. \n# This will remove the Namespaces entry from the Quick Index \n# and from the Folder Tree View (if specified). The default is YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that \n# doxygen should invoke to get the current version for each file (typically from \n# the version control system). Doxygen will invoke the program by executing (via \n# popen()) the command <command> <input-file>, where <command> is the value of \n# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file \n# provided by doxygen. Whatever the program writes to standard output \n# is used as the file version. See the manual for examples.\n\nFILE_VERSION_FILTER    = \n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by \n# doxygen. The layout file controls the global structure of the generated output files \n# in an output format independent way. The create the layout file that represents \n# doxygen's defaults, run doxygen with the -l option. You can optionally specify a \n# file name after the option, if omitted DoxygenLayout.xml will be used as the name \n# of the layout file.\n\nLAYOUT_FILE            = \n\n#---------------------------------------------------------------------------\n# configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated \n# by doxygen. Possible values are YES and NO. If left blank NO is used.\n\nQUIET                  = YES\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are \n# generated by doxygen. Possible values are YES and NO. If left blank \n# NO is used.\n\nWARNINGS               = YES\n\n# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings \n# for undocumented members. If EXTRACT_ALL is set to YES then this flag will \n# automatically be disabled.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for \n# potential errors in the documentation, such as not documenting some \n# parameters in a documented function, or documenting parameters that \n# don't exist or using markup commands wrongly.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be abled to get warnings for \n# functions that are documented, but have no documentation for their parameters \n# or return value. If set to NO (the default) doxygen will only warn about \n# wrong or incomplete parameter documentation, but not about the absence of \n# documentation.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that \n# doxygen can produce. The string should contain the $file, $line, and $text \n# tags, which will be replaced by the file and line number from which the \n# warning originated and the warning text. Optionally the format may contain \n# $version, which will be replaced by the version of the file (if it could \n# be obtained via FILE_VERSION_FILTER)\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning \n# and error messages should be written. If left blank the output is written \n# to stderr.\n\nWARN_LOGFILE           = Doxygen.log\n\n#---------------------------------------------------------------------------\n# configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag can be used to specify the files and/or directories that contain \n# documented source files. You may enter file names like \"myfile.cpp\" or \n# directories like \"/usr/src/myproject\". Separate the files or directories \n# with spaces.\n\nINPUT                  = . \\\n                         ../dialogs\n\n# This tag can be used to specify the character encoding of the source files \n# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is \n# also the default input encoding. Doxygen uses libiconv (or the iconv built \n# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for \n# the list of possible encodings.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the \n# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank the following patterns are tested: \n# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx \n# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90\n\nFILE_PATTERNS          = *.cpp \\\n                         *.h \\\n                         *.dox\n\n# The RECURSIVE tag can be used to turn specify whether or not subdirectories \n# should be searched for input files as well. Possible values are YES and NO. \n# If left blank NO is used.\n\nRECURSIVE              = NO\n\n# The EXCLUDE tag can be used to specify files and/or directories that should \n# excluded from the INPUT source files. This way you can easily exclude a \n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n\nEXCLUDE                = \n\n# The EXCLUDE_SYMLINKS tag can be used select whether or not files or \n# directories that are symbolic links (a Unix filesystem feature) are excluded \n# from the input.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the \n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude \n# certain files from those directories. Note that the wildcards are matched \n# against the file with absolute path, so to exclude all test directories \n# for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       = */test/*\n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names \n# (namespaces, classes, functions, etc.) that should be excluded from the \n# output. The symbol name can be a fully qualified name, a word, or if the \n# wildcard * is used, a substring. Examples: ANamespace, AClass, \n# AClass::ANamespace, ANamespace::*Test\n\nEXCLUDE_SYMBOLS        = \n\n# The EXAMPLE_PATH tag can be used to specify one or more files or \n# directories that contain example code fragments that are included (see \n# the \\include command).\n\nEXAMPLE_PATH           = ../examples ../\n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the \n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp \n# and *.h) to filter out the source-files in the directories. If left \n# blank all files are included.\n\nEXAMPLE_PATTERNS       = \n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be \n# searched for input files to be used with the \\include or \\dontinclude \n# commands irrespective of the value of the RECURSIVE tag. \n# Possible values are YES and NO. If left blank NO is used.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or \n# directories that contain image that are included in the documentation (see \n# the \\image command).\n\nIMAGE_PATH             = images\n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should \n# invoke to filter for each input file. Doxygen will invoke the filter program \n# by executing (via popen()) the command <filter> <input-file>, where <filter> \n# is the value of the INPUT_FILTER tag, and <input-file> is the name of an \n# input file. Doxygen will then use the output that the filter program writes \n# to standard output. \n# If FILTER_PATTERNS is specified, this tag will be \n# ignored.\n\nINPUT_FILTER           = \n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern \n# basis. \n# Doxygen will compare the file name with each pattern and apply the \n# filter if there is a match. \n# The filters are a list of the form: \n# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further \n# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER \n# is applied to all files.\n\nFILTER_PATTERNS        = \n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using \n# INPUT_FILTER) will be used to filter the input files when producing source \n# files to browse (i.e. when SOURCE_BROWSER is set to YES).\n\nFILTER_SOURCE_FILES    = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will \n# be generated. Documented entities will be cross-referenced with these sources. \n# Note: To get rid of all source code in the generated output, make sure also \n# VERBATIM_HEADERS is set to NO.\n\nSOURCE_BROWSER         = NO\n\n# Setting the INLINE_SOURCES tag to YES will include the body \n# of functions and classes directly in the documentation.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct \n# doxygen to hide any special comment blocks from generated source code \n# fragments. Normal C and C++ comments will always remain visible.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES \n# then for each documented function all documented \n# functions referencing it will be listed.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES \n# then for each documented function all documented entities \n# called/used by that function will be listed.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) \n# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from \n# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will \n# link to the source code. \n# Otherwise they will link to the documentation.\n\nREFERENCES_LINK_SOURCE = NO\n\n# If the USE_HTAGS tag is set to YES then the references to source code \n# will point to the HTML generated by the htags(1) tool instead of doxygen \n# built-in source browser. The htags tool is part of GNU's global source \n# tagging system (see http://www.gnu.org/software/global/global.html). You \n# will need version 4.8.6 or higher.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen \n# will generate a verbatim copy of the header file for each class for \n# which an include is specified. Set to NO to disable this.\n\nVERBATIM_HEADERS       = YES\n\n#---------------------------------------------------------------------------\n# configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index \n# of all compounds will be generated. Enable this if the project \n# contains a lot of classes, structs, unions or interfaces.\n\nALPHABETICAL_INDEX     = YES\n\n# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then \n# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns \n# in which this list will be split (can be a number in the range [1..20])\n\nCOLS_IN_ALPHA_INDEX    = 4\n\n# In case all classes in a project start with a common prefix, all \n# classes will be put under the same header in the alphabetical index. \n# The IGNORE_PREFIX tag can be used to specify one or more prefixes that \n# should be ignored while generating the index headers.\n\nIGNORE_PREFIX          = Q\n\n#---------------------------------------------------------------------------\n# configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES (the default) Doxygen will \n# generate HTML output.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `html' will be used as the default path.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for \n# each generated HTML page (for example: .htm,.php,.asp). If it is left blank \n# doxygen will generate files with .html extension.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a personal HTML header for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard header.\n\nHTML_HEADER            = \n\n# The HTML_FOOTER tag can be used to specify a personal HTML footer for \n# each generated HTML page. If it is left blank doxygen will generate a \n# standard footer.\n\nHTML_FOOTER            = \n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading \n# style sheet that is used by each HTML page. It can be used to \n# fine-tune the look of the HTML output. If the tag is left blank doxygen \n# will generate a default style sheet. Note that doxygen will try to copy \n# the style sheet file to the HTML output directory, so don't put your own \n# stylesheet in the HTML output directory as well, or it will be erased!\n\nHTML_STYLESHEET        = \n\n# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, \n# files or namespaces will be aligned in HTML using tables. If set to \n# NO a bullet list will be used.\n\nHTML_ALIGN_MEMBERS     = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML \n# documentation will contain sections that can be hidden and shown after the \n# page has loaded. For this to work a browser that supports \n# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox \n# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files \n# will be generated that can be used as input for Apple's Xcode 3 \n# integrated development environment, introduced with OSX 10.5 (Leopard). \n# To create a documentation set, doxygen will generate a Makefile in the \n# HTML output directory. Running make will produce the docset in that \n# directory and running \"make install\" will install the docset in \n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find \n# it at startup. \n# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.\n\nGENERATE_DOCSET        = NO\n\n# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the \n# feed. A documentation feed provides an umbrella under which multiple \n# documentation sets from a single provider (such as a company or product suite) \n# can be grouped.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that \n# should uniquely identify the documentation set bundle. This should be a \n# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen \n# will append .docset to the name.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# If the GENERATE_HTMLHELP tag is set to YES, additional index files \n# will be generated that can be used as input for tools like the \n# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) \n# of the generated HTML documentation.\n\nGENERATE_HTMLHELP      = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can \n# be used to specify the file name of the resulting .chm file. You \n# can add a path in front of the file if the result should not be \n# written to the html output directory.\n\nCHM_FILE               = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can \n# be used to specify the location (absolute path including file name) of \n# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run \n# the HTML help compiler on the generated index.hhp.\n\nHHC_LOCATION           = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag \n# controls if a separate .chi index file is generated (YES) or that \n# it should be included in the master .chm file (NO).\n\nGENERATE_CHI           = NO\n\n# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING \n# is used to encode HtmlHelp index (hhk), content (hhc) and project file \n# content.\n\nCHM_INDEX_ENCODING     = \n\n# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag \n# controls whether a binary table of contents is generated (YES) or a \n# normal table of contents (NO) in the .chm file.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members \n# to the contents of the HTML help documentation and to the tree view.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER \n# are set, an additional index file will be generated that can be used as input for \n# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated \n# HTML documentation.\n\nGENERATE_QHP           = yes\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can \n# be used to specify the file name of the resulting .qch file. \n# The path specified is relative to the HTML output folder.\n\nQCH_FILE               = \"qtfindreplacedialog.qch\"\n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating \n# Qt Help Project output. For more information please see \n# http://doc.trolltech.com/qthelpproject.html#namespace\n\nQHP_NAMESPACE          = \"my.qtfindreplacedialog\"\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating \n# Qt Help Project output. For more information please see \n# http://doc.trolltech.com/qthelpproject.html#virtual-folders\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. \n# For more information please see \n# http://doc.trolltech.com/qthelpproject.html#custom-filters\n\nQHP_CUST_FILTER_NAME   = \n\n# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see \n# <a href=\"http://doc.trolltech.com/qthelpproject.html#custom-filters\">Qt Help Project / Custom Filters</a>.\n\nQHP_CUST_FILTER_ATTRS  = \n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's \n# filter section matches. \n# <a href=\"http://doc.trolltech.com/qthelpproject.html#filter-attributes\">Qt Help Project / Filter Attributes</a>.\n\nQHP_SECT_FILTER_ATTRS  = \n\n# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can \n# be used to specify the location of Qt's qhelpgenerator. \n# If non-empty doxygen will try to run qhelpgenerator on the generated \n# .qhp file.\n\nQHG_LOCATION           = \"qhelpgenerator\"\n\n# The DISABLE_INDEX tag can be used to turn on/off the condensed index at \n# top of each HTML page. The value NO (the default) enables the index and \n# the value YES disables it.\n\nDISABLE_INDEX          = NO\n\n# This tag can be used to set the number of enum values (range [1..20]) \n# that doxygen will group on one line in the generated HTML documentation.\n\nENUM_VALUES_PER_LINE   = 1\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index \n# structure should be generated to display hierarchical information. \n# If the tag value is set to FRAME, a side panel will be generated \n# containing a tree-like index structure (just like the one that \n# is generated for HTML Help). For this to work a browser that supports \n# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, \n# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are \n# probably better off using the HTML help feature. Other possible values \n# for this tag are: HIERARCHIES, which will generate the Groups, Directories, \n# and Class Hierarchy pages using a tree view instead of an ordered list; \n# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which \n# disables this behavior completely. For backwards compatibility with previous \n# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE \n# respectively.\n\nGENERATE_TREEVIEW      = NO\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be \n# used to set the initial width (in pixels) of the frame in which the tree \n# is shown.\n\nTREEVIEW_WIDTH         = 250\n\n# Use this tag to change the font size of Latex formulas included \n# as images in the HTML documentation. The default is 10. Note that \n# when you change the font size after a successful doxygen run you need \n# to manually remove any form_*.png images from the HTML output directory \n# to force them to be regenerated.\n\nFORMULA_FONTSIZE       = 10\n\n#---------------------------------------------------------------------------\n# configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will \n# generate Latex output.\n\nGENERATE_LATEX         = NO\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `latex' will be used as the default path.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be \n# invoked. If left blank `latex' will be used as the default command name.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to \n# generate index for LaTeX. If left blank `makeindex' will be used as the \n# default command name.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact \n# LaTeX documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_LATEX          = YES\n\n# The PAPER_TYPE tag can be used to set the paper type that is used \n# by the printer. Possible values are: a4, a4wide, letter, legal and \n# executive. If left blank a4wide will be used.\n\nPAPER_TYPE             = a4wide\n\n# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX \n# packages that should be included in the LaTeX output.\n\nEXTRA_PACKAGES         = \n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for \n# the generated latex document. The header should contain everything until \n# the first chapter. If it is left blank doxygen will generate a \n# standard header. Notice: only use this tag if you know what you are doing!\n\nLATEX_HEADER           = \n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated \n# is prepared for conversion to pdf (using ps2pdf). The pdf file will \n# contain links (just like the HTML output) instead of page references \n# This makes the output suitable for online browsing using a pdf viewer.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of \n# plain latex in the generated Makefile. Set this option to YES to get a \n# higher quality PDF documentation.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\\\batchmode. \n# command to the generated LaTeX files. This will instruct LaTeX to keep \n# running if errors occur, instead of asking the user for help. \n# This option is also used when generating formulas in HTML.\n\nLATEX_BATCHMODE        = NO\n\n# If LATEX_HIDE_INDICES is set to YES then doxygen will not \n# include the index chapters (such as File Index, Compound Index, etc.) \n# in the output.\n\nLATEX_HIDE_INDICES     = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output \n# The RTF output is optimized for Word 97 and may not look very pretty with \n# other RTF readers or editors.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `rtf' will be used as the default path.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES Doxygen generates more compact \n# RTF documents. This may be useful for small projects and may help to \n# save some trees in general.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated \n# will contain hyperlink fields. The RTF file will \n# contain links (just like the HTML output) instead of page references. \n# This makes the output suitable for online browsing using WORD or other \n# programs which support those fields. \n# Note: wordpad (write) and others do not support links.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's \n# config file, i.e. a series of assignments. You only have to provide \n# replacements, missing definitions are set to their default value.\n\nRTF_STYLESHEET_FILE    = \n\n# Set optional variables used in the generation of an rtf document. \n# Syntax is similar to doxygen's config file.\n\nRTF_EXTENSIONS_FILE    = \n\n#---------------------------------------------------------------------------\n# configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES (the default) Doxygen will \n# generate man pages\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `man' will be used as the default path.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to \n# the generated man pages (default is the subroutine's section .3)\n\nMAN_EXTENSION          = .3\n\n# If the MAN_LINKS tag is set to YES and Doxygen generates man output, \n# then it will generate one additional man file for each entity \n# documented in the real man page(s). These additional files \n# only source the real man page, but without them the man command \n# would be unable to find the correct page. The default is NO.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES Doxygen will \n# generate an XML file that captures the structure of \n# the code including all documentation.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. \n# If a relative path is entered the value of OUTPUT_DIRECTORY will be \n# put in front of it. If left blank `xml' will be used as the default path.\n\nXML_OUTPUT             = xml\n\n# The XML_SCHEMA tag can be used to specify an XML schema, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_SCHEMA             = \n\n# The XML_DTD tag can be used to specify an XML DTD, \n# which can be used by a validating XML parser to check the \n# syntax of the XML files.\n\nXML_DTD                = \n\n# If the XML_PROGRAMLISTING tag is set to YES Doxygen will \n# dump the program listings (including syntax highlighting \n# and cross-referencing information) to the XML output. Note that \n# enabling this will significantly increase the size of the XML output.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will \n# generate an AutoGen Definitions (see autogen.sf.net) file \n# that captures the structure of the code including all \n# documentation. Note that this feature is still experimental \n# and incomplete at the moment.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES Doxygen will \n# generate a Perl module file that captures the structure of \n# the code including all documentation. Note that this \n# feature is still experimental and incomplete at the \n# moment.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES Doxygen will generate \n# the necessary Makefile rules, Perl scripts and LaTeX code to be able \n# to generate PDF and DVI output from the Perl module output.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be \n# nicely formatted so it can be parsed by a human reader. \n# This is useful \n# if you want to understand what is going on. \n# On the other hand, if this \n# tag is set to NO the size of the Perl module output will be much smaller \n# and Perl will parse it just the same.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file \n# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. \n# This is useful so different doxyrules.make files included by the same \n# Makefile don't overwrite each other's variables.\n\nPERLMOD_MAKEVAR_PREFIX = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor   \n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will \n# evaluate all C-preprocessor directives found in the sources and include \n# files.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro \n# names in the source code. If set to NO (the default) only conditional \n# compilation will be performed. Macro expansion can be done in a controlled \n# way by setting EXPAND_ONLY_PREDEF to YES.\n\nMACRO_EXPANSION        = YES\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES \n# then the macro expansion is limited to the macros specified with the \n# PREDEFINED and EXPAND_AS_DEFINED tags.\n\nEXPAND_ONLY_PREDEF     = YES\n\n# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files \n# in the INCLUDE_PATH (see below) will be search if a #include is found.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that \n# contain include files that are not input files but should be processed by \n# the preprocessor.\n\nINCLUDE_PATH           = ../\n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard \n# patterns (like *.h and *.hpp) to filter out the header-files in the \n# directories. If left blank, the patterns specified with FILE_PATTERNS will \n# be used.\n\nINCLUDE_FILE_PATTERNS  = *.h\n\n# The PREDEFINED tag can be used to specify one or more macro names that \n# are defined before the preprocessor is started (similar to the -D option of \n# gcc). The argument of the tag is a list of macros of the form: name \n# or name=definition (no spaces). If the definition and the = are \n# omitted =1 is assumed. To prevent a macro definition from being \n# undefined via #undef or recursively expanded use the := operator \n# instead of the = operator.\n\nPREDEFINED             = QwtArray=QwtArray \\\n                         QwtMatrix=QMatrix \\\n                         Q_ENUMS(x)= \\\n                         Q_EXPORT= \\\n                         Q_OBJECT= \\\n                         Q_PROPERTY(x)= \\\n                         QT_VERSION=0x040000\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then \n# this tag can be used to specify a list of macro names that should be expanded. \n# The macro definition that is found in the sources will be used. \n# Use the PREDEFINED tag if you want to use a different macro definition.\n\nEXPAND_AS_DEFINED      = \n\n# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then \n# doxygen's preprocessor will remove all function-like macros that are alone \n# on a line, have an all uppercase name, and do not end with a semicolon. Such \n# function macros are typically used for boiler-plate code, and will confuse \n# the parser if not removed.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration::additions related to external references   \n#---------------------------------------------------------------------------\n\n# The TAGFILES option can be used to specify one or more tagfiles. \n# Optionally an initial location of the external documentation \n# can be added for each tagfile. The format of a tag file without \n# this location is as follows: \n#  \n# TAGFILES = file1 file2 ... \n# Adding location for the tag files is done as follows: \n#  \n# TAGFILES = file1=loc1 \"file2 = loc2\" ... \n# where \"loc1\" and \"loc2\" can be relative or absolute paths or \n# URLs. If a location is present for each tag, the installdox tool \n# does not have to be run to correct the links. \n# Note that each tag file must have a unique name \n# (where the name does NOT include the path) \n# If a tag file is not located in the directory in which doxygen \n# is run, you must also specify the path to the tagfile here.\n\nTAGFILES               = \n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create \n# a tag file that is based on the input files it reads.\n\nGENERATE_TAGFILE       = \n\n# If the ALLEXTERNALS tag is set to YES all external classes will be listed \n# in the class index. If set to NO only the inherited external classes \n# will be listed.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed \n# in the modules index. If set to NO, only the current project's groups will \n# be listed.\n\nEXTERNAL_GROUPS        = NO\n\n# The PERL_PATH should be the absolute path and name of the perl script \n# interpreter (i.e. the result of `which perl').\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool   \n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will \n# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base \n# or super classes. Setting the tag to NO turns the diagrams off. Note that \n# this option is superseded by the HAVE_DOT option below. This is only a \n# fallback. It is recommended to install and use dot, since it yields more \n# powerful graphs.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc \n# command. Doxygen will then run the mscgen tool (see \n# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the \n# documentation. The MSCGEN_PATH tag allows you to specify the directory where \n# the mscgen tool resides. If left empty the tool is assumed to be found in the \n# default search path.\n\nMSCGEN_PATH            = \n\n# If set to YES, the inheritance and collaboration graphs will hide \n# inheritance and usage relations if the target is undocumented \n# or is not a class.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is \n# available from the path. This tool is part of Graphviz, a graph visualization \n# toolkit from AT&T and Lucent Bell Labs. The other options in this section \n# have no effect if this option is set to NO (the default)\n\nHAVE_DOT               = YES\n\n# By default doxygen will write a font called FreeSans.ttf to the output \n# directory and reference it in all dot files that doxygen generates. This \n# font does not include all possible unicode characters however, so when you need \n# these (or just want a differently looking font) you can specify the font name \n# using DOT_FONTNAME. You need need to make sure dot is able to find the font, \n# which can be done by putting it in a standard location or by setting the \n# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory \n# containing the font.\n\nDOT_FONTNAME           = FreeSans\n\n# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. \n# The default size is 10pt.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the output directory to look for the \n# FreeSans.ttf font (which doxygen will put there itself). If you specify a \n# different font using DOT_FONTNAME you can set the path where dot \n# can find it using this tag.\n\nDOT_FONTPATH           = \n\n# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect inheritance relations. Setting this tag to YES will force the \n# the CLASS_DIAGRAMS tag to NO.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for each documented class showing the direct and \n# indirect implementation dependencies (inheritance, containment, and \n# class references variables) of the class with other documented classes.\n\nCOLLABORATION_GRAPH    = NO\n\n# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen \n# will generate a graph for groups, showing the direct groups dependencies\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and \n# collaboration diagrams in a style similar to the OMG's Unified Modeling \n# Language.\n\nUML_LOOK               = NO\n\n# If set to YES, the inheritance and collaboration graphs will show the \n# relations between templates and their instances.\n\nTEMPLATE_RELATIONS     = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT \n# tags are set to YES then doxygen will generate a graph for each documented \n# file showing the direct and indirect include dependencies of the file with \n# other documented files.\n\nINCLUDE_GRAPH          = YES\n\n# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and \n# HAVE_DOT tags are set to YES then doxygen will generate a graph for each \n# documented header file showing the documented files that directly or \n# indirectly include this file.\n\nINCLUDED_BY_GRAPH      = NO\n\n# If the CALL_GRAPH and HAVE_DOT options are set to YES then \n# doxygen will generate a call dependency graph for every global function \n# or class method. Note that enabling this option will significantly increase \n# the time of a run. So in most cases it will be better to enable call graphs \n# for selected functions only using the \\callgraph command.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then \n# doxygen will generate a caller dependency graph for every global function \n# or class method. Note that enabling this option will significantly increase \n# the time of a run. So in most cases it will be better to enable caller \n# graphs for selected functions only using the \\callergraph command.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen \n# will graphical hierarchy of all classes instead of a textual one.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES \n# then doxygen will show the dependencies a directory has on other directories \n# in a graphical way. The dependency relations are determined by the #include \n# relations between the files in the directories.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images \n# generated by dot. Possible values are png, jpg, or gif \n# If left blank png will be used.\n\nDOT_IMAGE_FORMAT       = png\n\n# The tag DOT_PATH can be used to specify the path where the dot tool can be \n# found. If left blank, it is assumed the dot tool can be found in the path.\n\nDOT_PATH               = \n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that \n# contain dot files that are included in the documentation (see the \n# \\dotfile command).\n\nDOTFILE_DIRS           = \n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of \n# nodes that will be shown in the graph. If the number of nodes in a graph \n# becomes larger than this value, doxygen will truncate the graph, which is \n# visualized by representing a node as a red box. Note that doxygen if the \n# number of direct children of the root node in a graph is already larger than \n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note \n# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the \n# graphs generated by dot. A depth value of 3 means that only nodes reachable \n# from the root by following a path via at most 3 edges will be shown. Nodes \n# that lay further from the root node will be omitted. Note that setting this \n# option to 1 or 2 may greatly reduce the computation time needed for large \n# code bases. Also note that the size of a graph can be further restricted by \n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent \n# background. This is disabled by default, because dot on Windows does not \n# seem to support this out of the box. Warning: Depending on the platform used, \n# enabling this option may lead to badly anti-aliased labels on the edges of \n# a graph (i.e. they become hard to read).\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output \n# files in one run (i.e. multiple -o and -T options on the command line). This \n# makes dot run faster, but since only newer versions of dot (>1.8.10) \n# support this, this feature is disabled by default.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will \n# generate a legend page explaining the meaning of the various boxes and \n# arrows in the dot generated graphs.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will \n# remove the intermediate dot files that are used to generate \n# the various graphs.\n\nDOT_CLEANUP            = YES\n\n#---------------------------------------------------------------------------\n# Options related to the search engine\n#---------------------------------------------------------------------------\n\n# The SEARCHENGINE tag specifies whether or not a search engine should be \n# used. If set to NO the values of all tags below this one will be ignored.\n\nSEARCHENGINE           = NO\n"
  },
  {
    "path": "external/QtFindReplaceDialog/doc/README.txt",
    "content": "If you get the sources from the git repository\nyou'll have to build the documentation yourself, using\ndoxygen http://www.doxygen.org\n\nSimply run \n\ndoxygen\n\nin this directory.\n"
  },
  {
    "path": "external/QtFindReplaceDialog/doc/doc.pro",
    "content": "# for installing documentation\n\nHTMLDIR=$$PWD/output/html\n\nhtml_docs.files = $$HTMLDIR/*\nhtml_docs.path = /share/doc/qtfindreplacedialog\nhtml_docs.CONFIG += no_check_exist\n\nINSTALLS += html_docs\n\nOTHER_FILES = Doxyfile \\\n    qtfindreplacedialog.dox\n"
  },
  {
    "path": "external/QtFindReplaceDialog/doc/qtfindreplacedialog.dox",
    "content": "/* -*- mode: C++ ; c-file-style: \"stroustrup\" -*- *****************************\n * QtFindReplaceDialog\n * Copyright (C) 2009   Lorenzo Bettini <http://www.lorenzobettini.it>\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the Qwt License, Version 1.0\n *****************************************************************************/\n\n/*\n  This file contains NO source code, just some documentation for doxygen to\n  parse.\n*/\n\n/*!\n  \\mainpage QtFindReplaceDialog - Find/Replace Qt dialog\n\n  QtFindReplaceDialog is an implementation of a Find/Replace Qt dialog to be used in qt text edit based applications.\n  A simple Find (only) dialog is also provided.\n\n  The dialogs can be used as a library, or simply by importing the sources into your own applications.\n\n  \\section homepage Project page\n\n  The project page for QtFindReplaceDialog is:\n  http://qtfindreplace.sourceforge.net\n\n  The git repository for QtFindReplaceDialog can be found here:\n  http://gitorious.org/qtfindreplacedialog/qtfindreplacedialog\n\n  \\section install Installation\n\n  You can use these dialogs in your applications either by copying the files in\n  the \\c dialogs directory, or by building the dialogs as library.\n\n  You can build the library by using qmake and then make.\n  For instance, if you use a shadow build (which is reccomended), simply create\n  a build directory and enter there.  Then run\n\n  \\verbatim\n  qmake -recursive ../qtfindreplacedialog.pro\n  make  \\endverbatim\n\n  A running example, using the find and find/replace dialogs, can be found in\n  the directory <tt>examples</tt> (this will be built also).  You can take\n  a look at the examples in the section \\ref examples.\n\n  You can specify additional arguments for qmake, for instance, if you want to build the\n  library statically use <tt>CONFIG+=static</tt>.  Then, you can install it using <tt>make install</tt>,\n  possibly by using a specific installation root:\n\n  \\verbatim\n  INSTALL_ROOT=$HOME/usr/local make install   \\endverbatim\n\n  \\section screenshots Screenshots\n\n  Here are some screenshots:\n\n  \\image html Screenshot-FindReplace.png Find/Replace dialog in Gnome\n\n  \\image html Screenshot-FindReplace2.png Find/Replace dialog after a replace all operation\n\n  \\image html Screenshot-FindReplaceKDE.png Find/Replace dialog in KDE\n\n  \\image html Screenshot-FindReplaceWin.png Find/Replace dialog in Windows XP\n\n  \\image html Screenshot-Find.png Find dialog\n\n\n\n  \\section license License\n\n  QtFindReplaceDialog is distributed under the terms of the \\ref gpllicence.\n\n*/\n\n/*!\n  \\page gpllicence GNU LGPL Licence\n  \\verbinclude \"COPYING\"\n*/\n\n/*!\n  \\page examples Examples\n  \\include mainwindow.h\n  \\include mainwindow.cpp\n*/\n"
  },
  {
    "path": "external/QtFindReplaceDialog/make-dist.sh",
    "content": "#!/bin/bash\n\n# a script to make a .tar.gz (with version in the name)\n# the archive will contain a directory $PACKAGE-$VERSION with\n# all the files in the current directory with some exclusions:\n# CVS files and build directories\n\nPACKAGE=qtfindreplacedialog\nVERSION=1.1\n\ntar \\\n    --exclude-vcs \\\n    --exclude='*~' \\\n    --exclude='*.tar.gz' \\\n    --exclude='*.user' \\\n    --exclude='build*' \\\n    -czf $PACKAGE-$VERSION.tar.gz \\\n    --transform=\"s,^.,$PACKAGE-$VERSION,\" --verbose .\n\n"
  },
  {
    "path": "external/QtFindReplaceDialog/qtfindreplacedialog.pri",
    "content": "!contains( included_modules, QtFindReplaceDialog/qtfindreplacedialog.pri) {\n\t\tincluded_modules += QtFindReplaceDialog/qtfindreplacedialog.pri\n\nINCLUDEPATH += $$PWD/dialogs\nDEPENDPATH += $$PWD/dialogs\n\nQtFindReplaceDialog-uselib:!QtFindReplaceDialog-buildlib {\n    LIBS += -L$$QTFINDREPLACEDIALOG_LIBDIR -l$$QTFINDREPLACEDIALOG_LIBNAME\n} else {\n\tSOURCES +=\t$$PWD/dialogs/finddialog.cpp \\\n\t\t\t\t$$PWD/dialogs/findform.cpp \\\n\t\t\t\t$$PWD/dialogs/findreplaceform.cpp \\\n\t\t\t\t$$PWD/dialogs/findreplacedialog.cpp\n\n\tHEADERS +=\t$$PWD/dialogs/finddialog.h \\\n\t\t\t\t$$PWD/dialogs/findform.h \\\n\t\t\t\t$$PWD/dialogs/findreplaceform.h \\\n\t\t\t\t$$PWD/dialogs/findreplacedialog.h \\\n\t\t\t\t$$PWD/dialogs/findreplace_global.h\n\n\tFORMS +=\t$$PWD/dialogs/findreplaceform.ui \\\n\t\t\t\t$$PWD/dialogs/findreplacedialog.ui\n\n\t!QtFindReplaceDialog-buildlib:DEFINES += \"FINDREPLACESHARED_EXPORT=\"\n}\n\n}\n"
  },
  {
    "path": "external/QtFindReplaceDialog/qtfindreplacedialog.pro",
    "content": "#-------------------------------------------------\n#\n# Project created by QtCreator 2009-11-07T11:36:25\n#\n#-------------------------------------------------\n\ninclude (doc/doc.pro)\n\nTEMPLATE = subdirs\n\nSUBDIRS = dialogs examples\n\nCONFIG += ordered recursive\n\nOTHER_FILES = TODO \\\n    COPYING README.txt\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.appveyor.yml",
    "content": "version: 1.0.{build}\nimage:\n- Visual Studio 2017\ntest: off\nskip_branch_with_pr: true\nbuild:\n  parallel: true\nplatform:\n- x86\nenvironment:\n  matrix:\n  - PYTHON: 36\n    CONFIG: Debug\ninstall:\n- ps: |\n    $env:CMAKE_GENERATOR = \"Visual Studio 15 2017\"\n    if ($env:PLATFORM -eq \"x64\") { $env:PYTHON = \"$env:PYTHON-x64\" }\n    $env:PATH = \"C:\\Python$env:PYTHON\\;C:\\Python$env:PYTHON\\Scripts\\;$env:PATH\"\n    python -W ignore -m pip install --upgrade pip wheel\n    python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout\n- ps: |\n    Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'\n    7z x eigen-3.3.7.zip -y > $null\n    $env:CMAKE_INCLUDE_PATH = \"eigen-3.3.7;$env:CMAKE_INCLUDE_PATH\"\nbuild_script:\n- cmake -G \"%CMAKE_GENERATOR%\" -A \"%CMAKE_ARCH%\"\n    -DCMAKE_CXX_STANDARD=14\n    -DPYBIND11_WERROR=ON\n    -DDOWNLOAD_CATCH=ON\n    -DCMAKE_SUPPRESS_REGENERATION=1\n    .\n- set MSBuildLogger=\"C:\\Program Files\\AppVeyor\\BuildAgent\\Appveyor.MSBuildLogger.dll\"\n- cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%\n- cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%\non_failure: if exist \"tests\\test_cmake_build\" type tests\\test_cmake_build\\*.log*\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.clang-format",
    "content": "---\n# See all possible options and defaults with:\n# clang-format --style=llvm --dump-config\nBasedOnStyle: LLVM\nAccessModifierOffset: -4\nAllowShortLambdasOnASingleLine: true\nAlwaysBreakTemplateDeclarations: Yes\nBinPackArguments: false\nBinPackParameters: false\nBreakBeforeBinaryOperators: All\nBreakConstructorInitializers: BeforeColon\nColumnLimit: 99\nCommentPragmas: 'NOLINT:.*|^ IWYU pragma:'\nIncludeBlocks: Regroup\nIndentCaseLabels: true\nIndentPPDirectives: AfterHash\nIndentWidth: 4\nLanguage: Cpp\nSpaceAfterCStyleCast: true\nStandard: Cpp11\nStatementMacros: ['PyObject_HEAD']\nTabWidth: 4\nIncludeCategories:\n  - Regex:           '<pybind11/.*'\n    Priority:        -1\n  - Regex:           'pybind11.h\"$'\n    Priority:        1\n  - Regex:           '^\".*/?detail/'\n    Priority:        1\n    SortPriority:    2\n  - Regex:           '^\"'\n    Priority:        1\n    SortPriority:    3\n  - Regex:           '<[[:alnum:]._]+>'\n    Priority:        4\n  - Regex:           '.*'\n    Priority:        5\n...\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.clang-tidy",
    "content": "FormatStyle: file\n\nChecks: |\n  *bugprone*,\n  *performance*,\n  clang-analyzer-optin.cplusplus.VirtualCall,\n  clang-analyzer-optin.performance.Padding,\n  cppcoreguidelines-init-variables,\n  cppcoreguidelines-prefer-member-initializer,\n  cppcoreguidelines-pro-type-static-cast-downcast,\n  cppcoreguidelines-slicing,\n  google-explicit-constructor,\n  llvm-namespace-comment,\n  misc-definitions-in-headers,\n  misc-misplaced-const,\n  misc-non-copyable-objects,\n  misc-static-assert,\n  misc-throw-by-value-catch-by-reference,\n  misc-uniqueptr-reset-release,\n  misc-unused-parameters,\n  modernize-avoid-bind,\n  modernize-loop-convert,\n  modernize-make-shared,\n  modernize-redundant-void-arg,\n  modernize-replace-auto-ptr,\n  modernize-replace-disallow-copy-and-assign-macro,\n  modernize-replace-random-shuffle,\n  modernize-shrink-to-fit,\n  modernize-use-auto,\n  modernize-use-bool-literals,\n  modernize-use-default-member-init,\n  modernize-use-emplace,\n  modernize-use-equals-default,\n  modernize-use-equals-delete,\n  modernize-use-noexcept,\n  modernize-use-nullptr,\n  modernize-use-override,\n  modernize-use-using,\n  readability-avoid-const-params-in-decls,\n  readability-braces-around-statements,\n  readability-const-return-type,\n  readability-container-size-empty,\n  readability-delete-null-pointer,\n  readability-else-after-return,\n  readability-implicit-bool-conversion,\n  readability-inconsistent-declaration-parameter-name,\n  readability-make-member-function-const,\n  readability-misplaced-array-index,\n  readability-non-const-parameter,\n  readability-qualified-auto,\n  readability-redundant-function-ptr-dereference,\n  readability-redundant-smartptr-get,\n  readability-redundant-string-cstr,\n  readability-simplify-subscript-expr,\n  readability-static-accessed-through-instance,\n  readability-static-definition-in-anonymous-namespace,\n  readability-string-compare,\n  readability-suspicious-call-argument,\n  readability-uniqueptr-delete-release,\n  -bugprone-easily-swappable-parameters,\n  -bugprone-exception-escape,\n  -bugprone-reserved-identifier,\n  -bugprone-unused-raii,\n\nCheckOptions:\n- key:             modernize-use-equals-default.IgnoreMacros\n  value:           false\n- key:             performance-for-range-copy.WarnOnAllAutoCopies\n  value:           true\n- key:             performance-inefficient-string-concatenation.StrictMode\n  value:           true\n- key:             performance-unnecessary-value-param.AllowedTypes\n  value:           'exception_ptr$;'\n- key:             readability-implicit-bool-conversion.AllowPointerConditions\n  value:           true\n\nHeaderFilterRegex: 'pybind11/.*h'\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.cmake-format.yaml",
    "content": "parse:\n  additional_commands:\n    pybind11_add_module:\n      flags:\n        - THIN_LTO\n        - MODULE\n        - SHARED\n        - NO_EXTRAS\n        - EXCLUDE_FROM_ALL\n        - SYSTEM\n\nformat:\n  line_width: 99\n  tab_size: 2\n\n  # If an argument group contains more than this many sub-groups\n  # (parg or kwarg groups) then force it to a vertical layout.\n  max_subgroups_hwrap: 2\n\n  # If a positional argument group contains more than this many\n  # arguments, then force it to a vertical layout.\n  max_pargs_hwrap: 6\n\n  # If a cmdline positional group consumes more than this many\n  # lines without nesting, then invalidate the layout (and nest)\n  max_rows_cmdline: 2\n  separate_ctrl_name_with_space: false\n  separate_fn_name_with_space: false\n  dangle_parens: false\n\n  # If the trailing parenthesis must be 'dangled' on its on\n  # 'line, then align it to this reference: `prefix`: the start'\n  # 'of the statement,  `prefix-indent`: the start of the'\n  # 'statement, plus one indentation  level, `child`: align to'\n  # the column of the arguments\n  dangle_align: prefix\n  # If the statement spelling length (including space and\n  # parenthesis) is smaller than this amount, then force reject\n  # nested layouts.\n  min_prefix_chars: 4\n\n  # If the statement spelling length (including space and\n  # parenthesis) is larger than the tab width by more than this\n  # amount, then force reject un-nested layouts.\n  max_prefix_chars: 10\n\n  # If a candidate layout is wrapped horizontally but it exceeds\n  # this many lines, then reject the layout.\n  max_lines_hwrap: 2\n\n  line_ending: unix\n\n  # Format command names consistently as 'lower' or 'upper' case\n  command_case: canonical\n\n  # Format keywords consistently as 'lower' or 'upper' case\n  # unchanged is valid too\n  keyword_case: 'upper'\n\n  # A list of command names which should always be wrapped\n  always_wrap: []\n\n  # If true, the argument lists which are known to be sortable\n  # will be sorted lexicographically\n  enable_sort: true\n\n  # If true, the parsers may infer whether or not an argument\n  # list is sortable (without annotation).\n  autosort: false\n\n# Causes a few issues - can be solved later, possibly.\nmarkup:\n  enable_markup: false\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.codespell-ignore-lines",
    "content": "template <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>\n    template <typename ThisT>\n        auto &this_ = static_cast<ThisT &>(*this);\n                if (load_impl<ThisT>(temp, false)) {\n        ssize_t nd = 0;\n        auto trivial = broadcast(buffers, nd, shape);\n        auto ndim = (size_t) nd;\n    int nd;\n    ssize_t ndim() const { return detail::array_proxy(m_ptr)->nd; }\n        using op = op_impl<id, ot, Base, L_type, R_type>;\ntemplate <op_id id, op_type ot, typename L, typename R>\n    template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>\n    class_ &def(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {\n    class_ &def_cast(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {\n@pytest.mark.parametrize(\"access\", [\"ro\", \"rw\", \"static_ro\", \"static_rw\"])\nstruct IntStruct {\n    explicit IntStruct(int v) : value(v){};\n    ~IntStruct() { value = -value; }\n    IntStruct(const IntStruct &) = default;\n    IntStruct &operator=(const IntStruct &) = default;\n    py::class_<IntStruct>(m, \"IntStruct\").def(py::init([](const int i) { return IntStruct(i); }));\n    py::implicitly_convertible<int, IntStruct>();\n    m.def(\"test\", [](int expected, const IntStruct &in) {\n        [](int expected, const IntStruct &in) {\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.gitignore",
    "content": "CMakeCache.txt\nCMakeFiles\nMakefile\ncmake_install.cmake\ncmake_uninstall.cmake\n.DS_Store\n*.so\n*.pyd\n*.dll\n*.sln\n*.sdf\n*.opensdf\n*.vcxproj\n*.vcxproj.user\n*.filters\nexample.dir\nWin32\nx64\nRelease\nDebug\n.vs\nCTestTestfile.cmake\nTesting\nautogen\nMANIFEST\n/.ninja_*\n/*.ninja\n/docs/.build\n*.py[co]\n*.egg-info\n*~\n.*.swp\n.DS_Store\n/dist\n/*build*\n.cache/\nsosize-*.txt\npybind11Config*.cmake\npybind11Targets.cmake\n/*env*\n/.vscode\n/pybind11/include/*\n/pybind11/share/*\n/docs/_build/*\n.ipynb_checkpoints/\ntests/main.cpp\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/.readthedocs.yml",
    "content": "python:\n  version: 3\nrequirements_file: docs/requirements.txt\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/CMakeLists.txt",
    "content": "# CMakeLists.txt -- Build system for the pybind11 modules\n#\n# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\ncmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.22)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.22)\nendif()\n\n# Avoid infinite recursion if tests include this as a subdirectory\nif(DEFINED PYBIND11_MASTER_PROJECT)\n  return()\nendif()\n\n# Extract project version from source\nfile(STRINGS \"${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h\"\n     pybind11_version_defines REGEX \"#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) \")\n\nforeach(ver ${pybind11_version_defines})\n  if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])\n    set(PYBIND11_VERSION_${CMAKE_MATCH_1} \"${CMAKE_MATCH_2}\")\n  endif()\nendforeach()\n\nif(PYBIND11_VERSION_PATCH MATCHES [[\\.([a-zA-Z0-9]+)$]])\n  set(pybind11_VERSION_TYPE \"${CMAKE_MATCH_1}\")\nendif()\nstring(REGEX MATCH \"^[0-9]+\" PYBIND11_VERSION_PATCH \"${PYBIND11_VERSION_PATCH}\")\n\nproject(\n  pybind11\n  LANGUAGES CXX\n  VERSION \"${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}\")\n\n# Standard includes\ninclude(GNUInstallDirs)\ninclude(CMakePackageConfigHelpers)\ninclude(CMakeDependentOption)\n\nif(NOT pybind11_FIND_QUIETLY)\n  message(STATUS \"pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}\")\nendif()\n\n# Check if pybind11 is being used directly or via add_subdirectory\nif(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)\n  ### Warn if not an out-of-source builds\n  if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n    set(lines\n        \"You are building in-place. If that is not what you intended to \"\n        \"do, you can clean the source directory with:\\n\"\n        \"rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake \"\n        \"pybind11ConfigVersion.cmake tests/CMakeFiles/\\n\")\n    message(AUTHOR_WARNING ${lines})\n  endif()\n\n  set(PYBIND11_MASTER_PROJECT ON)\n\n  if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)\n    # Bug in macOS CMake < 3.7 is unable to download catch\n    message(WARNING \"CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended\")\n  elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)\n    # Only tested with 3.8+ in CI.\n    message(WARNING \"CMAKE 3.8+ tested on Windows, previous versions untested\")\n  endif()\n\n  message(STATUS \"CMake ${CMAKE_VERSION}\")\n\n  if(CMAKE_CXX_STANDARD)\n    set(CMAKE_CXX_EXTENSIONS OFF)\n    set(CMAKE_CXX_STANDARD_REQUIRED ON)\n  endif()\n\n  set(pybind11_system \"\")\n\n  set_property(GLOBAL PROPERTY USE_FOLDERS ON)\nelse()\n  set(PYBIND11_MASTER_PROJECT OFF)\n  set(pybind11_system SYSTEM)\nendif()\n\n# Options\noption(PYBIND11_INSTALL \"Install pybind11 header files?\" ${PYBIND11_MASTER_PROJECT})\noption(PYBIND11_TEST \"Build pybind11 test suite?\" ${PYBIND11_MASTER_PROJECT})\noption(PYBIND11_NOPYTHON \"Disable search for Python\" OFF)\noption(PYBIND11_SIMPLE_GIL_MANAGEMENT\n       \"Use simpler GIL management logic that does not support disassociation\" OFF)\nset(PYBIND11_INTERNALS_VERSION\n    \"\"\n    CACHE STRING \"Override the ABI version, may be used to enable the unstable ABI.\")\n\nif(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n  add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)\nendif()\n\ncmake_dependent_option(\n  USE_PYTHON_INCLUDE_DIR\n  \"Install pybind11 headers in Python include directory instead of default installation prefix\"\n  OFF \"PYBIND11_INSTALL\" OFF)\n\ncmake_dependent_option(PYBIND11_FINDPYTHON \"Force new FindPython\" OFF\n                       \"NOT CMAKE_VERSION VERSION_LESS 3.12\" OFF)\n\n# NB: when adding a header don't forget to also add it to setup.py\nset(PYBIND11_HEADERS\n    include/pybind11/detail/class.h\n    include/pybind11/detail/common.h\n    include/pybind11/detail/descr.h\n    include/pybind11/detail/init.h\n    include/pybind11/detail/internals.h\n    include/pybind11/detail/type_caster_base.h\n    include/pybind11/detail/typeid.h\n    include/pybind11/attr.h\n    include/pybind11/buffer_info.h\n    include/pybind11/cast.h\n    include/pybind11/chrono.h\n    include/pybind11/common.h\n    include/pybind11/complex.h\n    include/pybind11/options.h\n    include/pybind11/eigen.h\n    include/pybind11/eigen/matrix.h\n    include/pybind11/eigen/tensor.h\n    include/pybind11/embed.h\n    include/pybind11/eval.h\n    include/pybind11/gil.h\n    include/pybind11/iostream.h\n    include/pybind11/functional.h\n    include/pybind11/numpy.h\n    include/pybind11/operators.h\n    include/pybind11/pybind11.h\n    include/pybind11/pytypes.h\n    include/pybind11/stl.h\n    include/pybind11/stl_bind.h\n    include/pybind11/stl/filesystem.h)\n\n# Compare with grep and warn if mismatched\nif(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)\n  file(\n    GLOB_RECURSE _pybind11_header_check\n    LIST_DIRECTORIES false\n    RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    CONFIGURE_DEPENDS \"include/pybind11/*.h\")\n  set(_pybind11_here_only ${PYBIND11_HEADERS})\n  set(_pybind11_disk_only ${_pybind11_header_check})\n  list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})\n  list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})\n  if(_pybind11_here_only)\n    message(AUTHOR_WARNING \"PYBIND11_HEADERS has extra files:\" ${_pybind11_here_only})\n  endif()\n  if(_pybind11_disk_only)\n    message(AUTHOR_WARNING \"PYBIND11_HEADERS is missing files:\" ${_pybind11_disk_only})\n  endif()\nendif()\n\n# CMake 3.12 added list(TRANSFORM <list> PREPEND\n# But we can't use it yet\nstring(REPLACE \"include/\" \"${CMAKE_CURRENT_SOURCE_DIR}/include/\" PYBIND11_HEADERS\n               \"${PYBIND11_HEADERS}\")\n\n# Cache variable so this can be used in parent projects\nset(pybind11_INCLUDE_DIR\n    \"${CMAKE_CURRENT_LIST_DIR}/include\"\n    CACHE INTERNAL \"Directory where pybind11 headers are located\")\n\n# Backward compatible variable for add_subdirectory mode\nif(NOT PYBIND11_MASTER_PROJECT)\n  set(PYBIND11_INCLUDE_DIR\n      \"${pybind11_INCLUDE_DIR}\"\n      CACHE INTERNAL \"\")\nendif()\n\n# Note: when creating targets, you cannot use if statements at configure time -\n# you need generator expressions, because those will be placed in the target file.\n# You can also place ifs *in* the Config.in, but not here.\n\n# This section builds targets, but does *not* touch Python\n# Non-IMPORT targets cannot be defined twice\nif(NOT TARGET pybind11_headers)\n  # Build the headers-only target (no Python included):\n  # (long name used here to keep this from clashing in subdirectory mode)\n  add_library(pybind11_headers INTERFACE)\n  add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target\n  add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember\n\n  target_include_directories(\n    pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>\n                                                  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)\n\n  target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals\n                                                     cxx_right_angle_brackets)\n  if(NOT \"${PYBIND11_INTERNALS_VERSION}\" STREQUAL \"\")\n    target_compile_definitions(\n      pybind11_headers INTERFACE \"PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}\")\n  endif()\nelse()\n  # It is invalid to install a target twice, too.\n  set(PYBIND11_INSTALL OFF)\nendif()\n\ninclude(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake\")\n# https://github.com/jtojnar/cmake-snips/#concatenating-paths-when-building-pkg-config-files\n# TODO: cmake 3.20 adds the cmake_path() function, which obsoletes this snippet\ninclude(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/JoinPaths.cmake\")\n\n# Relative directory setting\nif(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)\n  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})\nelseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)\n  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})\nendif()\n\nif(PYBIND11_INSTALL)\n  install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})\n  set(PYBIND11_CMAKECONFIG_INSTALL_DIR\n      \"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}\"\n      CACHE STRING \"install path for pybind11Config.cmake\")\n\n  if(IS_ABSOLUTE \"${CMAKE_INSTALL_INCLUDEDIR}\")\n    set(pybind11_INCLUDEDIR \"${CMAKE_INSTALL_FULL_INCLUDEDIR}\")\n  else()\n    set(pybind11_INCLUDEDIR \"\\$\\{PACKAGE_PREFIX_DIR\\}/${CMAKE_INSTALL_INCLUDEDIR}\")\n  endif()\n\n  configure_package_config_file(\n    tools/${PROJECT_NAME}Config.cmake.in \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake\"\n    INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  if(CMAKE_VERSION VERSION_LESS 3.14)\n    # Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does\n    # not depend on architecture specific settings or libraries.\n    set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})\n    unset(CMAKE_SIZEOF_VOID_P)\n\n    write_basic_package_version_file(\n      ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n      VERSION ${PROJECT_VERSION}\n      COMPATIBILITY AnyNewerVersion)\n\n    set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})\n  else()\n    # CMake 3.14+ natively supports header-only libraries\n    write_basic_package_version_file(\n      ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n      VERSION ${PROJECT_VERSION}\n      COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)\n  endif()\n\n  install(\n    FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake\n          ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n          tools/FindPythonLibsNew.cmake\n          tools/pybind11Common.cmake\n          tools/pybind11Tools.cmake\n          tools/pybind11NewTools.cmake\n    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  if(NOT PYBIND11_EXPORT_NAME)\n    set(PYBIND11_EXPORT_NAME \"${PROJECT_NAME}Targets\")\n  endif()\n\n  install(TARGETS pybind11_headers EXPORT \"${PYBIND11_EXPORT_NAME}\")\n\n  install(\n    EXPORT \"${PYBIND11_EXPORT_NAME}\"\n    NAMESPACE \"pybind11::\"\n    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  # pkg-config support\n  if(NOT prefix_for_pc_file)\n    set(prefix_for_pc_file \"${CMAKE_INSTALL_PREFIX}\")\n  endif()\n  join_paths(includedir_for_pc_file \"\\${prefix}\" \"${CMAKE_INSTALL_INCLUDEDIR}\")\n  configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11.pc.in\"\n                 \"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc\" @ONLY)\n  install(FILES \"${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc\"\n          DESTINATION \"${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/\")\n\n  # Uninstall target\n  if(PYBIND11_MASTER_PROJECT)\n    configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in\"\n                   \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\" IMMEDIATE @ONLY)\n\n    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P\n                                        ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)\n  endif()\nendif()\n\n# BUILD_TESTING takes priority, but only if this is the master project\nif(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)\n  if(BUILD_TESTING)\n    if(_pybind11_nopython)\n      message(FATAL_ERROR \"Cannot activate tests in NOPYTHON mode\")\n    else()\n      add_subdirectory(tests)\n    endif()\n  endif()\nelse()\n  if(PYBIND11_TEST)\n    if(_pybind11_nopython)\n      message(FATAL_ERROR \"Cannot activate tests in NOPYTHON mode\")\n    else()\n      add_subdirectory(tests)\n    endif()\n  endif()\nendif()\n\n# Better symmetry with find_package(pybind11 CONFIG) mode.\nif(NOT PYBIND11_MASTER_PROJECT)\n  set(pybind11_FOUND\n      TRUE\n      CACHE INTERNAL \"True if pybind11 and all required components found on the system\")\nendif()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/LICENSE",
    "content": "Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n   may be used to endorse or promote products derived from this software\n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nPlease also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of\nexternal contributions to this project including patches, pull requests, etc.\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/MANIFEST.in",
    "content": "recursive-include pybind11/include/pybind11 *.h\nrecursive-include pybind11 *.py\nrecursive-include pybind11 py.typed\ninclude pybind11/share/cmake/pybind11/*.cmake\ninclude LICENSE README.rst pyproject.toml setup.py setup.cfg\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/README.rst",
    "content": ".. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png\n   :alt: pybind11 logo\n\n**pybind11 — Seamless operability between C++11 and Python**\n\n|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|\n\n|Repology| |PyPI package| |Conda-forge| |Python Versions|\n\n`Setuptools example <https://github.com/pybind/python_example>`_\n• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_\n• `CMake example <https://github.com/pybind/cmake_example>`_\n\n.. start\n\n\n**pybind11** is a lightweight header-only library that exposes C++ types\nin Python and vice versa, mainly to create Python bindings of existing\nC++ code. Its goals and syntax are similar to the excellent\n`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_\nlibrary by David Abrahams: to minimize boilerplate code in traditional\nextension modules by inferring type information using compile-time\nintrospection.\n\nThe main issue with Boost.Python—and the reason for creating such a\nsimilar project—is Boost. Boost is an enormously large and complex suite\nof utility libraries that works with almost every C++ compiler in\nexistence. This compatibility has its cost: arcane template tricks and\nworkarounds are necessary to support the oldest and buggiest of compiler\nspecimens. Now that C++11-compatible compilers are widely available,\nthis heavy machinery has become an excessively large and unnecessary\ndependency.\n\nThink of this library as a tiny self-contained version of Boost.Python\nwith everything stripped away that isn't relevant for binding\ngeneration. Without comments, the core header files only require ~4K\nlines of code and depend on Python (3.6+, or PyPy) and the C++\nstandard library. This compact implementation was possible thanks to\nsome of the new C++11 language features (specifically: tuples, lambda\nfunctions and variadic templates). Since its creation, this library has\ngrown beyond Boost.Python in many ways, leading to dramatically simpler\nbinding code in many common situations.\n\nTutorial and reference documentation is provided at\n`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.\nA PDF version of the manual is available\n`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.\nAnd the source code is always available at\n`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.\n\n\nCore features\n-------------\n\n\npybind11 can map the following core C++ features to Python:\n\n- Functions accepting and returning custom data structures per value,\n  reference, or pointer\n- Instance methods and static methods\n- Overloaded functions\n- Instance attributes and static attributes\n- Arbitrary exception types\n- Enumerations\n- Callbacks\n- Iterators and ranges\n- Custom operators\n- Single and multiple inheritance\n- STL data structures\n- Smart pointers with reference counting like ``std::shared_ptr``\n- Internal references with correct reference counting\n- C++ classes with virtual (and pure virtual) methods can be extended\n  in Python\n\nGoodies\n-------\n\nIn addition to the core functionality, pybind11 provides some extra\ngoodies:\n\n- Python 3.6+, and PyPy3 7.3 are supported with an implementation-agnostic\n  interface (pybind11 2.9 was the last version to support Python 2 and 3.5).\n\n- It is possible to bind C++11 lambda functions with captured\n  variables. The lambda capture data is stored inside the resulting\n  Python function object.\n\n- pybind11 uses C++11 move constructors and move assignment operators\n  whenever possible to efficiently transfer custom data types.\n\n- It's easy to expose the internal storage of custom data types through\n  Pythons' buffer protocols. This is handy e.g. for fast conversion\n  between C++ matrix classes like Eigen and NumPy without expensive\n  copy operations.\n\n- pybind11 can automatically vectorize functions so that they are\n  transparently applied to all entries of one or more NumPy array\n  arguments.\n\n- Python's slice-based access and assignment operations can be\n  supported with just a few lines of code.\n\n- Everything is contained in just a few header files; there is no need\n  to link against any additional libraries.\n\n- Binaries are generally smaller by a factor of at least 2 compared to\n  equivalent bindings generated by Boost.Python. A recent pybind11\n  conversion of PyRosetta, an enormous Boost.Python binding project,\n  `reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_\n  a binary size reduction of **5.4x** and compile time reduction by\n  **5.8x**.\n\n- Function signatures are precomputed at compile time (using\n  ``constexpr``), leading to smaller binaries.\n\n- With little extra effort, C++ types can be pickled and unpickled\n  similar to regular Python objects.\n\nSupported compilers\n-------------------\n\n1. Clang/LLVM 3.3 or newer (for Apple Xcode's clang, this is 5.0.0 or\n   newer)\n2. GCC 4.8 or newer\n3. Microsoft Visual Studio 2017 or newer\n4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)\n5. Cygwin/GCC (previously tested on 2.5.1)\n6. NVCC (CUDA 11.0 tested in CI)\n7. NVIDIA PGI (20.9 tested in CI)\n\nAbout\n-----\n\nThis project was created by `Wenzel\nJakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or\nimprovements to the code were contributed by Jonas Adler, Lori A. Burns,\nSylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel\nHuebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,\nDean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim\nSchellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.\n\nWe thank Google for a generous financial contribution to the continuous\nintegration infrastructure used by this project.\n\n\nContributing\n~~~~~~~~~~~~\n\nSee the `contributing\nguide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_\nfor information on building and contributing to pybind11.\n\nLicense\n~~~~~~~\n\npybind11 is provided under a BSD-style license that can be found in the\n`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_\nfile. By using, distributing, or contributing to this project, you agree\nto the terms and conditions of this license.\n\n.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest\n   :target: http://pybind11.readthedocs.org/en/latest\n.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg\n   :target: http://pybind11.readthedocs.org/en/stable\n.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg\n   :target: https://gitter.im/pybind/Lobby\n.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg\n   :target: https://github.com/pybind/pybind11/actions\n.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true\n   :target: https://ci.appveyor.com/project/wjakob/pybind11\n.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg\n   :target: https://pypi.org/project/pybind11/\n.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg\n   :target: https://github.com/conda-forge/pybind11-feedstock\n.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg\n   :target: https://repology.org/project/python:pybind11/versions\n.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg\n   :target: https://pypi.org/project/pybind11/\n.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github\n   :target: https://github.com/pybind/pybind11/discussions\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/attr.h",
    "content": "/*\n    pybind11/attr.h: Infrastructure for processing custom\n    type and function attributes\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"cast.h\"\n\n#include <functional>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n/// \\addtogroup annotations\n/// @{\n\n/// Annotation for methods\nstruct is_method {\n    handle class_;\n    explicit is_method(const handle &c) : class_(c) {}\n};\n\n/// Annotation for operators\nstruct is_operator {};\n\n/// Annotation for classes that cannot be subclassed\nstruct is_final {};\n\n/// Annotation for parent scope\nstruct scope {\n    handle value;\n    explicit scope(const handle &s) : value(s) {}\n};\n\n/// Annotation for documentation\nstruct doc {\n    const char *value;\n    explicit doc(const char *value) : value(value) {}\n};\n\n/// Annotation for function names\nstruct name {\n    const char *value;\n    explicit name(const char *value) : value(value) {}\n};\n\n/// Annotation indicating that a function is an overload associated with a given \"sibling\"\nstruct sibling {\n    handle value;\n    explicit sibling(const handle &value) : value(value.ptr()) {}\n};\n\n/// Annotation indicating that a class derives from another given type\ntemplate <typename T>\nstruct base {\n\n    PYBIND11_DEPRECATED(\n        \"base<T>() was deprecated in favor of specifying 'T' as a template argument to class_\")\n    base() = default;\n};\n\n/// Keep patient alive while nurse lives\ntemplate <size_t Nurse, size_t Patient>\nstruct keep_alive {};\n\n/// Annotation indicating that a class is involved in a multiple inheritance relationship\nstruct multiple_inheritance {};\n\n/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class\nstruct dynamic_attr {};\n\n/// Annotation which enables the buffer protocol for a type\nstruct buffer_protocol {};\n\n/// Annotation which requests that a special metaclass is created for a type\nstruct metaclass {\n    handle value;\n\n    PYBIND11_DEPRECATED(\"py::metaclass() is no longer required. It's turned on by default now.\")\n    metaclass() = default;\n\n    /// Override pybind11's default metaclass\n    explicit metaclass(handle value) : value(value) {}\n};\n\n/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that\n/// may be used to customize the Python type.\n///\n/// The callback is invoked immediately before `PyType_Ready`.\n///\n/// Note: This is an advanced interface, and uses of it may require changes to\n/// work with later versions of pybind11.  You may wish to consult the\n/// implementation of `make_new_python_type` in `detail/classes.h` to understand\n/// the context in which the callback will be run.\nstruct custom_type_setup {\n    using callback = std::function<void(PyHeapTypeObject *heap_type)>;\n\n    explicit custom_type_setup(callback value) : value(std::move(value)) {}\n\n    callback value;\n};\n\n/// Annotation that marks a class as local to the module:\nstruct module_local {\n    const bool value;\n    constexpr explicit module_local(bool v = true) : value(v) {}\n};\n\n/// Annotation to mark enums as an arithmetic type\nstruct arithmetic {};\n\n/// Mark a function for addition at the beginning of the existing overload chain instead of the end\nstruct prepend {};\n\n/** \\rst\n    A call policy which places one or more guard variables (``Ts...``) around the function call.\n\n    For example, this definition:\n\n    .. code-block:: cpp\n\n        m.def(\"foo\", foo, py::call_guard<T>());\n\n    is equivalent to the following pseudocode:\n\n    .. code-block:: cpp\n\n        m.def(\"foo\", [](args...) {\n            T scope_guard;\n            return foo(args...); // forwarded arguments\n        });\n \\endrst */\ntemplate <typename... Ts>\nstruct call_guard;\n\ntemplate <>\nstruct call_guard<> {\n    using type = detail::void_type;\n};\n\ntemplate <typename T>\nstruct call_guard<T> {\n    static_assert(std::is_default_constructible<T>::value,\n                  \"The guard type must be default constructible\");\n\n    using type = T;\n};\n\ntemplate <typename T, typename... Ts>\nstruct call_guard<T, Ts...> {\n    struct type {\n        T guard{}; // Compose multiple guard types with left-to-right default-constructor order\n        typename call_guard<Ts...>::type next{};\n    };\n};\n\n/// @} annotations\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n/* Forward declarations */\nenum op_id : int;\nenum op_type : int;\nstruct undefined_t;\ntemplate <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>\nstruct op_;\nvoid keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);\n\n/// Internal data structure which holds metadata about a keyword argument\nstruct argument_record {\n    const char *name;  ///< Argument name\n    const char *descr; ///< Human-readable version of the argument value\n    handle value;      ///< Associated Python object\n    bool convert : 1;  ///< True if the argument is allowed to convert when loading\n    bool none : 1;     ///< True if None is allowed when loading\n\n    argument_record(const char *name, const char *descr, handle value, bool convert, bool none)\n        : name(name), descr(descr), value(value), convert(convert), none(none) {}\n};\n\n/// Internal data structure which holds metadata about a bound function (signature, overloads,\n/// etc.)\nstruct function_record {\n    function_record()\n        : is_constructor(false), is_new_style_constructor(false), is_stateless(false),\n          is_operator(false), is_method(false), has_args(false), has_kwargs(false),\n          prepend(false) {}\n\n    /// Function name\n    char *name = nullptr; /* why no C++ strings? They generate heavier code.. */\n\n    // User-specified documentation string\n    char *doc = nullptr;\n\n    /// Human-readable version of the function signature\n    char *signature = nullptr;\n\n    /// List of registered keyword arguments\n    std::vector<argument_record> args;\n\n    /// Pointer to lambda function which converts arguments and performs the actual call\n    handle (*impl)(function_call &) = nullptr;\n\n    /// Storage for the wrapped function pointer and captured data, if any\n    void *data[3] = {};\n\n    /// Pointer to custom destructor for 'data' (if needed)\n    void (*free_data)(function_record *ptr) = nullptr;\n\n    /// Return value policy associated with this function\n    return_value_policy policy = return_value_policy::automatic;\n\n    /// True if name == '__init__'\n    bool is_constructor : 1;\n\n    /// True if this is a new-style `__init__` defined in `detail/init.h`\n    bool is_new_style_constructor : 1;\n\n    /// True if this is a stateless function pointer\n    bool is_stateless : 1;\n\n    /// True if this is an operator (__add__), etc.\n    bool is_operator : 1;\n\n    /// True if this is a method\n    bool is_method : 1;\n\n    /// True if the function has a '*args' argument\n    bool has_args : 1;\n\n    /// True if the function has a '**kwargs' argument\n    bool has_kwargs : 1;\n\n    /// True if this function is to be inserted at the beginning of the overload resolution chain\n    bool prepend : 1;\n\n    /// Number of arguments (including py::args and/or py::kwargs, if present)\n    std::uint16_t nargs;\n\n    /// Number of leading positional arguments, which are terminated by a py::args or py::kwargs\n    /// argument or by a py::kw_only annotation.\n    std::uint16_t nargs_pos = 0;\n\n    /// Number of leading arguments (counted in `nargs`) that are positional-only\n    std::uint16_t nargs_pos_only = 0;\n\n    /// Python method object\n    PyMethodDef *def = nullptr;\n\n    /// Python handle to the parent scope (a class or a module)\n    handle scope;\n\n    /// Python handle to the sibling function representing an overload chain\n    handle sibling;\n\n    /// Pointer to next overload\n    function_record *next = nullptr;\n};\n\n/// Special data structure which (temporarily) holds metadata about a bound class\nstruct type_record {\n    PYBIND11_NOINLINE type_record()\n        : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),\n          default_holder(true), module_local(false), is_final(false) {}\n\n    /// Handle to the parent scope\n    handle scope;\n\n    /// Name of the class\n    const char *name = nullptr;\n\n    // Pointer to RTTI type_info data structure\n    const std::type_info *type = nullptr;\n\n    /// How large is the underlying C++ type?\n    size_t type_size = 0;\n\n    /// What is the alignment of the underlying C++ type?\n    size_t type_align = 0;\n\n    /// How large is the type's holder?\n    size_t holder_size = 0;\n\n    /// The global operator new can be overridden with a class-specific variant\n    void *(*operator_new)(size_t) = nullptr;\n\n    /// Function pointer to class_<..>::init_instance\n    void (*init_instance)(instance *, const void *) = nullptr;\n\n    /// Function pointer to class_<..>::dealloc\n    void (*dealloc)(detail::value_and_holder &) = nullptr;\n\n    /// List of base classes of the newly created type\n    list bases;\n\n    /// Optional docstring\n    const char *doc = nullptr;\n\n    /// Custom metaclass (optional)\n    handle metaclass;\n\n    /// Custom type setup.\n    custom_type_setup::callback custom_type_setup_callback;\n\n    /// Multiple inheritance marker\n    bool multiple_inheritance : 1;\n\n    /// Does the class manage a __dict__?\n    bool dynamic_attr : 1;\n\n    /// Does the class implement the buffer protocol?\n    bool buffer_protocol : 1;\n\n    /// Is the default (unique_ptr) holder type used?\n    bool default_holder : 1;\n\n    /// Is the class definition local to the module shared object?\n    bool module_local : 1;\n\n    /// Is the class inheritable from python classes?\n    bool is_final : 1;\n\n    PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {\n        auto *base_info = detail::get_type_info(base, false);\n        if (!base_info) {\n            std::string tname(base.name());\n            detail::clean_type_id(tname);\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(name)\n                          + \"\\\" referenced unknown base type \\\"\" + tname + \"\\\"\");\n        }\n\n        if (default_holder != base_info->default_holder) {\n            std::string tname(base.name());\n            detail::clean_type_id(tname);\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(name) + \"\\\" \"\n                          + (default_holder ? \"does not have\" : \"has\")\n                          + \" a non-default holder type while its base \\\"\" + tname + \"\\\" \"\n                          + (base_info->default_holder ? \"does not\" : \"does\"));\n        }\n\n        bases.append((PyObject *) base_info->type);\n\n#if PY_VERSION_HEX < 0x030B0000\n        dynamic_attr |= base_info->type->tp_dictoffset != 0;\n#else\n        dynamic_attr |= (base_info->type->tp_flags & Py_TPFLAGS_MANAGED_DICT) != 0;\n#endif\n\n        if (caster) {\n            base_info->implicit_casts.emplace_back(type, caster);\n        }\n    }\n};\n\ninline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {\n    args.reserve(f.nargs);\n    args_convert.reserve(f.nargs);\n}\n\n/// Tag for a new-style `__init__` defined in `detail/init.h`\nstruct is_new_style_constructor {};\n\n/**\n * Partial template specializations to process custom attributes provided to\n * cpp_function_ and class_. These are either used to initialize the respective\n * fields in the type_record and function_record data structures or executed at\n * runtime to deal with custom call policies (e.g. keep_alive).\n */\ntemplate <typename T, typename SFINAE = void>\nstruct process_attribute;\n\ntemplate <typename T>\nstruct process_attribute_default {\n    /// Default implementation: do nothing\n    static void init(const T &, function_record *) {}\n    static void init(const T &, type_record *) {}\n    static void precall(function_call &) {}\n    static void postcall(function_call &, handle) {}\n};\n\n/// Process an attribute specifying the function's name\ntemplate <>\nstruct process_attribute<name> : process_attribute_default<name> {\n    static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }\n};\n\n/// Process an attribute specifying the function's docstring\ntemplate <>\nstruct process_attribute<doc> : process_attribute_default<doc> {\n    static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }\n};\n\n/// Process an attribute specifying the function's docstring (provided as a C-style string)\ntemplate <>\nstruct process_attribute<const char *> : process_attribute_default<const char *> {\n    static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }\n    static void init(const char *d, type_record *r) { r->doc = const_cast<char *>(d); }\n};\ntemplate <>\nstruct process_attribute<char *> : process_attribute<const char *> {};\n\n/// Process an attribute indicating the function's return value policy\ntemplate <>\nstruct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {\n    static void init(const return_value_policy &p, function_record *r) { r->policy = p; }\n};\n\n/// Process an attribute which indicates that this is an overloaded function associated with a\n/// given sibling\ntemplate <>\nstruct process_attribute<sibling> : process_attribute_default<sibling> {\n    static void init(const sibling &s, function_record *r) { r->sibling = s.value; }\n};\n\n/// Process an attribute which indicates that this function is a method\ntemplate <>\nstruct process_attribute<is_method> : process_attribute_default<is_method> {\n    static void init(const is_method &s, function_record *r) {\n        r->is_method = true;\n        r->scope = s.class_;\n    }\n};\n\n/// Process an attribute which indicates the parent scope of a method\ntemplate <>\nstruct process_attribute<scope> : process_attribute_default<scope> {\n    static void init(const scope &s, function_record *r) { r->scope = s.value; }\n};\n\n/// Process an attribute which indicates that this function is an operator\ntemplate <>\nstruct process_attribute<is_operator> : process_attribute_default<is_operator> {\n    static void init(const is_operator &, function_record *r) { r->is_operator = true; }\n};\n\ntemplate <>\nstruct process_attribute<is_new_style_constructor>\n    : process_attribute_default<is_new_style_constructor> {\n    static void init(const is_new_style_constructor &, function_record *r) {\n        r->is_new_style_constructor = true;\n    }\n};\n\ninline void check_kw_only_arg(const arg &a, function_record *r) {\n    if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\\0')) {\n        pybind11_fail(\"arg(): cannot specify an unnamed argument after a kw_only() annotation or \"\n                      \"args() argument\");\n    }\n}\n\ninline void append_self_arg_if_needed(function_record *r) {\n    if (r->is_method && r->args.empty()) {\n        r->args.emplace_back(\"self\", nullptr, handle(), /*convert=*/true, /*none=*/false);\n    }\n}\n\n/// Process a keyword argument attribute (*without* a default value)\ntemplate <>\nstruct process_attribute<arg> : process_attribute_default<arg> {\n    static void init(const arg &a, function_record *r) {\n        append_self_arg_if_needed(r);\n        r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);\n\n        check_kw_only_arg(a, r);\n    }\n};\n\n/// Process a keyword argument attribute (*with* a default value)\ntemplate <>\nstruct process_attribute<arg_v> : process_attribute_default<arg_v> {\n    static void init(const arg_v &a, function_record *r) {\n        if (r->is_method && r->args.empty()) {\n            r->args.emplace_back(\n                \"self\", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);\n        }\n\n        if (!a.value) {\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            std::string descr(\"'\");\n            if (a.name) {\n                descr += std::string(a.name) + \": \";\n            }\n            descr += a.type + \"'\";\n            if (r->is_method) {\n                if (r->name) {\n                    descr += \" in method '\" + (std::string) str(r->scope) + \".\"\n                             + (std::string) r->name + \"'\";\n                } else {\n                    descr += \" in method of '\" + (std::string) str(r->scope) + \"'\";\n                }\n            } else if (r->name) {\n                descr += \" in function '\" + (std::string) r->name + \"'\";\n            }\n            pybind11_fail(\"arg(): could not convert default argument \" + descr\n                          + \" into a Python object (type not registered yet?)\");\n#else\n            pybind11_fail(\"arg(): could not convert default argument \"\n                          \"into a Python object (type not registered yet?). \"\n                          \"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for \"\n                          \"more information.\");\n#endif\n        }\n        r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);\n\n        check_kw_only_arg(a, r);\n    }\n};\n\n/// Process a keyword-only-arguments-follow pseudo argument\ntemplate <>\nstruct process_attribute<kw_only> : process_attribute_default<kw_only> {\n    static void init(const kw_only &, function_record *r) {\n        append_self_arg_if_needed(r);\n        if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {\n            pybind11_fail(\"Mismatched args() and kw_only(): they must occur at the same relative \"\n                          \"argument location (or omit kw_only() entirely)\");\n        }\n        r->nargs_pos = static_cast<std::uint16_t>(r->args.size());\n    }\n};\n\n/// Process a positional-only-argument maker\ntemplate <>\nstruct process_attribute<pos_only> : process_attribute_default<pos_only> {\n    static void init(const pos_only &, function_record *r) {\n        append_self_arg_if_needed(r);\n        r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());\n        if (r->nargs_pos_only > r->nargs_pos) {\n            pybind11_fail(\"pos_only(): cannot follow a py::args() argument\");\n        }\n        // It also can't follow a kw_only, but a static_assert in pybind11.h checks that\n    }\n};\n\n/// Process a parent class attribute.  Single inheritance only (class_ itself already guarantees\n/// that)\ntemplate <typename T>\nstruct process_attribute<T, enable_if_t<is_pyobject<T>::value>>\n    : process_attribute_default<handle> {\n    static void init(const handle &h, type_record *r) { r->bases.append(h); }\n};\n\n/// Process a parent class attribute (deprecated, does not support multiple inheritance)\ntemplate <typename T>\nstruct process_attribute<base<T>> : process_attribute_default<base<T>> {\n    static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }\n};\n\n/// Process a multiple inheritance attribute\ntemplate <>\nstruct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {\n    static void init(const multiple_inheritance &, type_record *r) {\n        r->multiple_inheritance = true;\n    }\n};\n\ntemplate <>\nstruct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {\n    static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }\n};\n\ntemplate <>\nstruct process_attribute<custom_type_setup> {\n    static void init(const custom_type_setup &value, type_record *r) {\n        r->custom_type_setup_callback = value.value;\n    }\n};\n\ntemplate <>\nstruct process_attribute<is_final> : process_attribute_default<is_final> {\n    static void init(const is_final &, type_record *r) { r->is_final = true; }\n};\n\ntemplate <>\nstruct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {\n    static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }\n};\n\ntemplate <>\nstruct process_attribute<metaclass> : process_attribute_default<metaclass> {\n    static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }\n};\n\ntemplate <>\nstruct process_attribute<module_local> : process_attribute_default<module_local> {\n    static void init(const module_local &l, type_record *r) { r->module_local = l.value; }\n};\n\n/// Process a 'prepend' attribute, putting this at the beginning of the overload chain\ntemplate <>\nstruct process_attribute<prepend> : process_attribute_default<prepend> {\n    static void init(const prepend &, function_record *r) { r->prepend = true; }\n};\n\n/// Process an 'arithmetic' attribute for enums (does nothing here)\ntemplate <>\nstruct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};\n\ntemplate <typename... Ts>\nstruct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};\n\n/**\n * Process a keep_alive call policy -- invokes keep_alive_impl during the\n * pre-call handler if both Nurse, Patient != 0 and use the post-call handler\n * otherwise\n */\ntemplate <size_t Nurse, size_t Patient>\nstruct process_attribute<keep_alive<Nurse, Patient>>\n    : public process_attribute_default<keep_alive<Nurse, Patient>> {\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>\n    static void precall(function_call &call) {\n        keep_alive_impl(Nurse, Patient, call, handle());\n    }\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>\n    static void postcall(function_call &, handle) {}\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>\n    static void precall(function_call &) {}\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>\n    static void postcall(function_call &call, handle ret) {\n        keep_alive_impl(Nurse, Patient, call, ret);\n    }\n};\n\n/// Recursively iterate over variadic template arguments\ntemplate <typename... Args>\nstruct process_attributes {\n    static void init(const Args &...args, function_record *r) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);\n        using expander = int[];\n        (void) expander{\n            0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};\n    }\n    static void init(const Args &...args, type_record *r) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);\n        using expander = int[];\n        (void) expander{0,\n                        (process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};\n    }\n    static void precall(function_call &call) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);\n        using expander = int[];\n        (void) expander{0,\n                        (process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};\n    }\n    static void postcall(function_call &call, handle fn_ret) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);\n        using expander = int[];\n        (void) expander{\n            0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};\n    }\n};\n\ntemplate <typename T>\nusing is_call_guard = is_instantiation<call_guard, T>;\n\n/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)\ntemplate <typename... Extra>\nusing extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;\n\n/// Check the number of named arguments at compile time\ntemplate <typename... Extra,\n          size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),\n          size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>\nconstexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);\n    return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/buffer_info.h",
    "content": "/*\n    pybind11/buffer_info.h: Python buffer object interface\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Default, C-style strides\ninline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {\n    auto ndim = shape.size();\n    std::vector<ssize_t> strides(ndim, itemsize);\n    if (ndim > 0) {\n        for (size_t i = ndim - 1; i > 0; --i) {\n            strides[i - 1] = strides[i] * shape[i];\n        }\n    }\n    return strides;\n}\n\n// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`\ninline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {\n    auto ndim = shape.size();\n    std::vector<ssize_t> strides(ndim, itemsize);\n    for (size_t i = 1; i < ndim; ++i) {\n        strides[i] = strides[i - 1] * shape[i - 1];\n    }\n    return strides;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Information record describing a Python buffer object\nstruct buffer_info {\n    void *ptr = nullptr;          // Pointer to the underlying storage\n    ssize_t itemsize = 0;         // Size of individual items in bytes\n    ssize_t size = 0;             // Total number of entries\n    std::string format;           // For homogeneous buffers, this should be set to\n                                  // format_descriptor<T>::format()\n    ssize_t ndim = 0;             // Number of dimensions\n    std::vector<ssize_t> shape;   // Shape of the tensor (1 entry per dimension)\n    std::vector<ssize_t> strides; // Number of bytes between adjacent entries\n                                  // (for each per dimension)\n    bool readonly = false;        // flag to indicate if the underlying storage may be written to\n\n    buffer_info() = default;\n\n    buffer_info(void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t ndim,\n                detail::any_container<ssize_t> shape_in,\n                detail::any_container<ssize_t> strides_in,\n                bool readonly = false)\n        : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),\n          shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {\n        if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {\n            pybind11_fail(\"buffer_info: ndim doesn't match shape and/or strides length\");\n        }\n        for (size_t i = 0; i < (size_t) ndim; ++i) {\n            size *= shape[i];\n        }\n    }\n\n    template <typename T>\n    buffer_info(T *ptr,\n                detail::any_container<ssize_t> shape_in,\n                detail::any_container<ssize_t> strides_in,\n                bool readonly = false)\n        : buffer_info(private_ctr_tag(),\n                      ptr,\n                      sizeof(T),\n                      format_descriptor<T>::format(),\n                      static_cast<ssize_t>(shape_in->size()),\n                      std::move(shape_in),\n                      std::move(strides_in),\n                      readonly) {}\n\n    buffer_info(void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t size,\n                bool readonly = false)\n        : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {}\n\n    template <typename T>\n    buffer_info(T *ptr, ssize_t size, bool readonly = false)\n        : buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}\n\n    template <typename T>\n    buffer_info(const T *ptr, ssize_t size, bool readonly = true)\n        : buffer_info(\n            const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}\n\n    explicit buffer_info(Py_buffer *view, bool ownview = true)\n        : buffer_info(\n            view->buf,\n            view->itemsize,\n            view->format,\n            view->ndim,\n            {view->shape, view->shape + view->ndim},\n            /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects\n             * ignore this flag and return a view with NULL strides.\n             * When strides are NULL, build them manually.  */\n            view->strides\n                ? std::vector<ssize_t>(view->strides, view->strides + view->ndim)\n                : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),\n            (view->readonly != 0)) {\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        this->m_view = view;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        this->ownview = ownview;\n    }\n\n    buffer_info(const buffer_info &) = delete;\n    buffer_info &operator=(const buffer_info &) = delete;\n\n    buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }\n\n    buffer_info &operator=(buffer_info &&rhs) noexcept {\n        ptr = rhs.ptr;\n        itemsize = rhs.itemsize;\n        size = rhs.size;\n        format = std::move(rhs.format);\n        ndim = rhs.ndim;\n        shape = std::move(rhs.shape);\n        strides = std::move(rhs.strides);\n        std::swap(m_view, rhs.m_view);\n        std::swap(ownview, rhs.ownview);\n        readonly = rhs.readonly;\n        return *this;\n    }\n\n    ~buffer_info() {\n        if (m_view && ownview) {\n            PyBuffer_Release(m_view);\n            delete m_view;\n        }\n    }\n\n    Py_buffer *view() const { return m_view; }\n    Py_buffer *&view() { return m_view; }\n\nprivate:\n    struct private_ctr_tag {};\n\n    buffer_info(private_ctr_tag,\n                void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t ndim,\n                detail::any_container<ssize_t> &&shape_in,\n                detail::any_container<ssize_t> &&strides_in,\n                bool readonly)\n        : buffer_info(\n            ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}\n\n    Py_buffer *m_view = nullptr;\n    bool ownview = false;\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T, typename SFINAE = void>\nstruct compare_buffer_info {\n    static bool compare(const buffer_info &b) {\n        return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);\n    }\n};\n\ntemplate <typename T>\nstruct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {\n    static bool compare(const buffer_info &b) {\n        return (size_t) b.itemsize == sizeof(T)\n               && (b.format == format_descriptor<T>::value\n                   || ((sizeof(T) == sizeof(long))\n                       && b.format == (std::is_unsigned<T>::value ? \"L\" : \"l\"))\n                   || ((sizeof(T) == sizeof(size_t))\n                       && b.format == (std::is_unsigned<T>::value ? \"N\" : \"n\")));\n    }\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/cast.h",
    "content": "/*\n    pybind11/cast.h: Partial template specializations to cast between\n    C++ and Python types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"detail/descr.h\"\n#include \"detail/type_caster_base.h\"\n#include \"detail/typeid.h\"\n#include \"pytypes.h\"\n\n#include <array>\n#include <cstring>\n#include <functional>\n#include <iosfwd>\n#include <iterator>\n#include <memory>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename type, typename SFINAE = void>\nclass type_caster : public type_caster_base<type> {};\ntemplate <typename type>\nusing make_caster = type_caster<intrinsic_t<type>>;\n\n// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T\ntemplate <typename T>\ntypename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {\n    return caster.operator typename make_caster<T>::template cast_op_type<T>();\n}\ntemplate <typename T>\ntypename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>\ncast_op(make_caster<T> &&caster) {\n    return std::move(caster).operator typename make_caster<T>::\n        template cast_op_type<typename std::add_rvalue_reference<T>::type>();\n}\n\ntemplate <typename type>\nclass type_caster<std::reference_wrapper<type>> {\nprivate:\n    using caster_t = make_caster<type>;\n    caster_t subcaster;\n    using reference_t = type &;\n    using subcaster_cast_op_type = typename caster_t::template cast_op_type<reference_t>;\n\n    static_assert(\n        std::is_same<typename std::remove_const<type>::type &, subcaster_cast_op_type>::value\n            || std::is_same<reference_t, subcaster_cast_op_type>::value,\n        \"std::reference_wrapper<T> caster requires T to have a caster with an \"\n        \"`operator T &()` or `operator const T &()`\");\n\npublic:\n    bool load(handle src, bool convert) { return subcaster.load(src, convert); }\n    static constexpr auto name = caster_t::name;\n    static handle\n    cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {\n        // It is definitely wrong to take ownership of this pointer, so mask that rvp\n        if (policy == return_value_policy::take_ownership\n            || policy == return_value_policy::automatic) {\n            policy = return_value_policy::automatic_reference;\n        }\n        return caster_t::cast(&src.get(), policy, parent);\n    }\n    template <typename T>\n    using cast_op_type = std::reference_wrapper<type>;\n    explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }\n};\n\n#define PYBIND11_TYPE_CASTER(type, py_name)                                                       \\\nprotected:                                                                                        \\\n    type value;                                                                                   \\\n                                                                                                  \\\npublic:                                                                                           \\\n    static constexpr auto name = py_name;                                                         \\\n    template <typename T_,                                                                        \\\n              ::pybind11::detail::enable_if_t<                                                    \\\n                  std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value,                 \\\n                  int> = 0>                                                                       \\\n    static ::pybind11::handle cast(                                                               \\\n        T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) {             \\\n        if (!src)                                                                                 \\\n            return ::pybind11::none().release();                                                  \\\n        if (policy == ::pybind11::return_value_policy::take_ownership) {                          \\\n            auto h = cast(std::move(*src), policy, parent);                                       \\\n            delete src;                                                                           \\\n            return h;                                                                             \\\n        }                                                                                         \\\n        return cast(*src, policy, parent);                                                        \\\n    }                                                                                             \\\n    operator type *() { return &value; }               /* NOLINT(bugprone-macro-parentheses) */   \\\n    operator type &() { return value; }                /* NOLINT(bugprone-macro-parentheses) */   \\\n    operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */   \\\n    template <typename T_>                                                                        \\\n    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>\n\ntemplate <typename CharT>\nusing is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */\n#if defined(PYBIND11_HAS_U8STRING)\n                                std::is_same<CharT, char8_t>, /* std::u8string */\n#endif\n                                std::is_same<CharT, char16_t>, /* std::u16string */\n                                std::is_same<CharT, char32_t>, /* std::u32string */\n                                std::is_same<CharT, wchar_t>   /* std::wstring */\n                                >;\n\ntemplate <typename T>\nstruct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> {\n    using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>;\n    using _py_type_1 = conditional_t<std::is_signed<T>::value,\n                                     _py_type_0,\n                                     typename std::make_unsigned<_py_type_0>::type>;\n    using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>;\n\npublic:\n    bool load(handle src, bool convert) {\n        py_type py_value;\n\n        if (!src) {\n            return false;\n        }\n\n#if !defined(PYPY_VERSION)\n        auto index_check = [](PyObject *o) { return PyIndex_Check(o); };\n#else\n        // In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,\n        // while CPython only considers the existence of `nb_index`/`__index__`.\n        auto index_check = [](PyObject *o) { return hasattr(o, \"__index__\"); };\n#endif\n\n        if (std::is_floating_point<T>::value) {\n            if (convert || PyFloat_Check(src.ptr())) {\n                py_value = (py_type) PyFloat_AsDouble(src.ptr());\n            } else {\n                return false;\n            }\n        } else if (PyFloat_Check(src.ptr())\n                   || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) {\n            return false;\n        } else {\n            handle src_or_index = src;\n            // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.\n#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)\n            object index;\n            if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())\n                index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));\n                if (!index) {\n                    PyErr_Clear();\n                    if (!convert)\n                        return false;\n                } else {\n                    src_or_index = index;\n                }\n            }\n#endif\n            if (std::is_unsigned<py_type>::value) {\n                py_value = as_unsigned<py_type>(src_or_index.ptr());\n            } else { // signed integer:\n                py_value = sizeof(T) <= sizeof(long)\n                               ? (py_type) PyLong_AsLong(src_or_index.ptr())\n                               : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr());\n            }\n        }\n\n        // Python API reported an error\n        bool py_err = py_value == (py_type) -1 && PyErr_Occurred();\n\n        // Check to see if the conversion is valid (integers should match exactly)\n        // Signed/unsigned checks happen elsewhere\n        if (py_err\n            || (std::is_integral<T>::value && sizeof(py_type) != sizeof(T)\n                && py_value != (py_type) (T) py_value)) {\n            PyErr_Clear();\n            if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) {\n                auto tmp = reinterpret_steal<object>(std::is_floating_point<T>::value\n                                                         ? PyNumber_Float(src.ptr())\n                                                         : PyNumber_Long(src.ptr()));\n                PyErr_Clear();\n                return load(tmp, false);\n            }\n            return false;\n        }\n\n        value = (T) py_value;\n        return true;\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<std::is_floating_point<U>::value, handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyFloat_FromDouble((double) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value\n                                       && (sizeof(U) <= sizeof(long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PYBIND11_LONG_FROM_SIGNED((long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value\n                                       && (sizeof(U) <= sizeof(unsigned long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value\n                                       && (sizeof(U) > sizeof(long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyLong_FromLongLong((long long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value\n                                       && (sizeof(U) > sizeof(unsigned long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyLong_FromUnsignedLongLong((unsigned long long) src);\n    }\n\n    PYBIND11_TYPE_CASTER(T, const_name<std::is_integral<T>::value>(\"int\", \"float\"));\n};\n\ntemplate <typename T>\nstruct void_caster {\npublic:\n    bool load(handle src, bool) {\n        if (src && src.is_none()) {\n            return true;\n        }\n        return false;\n    }\n    static handle cast(T, return_value_policy /* policy */, handle /* parent */) {\n        return none().release();\n    }\n    PYBIND11_TYPE_CASTER(T, const_name(\"None\"));\n};\n\ntemplate <>\nclass type_caster<void_type> : public void_caster<void_type> {};\n\ntemplate <>\nclass type_caster<void> : public type_caster<void_type> {\npublic:\n    using type_caster<void_type>::cast;\n\n    bool load(handle h, bool) {\n        if (!h) {\n            return false;\n        }\n        if (h.is_none()) {\n            value = nullptr;\n            return true;\n        }\n\n        /* Check if this is a capsule */\n        if (isinstance<capsule>(h)) {\n            value = reinterpret_borrow<capsule>(h);\n            return true;\n        }\n\n        /* Check if this is a C++ type */\n        const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr());\n        if (bases.size() == 1) { // Only allowing loading from a single-value type\n            value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();\n            return true;\n        }\n\n        /* Fail */\n        return false;\n    }\n\n    static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {\n        if (ptr) {\n            return capsule(ptr).release();\n        }\n        return none().release();\n    }\n\n    template <typename T>\n    using cast_op_type = void *&;\n    explicit operator void *&() { return value; }\n    static constexpr auto name = const_name(\"capsule\");\n\nprivate:\n    void *value = nullptr;\n};\n\ntemplate <>\nclass type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> {};\n\ntemplate <>\nclass type_caster<bool> {\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.ptr() == Py_True) {\n            value = true;\n            return true;\n        }\n        if (src.ptr() == Py_False) {\n            value = false;\n            return true;\n        }\n        if (convert || (std::strcmp(\"numpy.bool_\", Py_TYPE(src.ptr())->tp_name) == 0)) {\n            // (allow non-implicit conversion for numpy booleans)\n\n            Py_ssize_t res = -1;\n            if (src.is_none()) {\n                res = 0; // None is implicitly converted to False\n            }\n#if defined(PYPY_VERSION)\n            // On PyPy, check that \"__bool__\" attr exists\n            else if (hasattr(src, PYBIND11_BOOL_ATTR)) {\n                res = PyObject_IsTrue(src.ptr());\n            }\n#else\n            // Alternate approach for CPython: this does the same as the above, but optimized\n            // using the CPython API so as to avoid an unneeded attribute lookup.\n            else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) {\n                if (PYBIND11_NB_BOOL(tp_as_number)) {\n                    res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());\n                }\n            }\n#endif\n            if (res == 0 || res == 1) {\n                value = (res != 0);\n                return true;\n            }\n            PyErr_Clear();\n        }\n        return false;\n    }\n    static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {\n        return handle(src ? Py_True : Py_False).inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(bool, const_name(\"bool\"));\n};\n\n// Helper class for UTF-{8,16,32} C++ stl strings:\ntemplate <typename StringType, bool IsView = false>\nstruct string_caster {\n    using CharT = typename StringType::value_type;\n\n    // Simplify life by being able to assume standard char sizes (the standard only guarantees\n    // minimums, but Python requires exact sizes)\n    static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1,\n                  \"Unsupported char size != 1\");\n#if defined(PYBIND11_HAS_U8STRING)\n    static_assert(!std::is_same<CharT, char8_t>::value || sizeof(CharT) == 1,\n                  \"Unsupported char8_t size != 1\");\n#endif\n    static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2,\n                  \"Unsupported char16_t size != 2\");\n    static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4,\n                  \"Unsupported char32_t size != 4\");\n    // wchar_t can be either 16 bits (Windows) or 32 (everywhere else)\n    static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4,\n                  \"Unsupported wchar_t size != 2/4\");\n    static constexpr size_t UTF_N = 8 * sizeof(CharT);\n\n    bool load(handle src, bool) {\n        handle load_src = src;\n        if (!src) {\n            return false;\n        }\n        if (!PyUnicode_Check(load_src.ptr())) {\n            return load_raw(load_src);\n        }\n\n        // For UTF-8 we avoid the need for a temporary `bytes` object by using\n        // `PyUnicode_AsUTF8AndSize`.\n        if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {\n            Py_ssize_t size = -1;\n            const auto *buffer\n                = reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));\n            if (!buffer) {\n                PyErr_Clear();\n                return false;\n            }\n            value = StringType(buffer, static_cast<size_t>(size));\n            return true;\n        }\n\n        auto utfNbytes\n            = reinterpret_steal<object>(PyUnicode_AsEncodedString(load_src.ptr(),\n                                                                  UTF_N == 8    ? \"utf-8\"\n                                                                  : UTF_N == 16 ? \"utf-16\"\n                                                                                : \"utf-32\",\n                                                                  nullptr));\n        if (!utfNbytes) {\n            PyErr_Clear();\n            return false;\n        }\n\n        const auto *buffer\n            = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));\n        size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);\n        // Skip BOM for UTF-16/32\n        if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {\n            buffer++;\n            length--;\n        }\n        value = StringType(buffer, length);\n\n        // If we're loading a string_view we need to keep the encoded Python object alive:\n        if (IsView) {\n            loader_life_support::add_patient(utfNbytes);\n        }\n\n        return true;\n    }\n\n    static handle\n    cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {\n        const char *buffer = reinterpret_cast<const char *>(src.data());\n        auto nbytes = ssize_t(src.size() * sizeof(CharT));\n        handle s = decode_utfN(buffer, nbytes);\n        if (!s) {\n            throw error_already_set();\n        }\n        return s;\n    }\n\n    PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME));\n\nprivate:\n    static handle decode_utfN(const char *buffer, ssize_t nbytes) {\n#if !defined(PYPY_VERSION)\n        return UTF_N == 8    ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr)\n               : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr)\n                             : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);\n#else\n        // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as\n        // well), so bypass the whole thing by just passing the encoding as a string value, which\n        // works properly:\n        return PyUnicode_Decode(buffer,\n                                nbytes,\n                                UTF_N == 8    ? \"utf-8\"\n                                : UTF_N == 16 ? \"utf-16\"\n                                              : \"utf-32\",\n                                nullptr);\n#endif\n    }\n\n    // When loading into a std::string or char*, accept a bytes/bytearray object as-is (i.e.\n    // without any encoding/decoding attempt).  For other C++ char sizes this is a no-op.\n    // which supports loading a unicode from a str, doesn't take this path.\n    template <typename C = CharT>\n    bool load_raw(enable_if_t<std::is_same<C, char>::value, handle> src) {\n        if (PYBIND11_BYTES_CHECK(src.ptr())) {\n            // We were passed raw bytes; accept it into a std::string or char*\n            // without any encoding attempt.\n            const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr());\n            if (!bytes) {\n                pybind11_fail(\"Unexpected PYBIND11_BYTES_AS_STRING() failure.\");\n            }\n            value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr()));\n            return true;\n        }\n        if (PyByteArray_Check(src.ptr())) {\n            // We were passed a bytearray; accept it into a std::string or char*\n            // without any encoding attempt.\n            const char *bytearray = PyByteArray_AsString(src.ptr());\n            if (!bytearray) {\n                pybind11_fail(\"Unexpected PyByteArray_AsString() failure.\");\n            }\n            value = StringType(bytearray, (size_t) PyByteArray_Size(src.ptr()));\n            return true;\n        }\n\n        return false;\n    }\n\n    template <typename C = CharT>\n    bool load_raw(enable_if_t<!std::is_same<C, char>::value, handle>) {\n        return false;\n    }\n};\n\ntemplate <typename CharT, class Traits, class Allocator>\nstruct type_caster<std::basic_string<CharT, Traits, Allocator>,\n                   enable_if_t<is_std_char_type<CharT>::value>>\n    : string_caster<std::basic_string<CharT, Traits, Allocator>> {};\n\n#ifdef PYBIND11_HAS_STRING_VIEW\ntemplate <typename CharT, class Traits>\nstruct type_caster<std::basic_string_view<CharT, Traits>,\n                   enable_if_t<is_std_char_type<CharT>::value>>\n    : string_caster<std::basic_string_view<CharT, Traits>, true> {};\n#endif\n\n// Type caster for C-style strings.  We basically use a std::string type caster, but also add the\n// ability to use None as a nullptr char* (which the string caster doesn't allow).\ntemplate <typename CharT>\nstruct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {\n    using StringType = std::basic_string<CharT>;\n    using StringCaster = make_caster<StringType>;\n    StringCaster str_caster;\n    bool none = false;\n    CharT one_char = 0;\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            none = true;\n            return true;\n        }\n        return str_caster.load(src, convert);\n    }\n\n    static handle cast(const CharT *src, return_value_policy policy, handle parent) {\n        if (src == nullptr) {\n            return pybind11::none().release();\n        }\n        return StringCaster::cast(StringType(src), policy, parent);\n    }\n\n    static handle cast(CharT src, return_value_policy policy, handle parent) {\n        if (std::is_same<char, CharT>::value) {\n            handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr);\n            if (!s) {\n                throw error_already_set();\n            }\n            return s;\n        }\n        return StringCaster::cast(StringType(1, src), policy, parent);\n    }\n\n    explicit operator CharT *() {\n        return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str());\n    }\n    explicit operator CharT &() {\n        if (none) {\n            throw value_error(\"Cannot convert None to a character\");\n        }\n\n        auto &value = static_cast<StringType &>(str_caster);\n        size_t str_len = value.size();\n        if (str_len == 0) {\n            throw value_error(\"Cannot convert empty string to a character\");\n        }\n\n        // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that\n        // is too high, and one for multiple unicode characters (caught later), so we need to\n        // figure out how long the first encoded character is in bytes to distinguish between these\n        // two errors.  We also allow want to allow unicode characters U+0080 through U+00FF, as\n        // those can fit into a single char value.\n        if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {\n            auto v0 = static_cast<unsigned char>(value[0]);\n            // low bits only: 0-127\n            // 0b110xxxxx - start of 2-byte sequence\n            // 0b1110xxxx - start of 3-byte sequence\n            // 0b11110xxx - start of 4-byte sequence\n            size_t char0_bytes = (v0 & 0x80) == 0      ? 1\n                                 : (v0 & 0xE0) == 0xC0 ? 2\n                                 : (v0 & 0xF0) == 0xE0 ? 3\n                                                       : 4;\n\n            if (char0_bytes == str_len) {\n                // If we have a 128-255 value, we can decode it into a single char:\n                if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx\n                    one_char = static_cast<CharT>(((v0 & 3) << 6)\n                                                  + (static_cast<unsigned char>(value[1]) & 0x3F));\n                    return one_char;\n                }\n                // Otherwise we have a single character, but it's > U+00FF\n                throw value_error(\"Character code point not in range(0x100)\");\n            }\n        }\n\n        // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a\n        // surrogate pair with total length 2 instantly indicates a range error (but not a \"your\n        // string was too long\" error).\n        else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {\n            one_char = static_cast<CharT>(value[0]);\n            if (one_char >= 0xD800 && one_char < 0xE000) {\n                throw value_error(\"Character code point not in range(0x10000)\");\n            }\n        }\n\n        if (str_len != 1) {\n            throw value_error(\"Expected a character, but multi-character string found\");\n        }\n\n        one_char = value[0];\n        return one_char;\n    }\n\n    static constexpr auto name = const_name(PYBIND11_STRING_NAME);\n    template <typename _T>\n    using cast_op_type = pybind11::detail::cast_op_type<_T>;\n};\n\n// Base implementation for std::tuple and std::pair\ntemplate <template <typename...> class Tuple, typename... Ts>\nclass tuple_caster {\n    using type = Tuple<Ts...>;\n    static constexpr auto size = sizeof...(Ts);\n    using indices = make_index_sequence<size>;\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src)) {\n            return false;\n        }\n        const auto seq = reinterpret_borrow<sequence>(src);\n        if (seq.size() != size) {\n            return false;\n        }\n        return load_impl(seq, convert, indices{});\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        return cast_impl(std::forward<T>(src), policy, parent, indices{});\n    }\n\n    // copied from the PYBIND11_TYPE_CASTER macro\n    template <typename T>\n    static handle cast(T *src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().release();\n        }\n        if (policy == return_value_policy::take_ownership) {\n            auto h = cast(std::move(*src), policy, parent);\n            delete src;\n            return h;\n        }\n        return cast(*src, policy, parent);\n    }\n\n    static constexpr auto name\n        = const_name(\"Tuple[\") + concat(make_caster<Ts>::name...) + const_name(\"]\");\n\n    template <typename T>\n    using cast_op_type = type;\n\n    explicit operator type() & { return implicit_cast(indices{}); }\n    explicit operator type() && { return std::move(*this).implicit_cast(indices{}); }\n\nprotected:\n    template <size_t... Is>\n    type implicit_cast(index_sequence<Is...>) & {\n        return type(cast_op<Ts>(std::get<Is>(subcasters))...);\n    }\n    template <size_t... Is>\n    type implicit_cast(index_sequence<Is...>) && {\n        return type(cast_op<Ts>(std::move(std::get<Is>(subcasters)))...);\n    }\n\n    static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }\n\n    template <size_t... Is>\n    bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {\n#ifdef __cpp_fold_expressions\n        if ((... || !std::get<Is>(subcasters).load(seq[Is], convert))) {\n            return false;\n        }\n#else\n        for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) {\n            if (!r) {\n                return false;\n            }\n        }\n#endif\n        return true;\n    }\n\n    /* Implementation: Convert a C++ tuple into a Python tuple */\n    template <typename T, size_t... Is>\n    static handle\n    cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);\n        std::array<object, size> entries{{reinterpret_steal<object>(\n            make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}};\n        for (const auto &entry : entries) {\n            if (!entry) {\n                return handle();\n            }\n        }\n        tuple result(size);\n        int counter = 0;\n        for (auto &entry : entries) {\n            PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr());\n        }\n        return result.release();\n    }\n\n    Tuple<make_caster<Ts>...> subcasters;\n};\n\ntemplate <typename T1, typename T2>\nclass type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {};\n\ntemplate <typename... Ts>\nclass type_caster<std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};\n\n/// Helper class which abstracts away certain actions. Users can provide specializations for\n/// custom holders, but it's only necessary if the type has a non-standard interface.\ntemplate <typename T>\nstruct holder_helper {\n    static auto get(const T &p) -> decltype(p.get()) { return p.get(); }\n};\n\n/// Type caster for holder types like std::shared_ptr, etc.\n/// The SFINAE hook is provided to help work around the current lack of support\n/// for smart-pointer interoperability. Please consider it an implementation\n/// detail that may change in the future, as formal support for smart-pointer\n/// interoperability is added into pybind11.\ntemplate <typename type, typename holder_type, typename SFINAE = void>\nstruct copyable_holder_caster : public type_caster_base<type> {\npublic:\n    using base = type_caster_base<type>;\n    static_assert(std::is_base_of<base, type_caster<type>>::value,\n                  \"Holder classes are only supported for custom types\");\n    using base::base;\n    using base::cast;\n    using base::typeinfo;\n    using base::value;\n\n    bool load(handle src, bool convert) {\n        return base::template load_impl<copyable_holder_caster<type, holder_type>>(src, convert);\n    }\n\n    explicit operator type *() { return this->value; }\n    // static_cast works around compiler error with MSVC 17 and CUDA 10.2\n    // see issue #2180\n    explicit operator type &() { return *(static_cast<type *>(this->value)); }\n    explicit operator holder_type *() { return std::addressof(holder); }\n    explicit operator holder_type &() { return holder; }\n\n    static handle cast(const holder_type &src, return_value_policy, handle) {\n        const auto *ptr = holder_helper<holder_type>::get(src);\n        return type_caster_base<type>::cast_holder(ptr, &src);\n    }\n\nprotected:\n    friend class type_caster_generic;\n    void check_holder_compat() {\n        if (typeinfo->default_holder) {\n            throw cast_error(\"Unable to load a custom holder type from a default-holder instance\");\n        }\n    }\n\n    bool load_value(value_and_holder &&v_h) {\n        if (v_h.holder_constructed()) {\n            value = v_h.value_ptr();\n            holder = v_h.template holder<holder_type>();\n            return true;\n        }\n        throw cast_error(\"Unable to cast from non-held to held instance (T& to Holder<T>) \"\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                         \"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for \"\n                         \"type information)\");\n#else\n                         \"of type '\"\n                         + type_id<holder_type>() + \"''\");\n#endif\n    }\n\n    template <typename T = holder_type,\n              detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>\n    bool try_implicit_casts(handle, bool) {\n        return false;\n    }\n\n    template <typename T = holder_type,\n              detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>\n    bool try_implicit_casts(handle src, bool convert) {\n        for (auto &cast : typeinfo->implicit_casts) {\n            copyable_holder_caster sub_caster(*cast.first);\n            if (sub_caster.load(src, convert)) {\n                value = cast.second(sub_caster.value);\n                holder = holder_type(sub_caster.holder, (type *) value);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    static bool try_direct_conversions(handle) { return false; }\n\n    holder_type holder;\n};\n\n/// Specialize for the common std::shared_ptr, so users don't need to\ntemplate <typename T>\nclass type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};\n\n/// Type caster for holder types like std::unique_ptr.\n/// Please consider the SFINAE hook an implementation detail, as explained\n/// in the comment for the copyable_holder_caster.\ntemplate <typename type, typename holder_type, typename SFINAE = void>\nstruct move_only_holder_caster {\n    static_assert(std::is_base_of<type_caster_base<type>, type_caster<type>>::value,\n                  \"Holder classes are only supported for custom types\");\n\n    static handle cast(holder_type &&src, return_value_policy, handle) {\n        auto *ptr = holder_helper<holder_type>::get(src);\n        return type_caster_base<type>::cast_holder(ptr, std::addressof(src));\n    }\n    static constexpr auto name = type_caster_base<type>::name;\n};\n\ntemplate <typename type, typename deleter>\nclass type_caster<std::unique_ptr<type, deleter>>\n    : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};\n\ntemplate <typename type, typename holder_type>\nusing type_caster_holder = conditional_t<is_copy_constructible<holder_type>::value,\n                                         copyable_holder_caster<type, holder_type>,\n                                         move_only_holder_caster<type, holder_type>>;\n\ntemplate <typename T, bool Value = false>\nstruct always_construct_holder {\n    static constexpr bool value = Value;\n};\n\n/// Create a specialization for custom holder types (silently ignores std::shared_ptr)\n#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...)                                      \\\n    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \\\n    namespace detail {                                                                            \\\n    template <typename type>                                                                      \\\n    struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> {  \\\n    };                                                                                            \\\n    template <typename type>                                                                      \\\n    class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>>               \\\n        : public type_caster_holder<type, holder_type> {};                                        \\\n    }                                                                                             \\\n    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n\n// PYBIND11_DECLARE_HOLDER_TYPE holder types:\ntemplate <typename base, typename holder>\nstruct is_holder_type\n    : std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {};\n// Specialization for always-supported unique_ptr holders:\ntemplate <typename base, typename deleter>\nstruct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};\n\ntemplate <typename T>\nstruct handle_type_name {\n    static constexpr auto name = const_name<T>();\n};\ntemplate <>\nstruct handle_type_name<bool_> {\n    static constexpr auto name = const_name(\"bool\");\n};\ntemplate <>\nstruct handle_type_name<bytes> {\n    static constexpr auto name = const_name(PYBIND11_BYTES_NAME);\n};\ntemplate <>\nstruct handle_type_name<int_> {\n    static constexpr auto name = const_name(\"int\");\n};\ntemplate <>\nstruct handle_type_name<iterable> {\n    static constexpr auto name = const_name(\"Iterable\");\n};\ntemplate <>\nstruct handle_type_name<iterator> {\n    static constexpr auto name = const_name(\"Iterator\");\n};\ntemplate <>\nstruct handle_type_name<float_> {\n    static constexpr auto name = const_name(\"float\");\n};\ntemplate <>\nstruct handle_type_name<none> {\n    static constexpr auto name = const_name(\"None\");\n};\ntemplate <>\nstruct handle_type_name<args> {\n    static constexpr auto name = const_name(\"*args\");\n};\ntemplate <>\nstruct handle_type_name<kwargs> {\n    static constexpr auto name = const_name(\"**kwargs\");\n};\n\ntemplate <typename type>\nstruct pyobject_caster {\n    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>\n    pyobject_caster() : value() {}\n\n    // `type` may not be default constructible (e.g. frozenset, anyset).  Initializing `value`\n    // to a nil handle is safe since it will only be accessed if `load` succeeds.\n    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>\n    pyobject_caster() : value(reinterpret_steal<type>(handle())) {}\n\n    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>\n    bool load(handle src, bool /* convert */) {\n        value = src;\n        return static_cast<bool>(value);\n    }\n\n    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>\n    bool load(handle src, bool /* convert */) {\n        if (!isinstance<type>(src)) {\n            return false;\n        }\n        value = reinterpret_borrow<type>(src);\n        return true;\n    }\n\n    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {\n        return src.inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);\n};\n\ntemplate <typename T>\nclass type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caster<T> {};\n\n// Our conditions for enabling moving are quite restrictive:\n// At compile time:\n// - T needs to be a non-const, non-pointer, non-reference type\n// - type_caster<T>::operator T&() must exist\n// - the type must be move constructible (obviously)\n// At run-time:\n// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it\n//   must have ref_count() == 1)h\n// If any of the above are not satisfied, we fall back to copying.\ntemplate <typename T>\nusing move_is_plain_type\n    = satisfies_none_of<T, std::is_void, std::is_pointer, std::is_reference, std::is_const>;\ntemplate <typename T, typename SFINAE = void>\nstruct move_always : std::false_type {};\ntemplate <typename T>\nstruct move_always<\n    T,\n    enable_if_t<\n        all_of<move_is_plain_type<T>,\n               negation<is_copy_constructible<T>>,\n               std::is_move_constructible<T>,\n               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>\n    : std::true_type {};\ntemplate <typename T, typename SFINAE = void>\nstruct move_if_unreferenced : std::false_type {};\ntemplate <typename T>\nstruct move_if_unreferenced<\n    T,\n    enable_if_t<\n        all_of<move_is_plain_type<T>,\n               negation<move_always<T>>,\n               std::is_move_constructible<T>,\n               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>\n    : std::true_type {};\ntemplate <typename T>\nusing move_never = none_of<move_always<T>, move_if_unreferenced<T>>;\n\n// Detect whether returning a `type` from a cast on type's type_caster is going to result in a\n// reference or pointer to a local variable of the type_caster.  Basically, only\n// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;\n// everything else returns a reference/pointer to a local variable.\ntemplate <typename type>\nusing cast_is_temporary_value_reference\n    = bool_constant<(std::is_reference<type>::value || std::is_pointer<type>::value)\n                    && !std::is_base_of<type_caster_generic, make_caster<type>>::value\n                    && !std::is_same<intrinsic_t<type>, void>::value>;\n\n// When a value returned from a C++ function is being cast back to Python, we almost always want to\n// force `policy = move`, regardless of the return value policy the function/method was declared\n// with.\ntemplate <typename Return, typename SFINAE = void>\nstruct return_value_policy_override {\n    static return_value_policy policy(return_value_policy p) { return p; }\n};\n\ntemplate <typename Return>\nstruct return_value_policy_override<\n    Return,\n    detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {\n    static return_value_policy policy(return_value_policy p) {\n        return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value\n                   ? return_value_policy::move\n                   : p;\n    }\n};\n\n// Basic python -> C++ casting; throws if casting fails\ntemplate <typename T, typename SFINAE>\ntype_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {\n    static_assert(!detail::is_pyobject<T>::value,\n                  \"Internal error: type_caster should only be used for C++ types\");\n    if (!conv.load(handle, true)) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n        throw cast_error(\"Unable to cast Python instance to C++ type (#define \"\n                         \"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\");\n#else\n        throw cast_error(\"Unable to cast Python instance of type \"\n                         + (std::string) str(type::handle_of(handle)) + \" to C++ type '\"\n                         + type_id<T>() + \"'\");\n#endif\n    }\n    return conv;\n}\n// Wrapper around the above that also constructs and returns a type_caster\ntemplate <typename T>\nmake_caster<T> load_type(const handle &handle) {\n    make_caster<T> conv;\n    load_type(conv, handle);\n    return conv;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n// pytype -> C++ type\ntemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>\nT cast(const handle &handle) {\n    using namespace detail;\n    static_assert(!cast_is_temporary_value_reference<T>::value,\n                  \"Unable to cast type to reference: value is local to type caster\");\n    return cast_op<T>(load_type<T>(handle));\n}\n\n// pytype -> pytype (calls converting constructor)\ntemplate <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>\nT cast(const handle &handle) {\n    return T(reinterpret_borrow<object>(handle));\n}\n\n// C++ type -> py::object\ntemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>\nobject cast(T &&value,\n            return_value_policy policy = return_value_policy::automatic_reference,\n            handle parent = handle()) {\n    using no_ref_T = typename std::remove_reference<T>::type;\n    if (policy == return_value_policy::automatic) {\n        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::take_ownership\n                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy\n                                                      : return_value_policy::move;\n    } else if (policy == return_value_policy::automatic_reference) {\n        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::reference\n                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy\n                                                      : return_value_policy::move;\n    }\n    return reinterpret_steal<object>(\n        detail::make_caster<T>::cast(std::forward<T>(value), policy, parent));\n}\n\ntemplate <typename T>\nT handle::cast() const {\n    return pybind11::cast<T>(*this);\n}\ntemplate <>\ninline void handle::cast() const {\n    return;\n}\n\ntemplate <typename T>\ndetail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {\n    if (obj.ref_count() > 1) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n        throw cast_error(\n            \"Unable to cast Python instance to C++ rvalue: instance has multiple references\"\n            \" (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\");\n#else\n        throw cast_error(\"Unable to move from Python \" + (std::string) str(type::handle_of(obj))\n                         + \" instance to C++ \" + type_id<T>()\n                         + \" instance: instance has multiple references\");\n#endif\n    }\n\n    // Move into a temporary and return that, because the reference may be a local value of `conv`\n    T ret = std::move(detail::load_type<T>(obj).operator T &());\n    return ret;\n}\n\n// Calling cast() on an rvalue calls pybind11::cast with the object rvalue, which does:\n// - If we have to move (because T has no copy constructor), do it.  This will fail if the moved\n//   object has multiple references, but trying to copy will fail to compile.\n// - If both movable and copyable, check ref count: if 1, move; otherwise copy\n// - Otherwise (not movable), copy.\ntemplate <typename T>\ndetail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_always<T>::value, T>\ncast(object &&object) {\n    return move<T>(std::move(object));\n}\ntemplate <typename T>\ndetail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_if_unreferenced<T>::value, T>\ncast(object &&object) {\n    if (object.ref_count() > 1) {\n        return cast<T>(object);\n    }\n    return move<T>(std::move(object));\n}\ntemplate <typename T>\ndetail::enable_if_t<!detail::is_pyobject<T>::value && detail::move_never<T>::value, T>\ncast(object &&object) {\n    return cast<T>(object);\n}\n\n// pytype rvalue -> pytype (calls converting constructor)\ntemplate <typename T>\ndetail::enable_if_t<detail::is_pyobject<T>::value, T> cast(object &&object) {\n    return T(std::move(object));\n}\n\ntemplate <typename T>\nT object::cast() const & {\n    return pybind11::cast<T>(*this);\n}\ntemplate <typename T>\nT object::cast() && {\n    return pybind11::cast<T>(std::move(*this));\n}\ntemplate <>\ninline void object::cast() const & {\n    return;\n}\ntemplate <>\ninline void object::cast() && {\n    return;\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Declared in pytypes.h:\ntemplate <typename T, enable_if_t<!is_pyobject<T>::value, int>>\nobject object_or_cast(T &&o) {\n    return pybind11::cast(std::forward<T>(o));\n}\n\n// Placeholder type for the unneeded (and dead code) static variable in the\n// PYBIND11_OVERRIDE_OVERRIDE macro\nstruct override_unused {};\ntemplate <typename ret_type>\nusing override_caster_t = conditional_t<cast_is_temporary_value_reference<ret_type>::value,\n                                        make_caster<ret_type>,\n                                        override_unused>;\n\n// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then\n// store the result in the given variable.  For other types, this is a no-op.\ntemplate <typename T>\nenable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o,\n                                                                     make_caster<T> &caster) {\n    return cast_op<T>(load_type(caster, o));\n}\ntemplate <typename T>\nenable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,\n                                                                      override_unused &) {\n    pybind11_fail(\"Internal error: cast_ref fallback invoked\");\n}\n\n// Trampoline use: Having a pybind11::cast with an invalid reference type is going to\n// static_assert, even though if it's in dead code, so we provide a \"trampoline\" to pybind11::cast\n// that only does anything in cases where pybind11::cast is valid.\ntemplate <typename T>\nenable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&) {\n    pybind11_fail(\"Internal error: cast_safe fallback invoked\");\n}\ntemplate <typename T>\nenable_if_t<std::is_void<T>::value, void> cast_safe(object &&) {}\ntemplate <typename T>\nenable_if_t<detail::none_of<cast_is_temporary_value_reference<T>, std::is_void<T>>::value, T>\ncast_safe(object &&o) {\n    return pybind11::cast<T>(std::move(o));\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n// The overloads could coexist, i.e. the #if is not strictly speaking needed,\n// but it is an easy minor optimization.\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\ninline cast_error cast_error_unable_to_convert_call_arg() {\n    return cast_error(\"Unable to convert call argument to Python object (#define \"\n                      \"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\");\n}\n#else\ninline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,\n                                                        const std::string &type) {\n    return cast_error(\"Unable to convert call argument '\" + name + \"' of type '\" + type\n                      + \"' to Python object\");\n}\n#endif\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\ntuple make_tuple() {\n    return tuple(0);\n}\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>\ntuple make_tuple(Args &&...args_) {\n    constexpr size_t size = sizeof...(Args);\n    std::array<object, size> args{{reinterpret_steal<object>(\n        detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};\n    for (size_t i = 0; i < args.size(); i++) {\n        if (!args[i]) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            std::array<std::string, size> argtypes{{type_id<Args>()...}};\n            throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);\n#endif\n        }\n    }\n    tuple result(size);\n    int counter = 0;\n    for (auto &arg_value : args) {\n        PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr());\n    }\n    return result;\n}\n\n/// \\ingroup annotations\n/// Annotation for arguments\nstruct arg {\n    /// Constructs an argument with the name of the argument; if null or omitted, this is a\n    /// positional argument.\n    constexpr explicit arg(const char *name = nullptr)\n        : name(name), flag_noconvert(false), flag_none(true) {}\n    /// Assign a value to this argument\n    template <typename T>\n    arg_v operator=(T &&value) const;\n    /// Indicate that the type should not be converted in the type caster\n    arg &noconvert(bool flag = true) {\n        flag_noconvert = flag;\n        return *this;\n    }\n    /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args)\n    arg &none(bool flag = true) {\n        flag_none = flag;\n        return *this;\n    }\n\n    const char *name;        ///< If non-null, this is a named kwargs argument\n    bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type\n                             ///< caster!)\n    bool flag_none : 1;      ///< If set (the default), allow None to be passed to this argument\n};\n\n/// \\ingroup annotations\n/// Annotation for arguments with values\nstruct arg_v : arg {\nprivate:\n    template <typename T>\n    arg_v(arg &&base, T &&x, const char *descr = nullptr)\n        : arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(\n                         std::forward<T>(x), return_value_policy::automatic, {}))),\n          descr(descr)\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n          ,\n          type(type_id<T>())\n#endif\n    {\n        // Workaround! See:\n        // https://github.com/pybind/pybind11/issues/2336\n        // https://github.com/pybind/pybind11/pull/2685#issuecomment-731286700\n        if (PyErr_Occurred()) {\n            PyErr_Clear();\n        }\n    }\n\npublic:\n    /// Direct construction with name, default, and description\n    template <typename T>\n    arg_v(const char *name, T &&x, const char *descr = nullptr)\n        : arg_v(arg(name), std::forward<T>(x), descr) {}\n\n    /// Called internally when invoking `py::arg(\"a\") = value`\n    template <typename T>\n    arg_v(const arg &base, T &&x, const char *descr = nullptr)\n        : arg_v(arg(base), std::forward<T>(x), descr) {}\n\n    /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg&\n    arg_v &noconvert(bool flag = true) {\n        arg::noconvert(flag);\n        return *this;\n    }\n\n    /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg&\n    arg_v &none(bool flag = true) {\n        arg::none(flag);\n        return *this;\n    }\n\n    /// The default value\n    object value;\n    /// The (optional) description of the default value\n    const char *descr;\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n    /// The C++ type name of the default value (only available when compiled in debug mode)\n    std::string type;\n#endif\n};\n\n/// \\ingroup annotations\n/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of\n/// an unnamed '*' argument\nstruct kw_only {};\n\n/// \\ingroup annotations\n/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of\n/// an unnamed '/' argument (in Python 3.8)\nstruct pos_only {};\n\ntemplate <typename T>\narg_v arg::operator=(T &&value) const {\n    return {*this, std::forward<T>(value)};\n}\n\n/// Alias for backward compatibility -- to be removed in version 2.0\ntemplate <typename /*unused*/>\nusing arg_t = arg_v;\n\ninline namespace literals {\n/** \\rst\n    String literal version of `arg`\n \\endrst */\nconstexpr arg operator\"\" _a(const char *name, size_t) { return arg(name); }\n} // namespace literals\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T>\nusing is_kw_only = std::is_same<intrinsic_t<T>, kw_only>;\ntemplate <typename T>\nusing is_pos_only = std::is_same<intrinsic_t<T>, pos_only>;\n\n// forward declaration (definition in attr.h)\nstruct function_record;\n\n/// Internal data associated with a single function call\nstruct function_call {\n    function_call(const function_record &f, handle p); // Implementation in attr.h\n\n    /// The function data:\n    const function_record &func;\n\n    /// Arguments passed to the function:\n    std::vector<handle> args;\n\n    /// The `convert` value the arguments should be loaded with\n    std::vector<bool> args_convert;\n\n    /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if\n    /// present, are also in `args` but without a reference).\n    object args_ref, kwargs_ref;\n\n    /// The parent, if any\n    handle parent;\n\n    /// If this is a call to an initializer, this argument contains `self`\n    handle init_self;\n};\n\n/// Helper class which loads arguments for C++ functions called from Python\ntemplate <typename... Args>\nclass argument_loader {\n    using indices = make_index_sequence<sizeof...(Args)>;\n\n    template <typename Arg>\n    using argument_is_args = std::is_same<intrinsic_t<Arg>, args>;\n    template <typename Arg>\n    using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>;\n    // Get kwargs argument position, or -1 if not present:\n    static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();\n\n    static_assert(kwargs_pos == -1 || kwargs_pos == (int) sizeof...(Args) - 1,\n                  \"py::kwargs is only permitted as the last argument of a function\");\n\npublic:\n    static constexpr bool has_kwargs = kwargs_pos != -1;\n\n    // py::args argument position; -1 if not present.\n    static constexpr int args_pos = constexpr_last<argument_is_args, Args...>();\n\n    static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),\n                  \"py::args cannot be specified more than once\");\n\n    static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...);\n\n    bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }\n\n    template <typename Return, typename Guard, typename Func>\n    // NOLINTNEXTLINE(readability-const-return-type)\n    enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {\n        return std::move(*this).template call_impl<remove_cv_t<Return>>(\n            std::forward<Func>(f), indices{}, Guard{});\n    }\n\n    template <typename Return, typename Guard, typename Func>\n    enable_if_t<std::is_void<Return>::value, void_type> call(Func &&f) && {\n        std::move(*this).template call_impl<remove_cv_t<Return>>(\n            std::forward<Func>(f), indices{}, Guard{});\n        return void_type();\n    }\n\nprivate:\n    static bool load_impl_sequence(function_call &, index_sequence<>) { return true; }\n\n    template <size_t... Is>\n    bool load_impl_sequence(function_call &call, index_sequence<Is...>) {\n#ifdef __cpp_fold_expressions\n        if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is]))) {\n            return false;\n        }\n#else\n        for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...}) {\n            if (!r) {\n                return false;\n            }\n        }\n#endif\n        return true;\n    }\n\n    template <typename Return, typename Func, size_t... Is, typename Guard>\n    Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {\n        return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);\n    }\n\n    std::tuple<make_caster<Args>...> argcasters;\n};\n\n/// Helper class which collects only positional arguments for a Python function call.\n/// A fancier version below can collect any argument, but this one is optimal for simple calls.\ntemplate <return_value_policy policy>\nclass simple_collector {\npublic:\n    template <typename... Ts>\n    explicit simple_collector(Ts &&...values)\n        : m_args(pybind11::make_tuple<policy>(std::forward<Ts>(values)...)) {}\n\n    const tuple &args() const & { return m_args; }\n    dict kwargs() const { return {}; }\n\n    tuple args() && { return std::move(m_args); }\n\n    /// Call a Python function and pass the collected arguments\n    object call(PyObject *ptr) const {\n        PyObject *result = PyObject_CallObject(ptr, m_args.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\nprivate:\n    tuple m_args;\n};\n\n/// Helper class which collects positional, keyword, * and ** arguments for a Python function call\ntemplate <return_value_policy policy>\nclass unpacking_collector {\npublic:\n    template <typename... Ts>\n    explicit unpacking_collector(Ts &&...values) {\n        // Tuples aren't (easily) resizable so a list is needed for collection,\n        // but the actual function call strictly requires a tuple.\n        auto args_list = list();\n        using expander = int[];\n        (void) expander{0, (process(args_list, std::forward<Ts>(values)), 0)...};\n\n        m_args = std::move(args_list);\n    }\n\n    const tuple &args() const & { return m_args; }\n    const dict &kwargs() const & { return m_kwargs; }\n\n    tuple args() && { return std::move(m_args); }\n    dict kwargs() && { return std::move(m_kwargs); }\n\n    /// Call a Python function and pass the collected arguments\n    object call(PyObject *ptr) const {\n        PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\nprivate:\n    template <typename T>\n    void process(list &args_list, T &&x) {\n        auto o = reinterpret_steal<object>(\n            detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));\n        if (!o) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),\n                                                        type_id<T>());\n#endif\n        }\n        args_list.append(std::move(o));\n    }\n\n    void process(list &args_list, detail::args_proxy ap) {\n        for (auto a : ap) {\n            args_list.append(a);\n        }\n    }\n\n    void process(list & /*args_list*/, arg_v a) {\n        if (!a.name) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            nameless_argument_error();\n#else\n            nameless_argument_error(a.type);\n#endif\n        }\n        if (m_kwargs.contains(a.name)) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            multiple_values_error();\n#else\n            multiple_values_error(a.name);\n#endif\n        }\n        if (!a.value) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            throw cast_error_unable_to_convert_call_arg(a.name, a.type);\n#endif\n        }\n        m_kwargs[a.name] = std::move(a.value);\n    }\n\n    void process(list & /*args_list*/, detail::kwargs_proxy kp) {\n        if (!kp) {\n            return;\n        }\n        for (auto k : reinterpret_borrow<dict>(kp)) {\n            if (m_kwargs.contains(k.first)) {\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                multiple_values_error();\n#else\n                multiple_values_error(str(k.first));\n#endif\n            }\n            m_kwargs[k.first] = k.second;\n        }\n    }\n\n    [[noreturn]] static void nameless_argument_error() {\n        throw type_error(\n            \"Got kwargs without a name; only named arguments \"\n            \"may be passed via py::arg() to a python function call. \"\n            \"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\");\n    }\n    [[noreturn]] static void nameless_argument_error(const std::string &type) {\n        throw type_error(\"Got kwargs without a name of type '\" + type\n                         + \"'; only named \"\n                           \"arguments may be passed via py::arg() to a python function call. \");\n    }\n    [[noreturn]] static void multiple_values_error() {\n        throw type_error(\n            \"Got multiple values for keyword argument \"\n            \"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\");\n    }\n\n    [[noreturn]] static void multiple_values_error(const std::string &name) {\n        throw type_error(\"Got multiple values for keyword argument '\" + name + \"'\");\n    }\n\nprivate:\n    tuple m_args;\n    dict m_kwargs;\n};\n\n// [workaround(intel)] Separate function required here\n// We need to put this into a separate function because the Intel compiler\n// fails to compile enable_if_t<!all_of<is_positional<Args>...>::value>\n// (tested with ICC 2021.1 Beta 20200827).\ntemplate <typename... Args>\nconstexpr bool args_are_all_positional() {\n    return all_of<is_positional<Args>...>::value;\n}\n\n/// Collect only positional arguments for a Python function call\ntemplate <return_value_policy policy,\n          typename... Args,\n          typename = enable_if_t<args_are_all_positional<Args...>()>>\nsimple_collector<policy> collect_arguments(Args &&...args) {\n    return simple_collector<policy>(std::forward<Args>(args)...);\n}\n\n/// Collect all arguments, including keywords and unpacking (only instantiated when needed)\ntemplate <return_value_policy policy,\n          typename... Args,\n          typename = enable_if_t<!args_are_all_positional<Args...>()>>\nunpacking_collector<policy> collect_arguments(Args &&...args) {\n    // Following argument order rules for generalized unpacking according to PEP 448\n    static_assert(constexpr_last<is_positional, Args...>()\n                          < constexpr_first<is_keyword_or_ds, Args...>()\n                      && constexpr_last<is_s_unpacking, Args...>()\n                             < constexpr_first<is_ds_unpacking, Args...>(),\n                  \"Invalid function call: positional args must precede keywords and ** unpacking; \"\n                  \"* unpacking must precede ** unpacking\");\n    return unpacking_collector<policy>(std::forward<Args>(args)...);\n}\n\ntemplate <typename Derived>\ntemplate <return_value_policy policy, typename... Args>\nobject object_api<Derived>::operator()(Args &&...args) const {\n#ifndef NDEBUG\n    if (!PyGILState_Check()) {\n        pybind11_fail(\"pybind11::object_api<>::operator() PyGILState_Check() failure.\");\n    }\n#endif\n    return detail::collect_arguments<policy>(std::forward<Args>(args)...).call(derived().ptr());\n}\n\ntemplate <typename Derived>\ntemplate <return_value_policy policy, typename... Args>\nobject object_api<Derived>::call(Args &&...args) const {\n    return operator()<policy>(std::forward<Args>(args)...);\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename T>\nhandle type::handle_of() {\n    static_assert(std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,\n                  \"py::type::of<T> only supports the case where T is a registered C++ types.\");\n\n    return detail::get_type_handle(typeid(T), true);\n}\n\n#define PYBIND11_MAKE_OPAQUE(...)                                                                 \\\n    PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)                                                  \\\n    namespace detail {                                                                            \\\n    template <>                                                                                   \\\n    class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> {};                     \\\n    }                                                                                             \\\n    PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n\n/// Lets you pass a type containing a `,` through a macro parameter without needing a separate\n/// typedef, e.g.:\n/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`\n#define PYBIND11_TYPE(...) __VA_ARGS__\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/chrono.h",
    "content": "/*\n    pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime\n\n    Copyright (c) 2016 Trent Houliston <trent@houliston.me> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <chrono>\n#include <cmath>\n#include <ctime>\n#include <datetime.h>\n#include <mutex>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename type>\nclass duration_caster {\npublic:\n    using rep = typename type::rep;\n    using period = typename type::period;\n\n    // signed 25 bits required by the standard.\n    using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;\n\n    bool load(handle src, bool) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        if (!src) {\n            return false;\n        }\n        // If invoked with datetime.delta object\n        if (PyDelta_Check(src.ptr())) {\n            value = type(duration_cast<duration<rep, period>>(\n                days(PyDateTime_DELTA_GET_DAYS(src.ptr()))\n                + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))\n                + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));\n            return true;\n        }\n        // If invoked with a float we assume it is seconds and convert\n        if (PyFloat_Check(src.ptr())) {\n            value = type(duration_cast<duration<rep, period>>(\n                duration<double>(PyFloat_AsDouble(src.ptr()))));\n            return true;\n        }\n        return false;\n    }\n\n    // If this is a duration just return it back\n    static const std::chrono::duration<rep, period> &\n    get_duration(const std::chrono::duration<rep, period> &src) {\n        return src;\n    }\n\n    // If this is a time_point get the time_since_epoch\n    template <typename Clock>\n    static std::chrono::duration<rep, period>\n    get_duration(const std::chrono::time_point<Clock, std::chrono::duration<rep, period>> &src) {\n        return src.time_since_epoch();\n    }\n\n    static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {\n        using namespace std::chrono;\n\n        // Use overloaded function to get our duration from our source\n        // Works out if it is a duration or time_point and get the duration\n        auto d = get_duration(src);\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        // Declare these special duration types so the conversions happen with the correct\n        // primitive types (int)\n        using dd_t = duration<int, std::ratio<86400>>;\n        using ss_t = duration<int, std::ratio<1>>;\n        using us_t = duration<int, std::micro>;\n\n        auto dd = duration_cast<dd_t>(d);\n        auto subd = d - dd;\n        auto ss = duration_cast<ss_t>(subd);\n        auto us = duration_cast<us_t>(subd - ss);\n        return PyDelta_FromDSU(dd.count(), ss.count(), us.count());\n    }\n\n    PYBIND11_TYPE_CASTER(type, const_name(\"datetime.timedelta\"));\n};\n\ninline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {\n#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER)\n    if (localtime_s(buf, time))\n        return nullptr;\n    return buf;\n#else\n    static std::mutex mtx;\n    std::lock_guard<std::mutex> lock(mtx);\n    std::tm *tm_ptr = std::localtime(time);\n    if (tm_ptr != nullptr) {\n        *buf = *tm_ptr;\n    }\n    return tm_ptr;\n#endif\n}\n\n// This is for casting times on the system clock into datetime.datetime instances\ntemplate <typename Duration>\nclass type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {\npublic:\n    using type = std::chrono::time_point<std::chrono::system_clock, Duration>;\n    bool load(handle src, bool) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        if (!src) {\n            return false;\n        }\n\n        std::tm cal;\n        microseconds msecs;\n\n        if (PyDateTime_Check(src.ptr())) {\n            cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());\n            cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());\n            cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());\n            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());\n            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;\n            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;\n            cal.tm_isdst = -1;\n            msecs = microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));\n        } else if (PyDate_Check(src.ptr())) {\n            cal.tm_sec = 0;\n            cal.tm_min = 0;\n            cal.tm_hour = 0;\n            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());\n            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;\n            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;\n            cal.tm_isdst = -1;\n            msecs = microseconds(0);\n        } else if (PyTime_Check(src.ptr())) {\n            cal.tm_sec = PyDateTime_TIME_GET_SECOND(src.ptr());\n            cal.tm_min = PyDateTime_TIME_GET_MINUTE(src.ptr());\n            cal.tm_hour = PyDateTime_TIME_GET_HOUR(src.ptr());\n            cal.tm_mday = 1;  // This date (day, month, year) = (1, 0, 70)\n            cal.tm_mon = 0;   // represents 1-Jan-1970, which is the first\n            cal.tm_year = 70; // earliest available date for Python's datetime\n            cal.tm_isdst = -1;\n            msecs = microseconds(PyDateTime_TIME_GET_MICROSECOND(src.ptr()));\n        } else {\n            return false;\n        }\n\n        value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);\n        return true;\n    }\n\n    static handle cast(const std::chrono::time_point<std::chrono::system_clock, Duration> &src,\n                       return_value_policy /* policy */,\n                       handle /* parent */) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        // Get out microseconds, and make sure they are positive, to avoid bug in eastern\n        // hemisphere time zones (cfr. https://github.com/pybind/pybind11/issues/2417)\n        using us_t = duration<int, std::micro>;\n        auto us = duration_cast<us_t>(src.time_since_epoch() % seconds(1));\n        if (us.count() < 0) {\n            us += seconds(1);\n        }\n\n        // Subtract microseconds BEFORE `system_clock::to_time_t`, because:\n        // > If std::time_t has lower precision, it is implementation-defined whether the value is\n        // rounded or truncated. (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t)\n        std::time_t tt\n            = system_clock::to_time_t(time_point_cast<system_clock::duration>(src - us));\n\n        std::tm localtime;\n        std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime);\n        if (!localtime_ptr) {\n            throw cast_error(\"Unable to represent system_clock in local time\");\n        }\n        return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,\n                                          localtime.tm_mon + 1,\n                                          localtime.tm_mday,\n                                          localtime.tm_hour,\n                                          localtime.tm_min,\n                                          localtime.tm_sec,\n                                          us.count());\n    }\n    PYBIND11_TYPE_CASTER(type, const_name(\"datetime.datetime\"));\n};\n\n// Other clocks that are not the system clock are not measured as datetime.datetime objects\n// since they are not measured on calendar time. So instead we just make them timedeltas\n// Or if they have passed us a time as a float we convert that\ntemplate <typename Clock, typename Duration>\nclass type_caster<std::chrono::time_point<Clock, Duration>>\n    : public duration_caster<std::chrono::time_point<Clock, Duration>> {};\n\ntemplate <typename Rep, typename Period>\nclass type_caster<std::chrono::duration<Rep, Period>>\n    : public duration_caster<std::chrono::duration<Rep, Period>> {};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/common.h",
    "content": "#include \"detail/common.h\"\n#warning \"Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'.\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/complex.h",
    "content": "/*\n    pybind11/complex.h: Complex number support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <complex>\n\n/// glibc defines I as a macro which breaks things, e.g., boost template names\n#ifdef I\n#    undef I\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\ntemplate <typename T>\nstruct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr const char c = format_descriptor<T>::c;\n    static constexpr const char value[3] = {'Z', c, '\\0'};\n    static std::string format() { return std::string(value); }\n};\n\n#ifndef PYBIND11_CPP17\n\ntemplate <typename T>\nconstexpr const char\n    format_descriptor<std::complex<T>,\n                      detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];\n\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T>\nstruct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr bool value = true;\n    static constexpr int index = is_fmt_numeric<T>::index + 3;\n};\n\ntemplate <typename T>\nclass type_caster<std::complex<T>> {\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (!convert && !PyComplex_Check(src.ptr())) {\n            return false;\n        }\n        Py_complex result = PyComplex_AsCComplex(src.ptr());\n        if (result.real == -1.0 && PyErr_Occurred()) {\n            PyErr_Clear();\n            return false;\n        }\n        value = std::complex<T>((T) result.real, (T) result.imag);\n        return true;\n    }\n\n    static handle\n    cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {\n        return PyComplex_FromDoubles((double) src.real(), (double) src.imag());\n    }\n\n    PYBIND11_TYPE_CASTER(std::complex<T>, const_name(\"complex\"));\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/class.h",
    "content": "/*\n    pybind11/detail/class.h: Python C API implementation details for py::class_\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../attr.h\"\n#include \"../options.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if !defined(PYPY_VERSION)\n#    define PYBIND11_BUILTIN_QUALNAME\n#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)\n#else\n// In PyPy, we still set __qualname__ so that we can produce reliable function type\n// signatures; in CPython this macro expands to nothing:\n#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)                                             \\\n        setattr((PyObject *) obj, \"__qualname__\", nameobj)\n#endif\n\ninline std::string get_fully_qualified_tp_name(PyTypeObject *type) {\n#if !defined(PYPY_VERSION)\n    return type->tp_name;\n#else\n    auto module_name = handle((PyObject *) type).attr(\"__module__\").cast<std::string>();\n    if (module_name == PYBIND11_BUILTINS_MODULE)\n        return type->tp_name;\n    else\n        return std::move(module_name) + \".\" + type->tp_name;\n#endif\n}\n\ninline PyTypeObject *type_incref(PyTypeObject *type) {\n    Py_INCREF(type);\n    return type;\n}\n\n#if !defined(PYPY_VERSION)\n\n/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.\nextern \"C\" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {\n    return PyProperty_Type.tp_descr_get(self, cls, cls);\n}\n\n/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.\nextern \"C\" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {\n    PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);\n    return PyProperty_Type.tp_descr_set(self, cls, value);\n}\n\n// Forward declaration to use in `make_static_property_type()`\ninline void enable_dynamic_attributes(PyHeapTypeObject *heap_type);\n\n/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`\n    methods are modified to always use the object type instead of a concrete instance.\n    Return value: New reference. */\ninline PyTypeObject *make_static_property_type() {\n    constexpr auto *name = \"pybind11_static_property\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_static_property_type(): error allocating type!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#    ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#    endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyProperty_Type);\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n    type->tp_descr_get = pybind11_static_get;\n    type->tp_descr_set = pybind11_static_set;\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"make_static_property_type(): failure in PyType_Ready()!\");\n    }\n\n#    if PY_VERSION_HEX >= 0x030C0000\n    // PRE 3.12 FEATURE FREEZE. PLEASE REVIEW AFTER FREEZE.\n    // Since Python-3.12 property-derived types are required to\n    // have dynamic attributes (to set `__doc__`)\n    enable_dynamic_attributes(heap_type);\n#    endif\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    return type;\n}\n\n#else // PYPY\n\n/** PyPy has some issues with the above C API, so we evaluate Python code instead.\n    This function will only be called once so performance isn't really a concern.\n    Return value: New reference. */\ninline PyTypeObject *make_static_property_type() {\n    auto d = dict();\n    PyObject *result = PyRun_String(R\"(\\\nclass pybind11_static_property(property):\n    def __get__(self, obj, cls):\n        return property.__get__(self, cls, cls)\n\n    def __set__(self, obj, value):\n        cls = obj if isinstance(obj, type) else type(obj)\n        property.__set__(self, cls, value)\n)\",\n                                    Py_file_input,\n                                    d.ptr(),\n                                    d.ptr());\n    if (result == nullptr)\n        throw error_already_set();\n    Py_DECREF(result);\n    return (PyTypeObject *) d[\"pybind11_static_property\"].cast<object>().release().ptr();\n}\n\n#endif // PYPY\n\n/** Types with static properties need to handle `Type.static_prop = x` in a specific way.\n    By default, Python replaces the `static_property` itself, but for wrapped C++ types\n    we need to call `static_property.__set__()` in order to propagate the new value to\n    the underlying C++ data structure. */\nextern \"C\" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {\n    // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw\n    // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).\n    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);\n\n    // The following assignment combinations are possible:\n    //   1. `Type.static_prop = value`             --> descr_set: `Type.static_prop.__set__(value)`\n    //   2. `Type.static_prop = other_static_prop` --> setattro:  replace existing `static_prop`\n    //   3. `Type.regular_attribute = value`       --> setattro:  regular attribute assignment\n    auto *const static_prop = (PyObject *) get_internals().static_property_type;\n    const auto call_descr_set = (descr != nullptr) && (value != nullptr)\n                                && (PyObject_IsInstance(descr, static_prop) != 0)\n                                && (PyObject_IsInstance(value, static_prop) == 0);\n    if (call_descr_set) {\n        // Call `static_property.__set__()` instead of replacing the `static_property`.\n#if !defined(PYPY_VERSION)\n        return Py_TYPE(descr)->tp_descr_set(descr, obj, value);\n#else\n        if (PyObject *result = PyObject_CallMethod(descr, \"__set__\", \"OO\", obj, value)) {\n            Py_DECREF(result);\n            return 0;\n        } else {\n            return -1;\n        }\n#endif\n    } else {\n        // Replace existing attribute.\n        return PyType_Type.tp_setattro(obj, name, value);\n    }\n}\n\n/**\n * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing\n * methods via cls.attr(\"m2\") = cls.attr(\"m1\"): instead the tp_descr_get returns a plain function,\n * when called on a class, or a PyMethod, when called on an instance.  Override that behaviour here\n * to do a special case bypass for PyInstanceMethod_Types.\n */\nextern \"C\" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {\n    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);\n    if (descr && PyInstanceMethod_Check(descr)) {\n        Py_INCREF(descr);\n        return descr;\n    }\n    return PyType_Type.tp_getattro(obj, name);\n}\n\n/// metaclass `__call__` function that is used to create all pybind11 objects.\nextern \"C\" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {\n\n    // use the default metaclass call to create/initialize the object\n    PyObject *self = PyType_Type.tp_call(type, args, kwargs);\n    if (self == nullptr) {\n        return nullptr;\n    }\n\n    // This must be a pybind11 instance\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n\n    // Ensure that the base __init__ function(s) were called\n    for (const auto &vh : values_and_holders(instance)) {\n        if (!vh.holder_constructed()) {\n            PyErr_Format(PyExc_TypeError,\n                         \"%.200s.__init__() must be called when overriding __init__\",\n                         get_fully_qualified_tp_name(vh.type->type).c_str());\n            Py_DECREF(self);\n            return nullptr;\n        }\n    }\n\n    return self;\n}\n\n/// Cleanup the type-info for a pybind11-registered type.\nextern \"C\" inline void pybind11_meta_dealloc(PyObject *obj) {\n    auto *type = (PyTypeObject *) obj;\n    auto &internals = get_internals();\n\n    // A pybind11-registered type will:\n    // 1) be found in internals.registered_types_py\n    // 2) have exactly one associated `detail::type_info`\n    auto found_type = internals.registered_types_py.find(type);\n    if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1\n        && found_type->second[0]->type == type) {\n\n        auto *tinfo = found_type->second[0];\n        auto tindex = std::type_index(*tinfo->cpptype);\n        internals.direct_conversions.erase(tindex);\n\n        if (tinfo->module_local) {\n            get_local_internals().registered_types_cpp.erase(tindex);\n        } else {\n            internals.registered_types_cpp.erase(tindex);\n        }\n        internals.registered_types_py.erase(tinfo->type);\n\n        // Actually just `std::erase_if`, but that's only available in C++20\n        auto &cache = internals.inactive_override_cache;\n        for (auto it = cache.begin(), last = cache.end(); it != last;) {\n            if (it->first == (PyObject *) tinfo->type) {\n                it = cache.erase(it);\n            } else {\n                ++it;\n            }\n        }\n\n        delete tinfo;\n    }\n\n    PyType_Type.tp_dealloc(obj);\n}\n\n/** This metaclass is assigned by default to all pybind11 types and is required in order\n    for static properties to function correctly. Users may override this using `py::metaclass`.\n    Return value: New reference. */\ninline PyTypeObject *make_default_metaclass() {\n    constexpr auto *name = \"pybind11_type\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_default_metaclass(): error allocating metaclass!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyType_Type);\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n\n    type->tp_call = pybind11_meta_call;\n\n    type->tp_setattro = pybind11_meta_setattro;\n    type->tp_getattro = pybind11_meta_getattro;\n\n    type->tp_dealloc = pybind11_meta_dealloc;\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"make_default_metaclass(): failure in PyType_Ready()!\");\n    }\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    return type;\n}\n\n/// For multiple inheritance types we need to recursively register/deregister base pointers for any\n/// base classes with pointers that are difference from the instance value pointer so that we can\n/// correctly recognize an offset base class pointer. This calls a function with any offset base\n/// ptrs.\ninline void traverse_offset_bases(void *valueptr,\n                                  const detail::type_info *tinfo,\n                                  instance *self,\n                                  bool (*f)(void * /*parentptr*/, instance * /*self*/)) {\n    for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {\n        if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {\n            for (auto &c : parent_tinfo->implicit_casts) {\n                if (c.first == tinfo->cpptype) {\n                    auto *parentptr = c.second(valueptr);\n                    if (parentptr != valueptr) {\n                        f(parentptr, self);\n                    }\n                    traverse_offset_bases(parentptr, parent_tinfo, self, f);\n                    break;\n                }\n            }\n        }\n    }\n}\n\ninline bool register_instance_impl(void *ptr, instance *self) {\n    get_internals().registered_instances.emplace(ptr, self);\n    return true; // unused, but gives the same signature as the deregister func\n}\ninline bool deregister_instance_impl(void *ptr, instance *self) {\n    auto &registered_instances = get_internals().registered_instances;\n    auto range = registered_instances.equal_range(ptr);\n    for (auto it = range.first; it != range.second; ++it) {\n        if (self == it->second) {\n            registered_instances.erase(it);\n            return true;\n        }\n    }\n    return false;\n}\n\ninline void register_instance(instance *self, void *valptr, const type_info *tinfo) {\n    register_instance_impl(valptr, self);\n    if (!tinfo->simple_ancestors) {\n        traverse_offset_bases(valptr, tinfo, self, register_instance_impl);\n    }\n}\n\ninline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {\n    bool ret = deregister_instance_impl(valptr, self);\n    if (!tinfo->simple_ancestors) {\n        traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);\n    }\n    return ret;\n}\n\n/// Instance creation function for all pybind11 types. It allocates the internal instance layout\n/// for holding C++ objects and holders.  Allocation is done lazily (the first time the instance is\n/// cast to a reference or pointer), and initialization is done by an `__init__` function.\ninline PyObject *make_new_instance(PyTypeObject *type) {\n#if defined(PYPY_VERSION)\n    // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first\n    // inherited object is a plain Python type (i.e. not derived from an extension type).  Fix it.\n    ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));\n    if (type->tp_basicsize < instance_size) {\n        type->tp_basicsize = instance_size;\n    }\n#endif\n    PyObject *self = type->tp_alloc(type, 0);\n    auto *inst = reinterpret_cast<instance *>(self);\n    // Allocate the value/holder internals:\n    inst->allocate_layout();\n\n    return self;\n}\n\n/// Instance creation function for all pybind11 types. It only allocates space for the\n/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.\nextern \"C\" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {\n    return make_new_instance(type);\n}\n\n/// An `__init__` function constructs the C++ object. Users should provide at least one\n/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the\n/// following default function will be used which simply throws an exception.\nextern \"C\" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {\n    PyTypeObject *type = Py_TYPE(self);\n    std::string msg = get_fully_qualified_tp_name(type) + \": No constructor defined!\";\n    PyErr_SetString(PyExc_TypeError, msg.c_str());\n    return -1;\n}\n\ninline void add_patient(PyObject *nurse, PyObject *patient) {\n    auto &internals = get_internals();\n    auto *instance = reinterpret_cast<detail::instance *>(nurse);\n    instance->has_patients = true;\n    Py_INCREF(patient);\n    internals.patients[nurse].push_back(patient);\n}\n\ninline void clear_patients(PyObject *self) {\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n    auto &internals = get_internals();\n    auto pos = internals.patients.find(self);\n    assert(pos != internals.patients.end());\n    // Clearing the patients can cause more Python code to run, which\n    // can invalidate the iterator. Extract the vector of patients\n    // from the unordered_map first.\n    auto patients = std::move(pos->second);\n    internals.patients.erase(pos);\n    instance->has_patients = false;\n    for (PyObject *&patient : patients) {\n        Py_CLEAR(patient);\n    }\n}\n\n/// Clears all internal data from the instance and removes it from registered instances in\n/// preparation for deallocation.\ninline void clear_instance(PyObject *self) {\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n\n    // Deallocate any values/holders, if present:\n    for (auto &v_h : values_and_holders(instance)) {\n        if (v_h) {\n\n            // We have to deregister before we call dealloc because, for virtual MI types, we still\n            // need to be able to get the parent pointers.\n            if (v_h.instance_registered()\n                && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {\n                pybind11_fail(\n                    \"pybind11_object_dealloc(): Tried to deallocate unregistered instance!\");\n            }\n\n            if (instance->owned || v_h.holder_constructed()) {\n                v_h.type->dealloc(v_h);\n            }\n        }\n    }\n    // Deallocate the value/holder layout internals:\n    instance->deallocate_layout();\n\n    if (instance->weakrefs) {\n        PyObject_ClearWeakRefs(self);\n    }\n\n    PyObject **dict_ptr = _PyObject_GetDictPtr(self);\n    if (dict_ptr) {\n        Py_CLEAR(*dict_ptr);\n    }\n\n    if (instance->has_patients) {\n        clear_patients(self);\n    }\n}\n\n/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`\n/// to destroy the C++ object itself, while the rest is Python bookkeeping.\nextern \"C\" inline void pybind11_object_dealloc(PyObject *self) {\n    clear_instance(self);\n\n    auto *type = Py_TYPE(self);\n    type->tp_free(self);\n\n#if PY_VERSION_HEX < 0x03080000\n    // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called\n    // as part of a derived type's dealloc, in which case we're not allowed to decref\n    // the type here. For cross-module compatibility, we shouldn't compare directly\n    // with `pybind11_object_dealloc`, but with the common one stashed in internals.\n    auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;\n    if (type->tp_dealloc == pybind11_object_type->tp_dealloc)\n        Py_DECREF(type);\n#else\n    // This was not needed before Python 3.8 (Python issue 35810)\n    // https://github.com/pybind/pybind11/issues/1946\n    Py_DECREF(type);\n#endif\n}\n\nstd::string error_string();\n\n/** Create the type which can be used as a common base for all classes.  This is\n    needed in order to satisfy Python's requirements for multiple inheritance.\n    Return value: New reference. */\ninline PyObject *make_object_base_type(PyTypeObject *metaclass) {\n    constexpr auto *name = \"pybind11_object\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_object_base_type(): error allocating type!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyBaseObject_Type);\n    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n\n    type->tp_new = pybind11_object_new;\n    type->tp_init = pybind11_object_init;\n    type->tp_dealloc = pybind11_object_dealloc;\n\n    /* Support weak references (needed for the keep_alive feature) */\n    type->tp_weaklistoffset = offsetof(instance, weakrefs);\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"PyType_Ready failed in make_object_base_type(): \" + error_string());\n    }\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));\n    return (PyObject *) heap_type;\n}\n\n/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.\nextern \"C\" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    Py_VISIT(dict);\n// https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse\n#if PY_VERSION_HEX >= 0x03090000\n    Py_VISIT(Py_TYPE(self));\n#endif\n    return 0;\n}\n\n/// dynamic_attr: Allow the GC to clear the dictionary.\nextern \"C\" inline int pybind11_clear(PyObject *self) {\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    Py_CLEAR(dict);\n    return 0;\n}\n\n/// Give instances of this type a `__dict__` and opt into garbage collection.\ninline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {\n    auto *type = &heap_type->ht_type;\n    type->tp_flags |= Py_TPFLAGS_HAVE_GC;\n#if PY_VERSION_HEX < 0x030B0000\n    type->tp_dictoffset = type->tp_basicsize;           // place dict at the end\n    type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it\n#else\n    type->tp_flags |= Py_TPFLAGS_MANAGED_DICT;\n#endif\n    type->tp_traverse = pybind11_traverse;\n    type->tp_clear = pybind11_clear;\n\n    static PyGetSetDef getset[] = {{\n#if PY_VERSION_HEX < 0x03070000\n                                       const_cast<char *>(\"__dict__\"),\n#else\n                                       \"__dict__\",\n#endif\n                                       PyObject_GenericGetDict,\n                                       PyObject_GenericSetDict,\n                                       nullptr,\n                                       nullptr},\n                                   {nullptr, nullptr, nullptr, nullptr, nullptr}};\n    type->tp_getset = getset;\n}\n\n/// buffer_protocol: Fill in the view as specified by flags.\nextern \"C\" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {\n    // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).\n    type_info *tinfo = nullptr;\n    for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {\n        tinfo = get_type_info((PyTypeObject *) type.ptr());\n        if (tinfo && tinfo->get_buffer) {\n            break;\n        }\n    }\n    if (view == nullptr || !tinfo || !tinfo->get_buffer) {\n        if (view) {\n            view->obj = nullptr;\n        }\n        PyErr_SetString(PyExc_BufferError, \"pybind11_getbuffer(): Internal error\");\n        return -1;\n    }\n    std::memset(view, 0, sizeof(Py_buffer));\n    buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);\n    if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {\n        delete info;\n        // view->obj = nullptr;  // Was just memset to 0, so not necessary\n        PyErr_SetString(PyExc_BufferError, \"Writable buffer requested for readonly storage\");\n        return -1;\n    }\n    view->obj = obj;\n    view->ndim = 1;\n    view->internal = info;\n    view->buf = info->ptr;\n    view->itemsize = info->itemsize;\n    view->len = view->itemsize;\n    for (auto s : info->shape) {\n        view->len *= s;\n    }\n    view->readonly = static_cast<int>(info->readonly);\n    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {\n        view->format = const_cast<char *>(info->format.c_str());\n    }\n    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {\n        view->ndim = (int) info->ndim;\n        view->strides = info->strides.data();\n        view->shape = info->shape.data();\n    }\n    Py_INCREF(view->obj);\n    return 0;\n}\n\n/// buffer_protocol: Release the resources of the buffer.\nextern \"C\" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {\n    delete (buffer_info *) view->internal;\n}\n\n/// Give this type a buffer interface.\ninline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {\n    heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;\n\n    heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;\n    heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;\n}\n\n/** Create a brand new Python type according to the `type_record` specification.\n    Return value: New reference. */\ninline PyObject *make_new_python_type(const type_record &rec) {\n    auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));\n\n    auto qualname = name;\n    if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, \"__qualname__\")) {\n        qualname = reinterpret_steal<object>(\n            PyUnicode_FromFormat(\"%U.%U\", rec.scope.attr(\"__qualname__\").ptr(), name.ptr()));\n    }\n\n    object module_;\n    if (rec.scope) {\n        if (hasattr(rec.scope, \"__module__\")) {\n            module_ = rec.scope.attr(\"__module__\");\n        } else if (hasattr(rec.scope, \"__name__\")) {\n            module_ = rec.scope.attr(\"__name__\");\n        }\n    }\n\n    const auto *full_name = c_str(\n#if !defined(PYPY_VERSION)\n        module_ ? str(module_).cast<std::string>() + \".\" + rec.name :\n#endif\n                rec.name);\n\n    char *tp_doc = nullptr;\n    if (rec.doc && options::show_user_defined_docstrings()) {\n        /* Allocate memory for docstring (using PyObject_MALLOC, since\n           Python will free this later on) */\n        size_t size = std::strlen(rec.doc) + 1;\n        tp_doc = (char *) PyObject_MALLOC(size);\n        std::memcpy((void *) tp_doc, rec.doc, size);\n    }\n\n    auto &internals = get_internals();\n    auto bases = tuple(rec.bases);\n    auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *metaclass\n        = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;\n\n    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);\n    if (!heap_type) {\n        pybind11_fail(std::string(rec.name) + \": Unable to create type object!\");\n    }\n\n    heap_type->ht_name = name.release().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = qualname.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = full_name;\n    type->tp_doc = tp_doc;\n    type->tp_base = type_incref((PyTypeObject *) base);\n    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));\n    if (!bases.empty()) {\n        type->tp_bases = bases.release().ptr();\n    }\n\n    /* Don't inherit base __init__ */\n    type->tp_init = pybind11_object_init;\n\n    /* Supported protocols */\n    type->tp_as_number = &heap_type->as_number;\n    type->tp_as_sequence = &heap_type->as_sequence;\n    type->tp_as_mapping = &heap_type->as_mapping;\n    type->tp_as_async = &heap_type->as_async;\n\n    /* Flags */\n    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;\n    if (!rec.is_final) {\n        type->tp_flags |= Py_TPFLAGS_BASETYPE;\n    }\n\n    if (rec.dynamic_attr) {\n        enable_dynamic_attributes(heap_type);\n    }\n\n    if (rec.buffer_protocol) {\n        enable_buffer_protocol(heap_type);\n    }\n\n    if (rec.custom_type_setup_callback) {\n        rec.custom_type_setup_callback(heap_type);\n    }\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(std::string(rec.name) + \": PyType_Ready failed: \" + error_string());\n    }\n\n    assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));\n\n    /* Register type with the parent scope */\n    if (rec.scope) {\n        setattr(rec.scope, rec.name, (PyObject *) type);\n    } else {\n        Py_INCREF(type); // Keep it alive forever (reference leak)\n    }\n\n    if (module_) { // Needed by pydoc\n        setattr((PyObject *) type, \"__module__\", module_);\n    }\n\n    PYBIND11_SET_OLDPY_QUALNAME(type, qualname);\n\n    return (PyObject *) type;\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/common.h",
    "content": "/*\n    pybind11/detail/common.h -- Basic macros\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#define PYBIND11_VERSION_MAJOR 2\n#define PYBIND11_VERSION_MINOR 11\n#define PYBIND11_VERSION_PATCH 0.dev1\n\n// Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html\n// Additional convention: 0xD = dev\n#define PYBIND11_VERSION_HEX 0x020B00D1\n\n#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {\n#define PYBIND11_NAMESPACE_END(name) }\n\n// Robust support for some features and loading modules compiled against different pybind versions\n// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute\n// on the main `pybind11` namespace.\n#if !defined(PYBIND11_NAMESPACE)\n#    ifdef __GNUG__\n#        define PYBIND11_NAMESPACE pybind11 __attribute__((visibility(\"hidden\")))\n#    else\n#        define PYBIND11_NAMESPACE pybind11\n#    endif\n#endif\n\n#if !(defined(_MSC_VER) && __cplusplus == 199711L)\n#    if __cplusplus >= 201402L\n#        define PYBIND11_CPP14\n#        if __cplusplus >= 201703L\n#            define PYBIND11_CPP17\n#            if __cplusplus >= 202002L\n#                define PYBIND11_CPP20\n// Please update tests/pybind11_tests.cpp `cpp_std()` when adding a macro here.\n#            endif\n#        endif\n#    endif\n#elif defined(_MSC_VER) && __cplusplus == 199711L\n// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully\n// implemented). Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3\n// or newer.\n#    if _MSVC_LANG >= 201402L\n#        define PYBIND11_CPP14\n#        if _MSVC_LANG > 201402L\n#            define PYBIND11_CPP17\n#            if _MSVC_LANG >= 202002L\n#                define PYBIND11_CPP20\n#            endif\n#        endif\n#    endif\n#endif\n\n// Compiler version assertions\n#if defined(__INTEL_COMPILER)\n#    if __INTEL_COMPILER < 1800\n#        error pybind11 requires Intel C++ compiler v18 or newer\n#    elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14)\n#        error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14.\n#    endif\n/* The following pragma cannot be pop'ed:\n   https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */\n#    pragma warning disable 2196 // warning #2196: routine is both \"inline\" and \"noinline\"\n#elif defined(__clang__) && !defined(__apple_build_version__)\n#    if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3)\n#        error pybind11 requires clang 3.3 or newer\n#    endif\n#elif defined(__clang__)\n// Apple changes clang version macros to its Xcode version; the first Xcode release based on\n// (upstream) clang 3.3 was Xcode 5:\n#    if __clang_major__ < 5\n#        error pybind11 requires Xcode/clang 5.0 or newer\n#    endif\n#elif defined(__GNUG__)\n#    if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)\n#        error pybind11 requires gcc 4.8 or newer\n#    endif\n#elif defined(_MSC_VER)\n#    if _MSC_VER < 1910\n#        error pybind11 2.10+ requires MSVC 2017 or newer\n#    endif\n#endif\n\n#if !defined(PYBIND11_EXPORT)\n#    if defined(WIN32) || defined(_WIN32)\n#        define PYBIND11_EXPORT __declspec(dllexport)\n#    else\n#        define PYBIND11_EXPORT __attribute__((visibility(\"default\")))\n#    endif\n#endif\n\n#if !defined(PYBIND11_EXPORT_EXCEPTION)\n#    if defined(__apple_build_version__)\n#        define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT\n#    else\n#        define PYBIND11_EXPORT_EXCEPTION\n#    endif\n#endif\n\n// For CUDA, GCC7, GCC8:\n// PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`.\n// When defining PYBIND11_NOINLINE_FORCED, it is best to also use `-Wno-attributes`.\n// However, the measured shared-library size saving when using noinline are only\n// 1.7% for CUDA, -0.2% for GCC7, and 0.0% for GCC8 (using -DCMAKE_BUILD_TYPE=MinSizeRel,\n// the default under pybind11/tests).\n#if !defined(PYBIND11_NOINLINE_FORCED)                                                            \\\n    && (defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)))\n#    define PYBIND11_NOINLINE_DISABLED\n#endif\n\n// The PYBIND11_NOINLINE macro is for function DEFINITIONS.\n// In contrast, FORWARD DECLARATIONS should never use this macro:\n// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions\n#if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation.\n#    define PYBIND11_NOINLINE inline\n#elif defined(_MSC_VER)\n#    define PYBIND11_NOINLINE __declspec(noinline) inline\n#else\n#    define PYBIND11_NOINLINE __attribute__((noinline)) inline\n#endif\n\n#if defined(__MINGW32__)\n// For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared\n// whether it is used or not\n#    define PYBIND11_DEPRECATED(reason)\n#elif defined(PYBIND11_CPP14)\n#    define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]]\n#else\n#    define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason)))\n#endif\n\n#if defined(PYBIND11_CPP17)\n#    define PYBIND11_MAYBE_UNUSED [[maybe_unused]]\n#elif defined(_MSC_VER) && !defined(__clang__)\n#    define PYBIND11_MAYBE_UNUSED\n#else\n#    define PYBIND11_MAYBE_UNUSED __attribute__((__unused__))\n#endif\n\n/* Don't let Python.h #define (v)snprintf as macro because they are implemented\n   properly in Visual Studio since 2015. */\n#if defined(_MSC_VER)\n#    define HAVE_SNPRINTF 1\n#endif\n\n/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode\n#if defined(_MSC_VER)\n#    pragma warning(push)\n// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)\n#    pragma warning(disable : 4505)\n#    if defined(_DEBUG) && !defined(Py_DEBUG)\n// Workaround for a VS 2022 issue.\n// NOTE: This workaround knowingly violates the Python.h include order requirement:\n// https://docs.python.org/3/c-api/intro.html#include-files\n// See https://github.com/pybind/pybind11/pull/3497 for full context.\n#        include <yvals.h>\n#        if _MSVC_STL_VERSION >= 143\n#            include <crtdefs.h>\n#        endif\n#        define PYBIND11_DEBUG_MARKER\n#        undef _DEBUG\n#    endif\n#endif\n\n// https://en.cppreference.com/w/c/chrono/localtime\n#if defined(__STDC_LIB_EXT1__) && !defined(__STDC_WANT_LIB_EXT1__)\n#    define __STDC_WANT_LIB_EXT1__\n#endif\n\n#ifdef __has_include\n// std::optional (but including it in c++14 mode isn't allowed)\n#    if defined(PYBIND11_CPP17) && __has_include(<optional>)\n#        define PYBIND11_HAS_OPTIONAL 1\n#    endif\n// std::experimental::optional (but not allowed in c++11 mode)\n#    if defined(PYBIND11_CPP14) && (__has_include(<experimental/optional>) && \\\n                                 !__has_include(<optional>))\n#        define PYBIND11_HAS_EXP_OPTIONAL 1\n#    endif\n// std::variant\n#    if defined(PYBIND11_CPP17) && __has_include(<variant>)\n#        define PYBIND11_HAS_VARIANT 1\n#    endif\n#elif defined(_MSC_VER) && defined(PYBIND11_CPP17)\n#    define PYBIND11_HAS_OPTIONAL 1\n#    define PYBIND11_HAS_VARIANT 1\n#endif\n\n#if defined(PYBIND11_CPP17)\n#    if defined(__has_include)\n#        if __has_include(<string_view>)\n#            define PYBIND11_HAS_STRING_VIEW\n#        endif\n#    elif defined(_MSC_VER)\n#        define PYBIND11_HAS_STRING_VIEW\n#    endif\n#endif\n\n#include <Python.h>\n// Reminder: WITH_THREAD is always defined if PY_VERSION_HEX >= 0x03070000\n#if PY_VERSION_HEX < 0x03060000\n#    error \"PYTHON < 3.6 IS UNSUPPORTED. pybind11 v2.9 was the last to support Python 2 and 3.5.\"\n#endif\n#include <frameobject.h>\n#include <pythread.h>\n\n/* Python #defines overrides on all sorts of core functions, which\n   tends to weak havok in C++ codebases that expect these to work\n   like regular functions (potentially with several overloads) */\n#if defined(isalnum)\n#    undef isalnum\n#    undef isalpha\n#    undef islower\n#    undef isspace\n#    undef isupper\n#    undef tolower\n#    undef toupper\n#endif\n\n#if defined(copysign)\n#    undef copysign\n#endif\n\n#if defined(PYPY_VERSION) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n#    define PYBIND11_SIMPLE_GIL_MANAGEMENT\n#endif\n\n#if defined(_MSC_VER)\n#    if defined(PYBIND11_DEBUG_MARKER)\n#        define _DEBUG\n#        undef PYBIND11_DEBUG_MARKER\n#    endif\n#    pragma warning(pop)\n#endif\n\n#include <cstddef>\n#include <cstring>\n#include <exception>\n#include <forward_list>\n#include <memory>\n#include <stdexcept>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <unordered_map>\n#include <unordered_set>\n#include <vector>\n#if defined(__has_include)\n#    if __has_include(<version>)\n#        include <version>\n#    endif\n#endif\n\n// Must be after including <version> or one of the other headers specified by the standard\n#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L\n#    define PYBIND11_HAS_U8STRING\n#endif\n\n// #define PYBIND11_STR_LEGACY_PERMISSIVE\n// If DEFINED, pybind11::str can hold PyUnicodeObject or PyBytesObject\n//             (probably surprising and never documented, but this was the\n//             legacy behavior until and including v2.6.x). As a side-effect,\n//             pybind11::isinstance<str>() is true for both pybind11::str and\n//             pybind11::bytes.\n// If UNDEFINED, pybind11::str can only hold PyUnicodeObject, and\n//               pybind11::isinstance<str>() is true only for pybind11::str.\n//               However, for Python 2 only (!), the pybind11::str caster\n//               implicitly decoded bytes to PyUnicodeObject. This was to ease\n//               the transition from the legacy behavior to the non-permissive\n//               behavior.\n\n/// Compatibility macros for Python 2 / Python 3 versions TODO: remove\n#define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)\n#define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check\n#define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION\n#define PYBIND11_BYTES_CHECK PyBytes_Check\n#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString\n#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize\n#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize\n#define PYBIND11_BYTES_AS_STRING PyBytes_AsString\n#define PYBIND11_BYTES_SIZE PyBytes_Size\n#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)\n#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)\n#define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))\n#define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))\n#define PYBIND11_BYTES_NAME \"bytes\"\n#define PYBIND11_STRING_NAME \"str\"\n#define PYBIND11_SLICE_OBJECT PyObject\n#define PYBIND11_FROM_STRING PyUnicode_FromString\n#define PYBIND11_STR_TYPE ::pybind11::str\n#define PYBIND11_BOOL_ATTR \"__bool__\"\n#define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool)\n#define PYBIND11_BUILTINS_MODULE \"builtins\"\n// Providing a separate declaration to make Clang's -Wmissing-prototypes happy.\n// See comment for PYBIND11_MODULE below for why this is marked \"maybe unused\".\n#define PYBIND11_PLUGIN_IMPL(name)                                                                \\\n    extern \"C\" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT PyObject *PyInit_##name();                   \\\n    extern \"C\" PYBIND11_EXPORT PyObject *PyInit_##name()\n\n#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code\n#define PYBIND11_STRINGIFY(x) #x\n#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)\n#define PYBIND11_CONCAT(first, second) first##second\n#define PYBIND11_ENSURE_INTERNALS_READY pybind11::detail::get_internals();\n\n#define PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n    {                                                                                             \\\n        const char *compiled_ver                                                                  \\\n            = PYBIND11_TOSTRING(PY_MAJOR_VERSION) \".\" PYBIND11_TOSTRING(PY_MINOR_VERSION);        \\\n        const char *runtime_ver = Py_GetVersion();                                                \\\n        size_t len = std::strlen(compiled_ver);                                                   \\\n        if (std::strncmp(runtime_ver, compiled_ver, len) != 0                                     \\\n            || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) {                            \\\n            PyErr_Format(PyExc_ImportError,                                                       \\\n                         \"Python version mismatch: module was compiled for Python %s, \"           \\\n                         \"but the interpreter version is incompatible: %s.\",                      \\\n                         compiled_ver,                                                            \\\n                         runtime_ver);                                                            \\\n            return nullptr;                                                                       \\\n        }                                                                                         \\\n    }\n\n#define PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    catch (pybind11::error_already_set & e) {                                                     \\\n        pybind11::raise_from(e, PyExc_ImportError, \"initialization failed\");                      \\\n        return nullptr;                                                                           \\\n    }                                                                                             \\\n    catch (const std::exception &e) {                                                             \\\n        PyErr_SetString(PyExc_ImportError, e.what());                                             \\\n        return nullptr;                                                                           \\\n    }\n\n/** \\rst\n    ***Deprecated in favor of PYBIND11_MODULE***\n\n    This macro creates the entry point that will be invoked when the Python interpreter\n    imports a plugin library. Please create a `module_` in the function body and return\n    the pointer to its underlying Python object at the end.\n\n    .. code-block:: cpp\n\n        PYBIND11_PLUGIN(example) {\n            pybind11::module_ m(\"example\", \"pybind11 example plugin\");\n            /// Set up bindings here\n            return m.ptr();\n        }\n\\endrst */\n#define PYBIND11_PLUGIN(name)                                                                     \\\n    PYBIND11_DEPRECATED(\"PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE\")                     \\\n    static PyObject *pybind11_init();                                                             \\\n    PYBIND11_PLUGIN_IMPL(name) {                                                                  \\\n        PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n        PYBIND11_ENSURE_INTERNALS_READY                                                           \\\n        try {                                                                                     \\\n            return pybind11_init();                                                               \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    PyObject *pybind11_init()\n\n/** \\rst\n    This macro creates the entry point that will be invoked when the Python interpreter\n    imports an extension module. The module name is given as the fist argument and it\n    should not be in quotes. The second macro argument defines a variable of type\n    `py::module_` which can be used to initialize the module.\n\n    The entry point is marked as \"maybe unused\" to aid dead-code detection analysis:\n    since the entry point is typically only looked up at runtime and not referenced\n    during translation, it would otherwise appear as unused (\"dead\") code.\n\n    .. code-block:: cpp\n\n        PYBIND11_MODULE(example, m) {\n            m.doc() = \"pybind11 example module\";\n\n            // Add bindings here\n            m.def(\"foo\", []() {\n                return \"Hello, World!\";\n            });\n        }\n\\endrst */\n#define PYBIND11_MODULE(name, variable)                                                           \\\n    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name)            \\\n        PYBIND11_MAYBE_UNUSED;                                                                    \\\n    PYBIND11_MAYBE_UNUSED                                                                         \\\n    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \\\n    PYBIND11_PLUGIN_IMPL(name) {                                                                  \\\n        PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n        PYBIND11_ENSURE_INTERNALS_READY                                                           \\\n        auto m = ::pybind11::module_::create_extension_module(                                    \\\n            PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name));      \\\n        try {                                                                                     \\\n            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \\\n            return m.ptr();                                                                       \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ & (variable))\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nusing ssize_t = Py_ssize_t;\nusing size_t = std::size_t;\n\ntemplate <typename IntType>\ninline ssize_t ssize_t_cast(const IntType &val) {\n    static_assert(sizeof(IntType) <= sizeof(ssize_t), \"Implicit narrowing is not permitted.\");\n    return static_cast<ssize_t>(val);\n}\n\n/// Approach used to cast a previously unknown C++ instance into a Python object\nenum class return_value_policy : uint8_t {\n    /** This is the default return value policy, which falls back to the policy\n        return_value_policy::take_ownership when the return value is a pointer.\n        Otherwise, it uses return_value::move or return_value::copy for rvalue\n        and lvalue references, respectively. See below for a description of what\n        all of these different policies do. */\n    automatic = 0,\n\n    /** As above, but use policy return_value_policy::reference when the return\n        value is a pointer. This is the default conversion policy for function\n        arguments when calling Python functions manually from C++ code (i.e. via\n        handle::operator()). You probably won't need to use this. */\n    automatic_reference,\n\n    /** Reference an existing object (i.e. do not create a new copy) and take\n        ownership. Python will call the destructor and delete operator when the\n        object's reference count reaches zero. Undefined behavior ensues when\n        the C++ side does the same.. */\n    take_ownership,\n\n    /** Create a new copy of the returned object, which will be owned by\n        Python. This policy is comparably safe because the lifetimes of the two\n        instances are decoupled. */\n    copy,\n\n    /** Use std::move to move the return value contents into a new instance\n        that will be owned by Python. This policy is comparably safe because the\n        lifetimes of the two instances (move source and destination) are\n        decoupled. */\n    move,\n\n    /** Reference an existing object, but do not take ownership. The C++ side\n        is responsible for managing the object's lifetime and deallocating it\n        when it is no longer used. Warning: undefined behavior will ensue when\n        the C++ side deletes an object that is still referenced and used by\n        Python. */\n    reference,\n\n    /** This policy only applies to methods and properties. It references the\n        object without taking ownership similar to the above\n        return_value_policy::reference policy. In contrast to that policy, the\n        function or property's implicit this argument (called the parent) is\n        considered to be the the owner of the return value (the child).\n        pybind11 then couples the lifetime of the parent to the child via a\n        reference relationship that ensures that the parent cannot be garbage\n        collected while Python is still using the child. More advanced\n        variations of this scheme are also possible using combinations of\n        return_value_policy::reference and the keep_alive call policy */\n    reference_internal\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline static constexpr int log2(size_t n, int k = 0) {\n    return (n <= 1) ? k : log2(n >> 1, k + 1);\n}\n\n// Returns the size as a multiple of sizeof(void *), rounded up.\ninline static constexpr size_t size_in_ptrs(size_t s) {\n    return 1 + ((s - 1) >> log2(sizeof(void *)));\n}\n\n/**\n * The space to allocate for simple layout instance holders (see below) in multiple of the size of\n * a pointer (e.g.  2 means 16 bytes on 64-bit architectures).  The default is the minimum required\n * to holder either a std::unique_ptr or std::shared_ptr (which is almost always\n * sizeof(std::shared_ptr<T>)).\n */\nconstexpr size_t instance_simple_holder_in_ptrs() {\n    static_assert(sizeof(std::shared_ptr<int>) >= sizeof(std::unique_ptr<int>),\n                  \"pybind assumes std::shared_ptrs are at least as big as std::unique_ptrs\");\n    return size_in_ptrs(sizeof(std::shared_ptr<int>));\n}\n\n// Forward declarations\nstruct type_info;\nstruct value_and_holder;\n\nstruct nonsimple_values_and_holders {\n    void **values_and_holders;\n    uint8_t *status;\n};\n\n/// The 'instance' type which needs to be standard layout (need to be able to use 'offsetof')\nstruct instance {\n    PyObject_HEAD\n    /// Storage for pointers and holder; see simple_layout, below, for a description\n    union {\n        void *simple_value_holder[1 + instance_simple_holder_in_ptrs()];\n        nonsimple_values_and_holders nonsimple;\n    };\n    /// Weak references\n    PyObject *weakrefs;\n    /// If true, the pointer is owned which means we're free to manage it with a holder.\n    bool owned : 1;\n    /**\n     * An instance has two possible value/holder layouts.\n     *\n     * Simple layout (when this flag is true), means the `simple_value_holder` is set with a\n     * pointer and the holder object governing that pointer, i.e. [val1*][holder].  This layout is\n     * applied whenever there is no python-side multiple inheritance of bound C++ types *and* the\n     * type's holder will fit in the default space (which is large enough to hold either a\n     * std::unique_ptr or std::shared_ptr).\n     *\n     * Non-simple layout applies when using custom holders that require more space than\n     * `shared_ptr` (which is typically the size of two pointers), or when multiple inheritance is\n     * used on the python side.  Non-simple layout allocates the required amount of memory to have\n     * multiple bound C++ classes as parents.  Under this layout, `nonsimple.values_and_holders` is\n     * set to a pointer to allocated space of the required space to hold a sequence of value\n     * pointers and holders followed `status`, a set of bit flags (1 byte each), i.e.\n     * [val1*][holder1][val2*][holder2]...[bb...]  where each [block] is rounded up to a multiple\n     * of `sizeof(void *)`.  `nonsimple.status` is, for convenience, a pointer to the beginning of\n     * the [bb...] block (but not independently allocated).\n     *\n     * Status bits indicate whether the associated holder is constructed (&\n     * status_holder_constructed) and whether the value pointer is registered (&\n     * status_instance_registered) in `registered_instances`.\n     */\n    bool simple_layout : 1;\n    /// For simple layout, tracks whether the holder has been constructed\n    bool simple_holder_constructed : 1;\n    /// For simple layout, tracks whether the instance is registered in `registered_instances`\n    bool simple_instance_registered : 1;\n    /// If true, get_internals().patients has an entry for this object\n    bool has_patients : 1;\n\n    /// Initializes all of the above type/values/holders data (but not the instance values\n    /// themselves)\n    void allocate_layout();\n\n    /// Destroys/deallocates all of the above\n    void deallocate_layout();\n\n    /// Returns the value_and_holder wrapper for the given type (or the first, if `find_type`\n    /// omitted).  Returns a default-constructed (with `.inst = nullptr`) object on failure if\n    /// `throw_if_missing` is false.\n    value_and_holder get_value_and_holder(const type_info *find_type = nullptr,\n                                          bool throw_if_missing = true);\n\n    /// Bit values for the non-simple status flags\n    static constexpr uint8_t status_holder_constructed = 1;\n    static constexpr uint8_t status_instance_registered = 2;\n};\n\nstatic_assert(std::is_standard_layout<instance>::value,\n              \"Internal error: `pybind11::detail::instance` is not standard layout!\");\n\n/// from __cpp_future__ import (convenient aliases from C++14/17)\n#if defined(PYBIND11_CPP14)\nusing std::conditional_t;\nusing std::enable_if_t;\nusing std::remove_cv_t;\nusing std::remove_reference_t;\n#else\ntemplate <bool B, typename T = void>\nusing enable_if_t = typename std::enable_if<B, T>::type;\ntemplate <bool B, typename T, typename F>\nusing conditional_t = typename std::conditional<B, T, F>::type;\ntemplate <typename T>\nusing remove_cv_t = typename std::remove_cv<T>::type;\ntemplate <typename T>\nusing remove_reference_t = typename std::remove_reference<T>::type;\n#endif\n\n#if defined(PYBIND11_CPP20)\nusing std::remove_cvref;\nusing std::remove_cvref_t;\n#else\ntemplate <class T>\nstruct remove_cvref {\n    using type = remove_cv_t<remove_reference_t<T>>;\n};\ntemplate <class T>\nusing remove_cvref_t = typename remove_cvref<T>::type;\n#endif\n\n/// Index sequences\n#if defined(PYBIND11_CPP14)\nusing std::index_sequence;\nusing std::make_index_sequence;\n#else\ntemplate <size_t...>\nstruct index_sequence {};\ntemplate <size_t N, size_t... S>\nstruct make_index_sequence_impl : make_index_sequence_impl<N - 1, N - 1, S...> {};\ntemplate <size_t... S>\nstruct make_index_sequence_impl<0, S...> {\n    using type = index_sequence<S...>;\n};\ntemplate <size_t N>\nusing make_index_sequence = typename make_index_sequence_impl<N>::type;\n#endif\n\n/// Make an index sequence of the indices of true arguments\ntemplate <typename ISeq, size_t, bool...>\nstruct select_indices_impl {\n    using type = ISeq;\n};\ntemplate <size_t... IPrev, size_t I, bool B, bool... Bs>\nstruct select_indices_impl<index_sequence<IPrev...>, I, B, Bs...>\n    : select_indices_impl<conditional_t<B, index_sequence<IPrev..., I>, index_sequence<IPrev...>>,\n                          I + 1,\n                          Bs...> {};\ntemplate <bool... Bs>\nusing select_indices = typename select_indices_impl<index_sequence<>, 0, Bs...>::type;\n\n/// Backports of std::bool_constant and std::negation to accommodate older compilers\ntemplate <bool B>\nusing bool_constant = std::integral_constant<bool, B>;\ntemplate <typename T>\nstruct negation : bool_constant<!T::value> {};\n\n// PGI/Intel cannot detect operator delete with the \"compatible\" void_t impl, so\n// using the new one (C++14 defect, so generally works on newer compilers, even\n// if not in C++17 mode)\n#if defined(__PGIC__) || defined(__INTEL_COMPILER)\ntemplate <typename...>\nusing void_t = void;\n#else\ntemplate <typename...>\nstruct void_t_impl {\n    using type = void;\n};\ntemplate <typename... Ts>\nusing void_t = typename void_t_impl<Ts...>::type;\n#endif\n\n/// Compile-time all/any/none of that check the boolean value of all template types\n#if defined(__cpp_fold_expressions) && !(defined(_MSC_VER) && (_MSC_VER < 1916))\ntemplate <class... Ts>\nusing all_of = bool_constant<(Ts::value && ...)>;\ntemplate <class... Ts>\nusing any_of = bool_constant<(Ts::value || ...)>;\n#elif !defined(_MSC_VER)\ntemplate <bool...>\nstruct bools {};\ntemplate <class... Ts>\nusing all_of = std::is_same<bools<Ts::value..., true>, bools<true, Ts::value...>>;\ntemplate <class... Ts>\nusing any_of = negation<all_of<negation<Ts>...>>;\n#else\n// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit\n// at a slight loss of compilation efficiency).\ntemplate <class... Ts>\nusing all_of = std::conjunction<Ts...>;\ntemplate <class... Ts>\nusing any_of = std::disjunction<Ts...>;\n#endif\ntemplate <class... Ts>\nusing none_of = negation<any_of<Ts...>>;\n\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_all_of = all_of<Predicates<T>...>;\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_any_of = any_of<Predicates<T>...>;\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_none_of = none_of<Predicates<T>...>;\n\n/// Strip the class from a method type\ntemplate <typename T>\nstruct remove_class {};\ntemplate <typename C, typename R, typename... A>\nstruct remove_class<R (C::*)(A...)> {\n    using type = R(A...);\n};\ntemplate <typename C, typename R, typename... A>\nstruct remove_class<R (C::*)(A...) const> {\n    using type = R(A...);\n};\n\n/// Helper template to strip away type modifiers\ntemplate <typename T>\nstruct intrinsic_type {\n    using type = T;\n};\ntemplate <typename T>\nstruct intrinsic_type<const T> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T *> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T &> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T &&> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T, size_t N>\nstruct intrinsic_type<const T[N]> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T, size_t N>\nstruct intrinsic_type<T[N]> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nusing intrinsic_t = typename intrinsic_type<T>::type;\n\n/// Helper type to replace 'void' in some expressions\nstruct void_type {};\n\n/// Helper template which holds a list of types\ntemplate <typename...>\nstruct type_list {};\n\n/// Compile-time integer sum\n#ifdef __cpp_fold_expressions\ntemplate <typename... Ts>\nconstexpr size_t constexpr_sum(Ts... ns) {\n    return (0 + ... + size_t{ns});\n}\n#else\nconstexpr size_t constexpr_sum() { return 0; }\ntemplate <typename T, typename... Ts>\nconstexpr size_t constexpr_sum(T n, Ts... ns) {\n    return size_t{n} + constexpr_sum(ns...);\n}\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(constexpr_impl)\n/// Implementation details for constexpr functions\nconstexpr int first(int i) { return i; }\ntemplate <typename T, typename... Ts>\nconstexpr int first(int i, T v, Ts... vs) {\n    return v ? i : first(i + 1, vs...);\n}\n\nconstexpr int last(int /*i*/, int result) { return result; }\ntemplate <typename T, typename... Ts>\nconstexpr int last(int i, int result, T v, Ts... vs) {\n    return last(i + 1, v ? i : result, vs...);\n}\nPYBIND11_NAMESPACE_END(constexpr_impl)\n\n/// Return the index of the first type in Ts which satisfies Predicate<T>.\n/// Returns sizeof...(Ts) if none match.\ntemplate <template <typename> class Predicate, typename... Ts>\nconstexpr int constexpr_first() {\n    return constexpr_impl::first(0, Predicate<Ts>::value...);\n}\n\n/// Return the index of the last type in Ts which satisfies Predicate<T>, or -1 if none match.\ntemplate <template <typename> class Predicate, typename... Ts>\nconstexpr int constexpr_last() {\n    return constexpr_impl::last(0, -1, Predicate<Ts>::value...);\n}\n\n/// Return the Nth element from the parameter pack\ntemplate <size_t N, typename T, typename... Ts>\nstruct pack_element {\n    using type = typename pack_element<N - 1, Ts...>::type;\n};\ntemplate <typename T, typename... Ts>\nstruct pack_element<0, T, Ts...> {\n    using type = T;\n};\n\n/// Return the one and only type which matches the predicate, or Default if none match.\n/// If more than one type matches the predicate, fail at compile-time.\ntemplate <template <typename> class Predicate, typename Default, typename... Ts>\nstruct exactly_one {\n    static constexpr auto found = constexpr_sum(Predicate<Ts>::value...);\n    static_assert(found <= 1, \"Found more than one type matching the predicate\");\n\n    static constexpr auto index = found ? constexpr_first<Predicate, Ts...>() : 0;\n    using type = conditional_t<found, typename pack_element<index, Ts...>::type, Default>;\n};\ntemplate <template <typename> class P, typename Default>\nstruct exactly_one<P, Default> {\n    using type = Default;\n};\n\ntemplate <template <typename> class Predicate, typename Default, typename... Ts>\nusing exactly_one_t = typename exactly_one<Predicate, Default, Ts...>::type;\n\n/// Defer the evaluation of type T until types Us are instantiated\ntemplate <typename T, typename... /*Us*/>\nstruct deferred_type {\n    using type = T;\n};\ntemplate <typename T, typename... Us>\nusing deferred_t = typename deferred_type<T, Us...>::type;\n\n/// Like is_base_of, but requires a strict base (i.e. `is_strict_base_of<T, T>::value == false`,\n/// unlike `std::is_base_of`)\ntemplate <typename Base, typename Derived>\nusing is_strict_base_of\n    = bool_constant<std::is_base_of<Base, Derived>::value && !std::is_same<Base, Derived>::value>;\n\n/// Like is_base_of, but also requires that the base type is accessible (i.e. that a Derived\n/// pointer can be converted to a Base pointer) For unions, `is_base_of<T, T>::value` is False, so\n/// we need to check `is_same` as well.\ntemplate <typename Base, typename Derived>\nusing is_accessible_base_of\n    = bool_constant<(std::is_same<Base, Derived>::value || std::is_base_of<Base, Derived>::value)\n                    && std::is_convertible<Derived *, Base *>::value>;\n\ntemplate <template <typename...> class Base>\nstruct is_template_base_of_impl {\n    template <typename... Us>\n    static std::true_type check(Base<Us...> *);\n    static std::false_type check(...);\n};\n\n/// Check if a template is the base of a type. For example:\n/// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything\ntemplate <template <typename...> class Base, typename T>\n// Sadly, all MSVC versions incl. 2022 need the workaround, even in C++20 mode.\n// See also: https://github.com/pybind/pybind11/pull/3741\n#if !defined(_MSC_VER)\nusing is_template_base_of\n    = decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr));\n#else\nstruct is_template_base_of\n    : decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr)) {\n};\n#endif\n\n/// Check if T is an instantiation of the template `Class`. For example:\n/// `is_instantiation<shared_ptr, T>` is true if `T == shared_ptr<U>` where U can be anything.\ntemplate <template <typename...> class Class, typename T>\nstruct is_instantiation : std::false_type {};\ntemplate <template <typename...> class Class, typename... Us>\nstruct is_instantiation<Class, Class<Us...>> : std::true_type {};\n\n/// Check if T is std::shared_ptr<U> where U can be anything\ntemplate <typename T>\nusing is_shared_ptr = is_instantiation<std::shared_ptr, T>;\n\n/// Check if T looks like an input iterator\ntemplate <typename T, typename = void>\nstruct is_input_iterator : std::false_type {};\ntemplate <typename T>\nstruct is_input_iterator<T,\n                         void_t<decltype(*std::declval<T &>()), decltype(++std::declval<T &>())>>\n    : std::true_type {};\n\ntemplate <typename T>\nusing is_function_pointer\n    = bool_constant<std::is_pointer<T>::value\n                    && std::is_function<typename std::remove_pointer<T>::type>::value>;\n\ntemplate <typename F>\nstruct strip_function_object {\n    // If you are encountering an\n    // 'error: name followed by \"::\" must be a class or namespace name'\n    // with the Intel compiler and a noexcept function here,\n    // try to use noexcept(true) instead of plain noexcept.\n    using type = typename remove_class<decltype(&F::operator())>::type;\n};\n\n// Extracts the function signature from a function, function pointer or lambda.\ntemplate <typename Function, typename F = remove_reference_t<Function>>\nusing function_signature_t = conditional_t<\n    std::is_function<F>::value,\n    F,\n    typename conditional_t<std::is_pointer<F>::value || std::is_member_pointer<F>::value,\n                           std::remove_pointer<F>,\n                           strip_function_object<F>>::type>;\n\n/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member\n/// pointer.  Note that this can catch all sorts of other things, too; this is intended to be used\n/// in a place where passing a lambda makes sense.\ntemplate <typename T>\nusing is_lambda = satisfies_none_of<remove_reference_t<T>,\n                                    std::is_function,\n                                    std::is_pointer,\n                                    std::is_member_pointer>;\n\n// [workaround(intel)] Internal error on fold expression\n/// Apply a function over each element of a parameter pack\n#if defined(__cpp_fold_expressions) && !defined(__INTEL_COMPILER)\n// Intel compiler produces an internal error on this fold expression (tested with ICC 19.0.2)\n#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) (((PATTERN), void()), ...)\n#else\nusing expand_side_effects = bool[];\n#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)                                                 \\\n        (void) pybind11::detail::expand_side_effects { ((PATTERN), void(), false)..., false }\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// C++ bindings of builtin Python exceptions\nclass PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {\npublic:\n    using std::runtime_error::runtime_error;\n    /// Set the error using the Python C API\n    virtual void set_error() const = 0;\n};\n\n#define PYBIND11_RUNTIME_EXCEPTION(name, type)                                                    \\\n    class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception {                             \\\n    public:                                                                                       \\\n        using builtin_exception::builtin_exception;                                               \\\n        name() : name(\"\") {}                                                                      \\\n        void set_error() const override { PyErr_SetString(type, what()); }                        \\\n    };\n\nPYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration)\nPYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError)\nPYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError)\nPYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError)\nPYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError)\nPYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError)\nPYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError)\nPYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError)\nPYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or\n                                                           /// handle::call fail due to a type\n                                                           /// casting error\nPYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally\n\n[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) {\n    assert(!PyErr_Occurred());\n    throw std::runtime_error(reason);\n}\n[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) {\n    assert(!PyErr_Occurred());\n    throw std::runtime_error(reason);\n}\n\ntemplate <typename T, typename SFINAE = void>\nstruct format_descriptor {};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Returns the index of the given type in the type char array below, and in the list in numpy.h\n// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double;\n// complex float,double,long double.  Note that the long double types only participate when long\n// double is actually longer than double (it isn't under MSVC).\n// NB: not only the string below but also complex.h and numpy.h rely on this order.\ntemplate <typename T, typename SFINAE = void>\nstruct is_fmt_numeric {\n    static constexpr bool value = false;\n};\ntemplate <typename T>\nstruct is_fmt_numeric<T, enable_if_t<std::is_arithmetic<T>::value>> {\n    static constexpr bool value = true;\n    static constexpr int index\n        = std::is_same<T, bool>::value\n              ? 0\n              : 1\n                    + (std::is_integral<T>::value\n                           ? detail::log2(sizeof(T)) * 2 + std::is_unsigned<T>::value\n                           : 8\n                                 + (std::is_same<T, double>::value        ? 1\n                                    : std::is_same<T, long double>::value ? 2\n                                                                          : 0));\n};\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>> {\n    static constexpr const char c = \"?bBhHiIqQfdg\"[detail::is_fmt_numeric<T>::index];\n    static constexpr const char value[2] = {c, '\\0'};\n    static std::string format() { return std::string(1, c); }\n};\n\n#if !defined(PYBIND11_CPP17)\n\ntemplate <typename T>\nconstexpr const char\n    format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>>::value[2];\n\n#endif\n\n/// RAII wrapper that temporarily clears any Python error state\nstruct error_scope {\n    PyObject *type, *value, *trace;\n    error_scope() { PyErr_Fetch(&type, &value, &trace); }\n    error_scope(const error_scope &) = delete;\n    error_scope &operator=(const error_scope &) = delete;\n    ~error_scope() { PyErr_Restore(type, value, trace); }\n};\n\n/// Dummy destructor wrapper that can be used to expose classes with a private destructor\nstruct nodelete {\n    template <typename T>\n    void operator()(T *) {}\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename... Args>\nstruct overload_cast_impl {\n    template <typename Return>\n    constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) {\n        return pf;\n    }\n\n    template <typename Return, typename Class>\n    constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept\n        -> decltype(pmf) {\n        return pmf;\n    }\n\n    template <typename Return, typename Class>\n    constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept\n        -> decltype(pmf) {\n        return pmf;\n    }\n};\nPYBIND11_NAMESPACE_END(detail)\n\n// overload_cast requires variable templates: C++14\n#if defined(PYBIND11_CPP14)\n#    define PYBIND11_OVERLOAD_CAST 1\n/// Syntax sugar for resolving overloaded function pointers:\n///  - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)\n///  - sweet:   overload_cast<Arg0, Arg1, Arg2>(&Class::func)\ntemplate <typename... Args>\nstatic constexpr detail::overload_cast_impl<Args...> overload_cast{};\n#endif\n\n/// Const member function selector for overload_cast\n///  - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)\n///  - sweet:   overload_cast<Arg>(&Class::func, const_)\nstatic constexpr auto const_ = std::true_type{};\n\n#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails:\ntemplate <typename... Args>\nstruct overload_cast {\n    static_assert(detail::deferred_t<std::false_type, Args...>::value,\n                  \"pybind11::overload_cast<...> requires compiling in C++14 mode\");\n};\n#endif // overload_cast\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from\n// any standard container (or C-style array) supporting std::begin/std::end, any singleton\n// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair.\ntemplate <typename T>\nclass any_container {\n    std::vector<T> v;\n\npublic:\n    any_container() = default;\n\n    // Can construct from a pair of iterators\n    template <typename It, typename = enable_if_t<is_input_iterator<It>::value>>\n    any_container(It first, It last) : v(first, last) {}\n\n    // Implicit conversion constructor from any arbitrary container type\n    // with values convertible to T\n    template <typename Container,\n              typename = enable_if_t<\n                  std::is_convertible<decltype(*std::begin(std::declval<const Container &>())),\n                                      T>::value>>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    any_container(const Container &c) : any_container(std::begin(c), std::end(c)) {}\n\n    // initializer_list's aren't deducible, so don't get matched by the above template;\n    // we need this to explicitly allow implicit conversion from one:\n    template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>\n    any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) {}\n\n    // Avoid copying if given an rvalue vector of the correct type.\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    any_container(std::vector<T> &&v) : v(std::move(v)) {}\n\n    // Moves the vector out of an rvalue any_container\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::vector<T> &&() && { return std::move(v); }\n\n    // Dereferencing obtains a reference to the underlying vector\n    std::vector<T> &operator*() { return v; }\n    const std::vector<T> &operator*() const { return v; }\n\n    // -> lets you call methods on the underlying vector\n    std::vector<T> *operator->() { return &v; }\n    const std::vector<T> *operator->() const { return &v; }\n};\n\n// Forward-declaration; see detail/class.h\nstd::string get_fully_qualified_tp_name(PyTypeObject *);\n\ntemplate <typename T>\ninline static std::shared_ptr<T>\ntry_get_shared_from_this(std::enable_shared_from_this<T> *holder_value_ptr) {\n// Pre C++17, this code path exploits undefined behavior, but is known to work on many platforms.\n// Use at your own risk!\n// See also https://en.cppreference.com/w/cpp/memory/enable_shared_from_this, and in particular\n// the `std::shared_ptr<Good> gp1 = not_so_good.getptr();` and `try`-`catch` parts of the example.\n#if defined(__cpp_lib_enable_shared_from_this) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n    return holder_value_ptr->weak_from_this().lock();\n#else\n    try {\n        return holder_value_ptr->shared_from_this();\n    } catch (const std::bad_weak_ptr &) {\n        return nullptr;\n    }\n#endif\n}\n\n// For silencing \"unused\" compiler warnings in special situations.\ntemplate <typename... Args>\n#if defined(_MSC_VER) && _MSC_VER < 1920 // MSVC 2017\nconstexpr\n#endif\n    inline void\n    silence_unused_warnings(Args &&...) {\n}\n\n// MSVC warning C4100: Unreferenced formal parameter\n#if defined(_MSC_VER) && _MSC_VER <= 1916\n#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)                                         \\\n        detail::silence_unused_warnings(__VA_ARGS__)\n#else\n#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)\n#endif\n\n// GCC -Wunused-but-set-parameter  All GCC versions (as of July 2021).\n#if defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)                       \\\n        detail::silence_unused_warnings(__VA_ARGS__)\n#else\n#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)\n#endif\n\n#if defined(_MSC_VER) // All versions (as of July 2021).\n\n// warning C4127: Conditional expression is constant\nconstexpr inline bool silence_msvc_c4127(bool cond) { return cond; }\n\n#    define PYBIND11_SILENCE_MSVC_C4127(...) ::pybind11::detail::silence_msvc_c4127(__VA_ARGS__)\n\n#else\n#    define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__\n#endif\n\n#if defined(__clang__)                                                                            \\\n    && (defined(__apple_build_version__) /* AppleClang 13.0.0.13000029 was the only data point    \\\n                                            available. */                                         \\\n        || (__clang_major__ >= 7                                                                  \\\n            && __clang_major__ <= 12) /* Clang 3, 5, 13, 14, 15 do not generate the warning. */   \\\n    )\n#    define PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING\n// Example:\n// tests/test_kwargs_and_defaults.cpp:46:68: error: local variable 'args' will be copied despite\n// being returned by name [-Werror,-Wreturn-std-move]\n//     m.def(\"args_function\", [](py::args args) -> py::tuple { return args; });\n//                                                                    ^~~~\n// test_kwargs_and_defaults.cpp:46:68: note: call 'std::move' explicitly to avoid copying\n//     m.def(\"args_function\", [](py::args args) -> py::tuple { return args; });\n//                                                                    ^~~~\n//                                                                    std::move(args)\n#endif\n\n// Pybind offers detailed error messages by default for all builts that are debug (through the\n// negation of ndebug). This can also be manually enabled by users, for any builds, through\n// defining PYBIND11_DETAILED_ERROR_MESSAGES.\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(NDEBUG)\n#    define PYBIND11_DETAILED_ERROR_MESSAGES\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/descr.h",
    "content": "/*\n    pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if !defined(_MSC_VER)\n#    define PYBIND11_DESCR_CONSTEXPR static constexpr\n#else\n#    define PYBIND11_DESCR_CONSTEXPR const\n#endif\n\n/* Concatenate type signatures at compile time */\ntemplate <size_t N, typename... Ts>\nstruct descr {\n    char text[N + 1]{'\\0'};\n\n    constexpr descr() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}\n\n    template <size_t... Is>\n    constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\\0'} {}\n\n    template <typename... Chars>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\\0'} {}\n\n    static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {\n        return {{&typeid(Ts)..., nullptr}};\n    }\n};\n\ntemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>\nconstexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,\n                                                   const descr<N2, Ts2...> &b,\n                                                   index_sequence<Is1...>,\n                                                   index_sequence<Is2...>) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);\n    return {a.text[Is1]..., b.text[Is2]...};\n}\n\ntemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2>\nconstexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,\n                                                   const descr<N2, Ts2...> &b) {\n    return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());\n}\n\ntemplate <size_t N>\nconstexpr descr<N - 1> const_name(char const (&text)[N]) {\n    return descr<N - 1>(text);\n}\nconstexpr descr<0> const_name(char const (&)[1]) { return {}; }\n\ntemplate <size_t Rem, size_t... Digits>\nstruct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};\ntemplate <size_t... Digits>\nstruct int_to_str<0, Digits...> {\n    // WARNING: This only works with C++17 or higher.\n    static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);\n};\n\n// Ternary description (like std::conditional)\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {\n    return const_name(text1);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {\n    return const_name(text2);\n}\n\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {\n    return d;\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {\n    return d;\n}\n\ntemplate <size_t Size>\nauto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {\n    return int_to_str<Size / 10, Size % 10>::digits;\n}\n\ntemplate <typename Type>\nconstexpr descr<1, Type> const_name() {\n    return {'%'};\n}\n\n// If \"_\" is defined as a macro, py::detail::_ cannot be provided.\n// It is therefore best to use py::detail::const_name universally.\n// This block is for backward compatibility only.\n// (The const_name code is repeated to avoid introducing a \"_\" #define ourselves.)\n#ifndef _\n#    define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\ntemplate <size_t N>\nconstexpr descr<N - 1> _(char const (&text)[N]) {\n    return const_name<N>(text);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {\n    return const_name<B, N1, N2>(text1, text2);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {\n    return const_name<B, N1, N2>(text1, text2);\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {\n    return const_name<B, T1, T2>(d1, d2);\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {\n    return const_name<B, T1, T2>(d1, d2);\n}\n\ntemplate <size_t Size>\nauto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {\n    return const_name<Size>();\n}\ntemplate <typename Type>\nconstexpr descr<1, Type> _() {\n    return const_name<Type>();\n}\n#endif // #ifndef _\n\nconstexpr descr<0> concat() { return {}; }\n\ntemplate <size_t N, typename... Ts>\nconstexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {\n    return descr;\n}\n\ntemplate <size_t N, typename... Ts, typename... Args>\nconstexpr auto concat(const descr<N, Ts...> &d, const Args &...args)\n    -> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {\n    return d + const_name(\", \") + concat(args...);\n}\n\ntemplate <size_t N, typename... Ts>\nconstexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {\n    return const_name(\"{\") + descr + const_name(\"}\");\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/init.h",
    "content": "/*\n    pybind11/detail/init.h: init factory function implementation and support code.\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"class.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <>\nclass type_caster<value_and_holder> {\npublic:\n    bool load(handle h, bool) {\n        value = reinterpret_cast<value_and_holder *>(h.ptr());\n        return true;\n    }\n\n    template <typename>\n    using cast_op_type = value_and_holder &;\n    explicit operator value_and_holder &() { return *value; }\n    static constexpr auto name = const_name<value_and_holder>();\n\nprivate:\n    value_and_holder *value = nullptr;\n};\n\nPYBIND11_NAMESPACE_BEGIN(initimpl)\n\ninline void no_nullptr(void *ptr) {\n    if (!ptr) {\n        throw type_error(\"pybind11::init(): factory function returned nullptr\");\n    }\n}\n\n// Implementing functions for all forms of py::init<...> and py::init(...)\ntemplate <typename Class>\nusing Cpp = typename Class::type;\ntemplate <typename Class>\nusing Alias = typename Class::type_alias;\ntemplate <typename Class>\nusing Holder = typename Class::holder_type;\n\ntemplate <typename Class>\nusing is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;\n\n// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.\ntemplate <typename Class, enable_if_t<Class::has_alias, int> = 0>\nbool is_alias(Cpp<Class> *ptr) {\n    return dynamic_cast<Alias<Class> *>(ptr) != nullptr;\n}\n// Failing fallback version of the above for a no-alias class (always returns false)\ntemplate <typename /*Class*/>\nconstexpr bool is_alias(void *) {\n    return false;\n}\n\n// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall\n// back to brace aggregate initiailization so that for aggregate initialization can be used with\n// py::init, e.g.  `py::init<int, int>` to initialize a `struct T { int a; int b; }`.  For\n// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually\n// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).\ntemplate <typename Class,\n          typename... Args,\n          detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>\ninline Class *construct_or_initialize(Args &&...args) {\n    return new Class(std::forward<Args>(args)...);\n}\ntemplate <typename Class,\n          typename... Args,\n          detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>\ninline Class *construct_or_initialize(Args &&...args) {\n    return new Class{std::forward<Args>(args)...};\n}\n\n// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor.  This allows types with\n// an alias to provide only a single Cpp factory function as long as the Alias can be\n// constructed from an rvalue reference of the base Cpp type.  This means that Alias classes\n// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to\n// inherit all the base class constructors.\ntemplate <typename Class>\nvoid construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,\n                              value_and_holder &v_h,\n                              Cpp<Class> &&base) {\n    v_h.value_ptr() = new Alias<Class>(std::move(base));\n}\ntemplate <typename Class>\n[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,\n                                           value_and_holder &,\n                                           Cpp<Class> &&) {\n    throw type_error(\"pybind11::init(): unable to convert returned instance to required \"\n                     \"alias class: no `Alias<Class>(Class &&)` constructor available\");\n}\n\n// Error-generating fallback for factories that don't match one of the below construction\n// mechanisms.\ntemplate <typename Class>\nvoid construct(...) {\n    static_assert(!std::is_same<Class, Class>::value /* always false */,\n                  \"pybind11::init(): init function must return a compatible pointer, \"\n                  \"holder, or value\");\n}\n\n// Pointer return v1: the factory function returns a class pointer for a registered class.\n// If we don't need an alias (because this class doesn't have one, or because the final type is\n// inherited on the Python side) we can simply take over ownership.  Otherwise we need to try to\n// construct an Alias from the returned base instance.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    no_nullptr(ptr);\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {\n        // We're going to try to construct an alias by moving the cpp type.  Whether or not\n        // that succeeds, we still need to destroy the original cpp pointer (either the\n        // moved away leftover, if the alias construction works, or the value itself if we\n        // throw an error), but we can't just call `delete ptr`: it might have a special\n        // deleter, or might be shared_from_this.  So we construct a holder around it as if\n        // it was a normal instance, then steal the holder away into a local variable; thus\n        // the holder and destruction happens when we leave the C++ scope, and the holder\n        // class gets to handle the destruction however it likes.\n        v_h.value_ptr() = ptr;\n        v_h.set_instance_registered(true);          // To prevent init_instance from registering it\n        v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder\n        Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder\n        v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null\n        v_h.set_instance_registered(false);\n\n        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));\n    } else {\n        // Otherwise the type isn't inherited, so we don't need an Alias\n        v_h.value_ptr() = ptr;\n    }\n}\n\n// Pointer return v2: a factory that always returns an alias instance ptr.  We simply take over\n// ownership of the pointer.\ntemplate <typename Class, enable_if_t<Class::has_alias, int> = 0>\nvoid construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {\n    no_nullptr(alias_ptr);\n    v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);\n}\n\n// Holder return: copy its pointer, and move or copy the returned holder into the new instance's\n// holder.  This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a\n// derived type (through those holder's implicit conversion from derived class holder\n// constructors).\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    auto *ptr = holder_helper<Holder<Class>>::get(holder);\n    no_nullptr(ptr);\n    // If we need an alias, check that the held pointer is actually an alias instance\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {\n        throw type_error(\"pybind11::init(): construction failed: returned holder-wrapped instance \"\n                         \"is not an alias instance\");\n    }\n\n    v_h.value_ptr() = ptr;\n    v_h.type->init_instance(v_h.inst, &holder);\n}\n\n// return-by-value version 1: returning a cpp class by value.  If the class has an alias and an\n// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct\n// the alias from the base when needed (i.e. because of Python-side inheritance).  When we don't\n// need it, we simply move-construct the cpp value into a new instance.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    static_assert(std::is_move_constructible<Cpp<Class>>::value,\n                  \"pybind11::init() return-by-value factory function requires a movable class\");\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias) {\n        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));\n    } else {\n        v_h.value_ptr() = new Cpp<Class>(std::move(result));\n    }\n}\n\n// return-by-value version 2: returning a value of the alias type itself.  We move-construct an\n// Alias instance (even if no the python-side inheritance is involved).  The is intended for\n// cases where Alias initialization is always desired.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Alias<Class> &&result, bool) {\n    static_assert(\n        std::is_move_constructible<Alias<Class>>::value,\n        \"pybind11::init() return-by-alias-value factory function requires a movable alias class\");\n    v_h.value_ptr() = new Alias<Class>(std::move(result));\n}\n\n// Implementing class for py::init<...>()\ntemplate <typename... Args>\nstruct constructor {\n    template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                if (Py_TYPE(v_h.inst) == v_h.type->type) {\n                    v_h.value_ptr()\n                        = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);\n                } else {\n                    v_h.value_ptr()\n                        = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n                }\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr()\n                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Implementing class for py::init_alias<...>()\ntemplate <typename... Args>\nstruct alias_constructor {\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr()\n                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Implementation class for py::init(Func) and py::init(Func, AliasFunc)\ntemplate <typename CFunc,\n          typename AFunc = void_type (*)(),\n          typename = function_signature_t<CFunc>,\n          typename = function_signature_t<AFunc>>\nstruct factory;\n\n// Specialization for py::init(Func)\ntemplate <typename Func, typename Return, typename... Args>\nstruct factory<Func, void_type (*)(), Return(Args...)> {\n    remove_reference_t<Func> class_factory;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    factory(Func &&f) : class_factory(std::forward<Func>(f)) {}\n\n    // The given class either has no alias or has no separate alias factory;\n    // this always constructs the class itself.  If the class is registered with an alias\n    // type and an alias instance is needed (i.e. because the final type is a Python class\n    // inheriting from the C++ type) the returned value needs to either already be an alias\n    // instance, or the alias needs to be constructible from a `Class &&` argument.\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__init__\",\n            [func = std::move(class_factory)]\n#else\n        auto &func = class_factory;\n        cl.def(\n            \"__init__\",\n            [func]\n#endif\n            (value_and_holder &v_h, Args... args) {\n                construct<Class>(\n                    v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Specialization for py::init(Func, AliasFunc)\ntemplate <typename CFunc,\n          typename AFunc,\n          typename CReturn,\n          typename... CArgs,\n          typename AReturn,\n          typename... AArgs>\nstruct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {\n    static_assert(sizeof...(CArgs) == sizeof...(AArgs),\n                  \"pybind11::init(class_factory, alias_factory): class and alias factories \"\n                  \"must have identical argument signatures\");\n    static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,\n                  \"pybind11::init(class_factory, alias_factory): class and alias factories \"\n                  \"must have identical argument signatures\");\n\n    remove_reference_t<CFunc> class_factory;\n    remove_reference_t<AFunc> alias_factory;\n\n    factory(CFunc &&c, AFunc &&a)\n        : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}\n\n    // The class factory is called when the `self` type passed to `__init__` is the direct\n    // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n        static_assert(Class::has_alias,\n                      \"The two-argument version of `py::init()` can \"\n                      \"only be used if the class has an alias\");\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__init__\",\n            [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]\n#else\n        auto &class_func = class_factory;\n        auto &alias_func = alias_factory;\n        cl.def(\n            \"__init__\",\n            [class_func, alias_func]\n#endif\n            (value_and_holder &v_h, CArgs... args) {\n                if (Py_TYPE(v_h.inst) == v_h.type->type) {\n                    // If the instance type equals the registered type we don't have inheritance,\n                    // so don't need the alias and can construct using the class function:\n                    construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);\n                } else {\n                    construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);\n                }\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n/// Set just the C++ state. Same as `__init__`.\ntemplate <typename Class, typename T>\nvoid setstate(value_and_holder &v_h, T &&result, bool need_alias) {\n    construct<Class>(v_h, std::forward<T>(result), need_alias);\n}\n\n/// Set both the C++ and Python states\ntemplate <typename Class,\n          typename T,\n          typename O,\n          enable_if_t<std::is_convertible<O, handle>::value, int> = 0>\nvoid setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {\n    construct<Class>(v_h, std::move(result.first), need_alias);\n    auto d = handle(result.second);\n    if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {\n        // Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.\n        // See PR #2972 for details.\n        return;\n    }\n    setattr((PyObject *) v_h.inst, \"__dict__\", d);\n}\n\n/// Implementation for py::pickle(GetState, SetState)\ntemplate <typename Get,\n          typename Set,\n          typename = function_signature_t<Get>,\n          typename = function_signature_t<Set>>\nstruct pickle_factory;\n\ntemplate <typename Get,\n          typename Set,\n          typename RetState,\n          typename Self,\n          typename NewInstance,\n          typename ArgState>\nstruct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {\n    static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,\n                  \"The type returned by `__getstate__` must be the same \"\n                  \"as the argument accepted by `__setstate__`\");\n\n    remove_reference_t<Get> get;\n    remove_reference_t<Set> set;\n\n    pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}\n\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n        cl.def(\"__getstate__\", std::move(get));\n\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__setstate__\",\n            [func = std::move(set)]\n#else\n        auto &func = set;\n        cl.def(\n            \"__setstate__\",\n            [func]\n#endif\n            (value_and_holder &v_h, ArgState state) {\n                setstate<Class>(\n                    v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\nPYBIND11_NAMESPACE_END(initimpl)\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/internals.h",
    "content": "/*\n    pybind11/detail/internals.h: Internal data structure and related functions\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"common.h\"\n\n#if defined(WITH_THREAD) && defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n#    include \"../gil.h\"\n#endif\n\n#include \"../pytypes.h\"\n\n#include <exception>\n\n/// Tracks the `internals` and `type_info` ABI version independent of the main library version.\n///\n/// Some portions of the code use an ABI that is conditional depending on this\n/// version number.  That allows ABI-breaking changes to be \"pre-implemented\".\n/// Once the default version number is incremented, the conditional logic that\n/// no longer applies can be removed.  Additionally, users that need not\n/// maintain ABI compatibility can increase the version number in order to take\n/// advantage of any functionality/efficiency improvements that depend on the\n/// newer ABI.\n///\n/// WARNING: If you choose to manually increase the ABI version, note that\n/// pybind11 may not be tested as thoroughly with a non-default ABI version, and\n/// further ABI-incompatible changes may be made before the ABI is officially\n/// changed to the new version.\n#ifndef PYBIND11_INTERNALS_VERSION\n#    define PYBIND11_INTERNALS_VERSION 4\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nusing ExceptionTranslator = void (*)(std::exception_ptr);\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\nconstexpr const char *internals_function_record_capsule_name = \"pybind11_function_record_capsule\";\n\n// Forward declarations\ninline PyTypeObject *make_static_property_type();\ninline PyTypeObject *make_default_metaclass();\ninline PyObject *make_object_base_type(PyTypeObject *metaclass);\n\n// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new\n// Thread Specific Storage (TSS) API.\n#if PY_VERSION_HEX >= 0x03070000\n// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use\n// `Py_LIMITED_API` anyway.\n#    if PYBIND11_INTERNALS_VERSION > 4\n#        define PYBIND11_TLS_KEY_REF Py_tss_t &\n#        if defined(__GNUC__) && !defined(__INTEL_COMPILER)\n// Clang on macOS warns due to `Py_tss_NEEDS_INIT` not specifying an initializer\n// for every field.\n#            define PYBIND11_TLS_KEY_INIT(var)                                                    \\\n                _Pragma(\"GCC diagnostic push\")                                         /**/       \\\n                    _Pragma(\"GCC diagnostic ignored \\\"-Wmissing-field-initializers\\\"\") /**/       \\\n                    Py_tss_t var                                                                  \\\n                    = Py_tss_NEEDS_INIT;                                                          \\\n                _Pragma(\"GCC diagnostic pop\")\n#        else\n#            define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;\n#        endif\n#        define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)\n#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)\n#        define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))\n#    else\n#        define PYBIND11_TLS_KEY_REF Py_tss_t *\n#        define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;\n#        define PYBIND11_TLS_KEY_CREATE(var)                                                      \\\n            (((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))\n#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)\n#        define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)\n#    endif\n#else\n// Usually an int but a long on Cygwin64 with Python 3.x\n#    define PYBIND11_TLS_KEY_REF decltype(PyThread_create_key())\n#    define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;\n#    define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)\n#    define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))\n#    if defined(PYPY_VERSION)\n// On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set\n// the value if it has already been set.  Instead, it must first be deleted and\n// then set again.\ninline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {\n    PyThread_delete_key_value(key);\n    PyThread_set_key_value(key, value);\n}\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_delete_key_value(key)\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value)                                            \\\n            ::pybind11::detail::tls_replace_value((key), (value))\n#    else\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_set_key_value((key), nullptr)\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_set_key_value((key), (value))\n#    endif\n#    define PYBIND11_TLS_FREE(key) (void) key\n#endif\n\n// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly\n// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module\n// even when `A` is the same, non-hidden-visibility type (e.g. from a common include).  Under\n// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,\n// which works.  If not under a known-good stl, provide our own name-based hash and equality\n// functions that use the type name.\n#if defined(__GLIBCXX__)\ninline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }\nusing type_hash = std::hash<std::type_index>;\nusing type_equal_to = std::equal_to<std::type_index>;\n#else\ninline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {\n    return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;\n}\n\nstruct type_hash {\n    size_t operator()(const std::type_index &t) const {\n        size_t hash = 5381;\n        const char *ptr = t.name();\n        while (auto c = static_cast<unsigned char>(*ptr++)) {\n            hash = (hash * 33) ^ c;\n        }\n        return hash;\n    }\n};\n\nstruct type_equal_to {\n    bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {\n        return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;\n    }\n};\n#endif\n\ntemplate <typename value_type>\nusing type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;\n\nstruct override_hash {\n    inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {\n        size_t value = std::hash<const void *>()(v.first);\n        value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);\n        return value;\n    }\n};\n\n/// Internal data structure used to track registered instances and types.\n/// Whenever binary incompatible changes are made to this structure,\n/// `PYBIND11_INTERNALS_VERSION` must be incremented.\nstruct internals {\n    // std::type_index -> pybind11's type information\n    type_map<type_info *> registered_types_cpp;\n    // PyTypeObject* -> base type_info(s)\n    std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;\n    std::unordered_multimap<const void *, instance *> registered_instances; // void * -> instance*\n    std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>\n        inactive_override_cache;\n    type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;\n    std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;\n    std::forward_list<ExceptionTranslator> registered_exception_translators;\n    std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across\n                                                         // extensions\n#if PYBIND11_INTERNALS_VERSION == 4\n    std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;\n#endif\n    std::forward_list<std::string> static_strings; // Stores the std::strings backing\n                                                   // detail::c_str()\n    PyTypeObject *static_property_type;\n    PyTypeObject *default_metaclass;\n    PyObject *instance_base;\n#if defined(WITH_THREAD)\n    // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:\n    PYBIND11_TLS_KEY_INIT(tstate)\n#    if PYBIND11_INTERNALS_VERSION > 4\n    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n#    endif // PYBIND11_INTERNALS_VERSION > 4\n    // Unused if PYBIND11_SIMPLE_GIL_MANAGEMENT is defined:\n    PyInterpreterState *istate = nullptr;\n\n#    if PYBIND11_INTERNALS_VERSION > 4\n    // Note that we have to use a std::string to allocate memory to ensure a unique address\n    // We want unique addresses since we use pointer equality to compare function records\n    std::string function_record_capsule_name = internals_function_record_capsule_name;\n#    endif\n\n    internals() = default;\n    internals(const internals &other) = delete;\n    internals &operator=(const internals &other) = delete;\n    ~internals() {\n#    if PYBIND11_INTERNALS_VERSION > 4\n        PYBIND11_TLS_FREE(loader_life_support_tls_key);\n#    endif // PYBIND11_INTERNALS_VERSION > 4\n\n        // This destructor is called *after* Py_Finalize() in finalize_interpreter().\n        // That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is\n        // called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does\n        // nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.\n        // PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).\n        // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*\n        // that the `tstate` be allocated with the CPython allocator.\n        PYBIND11_TLS_FREE(tstate);\n    }\n#endif\n};\n\n/// Additional type information which does not fit into the PyTypeObject.\n/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.\nstruct type_info {\n    PyTypeObject *type;\n    const std::type_info *cpptype;\n    size_t type_size, type_align, holder_size_in_ptrs;\n    void *(*operator_new)(size_t);\n    void (*init_instance)(instance *, const void *);\n    void (*dealloc)(value_and_holder &v_h);\n    std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;\n    std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;\n    std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;\n    buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;\n    void *get_buffer_data = nullptr;\n    void *(*module_local_load)(PyObject *, const type_info *) = nullptr;\n    /* A simple type never occurs as a (direct or indirect) parent\n     * of a class that makes use of multiple inheritance.\n     * A type can be simple even if it has non-simple ancestors as long as it has no descendants.\n     */\n    bool simple_type : 1;\n    /* True if there is no multiple inheritance in this type's inheritance tree */\n    bool simple_ancestors : 1;\n    /* for base vs derived holder_type checks */\n    bool default_holder : 1;\n    /* true if this is a type registered with py::module_local */\n    bool module_local : 1;\n};\n\n/// On MSVC, debug and release builds are not ABI-compatible!\n#if defined(_MSC_VER) && defined(_DEBUG)\n#    define PYBIND11_BUILD_TYPE \"_debug\"\n#else\n#    define PYBIND11_BUILD_TYPE \"\"\n#endif\n\n/// Let's assume that different compilers are ABI-incompatible.\n/// A user can manually set this string if they know their\n/// compiler is compatible.\n#ifndef PYBIND11_COMPILER_TYPE\n#    if defined(_MSC_VER)\n#        define PYBIND11_COMPILER_TYPE \"_msvc\"\n#    elif defined(__INTEL_COMPILER)\n#        define PYBIND11_COMPILER_TYPE \"_icc\"\n#    elif defined(__clang__)\n#        define PYBIND11_COMPILER_TYPE \"_clang\"\n#    elif defined(__PGI)\n#        define PYBIND11_COMPILER_TYPE \"_pgi\"\n#    elif defined(__MINGW32__)\n#        define PYBIND11_COMPILER_TYPE \"_mingw\"\n#    elif defined(__CYGWIN__)\n#        define PYBIND11_COMPILER_TYPE \"_gcc_cygwin\"\n#    elif defined(__GNUC__)\n#        define PYBIND11_COMPILER_TYPE \"_gcc\"\n#    else\n#        define PYBIND11_COMPILER_TYPE \"_unknown\"\n#    endif\n#endif\n\n/// Also standard libs\n#ifndef PYBIND11_STDLIB\n#    if defined(_LIBCPP_VERSION)\n#        define PYBIND11_STDLIB \"_libcpp\"\n#    elif defined(__GLIBCXX__) || defined(__GLIBCPP__)\n#        define PYBIND11_STDLIB \"_libstdcpp\"\n#    else\n#        define PYBIND11_STDLIB \"\"\n#    endif\n#endif\n\n/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.\n#ifndef PYBIND11_BUILD_ABI\n#    if defined(__GXX_ABI_VERSION)\n#        define PYBIND11_BUILD_ABI \"_cxxabi\" PYBIND11_TOSTRING(__GXX_ABI_VERSION)\n#    else\n#        define PYBIND11_BUILD_ABI \"\"\n#    endif\n#endif\n\n#ifndef PYBIND11_INTERNALS_KIND\n#    if defined(WITH_THREAD)\n#        define PYBIND11_INTERNALS_KIND \"\"\n#    else\n#        define PYBIND11_INTERNALS_KIND \"_without_thread\"\n#    endif\n#endif\n\n#define PYBIND11_INTERNALS_ID                                                                     \\\n    \"__pybind11_internals_v\" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                        \\\n        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \\\n            PYBIND11_BUILD_TYPE \"__\"\n\n#define PYBIND11_MODULE_LOCAL_ID                                                                  \\\n    \"__pybind11_module_local_v\" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                     \\\n        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \\\n            PYBIND11_BUILD_TYPE \"__\"\n\n/// Each module locally stores a pointer to the `internals` data. The data\n/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.\ninline internals **&get_internals_pp() {\n    static internals **internals_pp = nullptr;\n    return internals_pp;\n}\n\n// forward decl\ninline void translate_exception(std::exception_ptr);\n\ntemplate <class T,\n          enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>\nbool handle_nested_exception(const T &exc, const std::exception_ptr &p) {\n    std::exception_ptr nested = exc.nested_ptr();\n    if (nested != nullptr && nested != p) {\n        translate_exception(nested);\n        return true;\n    }\n    return false;\n}\n\ntemplate <class T,\n          enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>\nbool handle_nested_exception(const T &exc, const std::exception_ptr &p) {\n    if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {\n        return handle_nested_exception(*nep, p);\n    }\n    return false;\n}\n\ninline bool raise_err(PyObject *exc_type, const char *msg) {\n    if (PyErr_Occurred()) {\n        raise_from(exc_type, msg);\n        return true;\n    }\n    PyErr_SetString(exc_type, msg);\n    return false;\n}\n\ninline void translate_exception(std::exception_ptr p) {\n    if (!p) {\n        return;\n    }\n    try {\n        std::rethrow_exception(p);\n    } catch (error_already_set &e) {\n        handle_nested_exception(e, p);\n        e.restore();\n        return;\n    } catch (const builtin_exception &e) {\n        // Could not use template since it's an abstract class.\n        if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {\n            handle_nested_exception(*nep, p);\n        }\n        e.set_error();\n        return;\n    } catch (const std::bad_alloc &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_MemoryError, e.what());\n        return;\n    } catch (const std::domain_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::invalid_argument &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::length_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::out_of_range &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_IndexError, e.what());\n        return;\n    } catch (const std::range_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::overflow_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_OverflowError, e.what());\n        return;\n    } catch (const std::exception &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_RuntimeError, e.what());\n        return;\n    } catch (const std::nested_exception &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_RuntimeError, \"Caught an unknown nested exception!\");\n        return;\n    } catch (...) {\n        raise_err(PyExc_RuntimeError, \"Caught an unknown exception!\");\n        return;\n    }\n}\n\n#if !defined(__GLIBCXX__)\ninline void translate_local_exception(std::exception_ptr p) {\n    try {\n        if (p) {\n            std::rethrow_exception(p);\n        }\n    } catch (error_already_set &e) {\n        e.restore();\n        return;\n    } catch (const builtin_exception &e) {\n        e.set_error();\n        return;\n    }\n}\n#endif\n\n/// Return a reference to the current `internals` data\nPYBIND11_NOINLINE internals &get_internals() {\n    auto **&internals_pp = get_internals_pp();\n    if (internals_pp && *internals_pp) {\n        return **internals_pp;\n    }\n\n#if defined(WITH_THREAD)\n#    if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n    gil_scoped_acquire gil;\n#    else\n    // Ensure that the GIL is held since we will need to make Python calls.\n    // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.\n    struct gil_scoped_acquire_local {\n        gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}\n        gil_scoped_acquire_local(const gil_scoped_acquire_local &) = delete;\n        gil_scoped_acquire_local &operator=(const gil_scoped_acquire_local &) = delete;\n        ~gil_scoped_acquire_local() { PyGILState_Release(state); }\n        const PyGILState_STATE state;\n    } gil;\n#    endif\n#endif\n    error_scope err_scope;\n\n    PYBIND11_STR_TYPE id(PYBIND11_INTERNALS_ID);\n    auto builtins = handle(PyEval_GetBuiltins());\n    if (builtins.contains(id) && isinstance<capsule>(builtins[id])) {\n        internals_pp = static_cast<internals **>(capsule(builtins[id]));\n\n        // We loaded builtins through python's builtins, which means that our `error_already_set`\n        // and `builtin_exception` may be different local classes than the ones set up in the\n        // initial exception translator, below, so add another for our local exception classes.\n        //\n        // libstdc++ doesn't require this (types there are identified only by name)\n        // libc++ with CPython doesn't require this (types are explicitly exported)\n        // libc++ with PyPy still need it, awaiting further investigation\n#if !defined(__GLIBCXX__)\n        (*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);\n#endif\n    } else {\n        if (!internals_pp) {\n            internals_pp = new internals *();\n        }\n        auto *&internals_ptr = *internals_pp;\n        internals_ptr = new internals();\n#if defined(WITH_THREAD)\n\n        PyThreadState *tstate = PyThreadState_Get();\n        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {\n            pybind11_fail(\"get_internals: could not successfully initialize the tstate TSS key!\");\n        }\n        PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);\n\n#    if PYBIND11_INTERNALS_VERSION > 4\n        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {\n            pybind11_fail(\"get_internals: could not successfully initialize the \"\n                          \"loader_life_support TSS key!\");\n        }\n#    endif\n        internals_ptr->istate = tstate->interp;\n#endif\n        builtins[id] = capsule(internals_pp);\n        internals_ptr->registered_exception_translators.push_front(&translate_exception);\n        internals_ptr->static_property_type = make_static_property_type();\n        internals_ptr->default_metaclass = make_default_metaclass();\n        internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);\n    }\n    return **internals_pp;\n}\n\n// the internals struct (above) is shared between all the modules. local_internals are only\n// for a single module. Any changes made to internals may require an update to\n// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,\n// restricted to a single module. Whether a module has local internals or not should not\n// impact any other modules, because the only things accessing the local internals is the\n// module that contains them.\nstruct local_internals {\n    type_map<type_info *> registered_types_cpp;\n    std::forward_list<ExceptionTranslator> registered_exception_translators;\n#if defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4\n\n    // For ABI compatibility, we can't store the loader_life_support TLS key in\n    // the `internals` struct directly.  Instead, we store it in `shared_data` and\n    // cache a copy in `local_internals`.  If we allocated a separate TLS key for\n    // each instance of `local_internals`, we could end up allocating hundreds of\n    // TLS keys if hundreds of different pybind11 modules are loaded (which is a\n    // plausible number).\n    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n\n    // Holds the shared TLS key for the loader_life_support stack.\n    struct shared_loader_life_support_data {\n        PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n        shared_loader_life_support_data() {\n            if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {\n                pybind11_fail(\"local_internals: could not successfully initialize the \"\n                              \"loader_life_support TLS key!\");\n            }\n        }\n        // We can't help but leak the TLS key, because Python never unloads extension modules.\n    };\n\n    local_internals() {\n        auto &internals = get_internals();\n        // Get or create the `loader_life_support_stack_key`.\n        auto &ptr = internals.shared_data[\"_life_support\"];\n        if (!ptr) {\n            ptr = new shared_loader_life_support_data;\n        }\n        loader_life_support_tls_key\n            = static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;\n    }\n#endif //  defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4\n};\n\n/// Works like `get_internals`, but for things which are locally registered.\ninline local_internals &get_local_internals() {\n    // Current static can be created in the interpreter finalization routine. If the later will be\n    // destroyed in another static variable destructor, creation of this static there will cause\n    // static deinitialization fiasco. In order to avoid it we avoid destruction of the\n    // local_internals static. One can read more about the problem and current solution here:\n    // https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables\n    static auto *locals = new local_internals();\n    return *locals;\n}\n\n/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its\n/// `c_str()`.  Such strings objects have a long storage duration -- the internal strings are only\n/// cleared when the program exits or after interpreter shutdown (when embedding), and so are\n/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).\ntemplate <typename... Args>\nconst char *c_str(Args &&...args) {\n    auto &strings = get_internals().static_strings;\n    strings.emplace_front(std::forward<Args>(args)...);\n    return strings.front().c_str();\n}\n\ninline const char *get_function_record_capsule_name() {\n#if PYBIND11_INTERNALS_VERSION > 4\n    return get_internals().function_record_capsule_name.c_str();\n#else\n    return nullptr;\n#endif\n}\n\n// Determine whether or not the following capsule contains a pybind11 function record.\n// Note that we use `internals` to make sure that only ABI compatible records are touched.\n//\n// This check is currently used in two places:\n// - An important optimization in functional.h to avoid overhead in C++ -> Python -> C++\n// - The sibling feature of cpp_function to allow overloads\ninline bool is_function_record_capsule(const capsule &cap) {\n    // Pointer equality as we rely on internals() to ensure unique pointers\n    return cap.name() == get_function_record_capsule_name();\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Returns a named pointer that is shared among all extension modules (using the same\n/// pybind11 version) running in the current interpreter. Names starting with underscores\n/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.\nPYBIND11_NOINLINE void *get_shared_data(const std::string &name) {\n    auto &internals = detail::get_internals();\n    auto it = internals.shared_data.find(name);\n    return it != internals.shared_data.end() ? it->second : nullptr;\n}\n\n/// Set the shared data that can be later recovered by `get_shared_data()`.\nPYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {\n    detail::get_internals().shared_data[name] = data;\n    return data;\n}\n\n/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if\n/// such entry exists. Otherwise, a new object of default-constructible type `T` is\n/// added to the shared data under the given name and a reference to it is returned.\ntemplate <typename T>\nT &get_or_create_shared_data(const std::string &name) {\n    auto &internals = detail::get_internals();\n    auto it = internals.shared_data.find(name);\n    T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);\n    if (!ptr) {\n        ptr = new T();\n        internals.shared_data[name] = ptr;\n    }\n    return *ptr;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/type_caster_base.h",
    "content": "/*\n    pybind11/detail/type_caster_base.h (originally first part of pybind11/cast.h)\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../pytypes.h\"\n#include \"common.h\"\n#include \"descr.h\"\n#include \"internals.h\"\n#include \"typeid.h\"\n\n#include <cstdint>\n#include <iterator>\n#include <new>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <typeinfo>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// A life support system for temporary objects created by `type_caster::load()`.\n/// Adding a patient will keep it alive up until the enclosing function returns.\nclass loader_life_support {\nprivate:\n    loader_life_support *parent = nullptr;\n    std::unordered_set<PyObject *> keep_alive;\n\n#if defined(WITH_THREAD)\n    // Store stack pointer in thread-local storage.\n    static PYBIND11_TLS_KEY_REF get_stack_tls_key() {\n#    if PYBIND11_INTERNALS_VERSION == 4\n        return get_local_internals().loader_life_support_tls_key;\n#    else\n        return get_internals().loader_life_support_tls_key;\n#    endif\n    }\n    static loader_life_support *get_stack_top() {\n        return static_cast<loader_life_support *>(PYBIND11_TLS_GET_VALUE(get_stack_tls_key()));\n    }\n    static void set_stack_top(loader_life_support *value) {\n        PYBIND11_TLS_REPLACE_VALUE(get_stack_tls_key(), value);\n    }\n#else\n    // Use single global variable for stack.\n    static loader_life_support **get_stack_pp() {\n        static loader_life_support *global_stack = nullptr;\n        return global_stack;\n    }\n    static loader_life_support *get_stack_top() { return *get_stack_pp(); }\n    static void set_stack_top(loader_life_support *value) { *get_stack_pp() = value; }\n#endif\n\npublic:\n    /// A new patient frame is created when a function is entered\n    loader_life_support() : parent{get_stack_top()} { set_stack_top(this); }\n\n    /// ... and destroyed after it returns\n    ~loader_life_support() {\n        if (get_stack_top() != this) {\n            pybind11_fail(\"loader_life_support: internal error\");\n        }\n        set_stack_top(parent);\n        for (auto *item : keep_alive) {\n            Py_DECREF(item);\n        }\n    }\n\n    /// This can only be used inside a pybind11-bound function, either by `argument_loader`\n    /// at argument preparation time or by `py::cast()` at execution time.\n    PYBIND11_NOINLINE static void add_patient(handle h) {\n        loader_life_support *frame = get_stack_top();\n        if (!frame) {\n            // NOTE: It would be nice to include the stack frames here, as this indicates\n            // use of pybind11::cast<> outside the normal call framework, finding such\n            // a location is challenging. Developers could consider printing out\n            // stack frame addresses here using something like __builtin_frame_address(0)\n            throw cast_error(\"When called outside a bound function, py::cast() cannot \"\n                             \"do Python -> C++ conversions which require the creation \"\n                             \"of temporary values\");\n        }\n\n        if (frame->keep_alive.insert(h.ptr()).second) {\n            Py_INCREF(h.ptr());\n        }\n    }\n};\n\n// Gets the cache entry for the given type, creating it if necessary.  The return value is the pair\n// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was\n// just created.\ninline std::pair<decltype(internals::registered_types_py)::iterator, bool>\nall_type_info_get_cache(PyTypeObject *type);\n\n// Populates a just-created cache entry.\nPYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector<type_info *> &bases) {\n    std::vector<PyTypeObject *> check;\n    for (handle parent : reinterpret_borrow<tuple>(t->tp_bases)) {\n        check.push_back((PyTypeObject *) parent.ptr());\n    }\n\n    auto const &type_dict = get_internals().registered_types_py;\n    for (size_t i = 0; i < check.size(); i++) {\n        auto *type = check[i];\n        // Ignore Python2 old-style class super type:\n        if (!PyType_Check((PyObject *) type)) {\n            continue;\n        }\n\n        // Check `type` in the current set of registered python types:\n        auto it = type_dict.find(type);\n        if (it != type_dict.end()) {\n            // We found a cache entry for it, so it's either pybind-registered or has pre-computed\n            // pybind bases, but we have to make sure we haven't already seen the type(s) before:\n            // we want to follow Python/virtual C++ rules that there should only be one instance of\n            // a common base.\n            for (auto *tinfo : it->second) {\n                // NB: Could use a second set here, rather than doing a linear search, but since\n                // having a large number of immediate pybind11-registered types seems fairly\n                // unlikely, that probably isn't worthwhile.\n                bool found = false;\n                for (auto *known : bases) {\n                    if (known == tinfo) {\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {\n                    bases.push_back(tinfo);\n                }\n            }\n        } else if (type->tp_bases) {\n            // It's some python type, so keep follow its bases classes to look for one or more\n            // registered types\n            if (i + 1 == check.size()) {\n                // When we're at the end, we can pop off the current element to avoid growing\n                // `check` when adding just one base (which is typical--i.e. when there is no\n                // multiple inheritance)\n                check.pop_back();\n                i--;\n            }\n            for (handle parent : reinterpret_borrow<tuple>(type->tp_bases)) {\n                check.push_back((PyTypeObject *) parent.ptr());\n            }\n        }\n    }\n}\n\n/**\n * Extracts vector of type_info pointers of pybind-registered roots of the given Python type.  Will\n * be just 1 pybind type for the Python type of a pybind-registered class, or for any Python-side\n * derived class that uses single inheritance.  Will contain as many types as required for a Python\n * class that uses multiple inheritance to inherit (directly or indirectly) from multiple\n * pybind-registered classes.  Will be empty if neither the type nor any base classes are\n * pybind-registered.\n *\n * The value is cached for the lifetime of the Python type.\n */\ninline const std::vector<detail::type_info *> &all_type_info(PyTypeObject *type) {\n    auto ins = all_type_info_get_cache(type);\n    if (ins.second) {\n        // New cache entry: populate it\n        all_type_info_populate(type, ins.first->second);\n    }\n\n    return ins.first->second;\n}\n\n/**\n * Gets a single pybind11 type info for a python type.  Returns nullptr if neither the type nor any\n * ancestors are pybind11-registered.  Throws an exception if there are multiple bases--use\n * `all_type_info` instead if you want to support multiple bases.\n */\nPYBIND11_NOINLINE detail::type_info *get_type_info(PyTypeObject *type) {\n    const auto &bases = all_type_info(type);\n    if (bases.empty()) {\n        return nullptr;\n    }\n    if (bases.size() > 1) {\n        pybind11_fail(\n            \"pybind11::detail::get_type_info: type has multiple pybind11-registered bases\");\n    }\n    return bases.front();\n}\n\ninline detail::type_info *get_local_type_info(const std::type_index &tp) {\n    auto &locals = get_local_internals().registered_types_cpp;\n    auto it = locals.find(tp);\n    if (it != locals.end()) {\n        return it->second;\n    }\n    return nullptr;\n}\n\ninline detail::type_info *get_global_type_info(const std::type_index &tp) {\n    auto &types = get_internals().registered_types_cpp;\n    auto it = types.find(tp);\n    if (it != types.end()) {\n        return it->second;\n    }\n    return nullptr;\n}\n\n/// Return the type info for a given C++ type; on lookup failure can either throw or return\n/// nullptr.\nPYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp,\n                                                   bool throw_if_missing = false) {\n    if (auto *ltype = get_local_type_info(tp)) {\n        return ltype;\n    }\n    if (auto *gtype = get_global_type_info(tp)) {\n        return gtype;\n    }\n\n    if (throw_if_missing) {\n        std::string tname = tp.name();\n        detail::clean_type_id(tname);\n        pybind11_fail(\"pybind11::detail::get_type_info: unable to find type info for \\\"\"\n                      + std::move(tname) + '\"');\n    }\n    return nullptr;\n}\n\nPYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing) {\n    detail::type_info *type_info = get_type_info(tp, throw_if_missing);\n    return handle(type_info ? ((PyObject *) type_info->type) : nullptr);\n}\n\n// Searches the inheritance graph for a registered Python instance, using all_type_info().\nPYBIND11_NOINLINE handle find_registered_python_instance(void *src,\n                                                         const detail::type_info *tinfo) {\n    auto it_instances = get_internals().registered_instances.equal_range(src);\n    for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {\n        for (auto *instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {\n            if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) {\n                return handle((PyObject *) it_i->second).inc_ref();\n            }\n        }\n    }\n    return handle();\n}\n\nstruct value_and_holder {\n    instance *inst = nullptr;\n    size_t index = 0u;\n    const detail::type_info *type = nullptr;\n    void **vh = nullptr;\n\n    // Main constructor for a found value/holder:\n    value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)\n        : inst{i}, index{index}, type{type}, vh{inst->simple_layout\n                                                    ? inst->simple_value_holder\n                                                    : &inst->nonsimple.values_and_holders[vpos]} {}\n\n    // Default constructor (used to signal a value-and-holder not found by get_value_and_holder())\n    value_and_holder() = default;\n\n    // Used for past-the-end iterator\n    explicit value_and_holder(size_t index) : index{index} {}\n\n    template <typename V = void>\n    V *&value_ptr() const {\n        return reinterpret_cast<V *&>(vh[0]);\n    }\n    // True if this `value_and_holder` has a non-null value pointer\n    explicit operator bool() const { return value_ptr() != nullptr; }\n\n    template <typename H>\n    H &holder() const {\n        return reinterpret_cast<H &>(vh[1]);\n    }\n    bool holder_constructed() const {\n        return inst->simple_layout\n                   ? inst->simple_holder_constructed\n                   : (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;\n    }\n    // NOLINTNEXTLINE(readability-make-member-function-const)\n    void set_holder_constructed(bool v = true) {\n        if (inst->simple_layout) {\n            inst->simple_holder_constructed = v;\n        } else if (v) {\n            inst->nonsimple.status[index] |= instance::status_holder_constructed;\n        } else {\n            inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;\n        }\n    }\n    bool instance_registered() const {\n        return inst->simple_layout\n                   ? inst->simple_instance_registered\n                   : ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);\n    }\n    // NOLINTNEXTLINE(readability-make-member-function-const)\n    void set_instance_registered(bool v = true) {\n        if (inst->simple_layout) {\n            inst->simple_instance_registered = v;\n        } else if (v) {\n            inst->nonsimple.status[index] |= instance::status_instance_registered;\n        } else {\n            inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;\n        }\n    }\n};\n\n// Container for accessing and iterating over an instance's values/holders\nstruct values_and_holders {\nprivate:\n    instance *inst;\n    using type_vec = std::vector<detail::type_info *>;\n    const type_vec &tinfo;\n\npublic:\n    explicit values_and_holders(instance *inst)\n        : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {}\n\n    struct iterator {\n    private:\n        instance *inst = nullptr;\n        const type_vec *types = nullptr;\n        value_and_holder curr;\n        friend struct values_and_holders;\n        iterator(instance *inst, const type_vec *tinfo)\n            : inst{inst}, types{tinfo},\n              curr(inst /* instance */,\n                   types->empty() ? nullptr : (*types)[0] /* type info */,\n                   0, /* vpos: (non-simple types only): the first vptr comes first */\n                   0 /* index */) {}\n        // Past-the-end iterator:\n        explicit iterator(size_t end) : curr(end) {}\n\n    public:\n        bool operator==(const iterator &other) const { return curr.index == other.curr.index; }\n        bool operator!=(const iterator &other) const { return curr.index != other.curr.index; }\n        iterator &operator++() {\n            if (!inst->simple_layout) {\n                curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;\n            }\n            ++curr.index;\n            curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;\n            return *this;\n        }\n        value_and_holder &operator*() { return curr; }\n        value_and_holder *operator->() { return &curr; }\n    };\n\n    iterator begin() { return iterator(inst, &tinfo); }\n    iterator end() { return iterator(tinfo.size()); }\n\n    iterator find(const type_info *find_type) {\n        auto it = begin(), endit = end();\n        while (it != endit && it->type != find_type) {\n            ++it;\n        }\n        return it;\n    }\n\n    size_t size() { return tinfo.size(); }\n};\n\n/**\n * Extracts C++ value and holder pointer references from an instance (which may contain multiple\n * values/holders for python-side multiple inheritance) that match the given type.  Throws an error\n * if the given type (or ValueType, if omitted) is not a pybind11 base of the given instance.  If\n * `find_type` is omitted (or explicitly specified as nullptr) the first value/holder are returned,\n * regardless of type (and the resulting .type will be nullptr).\n *\n * The returned object should be short-lived: in particular, it must not outlive the called-upon\n * instance.\n */\nPYBIND11_NOINLINE value_and_holder\ninstance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/,\n                               bool throw_if_missing /*= true in common.h*/) {\n    // Optimize common case:\n    if (!find_type || Py_TYPE(this) == find_type->type) {\n        return value_and_holder(this, find_type, 0, 0);\n    }\n\n    detail::values_and_holders vhs(this);\n    auto it = vhs.find(find_type);\n    if (it != vhs.end()) {\n        return *it;\n    }\n\n    if (!throw_if_missing) {\n        return value_and_holder();\n    }\n\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n    pybind11_fail(\"pybind11::detail::instance::get_value_and_holder: `\"\n                  + get_fully_qualified_tp_name(find_type->type)\n                  + \"' is not a pybind11 base of the given `\"\n                  + get_fully_qualified_tp_name(Py_TYPE(this)) + \"' instance\");\n#else\n    pybind11_fail(\n        \"pybind11::detail::instance::get_value_and_holder: \"\n        \"type is not a pybind11 base of the given instance \"\n        \"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for type details)\");\n#endif\n}\n\nPYBIND11_NOINLINE void instance::allocate_layout() {\n    const auto &tinfo = all_type_info(Py_TYPE(this));\n\n    const size_t n_types = tinfo.size();\n\n    if (n_types == 0) {\n        pybind11_fail(\n            \"instance allocation failed: new instance has no pybind11-registered base types\");\n    }\n\n    simple_layout\n        = n_types == 1 && tinfo.front()->holder_size_in_ptrs <= instance_simple_holder_in_ptrs();\n\n    // Simple path: no python-side multiple inheritance, and a small-enough holder\n    if (simple_layout) {\n        simple_value_holder[0] = nullptr;\n        simple_holder_constructed = false;\n        simple_instance_registered = false;\n    } else { // multiple base types or a too-large holder\n        // Allocate space to hold: [v1*][h1][v2*][h2]...[bb...] where [vN*] is a value pointer,\n        // [hN] is the (uninitialized) holder instance for value N, and [bb...] is a set of bool\n        // values that tracks whether each associated holder has been initialized.  Each [block] is\n        // padded, if necessary, to an integer multiple of sizeof(void *).\n        size_t space = 0;\n        for (auto *t : tinfo) {\n            space += 1;                      // value pointer\n            space += t->holder_size_in_ptrs; // holder instance\n        }\n        size_t flags_at = space;\n        space += size_in_ptrs(n_types); // status bytes (holder_constructed and\n                                        // instance_registered)\n\n        // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values,\n        // in particular, need to be 0).  Use Python's memory allocation\n        // functions: Python is using pymalloc, which is designed to be\n        // efficient for small allocations like the one we're doing here;\n        // for larger allocations they are just wrappers around malloc.\n        // TODO: is this still true for pure Python 3.6?\n        nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *));\n        if (!nonsimple.values_and_holders) {\n            throw std::bad_alloc();\n        }\n        nonsimple.status\n            = reinterpret_cast<std::uint8_t *>(&nonsimple.values_and_holders[flags_at]);\n    }\n    owned = true;\n}\n\n// NOLINTNEXTLINE(readability-make-member-function-const)\nPYBIND11_NOINLINE void instance::deallocate_layout() {\n    if (!simple_layout) {\n        PyMem_Free(nonsimple.values_and_holders);\n    }\n}\n\nPYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp) {\n    handle type = detail::get_type_handle(tp, false);\n    if (!type) {\n        return false;\n    }\n    return isinstance(obj, type);\n}\n\nPYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type) {\n    auto &instances = get_internals().registered_instances;\n    auto range = instances.equal_range(ptr);\n    for (auto it = range.first; it != range.second; ++it) {\n        for (const auto &vh : values_and_holders(it->second)) {\n            if (vh.type == type) {\n                return handle((PyObject *) it->second);\n            }\n        }\n    }\n    return handle();\n}\n\ninline PyThreadState *get_thread_state_unchecked() {\n#if defined(PYPY_VERSION)\n    return PyThreadState_GET();\n#else\n    return _PyThreadState_UncheckedGet();\n#endif\n}\n\n// Forward declarations\nvoid keep_alive_impl(handle nurse, handle patient);\ninline PyObject *make_new_instance(PyTypeObject *type);\n\nclass type_caster_generic {\npublic:\n    PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)\n        : typeinfo(get_type_info(type_info)), cpptype(&type_info) {}\n\n    explicit type_caster_generic(const type_info *typeinfo)\n        : typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) {}\n\n    bool load(handle src, bool convert) { return load_impl<type_caster_generic>(src, convert); }\n\n    PYBIND11_NOINLINE static handle cast(const void *_src,\n                                         return_value_policy policy,\n                                         handle parent,\n                                         const detail::type_info *tinfo,\n                                         void *(*copy_constructor)(const void *),\n                                         void *(*move_constructor)(const void *),\n                                         const void *existing_holder = nullptr) {\n        if (!tinfo) { // no type info: error will be set already\n            return handle();\n        }\n\n        void *src = const_cast<void *>(_src);\n        if (src == nullptr) {\n            return none().release();\n        }\n\n        if (handle registered_inst = find_registered_python_instance(src, tinfo)) {\n            return registered_inst;\n        }\n\n        auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));\n        auto *wrapper = reinterpret_cast<instance *>(inst.ptr());\n        wrapper->owned = false;\n        void *&valueptr = values_and_holders(wrapper).begin()->value_ptr();\n\n        switch (policy) {\n            case return_value_policy::automatic:\n            case return_value_policy::take_ownership:\n                valueptr = src;\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::automatic_reference:\n            case return_value_policy::reference:\n                valueptr = src;\n                wrapper->owned = false;\n                break;\n\n            case return_value_policy::copy:\n                if (copy_constructor) {\n                    valueptr = copy_constructor(src);\n                } else {\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                    std::string type_name(tinfo->cpptype->name());\n                    detail::clean_type_id(type_name);\n                    throw cast_error(\"return_value_policy = copy, but type \" + type_name\n                                     + \" is non-copyable!\");\n#else\n                    throw cast_error(\"return_value_policy = copy, but type is \"\n                                     \"non-copyable! (#define PYBIND11_DETAILED_ERROR_MESSAGES or \"\n                                     \"compile in debug mode for details)\");\n#endif\n                }\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::move:\n                if (move_constructor) {\n                    valueptr = move_constructor(src);\n                } else if (copy_constructor) {\n                    valueptr = copy_constructor(src);\n                } else {\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                    std::string type_name(tinfo->cpptype->name());\n                    detail::clean_type_id(type_name);\n                    throw cast_error(\"return_value_policy = move, but type \" + type_name\n                                     + \" is neither movable nor copyable!\");\n#else\n                    throw cast_error(\"return_value_policy = move, but type is neither \"\n                                     \"movable nor copyable! \"\n                                     \"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in \"\n                                     \"debug mode for details)\");\n#endif\n                }\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::reference_internal:\n                valueptr = src;\n                wrapper->owned = false;\n                keep_alive_impl(inst, parent);\n                break;\n\n            default:\n                throw cast_error(\"unhandled return_value_policy: should not happen!\");\n        }\n\n        tinfo->init_instance(wrapper, existing_holder);\n\n        return inst.release();\n    }\n\n    // Base methods for generic caster; there are overridden in copyable_holder_caster\n    void load_value(value_and_holder &&v_h) {\n        auto *&vptr = v_h.value_ptr();\n        // Lazy allocation for unallocated values:\n        if (vptr == nullptr) {\n            const auto *type = v_h.type ? v_h.type : typeinfo;\n            if (type->operator_new) {\n                vptr = type->operator_new(type->type_size);\n            } else {\n#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n                if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {\n                    vptr = ::operator new(type->type_size, std::align_val_t(type->type_align));\n                } else {\n                    vptr = ::operator new(type->type_size);\n                }\n#else\n                vptr = ::operator new(type->type_size);\n#endif\n            }\n        }\n        value = vptr;\n    }\n    bool try_implicit_casts(handle src, bool convert) {\n        for (const auto &cast : typeinfo->implicit_casts) {\n            type_caster_generic sub_caster(*cast.first);\n            if (sub_caster.load(src, convert)) {\n                value = cast.second(sub_caster.value);\n                return true;\n            }\n        }\n        return false;\n    }\n    bool try_direct_conversions(handle src) {\n        for (auto &converter : *typeinfo->direct_conversions) {\n            if (converter(src.ptr(), value)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    void check_holder_compat() {}\n\n    PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) {\n        auto caster = type_caster_generic(ti);\n        if (caster.load(src, false)) {\n            return caster.value;\n        }\n        return nullptr;\n    }\n\n    /// Try to load with foreign typeinfo, if available. Used when there is no\n    /// native typeinfo, or when the native one wasn't able to produce a value.\n    PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {\n        constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;\n        const auto pytype = type::handle_of(src);\n        if (!hasattr(pytype, local_key)) {\n            return false;\n        }\n\n        type_info *foreign_typeinfo = reinterpret_borrow<capsule>(getattr(pytype, local_key));\n        // Only consider this foreign loader if actually foreign and is a loader of the correct cpp\n        // type\n        if (foreign_typeinfo->module_local_load == &local_load\n            || (cpptype && !same_type(*cpptype, *foreign_typeinfo->cpptype))) {\n            return false;\n        }\n\n        if (auto *result = foreign_typeinfo->module_local_load(src.ptr(), foreign_typeinfo)) {\n            value = result;\n            return true;\n        }\n        return false;\n    }\n\n    // Implementation of `load`; this takes the type of `this` so that it can dispatch the relevant\n    // bits of code between here and copyable_holder_caster where the two classes need different\n    // logic (without having to resort to virtual inheritance).\n    template <typename ThisT>\n    PYBIND11_NOINLINE bool load_impl(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (!typeinfo) {\n            return try_load_foreign_module_local(src);\n        }\n\n        auto &this_ = static_cast<ThisT &>(*this);\n        this_.check_holder_compat();\n\n        PyTypeObject *srctype = Py_TYPE(src.ptr());\n\n        // Case 1: If src is an exact type match for the target type then we can reinterpret_cast\n        // the instance's value pointer to the target type:\n        if (srctype == typeinfo->type) {\n            this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());\n            return true;\n        }\n        // Case 2: We have a derived class\n        if (PyType_IsSubtype(srctype, typeinfo->type)) {\n            const auto &bases = all_type_info(srctype);\n            bool no_cpp_mi = typeinfo->simple_type;\n\n            // Case 2a: the python type is a Python-inherited derived class that inherits from just\n            // one simple (no MI) pybind11 class, or is an exact match, so the C++ instance is of\n            // the right type and we can use reinterpret_cast.\n            // (This is essentially the same as case 2b, but because not using multiple inheritance\n            // is extremely common, we handle it specially to avoid the loop iterator and type\n            // pointer lookup overhead)\n            if (bases.size() == 1 && (no_cpp_mi || bases.front()->type == typeinfo->type)) {\n                this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());\n                return true;\n            }\n            // Case 2b: the python type inherits from multiple C++ bases.  Check the bases to see\n            // if we can find an exact match (or, for a simple C++ type, an inherited match); if\n            // so, we can safely reinterpret_cast to the relevant pointer.\n            if (bases.size() > 1) {\n                for (auto *base : bases) {\n                    if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type)\n                                  : base->type == typeinfo->type) {\n                        this_.load_value(\n                            reinterpret_cast<instance *>(src.ptr())->get_value_and_holder(base));\n                        return true;\n                    }\n                }\n            }\n\n            // Case 2c: C++ multiple inheritance is involved and we couldn't find an exact type\n            // match in the registered bases, above, so try implicit casting (needed for proper C++\n            // casting when MI is involved).\n            if (this_.try_implicit_casts(src, convert)) {\n                return true;\n            }\n        }\n\n        // Perform an implicit conversion\n        if (convert) {\n            for (const auto &converter : typeinfo->implicit_conversions) {\n                auto temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));\n                if (load_impl<ThisT>(temp, false)) {\n                    loader_life_support::add_patient(temp);\n                    return true;\n                }\n            }\n            if (this_.try_direct_conversions(src)) {\n                return true;\n            }\n        }\n\n        // Failed to match local typeinfo. Try again with global.\n        if (typeinfo->module_local) {\n            if (auto *gtype = get_global_type_info(*typeinfo->cpptype)) {\n                typeinfo = gtype;\n                return load(src, false);\n            }\n        }\n\n        // Global typeinfo has precedence over foreign module_local\n        if (try_load_foreign_module_local(src)) {\n            return true;\n        }\n\n        // Custom converters didn't take None, now we convert None to nullptr.\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            value = nullptr;\n            return true;\n        }\n\n        return false;\n    }\n\n    // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast\n    // isn't needed or can't be used.  If the type is unknown, sets the error and returns a pair\n    // with .second = nullptr.  (p.first = nullptr is not an error: it becomes None).\n    PYBIND11_NOINLINE static std::pair<const void *, const type_info *>\n    src_and_type(const void *src,\n                 const std::type_info &cast_type,\n                 const std::type_info *rtti_type = nullptr) {\n        if (auto *tpi = get_type_info(cast_type)) {\n            return {src, const_cast<const type_info *>(tpi)};\n        }\n\n        // Not found, set error:\n        std::string tname = rtti_type ? rtti_type->name() : cast_type.name();\n        detail::clean_type_id(tname);\n        std::string msg = \"Unregistered type : \" + tname;\n        PyErr_SetString(PyExc_TypeError, msg.c_str());\n        return {nullptr, nullptr};\n    }\n\n    const type_info *typeinfo = nullptr;\n    const std::type_info *cpptype = nullptr;\n    void *value = nullptr;\n};\n\n/**\n * Determine suitable casting operator for pointer-or-lvalue-casting type casters.  The type caster\n * needs to provide `operator T*()` and `operator T&()` operators.\n *\n * If the type supports moving the value away via an `operator T&&() &&` method, it should use\n * `movable_cast_op_type` instead.\n */\ntemplate <typename T>\nusing cast_op_type = conditional_t<std::is_pointer<remove_reference_t<T>>::value,\n                                   typename std::add_pointer<intrinsic_t<T>>::type,\n                                   typename std::add_lvalue_reference<intrinsic_t<T>>::type>;\n\n/**\n * Determine suitable casting operator for a type caster with a movable value.  Such a type caster\n * needs to provide `operator T*()`, `operator T&()`, and `operator T&&() &&`.  The latter will be\n * called in appropriate contexts where the value can be moved rather than copied.\n *\n * These operator are automatically provided when using the PYBIND11_TYPE_CASTER macro.\n */\ntemplate <typename T>\nusing movable_cast_op_type\n    = conditional_t<std::is_pointer<typename std::remove_reference<T>::type>::value,\n                    typename std::add_pointer<intrinsic_t<T>>::type,\n                    conditional_t<std::is_rvalue_reference<T>::value,\n                                  typename std::add_rvalue_reference<intrinsic_t<T>>::type,\n                                  typename std::add_lvalue_reference<intrinsic_t<T>>::type>>;\n\n// std::is_copy_constructible isn't quite enough: it lets std::vector<T> (and similar) through when\n// T is non-copyable, but code containing such a copy constructor fails to actually compile.\ntemplate <typename T, typename SFINAE = void>\nstruct is_copy_constructible : std::is_copy_constructible<T> {};\n\n// Specialization for types that appear to be copy constructible but also look like stl containers\n// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if\n// so, copy constructability depends on whether the value_type is copy constructible.\ntemplate <typename Container>\nstruct is_copy_constructible<\n    Container,\n    enable_if_t<\n        all_of<std::is_copy_constructible<Container>,\n               std::is_same<typename Container::value_type &, typename Container::reference>,\n               // Avoid infinite recursion\n               negation<std::is_same<Container, typename Container::value_type>>>::value>>\n    : is_copy_constructible<typename Container::value_type> {};\n\n// Likewise for std::pair\n// (after C++17 it is mandatory that the copy constructor not exist when the two types aren't\n// themselves copy constructible, but this can not be relied upon when T1 or T2 are themselves\n// containers).\ntemplate <typename T1, typename T2>\nstruct is_copy_constructible<std::pair<T1, T2>>\n    : all_of<is_copy_constructible<T1>, is_copy_constructible<T2>> {};\n\n// The same problems arise with std::is_copy_assignable, so we use the same workaround.\ntemplate <typename T, typename SFINAE = void>\nstruct is_copy_assignable : std::is_copy_assignable<T> {};\ntemplate <typename Container>\nstruct is_copy_assignable<Container,\n                          enable_if_t<all_of<std::is_copy_assignable<Container>,\n                                             std::is_same<typename Container::value_type &,\n                                                          typename Container::reference>>::value>>\n    : is_copy_assignable<typename Container::value_type> {};\ntemplate <typename T1, typename T2>\nstruct is_copy_assignable<std::pair<T1, T2>>\n    : all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};\n\nPYBIND11_NAMESPACE_END(detail)\n\n// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed\n// to by `src` actually is an instance of some class derived from `itype`.\n// If so, it sets `tinfo` to point to the std::type_info representing that derived\n// type, and returns a pointer to the start of the most-derived object of that type\n// (in which `src` is a subobject; this will be the same address as `src` in most\n// single inheritance cases). If not, or if `src` is nullptr, it simply returns `src`\n// and leaves `tinfo` at its default value of nullptr.\n//\n// The default polymorphic_type_hook just returns src. A specialization for polymorphic\n// types determines the runtime type of the passed object and adjusts the this-pointer\n// appropriately via dynamic_cast<void*>. This is what enables a C++ Animal* to appear\n// to Python as a Dog (if Dog inherits from Animal, Animal is polymorphic, Dog is\n// registered with pybind11, and this Animal is in fact a Dog).\n//\n// You may specialize polymorphic_type_hook yourself for types that want to appear\n// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern\n// in performance-sensitive applications, used most notably in LLVM.)\n//\n// polymorphic_type_hook_base allows users to specialize polymorphic_type_hook with\n// std::enable_if. User provided specializations will always have higher priority than\n// the default implementation and specialization provided in polymorphic_type_hook_base.\ntemplate <typename itype, typename SFINAE = void>\nstruct polymorphic_type_hook_base {\n    static const void *get(const itype *src, const std::type_info *&) { return src; }\n};\ntemplate <typename itype>\nstruct polymorphic_type_hook_base<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>> {\n    static const void *get(const itype *src, const std::type_info *&type) {\n        type = src ? &typeid(*src) : nullptr;\n        return dynamic_cast<const void *>(src);\n    }\n};\ntemplate <typename itype, typename SFINAE = void>\nstruct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Generic type caster for objects stored on the heap\ntemplate <typename type>\nclass type_caster_base : public type_caster_generic {\n    using itype = intrinsic_t<type>;\n\npublic:\n    static constexpr auto name = const_name<type>();\n\n    type_caster_base() : type_caster_base(typeid(type)) {}\n    explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) {}\n\n    static handle cast(const itype &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n\n    static handle cast(itype &&src, return_value_policy, handle parent) {\n        return cast(&src, return_value_policy::move, parent);\n    }\n\n    // Returns a (pointer, type_info) pair taking care of necessary type lookup for a\n    // polymorphic type (using RTTI by default, but can be overridden by specializing\n    // polymorphic_type_hook). If the instance isn't derived, returns the base version.\n    static std::pair<const void *, const type_info *> src_and_type(const itype *src) {\n        const auto &cast_type = typeid(itype);\n        const std::type_info *instance_type = nullptr;\n        const void *vsrc = polymorphic_type_hook<itype>::get(src, instance_type);\n        if (instance_type && !same_type(cast_type, *instance_type)) {\n            // This is a base pointer to a derived type. If the derived type is registered\n            // with pybind11, we want to make the full derived object available.\n            // In the typical case where itype is polymorphic, we get the correct\n            // derived pointer (which may be != base pointer) by a dynamic_cast to\n            // most derived type. If itype is not polymorphic, we won't get here\n            // except via a user-provided specialization of polymorphic_type_hook,\n            // and the user has promised that no this-pointer adjustment is\n            // required in that case, so it's OK to use static_cast.\n            if (const auto *tpi = get_type_info(*instance_type)) {\n                return {vsrc, tpi};\n            }\n        }\n        // Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer,\n        // so don't do a cast\n        return type_caster_generic::src_and_type(src, cast_type, instance_type);\n    }\n\n    static handle cast(const itype *src, return_value_policy policy, handle parent) {\n        auto st = src_and_type(src);\n        return type_caster_generic::cast(st.first,\n                                         policy,\n                                         parent,\n                                         st.second,\n                                         make_copy_constructor(src),\n                                         make_move_constructor(src));\n    }\n\n    static handle cast_holder(const itype *src, const void *holder) {\n        auto st = src_and_type(src);\n        return type_caster_generic::cast(st.first,\n                                         return_value_policy::take_ownership,\n                                         {},\n                                         st.second,\n                                         nullptr,\n                                         nullptr,\n                                         holder);\n    }\n\n    template <typename T>\n    using cast_op_type = detail::cast_op_type<T>;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator itype *() { return (type *) value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator itype &() {\n        if (!value) {\n            throw reference_cast_error();\n        }\n        return *((itype *) value);\n    }\n\nprotected:\n    using Constructor = void *(*) (const void *);\n\n    /* Only enabled when the types are {copy,move}-constructible *and* when the type\n       does not have a private operator new implementation. A comma operator is used in the\n       decltype argument to apply SFINAE to the public copy/move constructors.*/\n    template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>\n    static auto make_copy_constructor(const T *)\n        -> decltype(new T(std::declval<const T>()), Constructor{}) {\n        return [](const void *arg) -> void * { return new T(*reinterpret_cast<const T *>(arg)); };\n    }\n\n    template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>\n    static auto make_move_constructor(const T *)\n        -> decltype(new T(std::declval<T &&>()), Constructor{}) {\n        return [](const void *arg) -> void * {\n            return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));\n        };\n    }\n\n    static Constructor make_copy_constructor(...) { return nullptr; }\n    static Constructor make_move_constructor(...) { return nullptr; }\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/detail/typeid.h",
    "content": "/*\n    pybind11/detail/typeid.h: Compiler-independent access to type identifiers\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include <cstdio>\n#include <cstdlib>\n\n#if defined(__GNUG__)\n#    include <cxxabi.h>\n#endif\n\n#include \"common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Erase all occurrences of a substring\ninline void erase_all(std::string &string, const std::string &search) {\n    for (size_t pos = 0;;) {\n        pos = string.find(search, pos);\n        if (pos == std::string::npos) {\n            break;\n        }\n        string.erase(pos, search.length());\n    }\n}\n\nPYBIND11_NOINLINE void clean_type_id(std::string &name) {\n#if defined(__GNUG__)\n    int status = 0;\n    std::unique_ptr<char, void (*)(void *)> res{\n        abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free};\n    if (status == 0) {\n        name = res.get();\n    }\n#else\n    detail::erase_all(name, \"class \");\n    detail::erase_all(name, \"struct \");\n    detail::erase_all(name, \"enum \");\n#endif\n    detail::erase_all(name, \"pybind11::\");\n}\n\ninline std::string clean_type_id(const char *typeid_name) {\n    std::string name(typeid_name);\n    detail::clean_type_id(name);\n    return name;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Return a string representation of a C++ type\ntemplate <typename T>\nstatic std::string type_id() {\n    return detail::clean_type_id(typeid(T).name());\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/eigen/matrix.h",
    "content": "/*\n    pybind11/eigen/matrix.h: Transparent conversion for dense and sparse Eigen matrices\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../numpy.h\"\n\n/* HINT: To suppress warnings originating from the Eigen headers, use -isystem.\n   See also:\n       https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir\n       https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler\n*/\n// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could\n// make it version specific, or even remove it later, but considering that\n// 1. C4127 is generally far more distracting than useful for modern template code, and\n// 2. we definitely want to ignore any MSVC warnings originating from Eigen code,\n//    it is probably best to keep this around indefinitely.\n#if defined(_MSC_VER)\n#    pragma warning(push)\n#    pragma warning(disable : 4127) // C4127: conditional expression is constant\n#    pragma warning(disable : 5054) // https://github.com/pybind/pybind11/pull/3741\n//       C5054: operator '&': deprecated between enumerations of different types\n#elif defined(__MINGW32__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wmaybe-uninitialized\"\n#endif\n\n#include <Eigen/Core>\n#include <Eigen/SparseCore>\n\n#if defined(_MSC_VER)\n#    pragma warning(pop)\n#elif defined(__MINGW32__)\n#    pragma GCC diagnostic pop\n#endif\n\n// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit\n// move constructors that break things.  We could detect this an explicitly copy, but an extra copy\n// of matrices seems highly undesirable.\nstatic_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),\n              \"Eigen matrix support in pybind11 requires Eigen >= 3.2.7\");\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:\nusing EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;\ntemplate <typename MatrixType>\nusing EigenDRef = Eigen::Ref<MatrixType, 0, EigenDStride>;\ntemplate <typename MatrixType>\nusing EigenDMap = Eigen::Map<MatrixType, 0, EigenDStride>;\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if EIGEN_VERSION_AT_LEAST(3, 3, 0)\nusing EigenIndex = Eigen::Index;\ntemplate <typename Scalar, int Flags, typename StorageIndex>\nusing EigenMapSparseMatrix = Eigen::Map<Eigen::SparseMatrix<Scalar, Flags, StorageIndex>>;\n#else\nusing EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE;\ntemplate <typename Scalar, int Flags, typename StorageIndex>\nusing EigenMapSparseMatrix = Eigen::MappedSparseMatrix<Scalar, Flags, StorageIndex>;\n#endif\n\n// Matches Eigen::Map, Eigen::Ref, blocks, etc:\ntemplate <typename T>\nusing is_eigen_dense_map = all_of<is_template_base_of<Eigen::DenseBase, T>,\n                                  std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;\ntemplate <typename T>\nusing is_eigen_mutable_map = std::is_base_of<Eigen::MapBase<T, Eigen::WriteAccessors>, T>;\ntemplate <typename T>\nusing is_eigen_dense_plain\n    = all_of<negation<is_eigen_dense_map<T>>, is_template_base_of<Eigen::PlainObjectBase, T>>;\ntemplate <typename T>\nusing is_eigen_sparse = is_template_base_of<Eigen::SparseMatrixBase, T>;\n// Test for objects inheriting from EigenBase<Derived> that aren't captured by the above.  This\n// basically covers anything that can be assigned to a dense matrix but that don't have a typical\n// matrix data layout that can be copied from their .data().  For example, DiagonalMatrix and\n// SelfAdjointView fall into this category.\ntemplate <typename T>\nusing is_eigen_other\n    = all_of<is_template_base_of<Eigen::EigenBase, T>,\n             negation<any_of<is_eigen_dense_map<T>, is_eigen_dense_plain<T>, is_eigen_sparse<T>>>>;\n\n// Captures numpy/eigen conformability status (returned by EigenProps::conformable()):\ntemplate <bool EigenRowMajor>\nstruct EigenConformable {\n    bool conformable = false;\n    EigenIndex rows = 0, cols = 0;\n    EigenDStride stride{0, 0};    // Only valid if negativestrides is false!\n    bool negativestrides = false; // If true, do not use stride!\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    EigenConformable(bool fits = false) : conformable{fits} {}\n    // Matrix type:\n    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex rstride, EigenIndex cstride)\n        : conformable{true}, rows{r}, cols{c},\n          // TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity.\n          // http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747\n          stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)\n                               : (cstride > 0 ? cstride : 0) /* outer stride */,\n                 EigenRowMajor ? (cstride > 0 ? cstride : 0)\n                               : (rstride > 0 ? rstride : 0) /* inner stride */},\n          negativestrides{rstride < 0 || cstride < 0} {}\n    // Vector type:\n    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride)\n        : EigenConformable(r, c, r == 1 ? c * stride : stride, c == 1 ? r : r * stride) {}\n\n    template <typename props>\n    bool stride_compatible() const {\n        // To have compatible strides, we need (on both dimensions) one of fully dynamic strides,\n        // matching strides, or a dimension size of 1 (in which case the stride value is\n        // irrelevant). Alternatively, if any dimension size is 0, the strides are not relevant\n        // (and numpy ≥ 1.23 sets the strides to 0 in that case, so we need to check explicitly).\n        if (negativestrides) {\n            return false;\n        }\n        if (rows == 0 || cols == 0) {\n            return true;\n        }\n        return (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner()\n                || (EigenRowMajor ? cols : rows) == 1)\n               && (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer()\n                   || (EigenRowMajor ? rows : cols) == 1);\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator bool() const { return conformable; }\n};\n\ntemplate <typename Type>\nstruct eigen_extract_stride {\n    using type = Type;\n};\ntemplate <typename PlainObjectType, int MapOptions, typename StrideType>\nstruct eigen_extract_stride<Eigen::Map<PlainObjectType, MapOptions, StrideType>> {\n    using type = StrideType;\n};\ntemplate <typename PlainObjectType, int Options, typename StrideType>\nstruct eigen_extract_stride<Eigen::Ref<PlainObjectType, Options, StrideType>> {\n    using type = StrideType;\n};\n\n// Helper struct for extracting information from an Eigen type\ntemplate <typename Type_>\nstruct EigenProps {\n    using Type = Type_;\n    using Scalar = typename Type::Scalar;\n    using StrideType = typename eigen_extract_stride<Type>::type;\n    static constexpr EigenIndex rows = Type::RowsAtCompileTime, cols = Type::ColsAtCompileTime,\n                                size = Type::SizeAtCompileTime;\n    static constexpr bool row_major = Type::IsRowMajor,\n                          vector\n                          = Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1\n        fixed_rows = rows != Eigen::Dynamic, fixed_cols = cols != Eigen::Dynamic,\n                          fixed = size != Eigen::Dynamic, // Fully-fixed size\n        dynamic = !fixed_rows && !fixed_cols;             // Fully-dynamic size\n\n    template <EigenIndex i, EigenIndex ifzero>\n    using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;\n    static constexpr EigenIndex inner_stride\n        = if_zero<StrideType::InnerStrideAtCompileTime, 1>::value,\n        outer_stride = if_zero < StrideType::OuterStrideAtCompileTime,\n        vector      ? size\n        : row_major ? cols\n                    : rows > ::value;\n    static constexpr bool dynamic_stride\n        = inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic;\n    static constexpr bool requires_row_major\n        = !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1;\n    static constexpr bool requires_col_major\n        = !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1;\n\n    // Takes an input array and determines whether we can make it fit into the Eigen type.  If\n    // the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector\n    // (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type).\n    static EigenConformable<row_major> conformable(const array &a) {\n        const auto dims = a.ndim();\n        if (dims < 1 || dims > 2) {\n            return false;\n        }\n\n        if (dims == 2) { // Matrix type: require exact match (or dynamic)\n\n            EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),\n                       np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),\n                       np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));\n            if ((PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && np_rows != rows)\n                || (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {\n                return false;\n            }\n\n            return {np_rows, np_cols, np_rstride, np_cstride};\n        }\n\n        // Otherwise we're storing an n-vector.  Only one of the strides will be used, but\n        // whichever is used, we want the (single) numpy stride value.\n        const EigenIndex n = a.shape(0),\n                         stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));\n\n        if (vector) { // Eigen type is a compile-time vector\n            if (PYBIND11_SILENCE_MSVC_C4127(fixed) && size != n) {\n                return false; // Vector size mismatch\n            }\n            return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};\n        }\n        if (fixed) {\n            // The type has a fixed size, but is not a vector: abort\n            return false;\n        }\n        if (fixed_cols) {\n            // Since this isn't a vector, cols must be != 1.  We allow this only if it exactly\n            // equals the number of elements (rows is Dynamic, and so 1 row is allowed).\n            if (cols != n) {\n                return false;\n            }\n            return {1, n, stride};\n        } // Otherwise it's either fully dynamic, or column dynamic; both become a column vector\n        if (PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && rows != n) {\n            return false;\n        }\n        return {n, 1, stride};\n    }\n\n    static constexpr bool show_writeable\n        = is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;\n    static constexpr bool show_order = is_eigen_dense_map<Type>::value;\n    static constexpr bool show_c_contiguous = show_order && requires_row_major;\n    static constexpr bool show_f_contiguous\n        = !show_c_contiguous && show_order && requires_col_major;\n\n    static constexpr auto descriptor\n        = const_name(\"numpy.ndarray[\") + npy_format_descriptor<Scalar>::name + const_name(\"[\")\n          + const_name<fixed_rows>(const_name<(size_t) rows>(), const_name(\"m\")) + const_name(\", \")\n          + const_name<fixed_cols>(const_name<(size_t) cols>(), const_name(\"n\")) + const_name(\"]\")\n          +\n          // For a reference type (e.g. Ref<MatrixXd>) we have other constraints that might need to\n          // be satisfied: writeable=True (for a mutable reference), and, depending on the map's\n          // stride options, possibly f_contiguous or c_contiguous.  We include them in the\n          // descriptor output to provide some hint as to why a TypeError is occurring (otherwise\n          // it can be confusing to see that a function accepts a 'numpy.ndarray[float64[3,2]]' and\n          // an error message that you *gave* a numpy.ndarray of the right type and dimensions.\n          const_name<show_writeable>(\", flags.writeable\", \"\")\n          + const_name<show_c_contiguous>(\", flags.c_contiguous\", \"\")\n          + const_name<show_f_contiguous>(\", flags.f_contiguous\", \"\") + const_name(\"]\");\n};\n\n// Casts an Eigen type to numpy array.  If given a base, the numpy array references the src data,\n// otherwise it'll make a copy.  writeable lets you turn off the writeable flag for the array.\ntemplate <typename props>\nhandle\neigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) {\n    constexpr ssize_t elem_size = sizeof(typename props::Scalar);\n    array a;\n    if (props::vector) {\n        a = array({src.size()}, {elem_size * src.innerStride()}, src.data(), base);\n    } else {\n        a = array({src.rows(), src.cols()},\n                  {elem_size * src.rowStride(), elem_size * src.colStride()},\n                  src.data(),\n                  base);\n    }\n\n    if (!writeable) {\n        array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;\n    }\n\n    return a.release();\n}\n\n// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that\n// reference the Eigen object's data with `base` as the python-registered base class (if omitted,\n// the base will be set to None, and lifetime management is up to the caller).  The numpy array is\n// non-writeable if the given type is const.\ntemplate <typename props, typename Type>\nhandle eigen_ref_array(Type &src, handle parent = none()) {\n    // none here is to get past array's should-we-copy detection, which currently always\n    // copies when there is no base.  Setting the base to None should be harmless.\n    return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);\n}\n\n// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a\n// numpy array that references the encapsulated data with a python-side reference to the capsule to\n// tie its destruction to that of any dependent python objects.  Const-ness is determined by\n// whether or not the Type of the pointer given is const.\ntemplate <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>\nhandle eigen_encapsulate(Type *src) {\n    capsule base(src, [](void *o) { delete static_cast<Type *>(o); });\n    return eigen_ref_array<props>(*src, base);\n}\n\n// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense\n// types.\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {\n    using Scalar = typename Type::Scalar;\n    using props = EigenProps<Type>;\n\n    bool load(handle src, bool convert) {\n        // If we're in no-convert mode, only load if given an array of the correct type\n        if (!convert && !isinstance<array_t<Scalar>>(src)) {\n            return false;\n        }\n\n        // Coerce into an array, but don't do type conversion yet; the copy below handles it.\n        auto buf = array::ensure(src);\n\n        if (!buf) {\n            return false;\n        }\n\n        auto dims = buf.ndim();\n        if (dims < 1 || dims > 2) {\n            return false;\n        }\n\n        auto fits = props::conformable(buf);\n        if (!fits) {\n            return false;\n        }\n\n        // Allocate the new type, then build a numpy reference into it\n        value = Type(fits.rows, fits.cols);\n        auto ref = reinterpret_steal<array>(eigen_ref_array<props>(value));\n        if (dims == 1) {\n            ref = ref.squeeze();\n        } else if (ref.ndim() == 1) {\n            buf = buf.squeeze();\n        }\n\n        int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr());\n\n        if (result < 0) { // Copy failed!\n            PyErr_Clear();\n            return false;\n        }\n\n        return true;\n    }\n\nprivate:\n    // Cast implementation\n    template <typename CType>\n    static handle cast_impl(CType *src, return_value_policy policy, handle parent) {\n        switch (policy) {\n            case return_value_policy::take_ownership:\n            case return_value_policy::automatic:\n                return eigen_encapsulate<props>(src);\n            case return_value_policy::move:\n                return eigen_encapsulate<props>(new CType(std::move(*src)));\n            case return_value_policy::copy:\n                return eigen_array_cast<props>(*src);\n            case return_value_policy::reference:\n            case return_value_policy::automatic_reference:\n                return eigen_ref_array<props>(*src);\n            case return_value_policy::reference_internal:\n                return eigen_ref_array<props>(*src, parent);\n            default:\n                throw cast_error(\"unhandled return_value_policy: should not happen!\");\n        };\n    }\n\npublic:\n    // Normal returned non-reference, non-const value:\n    static handle cast(Type &&src, return_value_policy /* policy */, handle parent) {\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n    // If you return a non-reference const, we mark the numpy array readonly:\n    static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) {\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n    // lvalue reference return; default (automatic) becomes copy\n    static handle cast(Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast_impl(&src, policy, parent);\n    }\n    // const lvalue reference return; default (automatic) becomes copy\n    static handle cast(const Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n    // non-const pointer return\n    static handle cast(Type *src, return_value_policy policy, handle parent) {\n        return cast_impl(src, policy, parent);\n    }\n    // const pointer return\n    static handle cast(const Type *src, return_value_policy policy, handle parent) {\n        return cast_impl(src, policy, parent);\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type *() { return &value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &() { return value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &&() && { return std::move(value); }\n    template <typename T>\n    using cast_op_type = movable_cast_op_type<T>;\n\nprivate:\n    Type value;\n};\n\n// Base class for casting reference/map/block/etc. objects back to python.\ntemplate <typename MapType>\nstruct eigen_map_caster {\nprivate:\n    using props = EigenProps<MapType>;\n\npublic:\n    // Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has\n    // to stay around), but we'll allow it under the assumption that you know what you're doing\n    // (and have an appropriate keep_alive in place).  We return a numpy array pointing directly at\n    // the ref's data (The numpy array ends up read-only if the ref was to a const matrix type.)\n    // Note that this means you need to ensure you don't destroy the object in some other way (e.g.\n    // with an appropriate keep_alive, or with a reference to a statically allocated matrix).\n    static handle cast(const MapType &src, return_value_policy policy, handle parent) {\n        switch (policy) {\n            case return_value_policy::copy:\n                return eigen_array_cast<props>(src);\n            case return_value_policy::reference_internal:\n                return eigen_array_cast<props>(src, parent, is_eigen_mutable_map<MapType>::value);\n            case return_value_policy::reference:\n            case return_value_policy::automatic:\n            case return_value_policy::automatic_reference:\n                return eigen_array_cast<props>(src, none(), is_eigen_mutable_map<MapType>::value);\n            default:\n                // move, take_ownership don't make any sense for a ref/map:\n                pybind11_fail(\"Invalid return_value_policy for Eigen Map/Ref/Block type\");\n        }\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return\n    // types but not bound arguments).  We still provide them (with an explicitly delete) so that\n    // you end up here if you try anyway.\n    bool load(handle, bool) = delete;\n    operator MapType() = delete;\n    template <typename>\n    using cast_op_type = MapType;\n};\n\n// We can return any map-like object (but can only load Refs, specialized next):\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_dense_map<Type>::value>> : eigen_map_caster<Type> {};\n\n// Loader for Ref<...> arguments.  See the documentation for info on how to make this work without\n// copying (it requires some extra effort in many cases).\ntemplate <typename PlainObjectType, typename StrideType>\nstruct type_caster<\n    Eigen::Ref<PlainObjectType, 0, StrideType>,\n    enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>\n    : public eigen_map_caster<Eigen::Ref<PlainObjectType, 0, StrideType>> {\nprivate:\n    using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;\n    using props = EigenProps<Type>;\n    using Scalar = typename props::Scalar;\n    using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;\n    using Array\n        = array_t<Scalar,\n                  array::forcecast\n                      | ((props::row_major ? props::inner_stride : props::outer_stride) == 1\n                             ? array::c_style\n                         : (props::row_major ? props::outer_stride : props::inner_stride) == 1\n                             ? array::f_style\n                             : 0)>;\n    static constexpr bool need_writeable = is_eigen_mutable_map<Type>::value;\n    // Delay construction (these have no default constructor)\n    std::unique_ptr<MapType> map;\n    std::unique_ptr<Type> ref;\n    // Our array.  When possible, this is just a numpy array pointing to the source data, but\n    // sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an\n    // incompatible layout, or is an array of a type that needs to be converted).  Using a numpy\n    // temporary (rather than an Eigen temporary) saves an extra copy when we need both type\n    // conversion and storage order conversion.  (Note that we refuse to use this temporary copy\n    // when loading an argument for a Ref<M> with M non-const, i.e. a read-write reference).\n    Array copy_or_ref;\n\npublic:\n    bool load(handle src, bool convert) {\n        // First check whether what we have is already an array of the right type.  If not, we\n        // can't avoid a copy (because the copy is also going to do type conversion).\n        bool need_copy = !isinstance<Array>(src);\n\n        EigenConformable<props::row_major> fits;\n        if (!need_copy) {\n            // We don't need a converting copy, but we also need to check whether the strides are\n            // compatible with the Ref's stride requirements\n            auto aref = reinterpret_borrow<Array>(src);\n\n            if (aref && (!need_writeable || aref.writeable())) {\n                fits = props::conformable(aref);\n                if (!fits) {\n                    return false; // Incompatible dimensions\n                }\n                if (!fits.template stride_compatible<props>()) {\n                    need_copy = true;\n                } else {\n                    copy_or_ref = std::move(aref);\n                }\n            } else {\n                need_copy = true;\n            }\n        }\n\n        if (need_copy) {\n            // We need to copy: If we need a mutable reference, or we're not supposed to convert\n            // (either because we're in the no-convert overload pass, or because we're explicitly\n            // instructed not to copy (via `py::arg().noconvert()`) we have to fail loading.\n            if (!convert || need_writeable) {\n                return false;\n            }\n\n            Array copy = Array::ensure(src);\n            if (!copy) {\n                return false;\n            }\n            fits = props::conformable(copy);\n            if (!fits || !fits.template stride_compatible<props>()) {\n                return false;\n            }\n            copy_or_ref = std::move(copy);\n            loader_life_support::add_patient(copy_or_ref);\n        }\n\n        ref.reset();\n        map.reset(new MapType(data(copy_or_ref),\n                              fits.rows,\n                              fits.cols,\n                              make_stride(fits.stride.outer(), fits.stride.inner())));\n        ref.reset(new Type(*map));\n\n        return true;\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type *() { return ref.get(); }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &() { return *ref; }\n    template <typename _T>\n    using cast_op_type = pybind11::detail::cast_op_type<_T>;\n\nprivate:\n    template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value, int> = 0>\n    Scalar *data(Array &a) {\n        return a.mutable_data();\n    }\n\n    template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value, int> = 0>\n    const Scalar *data(Array &a) {\n        return a.data();\n    }\n\n    // Attempt to figure out a constructor of `Stride` that will work.\n    // If both strides are fixed, use a default constructor:\n    template <typename S>\n    using stride_ctor_default = bool_constant<S::InnerStrideAtCompileTime != Eigen::Dynamic\n                                              && S::OuterStrideAtCompileTime != Eigen::Dynamic\n                                              && std::is_default_constructible<S>::value>;\n    // Otherwise, if there is a two-index constructor, assume it is (outer,inner) like\n    // Eigen::Stride, and use it:\n    template <typename S>\n    using stride_ctor_dual\n        = bool_constant<!stride_ctor_default<S>::value\n                        && std::is_constructible<S, EigenIndex, EigenIndex>::value>;\n    // Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use\n    // it (passing whichever stride is dynamic).\n    template <typename S>\n    using stride_ctor_outer\n        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value\n                        && S::OuterStrideAtCompileTime == Eigen::Dynamic\n                        && S::InnerStrideAtCompileTime != Eigen::Dynamic\n                        && std::is_constructible<S, EigenIndex>::value>;\n    template <typename S>\n    using stride_ctor_inner\n        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value\n                        && S::InnerStrideAtCompileTime == Eigen::Dynamic\n                        && S::OuterStrideAtCompileTime != Eigen::Dynamic\n                        && std::is_constructible<S, EigenIndex>::value>;\n\n    template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value, int> = 0>\n    static S make_stride(EigenIndex, EigenIndex) {\n        return S();\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value, int> = 0>\n    static S make_stride(EigenIndex outer, EigenIndex inner) {\n        return S(outer, inner);\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value, int> = 0>\n    static S make_stride(EigenIndex outer, EigenIndex) {\n        return S(outer);\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value, int> = 0>\n    static S make_stride(EigenIndex, EigenIndex inner) {\n        return S(inner);\n    }\n};\n\n// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not\n// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout).\n// load() is not supported, but we can cast them into the python domain by first copying to a\n// regular Eigen::Matrix, then casting that.\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_other<Type>::value>> {\nprotected:\n    using Matrix\n        = Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;\n    using props = EigenProps<Matrix>;\n\npublic:\n    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {\n        handle h = eigen_encapsulate<props>(new Matrix(src));\n        return h;\n    }\n    static handle cast(const Type *src, return_value_policy policy, handle parent) {\n        return cast(*src, policy, parent);\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return\n    // types but not bound arguments).  We still provide them (with an explicitly delete) so that\n    // you end up here if you try anyway.\n    bool load(handle, bool) = delete;\n    operator Type() = delete;\n    template <typename>\n    using cast_op_type = Type;\n};\n\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {\n    using Scalar = typename Type::Scalar;\n    using StorageIndex = remove_reference_t<decltype(*std::declval<Type>().outerIndexPtr())>;\n    using Index = typename Type::Index;\n    static constexpr bool rowMajor = Type::IsRowMajor;\n\n    bool load(handle src, bool) {\n        if (!src) {\n            return false;\n        }\n\n        auto obj = reinterpret_borrow<object>(src);\n        object sparse_module = module_::import(\"scipy.sparse\");\n        object matrix_type = sparse_module.attr(rowMajor ? \"csr_matrix\" : \"csc_matrix\");\n\n        if (!type::handle_of(obj).is(matrix_type)) {\n            try {\n                obj = matrix_type(obj);\n            } catch (const error_already_set &) {\n                return false;\n            }\n        }\n\n        auto values = array_t<Scalar>((object) obj.attr(\"data\"));\n        auto innerIndices = array_t<StorageIndex>((object) obj.attr(\"indices\"));\n        auto outerIndices = array_t<StorageIndex>((object) obj.attr(\"indptr\"));\n        auto shape = pybind11::tuple((pybind11::object) obj.attr(\"shape\"));\n        auto nnz = obj.attr(\"nnz\").cast<Index>();\n\n        if (!values || !innerIndices || !outerIndices) {\n            return false;\n        }\n\n        value = EigenMapSparseMatrix<Scalar,\n                                     Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),\n                                     StorageIndex>(shape[0].cast<Index>(),\n                                                   shape[1].cast<Index>(),\n                                                   std::move(nnz),\n                                                   outerIndices.mutable_data(),\n                                                   innerIndices.mutable_data(),\n                                                   values.mutable_data());\n\n        return true;\n    }\n\n    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {\n        const_cast<Type &>(src).makeCompressed();\n\n        object matrix_type\n            = module_::import(\"scipy.sparse\").attr(rowMajor ? \"csr_matrix\" : \"csc_matrix\");\n\n        array data(src.nonZeros(), src.valuePtr());\n        array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());\n        array innerIndices(src.nonZeros(), src.innerIndexPtr());\n\n        return matrix_type(pybind11::make_tuple(\n                               std::move(data), std::move(innerIndices), std::move(outerIndices)),\n                           pybind11::make_tuple(src.rows(), src.cols()))\n            .release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name<(Type::IsRowMajor) != 0>(\"scipy.sparse.csr_matrix[\",\n                                                             \"scipy.sparse.csc_matrix[\")\n                             + npy_format_descriptor<Scalar>::name + const_name(\"]\"));\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/eigen/tensor.h",
    "content": "/*\n    pybind11/eigen/tensor.h: Transparent conversion for Eigen tensors\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../numpy.h\"\n\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)\nstatic_assert(__GNUC__ > 5, \"Eigen Tensor support in pybind11 requires GCC > 5.0\");\n#endif\n\n#if defined(_MSC_VER)\n#    pragma warning(push)\n#    pragma warning(disable : 4554) // Tensor.h warning\n#    pragma warning(disable : 4127) // Tensor.h warning\n#elif defined(__MINGW32__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wmaybe-uninitialized\"\n#endif\n\n#include <unsupported/Eigen/CXX11/Tensor>\n\n#if defined(_MSC_VER)\n#    pragma warning(pop)\n#elif defined(__MINGW32__)\n#    pragma GCC diagnostic pop\n#endif\n\nstatic_assert(EIGEN_VERSION_AT_LEAST(3, 3, 0),\n              \"Eigen Tensor support in pybind11 requires Eigen >= 3.3.0\");\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline bool is_tensor_aligned(const void *data) {\n    return (reinterpret_cast<std::size_t>(data) % EIGEN_DEFAULT_ALIGN_BYTES) == 0;\n}\n\ntemplate <typename T>\nconstexpr int compute_array_flag_from_tensor() {\n    static_assert((static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor))\n                      || (static_cast<int>(T::Layout) == static_cast<int>(Eigen::ColMajor)),\n                  \"Layout must be row or column major\");\n    return (static_cast<int>(T::Layout) == static_cast<int>(Eigen::RowMajor)) ? array::c_style\n                                                                              : array::f_style;\n}\n\ntemplate <typename T>\nstruct eigen_tensor_helper {};\n\ntemplate <typename Scalar_, int NumIndices_, int Options_, typename IndexType>\nstruct eigen_tensor_helper<Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>> {\n    using Type = Eigen::Tensor<Scalar_, NumIndices_, Options_, IndexType>;\n    using ValidType = void;\n\n    static Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape(const Type &f) {\n        return f.dimensions();\n    }\n\n    static constexpr bool\n    is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> & /*shape*/) {\n        return true;\n    }\n\n    template <typename T>\n    struct helper {};\n\n    template <size_t... Is>\n    struct helper<index_sequence<Is...>> {\n        static constexpr auto value = concat(const_name(((void) Is, \"?\"))...);\n    };\n\n    static constexpr auto dimensions_descriptor\n        = helper<decltype(make_index_sequence<Type::NumIndices>())>::value;\n\n    template <typename... Args>\n    static Type *alloc(Args &&...args) {\n        return new Type(std::forward<Args>(args)...);\n    }\n\n    static void free(Type *tensor) { delete tensor; }\n};\n\ntemplate <typename Scalar_, typename std::ptrdiff_t... Indices, int Options_, typename IndexType>\nstruct eigen_tensor_helper<\n    Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>> {\n    using Type = Eigen::TensorFixedSize<Scalar_, Eigen::Sizes<Indices...>, Options_, IndexType>;\n    using ValidType = void;\n\n    static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices>\n    get_shape(const Type & /*f*/) {\n        return get_shape();\n    }\n\n    static constexpr Eigen::DSizes<typename Type::Index, Type::NumIndices> get_shape() {\n        return Eigen::DSizes<typename Type::Index, Type::NumIndices>(Indices...);\n    }\n\n    static bool\n    is_correct_shape(const Eigen::DSizes<typename Type::Index, Type::NumIndices> &shape) {\n        return get_shape() == shape;\n    }\n\n    static constexpr auto dimensions_descriptor = concat(const_name<Indices>()...);\n\n    template <typename... Args>\n    static Type *alloc(Args &&...args) {\n        Eigen::aligned_allocator<Type> allocator;\n        return ::new (allocator.allocate(1)) Type(std::forward<Args>(args)...);\n    }\n\n    static void free(Type *tensor) {\n        Eigen::aligned_allocator<Type> allocator;\n        tensor->~Type();\n        allocator.deallocate(tensor, 1);\n    }\n};\n\ntemplate <typename Type, bool ShowDetails, bool NeedsWriteable = false>\nstruct get_tensor_descriptor {\n    static constexpr auto details\n        = const_name<NeedsWriteable>(\", flags.writeable\", \"\")\n          + const_name<static_cast<int>(Type::Layout) == static_cast<int>(Eigen::RowMajor)>(\n              \", flags.c_contiguous\", \", flags.f_contiguous\");\n    static constexpr auto value\n        = const_name(\"numpy.ndarray[\") + npy_format_descriptor<typename Type::Scalar>::name\n          + const_name(\"[\") + eigen_tensor_helper<remove_cv_t<Type>>::dimensions_descriptor\n          + const_name(\"]\") + const_name<ShowDetails>(details, const_name(\"\")) + const_name(\"]\");\n};\n\n// When EIGEN_AVOID_STL_ARRAY is defined, Eigen::DSizes<T, 0> does not have the begin() member\n// function. Falling back to a simple loop works around this issue.\n//\n// We need to disable the type-limits warning for the inner loop when size = 0.\n\n#if defined(__GNUC__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wtype-limits\"\n#endif\n\ntemplate <typename T, int size>\nstd::vector<T> convert_dsizes_to_vector(const Eigen::DSizes<T, size> &arr) {\n    std::vector<T> result(size);\n\n    for (size_t i = 0; i < size; i++) {\n        result[i] = arr[i];\n    }\n\n    return result;\n}\n\ntemplate <typename T, int size>\nEigen::DSizes<T, size> get_shape_for_array(const array &arr) {\n    Eigen::DSizes<T, size> result;\n    const T *shape = arr.shape();\n    for (size_t i = 0; i < size; i++) {\n        result[i] = shape[i];\n    }\n\n    return result;\n}\n\n#if defined(__GNUC__)\n#    pragma GCC diagnostic pop\n#endif\n\ntemplate <typename Type>\nstruct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> {\n    using Helper = eigen_tensor_helper<Type>;\n    static constexpr auto temp_name = get_tensor_descriptor<Type, false>::value;\n    PYBIND11_TYPE_CASTER(Type, temp_name);\n\n    bool load(handle src, bool convert) {\n        if (!convert) {\n            if (!isinstance<array>(src)) {\n                return false;\n            }\n            array temp = array::ensure(src);\n            if (!temp) {\n                return false;\n            }\n\n            if (!convert && !temp.dtype().is(dtype::of<typename Type::Scalar>())) {\n                return false;\n            }\n        }\n\n        array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()> arr(\n            reinterpret_borrow<object>(src));\n\n        if (arr.ndim() != Type::NumIndices) {\n            return false;\n        }\n        auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);\n\n        if (!Helper::is_correct_shape(shape)) {\n            return false;\n        }\n\n#if EIGEN_VERSION_AT_LEAST(3, 4, 0)\n        auto data_pointer = arr.data();\n#else\n        // Handle Eigen bug\n        auto data_pointer = const_cast<typename Type::Scalar *>(arr.data());\n#endif\n\n        if (is_tensor_aligned(arr.data())) {\n            value = Eigen::TensorMap<const Type, Eigen::Aligned>(data_pointer, shape);\n        } else {\n            value = Eigen::TensorMap<const Type>(data_pointer, shape);\n        }\n\n        return true;\n    }\n\n    static handle cast(Type &&src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::reference\n            || policy == return_value_policy::reference_internal) {\n            pybind11_fail(\"Cannot use a reference return value policy for an rvalue\");\n        }\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n\n    static handle cast(const Type &&src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::reference\n            || policy == return_value_policy::reference_internal) {\n            pybind11_fail(\"Cannot use a reference return value policy for an rvalue\");\n        }\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n\n    static handle cast(Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast_impl(&src, policy, parent);\n    }\n\n    static handle cast(const Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n\n    static handle cast(Type *src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic) {\n            policy = return_value_policy::take_ownership;\n        } else if (policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::reference;\n        }\n        return cast_impl(src, policy, parent);\n    }\n\n    static handle cast(const Type *src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic) {\n            policy = return_value_policy::take_ownership;\n        } else if (policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::reference;\n        }\n        return cast_impl(src, policy, parent);\n    }\n\n    template <typename C>\n    static handle cast_impl(C *src, return_value_policy policy, handle parent) {\n        object parent_object;\n        bool writeable = false;\n        switch (policy) {\n            case return_value_policy::move:\n                if (std::is_const<C>::value) {\n                    pybind11_fail(\"Cannot move from a constant reference\");\n                }\n\n                src = Helper::alloc(std::move(*src));\n\n                parent_object\n                    = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });\n                writeable = true;\n                break;\n\n            case return_value_policy::take_ownership:\n                if (std::is_const<C>::value) {\n                    // This cast is ugly, and might be UB in some cases, but we don't have an\n                    // alterantive here as we must free that memory\n                    Helper::free(const_cast<Type *>(src));\n                    pybind11_fail(\"Cannot take ownership of a const reference\");\n                }\n\n                parent_object\n                    = capsule(src, [](void *ptr) { Helper::free(reinterpret_cast<Type *>(ptr)); });\n                writeable = true;\n                break;\n\n            case return_value_policy::copy:\n                writeable = true;\n                break;\n\n            case return_value_policy::reference:\n                parent_object = none();\n                writeable = !std::is_const<C>::value;\n                break;\n\n            case return_value_policy::reference_internal:\n                // Default should do the right thing\n                if (!parent) {\n                    pybind11_fail(\"Cannot use reference internal when there is no parent\");\n                }\n                parent_object = reinterpret_borrow<object>(parent);\n                writeable = !std::is_const<C>::value;\n                break;\n\n            default:\n                pybind11_fail(\"pybind11 bug in eigen.h, please file a bug report\");\n        }\n\n        auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(\n            convert_dsizes_to_vector(Helper::get_shape(*src)), src->data(), parent_object);\n\n        if (!writeable) {\n            array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;\n        }\n\n        return result.release();\n    }\n};\n\ntemplate <typename StoragePointerType,\n          bool needs_writeable,\n          enable_if_t<!needs_writeable, bool> = true>\nStoragePointerType get_array_data_for_type(array &arr) {\n#if EIGEN_VERSION_AT_LEAST(3, 4, 0)\n    return reinterpret_cast<StoragePointerType>(arr.data());\n#else\n    // Handle Eigen bug\n    return reinterpret_cast<StoragePointerType>(const_cast<void *>(arr.data()));\n#endif\n}\n\ntemplate <typename StoragePointerType,\n          bool needs_writeable,\n          enable_if_t<needs_writeable, bool> = true>\nStoragePointerType get_array_data_for_type(array &arr) {\n    return reinterpret_cast<StoragePointerType>(arr.mutable_data());\n}\n\ntemplate <typename T, typename = void>\nstruct get_storage_pointer_type;\n\ntemplate <typename MapType>\nstruct get_storage_pointer_type<MapType, void_t<typename MapType::StoragePointerType>> {\n    using SPT = typename MapType::StoragePointerType;\n};\n\ntemplate <typename MapType>\nstruct get_storage_pointer_type<MapType, void_t<typename MapType::PointerArgType>> {\n    using SPT = typename MapType::PointerArgType;\n};\n\ntemplate <typename Type, int Options>\nstruct type_caster<Eigen::TensorMap<Type, Options>,\n                   typename eigen_tensor_helper<remove_cv_t<Type>>::ValidType> {\n    using MapType = Eigen::TensorMap<Type, Options>;\n    using Helper = eigen_tensor_helper<remove_cv_t<Type>>;\n\n    bool load(handle src, bool /*convert*/) {\n        // Note that we have a lot more checks here as we want to make sure to avoid copies\n        if (!isinstance<array>(src)) {\n            return false;\n        }\n        auto arr = reinterpret_borrow<array>(src);\n        if ((arr.flags() & compute_array_flag_from_tensor<Type>()) == 0) {\n            return false;\n        }\n\n        if (!arr.dtype().is(dtype::of<typename Type::Scalar>())) {\n            return false;\n        }\n\n        if (arr.ndim() != Type::NumIndices) {\n            return false;\n        }\n\n        constexpr bool is_aligned = (Options & Eigen::Aligned) != 0;\n\n        if (PYBIND11_SILENCE_MSVC_C4127(is_aligned) && !is_tensor_aligned(arr.data())) {\n            return false;\n        }\n\n        auto shape = get_shape_for_array<typename Type::Index, Type::NumIndices>(arr);\n\n        if (!Helper::is_correct_shape(shape)) {\n            return false;\n        }\n\n        if (PYBIND11_SILENCE_MSVC_C4127(needs_writeable) && !arr.writeable()) {\n            return false;\n        }\n\n        auto result = get_array_data_for_type<typename get_storage_pointer_type<MapType>::SPT,\n                                              needs_writeable>(arr);\n\n        value.reset(new MapType(std::move(result), std::move(shape)));\n\n        return true;\n    }\n\n    static handle cast(MapType &&src, return_value_policy policy, handle parent) {\n        return cast_impl(&src, policy, parent);\n    }\n\n    static handle cast(const MapType &&src, return_value_policy policy, handle parent) {\n        return cast_impl(&src, policy, parent);\n    }\n\n    static handle cast(MapType &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast_impl(&src, policy, parent);\n    }\n\n    static handle cast(const MapType &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n\n    static handle cast(MapType *src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic) {\n            policy = return_value_policy::take_ownership;\n        } else if (policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::reference;\n        }\n        return cast_impl(src, policy, parent);\n    }\n\n    static handle cast(const MapType *src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic) {\n            policy = return_value_policy::take_ownership;\n        } else if (policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::reference;\n        }\n        return cast_impl(src, policy, parent);\n    }\n\n    template <typename C>\n    static handle cast_impl(C *src, return_value_policy policy, handle parent) {\n        object parent_object;\n        constexpr bool writeable = !std::is_const<C>::value;\n        switch (policy) {\n            case return_value_policy::reference:\n                parent_object = none();\n                break;\n\n            case return_value_policy::reference_internal:\n                // Default should do the right thing\n                if (!parent) {\n                    pybind11_fail(\"Cannot use reference internal when there is no parent\");\n                }\n                parent_object = reinterpret_borrow<object>(parent);\n                break;\n\n            case return_value_policy::take_ownership:\n                delete src;\n                // fallthrough\n            default:\n                // move, take_ownership don't make any sense for a ref/map:\n                pybind11_fail(\"Invalid return_value_policy for Eigen Map type, must be either \"\n                              \"reference or reference_internal\");\n        }\n\n        auto result = array_t<typename Type::Scalar, compute_array_flag_from_tensor<Type>()>(\n            convert_dsizes_to_vector(Helper::get_shape(*src)),\n            src->data(),\n            std::move(parent_object));\n\n        if (!writeable) {\n            array_proxy(result.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;\n        }\n\n        return result.release();\n    }\n\n#if EIGEN_VERSION_AT_LEAST(3, 4, 0)\n\n    static constexpr bool needs_writeable = !std::is_const<typename std::remove_pointer<\n        typename get_storage_pointer_type<MapType>::SPT>::type>::value;\n#else\n    // Handle Eigen bug\n    static constexpr bool needs_writeable = !std::is_const<Type>::value;\n#endif\n\nprotected:\n    // TODO: Move to std::optional once std::optional has more support\n    std::unique_ptr<MapType> value;\n\npublic:\n    static constexpr auto name = get_tensor_descriptor<Type, true, needs_writeable>::value;\n    explicit operator MapType *() { return value.get(); }\n    explicit operator MapType &() { return *value; }\n    explicit operator MapType &&() && { return std::move(*value); }\n\n    template <typename T_>\n    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>;\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/eigen.h",
    "content": "/*\n    pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"eigen/matrix.h\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/embed.h",
    "content": "/*\n    pybind11/embed.h: Support for embedding the interpreter\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"eval.h\"\n\n#include <memory>\n#include <vector>\n\n#if defined(PYPY_VERSION)\n#    error Embedding the interpreter is not supported with PyPy\n#endif\n\n#define PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                       \\\n    extern \"C\" PyObject *pybind11_init_impl_##name();                                             \\\n    extern \"C\" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }\n\n/** \\rst\n    Add a new module to the table of builtins for the interpreter. Must be\n    defined in global scope. The first macro parameter is the name of the\n    module (without quotes). The second parameter is the variable which will\n    be used as the interface to add functions and classes to the module.\n\n    .. code-block:: cpp\n\n        PYBIND11_EMBEDDED_MODULE(example, m) {\n            // ... initialize functions and classes here\n            m.def(\"foo\", []() {\n                return \"Hello, World!\";\n            });\n        }\n \\endrst */\n#define PYBIND11_EMBEDDED_MODULE(name, variable)                                                  \\\n    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name);           \\\n    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \\\n    static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() {                            \\\n        auto m = ::pybind11::module_::create_extension_module(                                    \\\n            PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name));      \\\n        try {                                                                                     \\\n            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \\\n            return m.ptr();                                                                       \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                           \\\n    ::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)(                  \\\n        PYBIND11_TOSTRING(name), PYBIND11_CONCAT(pybind11_init_impl_, name));                     \\\n    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_                                \\\n                                               & variable) // NOLINT(bugprone-macro-parentheses)\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks.\nstruct embedded_module {\n    using init_t = PyObject *(*) ();\n    embedded_module(const char *name, init_t init) {\n        if (Py_IsInitialized() != 0) {\n            pybind11_fail(\"Can't add new modules after the interpreter has been initialized\");\n        }\n\n        auto result = PyImport_AppendInittab(name, init);\n        if (result == -1) {\n            pybind11_fail(\"Insufficient memory to add a new module\");\n        }\n    }\n};\n\nstruct wide_char_arg_deleter {\n    void operator()(wchar_t *ptr) const {\n        // API docs: https://docs.python.org/3/c-api/sys.html#c.Py_DecodeLocale\n        PyMem_RawFree(ptr);\n    }\n};\n\ninline wchar_t *widen_chars(const char *safe_arg) {\n    wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);\n    return widened_arg;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    Initialize the Python interpreter. No other pybind11 or CPython API functions can be\n    called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The\n    optional `init_signal_handlers` parameter can be used to skip the registration of\n    signal handlers (see the `Python documentation`_ for details). Calling this function\n    again after the interpreter has already been initialized is a fatal error.\n\n    If initializing the Python interpreter fails, then the program is terminated.  (This\n    is controlled by the CPython runtime and is an exception to pybind11's normal behavior\n    of throwing exceptions on errors.)\n\n    The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are\n    used to populate ``sys.argv`` and ``sys.path``.\n    See the |PySys_SetArgvEx documentation|_ for details.\n\n    .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx\n    .. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation\n    .. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx\n \\endrst */\ninline void initialize_interpreter(bool init_signal_handlers = true,\n                                   int argc = 0,\n                                   const char *const *argv = nullptr,\n                                   bool add_program_dir_to_path = true) {\n    if (Py_IsInitialized() != 0) {\n        pybind11_fail(\"The interpreter is already running\");\n    }\n\n#if PY_VERSION_HEX < 0x030B0000\n\n    Py_InitializeEx(init_signal_handlers ? 1 : 0);\n#    if defined(WITH_THREAD) && PY_VERSION_HEX < 0x03070000\n    PyEval_InitThreads();\n#    endif\n\n    // Before it was special-cased in python 3.8, passing an empty or null argv\n    // caused a segfault, so we have to reimplement the special case ourselves.\n    bool special_case = (argv == nullptr || argc <= 0);\n\n    const char *const empty_argv[]{\"\\0\"};\n    const char *const *safe_argv = special_case ? empty_argv : argv;\n    if (special_case) {\n        argc = 1;\n    }\n\n    auto argv_size = static_cast<size_t>(argc);\n    // SetArgv* on python 3 takes wchar_t, so we have to convert.\n    std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);\n    std::vector<std::unique_ptr<wchar_t[], detail::wide_char_arg_deleter>> widened_argv_entries;\n    widened_argv_entries.reserve(argv_size);\n    for (size_t ii = 0; ii < argv_size; ++ii) {\n        widened_argv_entries.emplace_back(detail::widen_chars(safe_argv[ii]));\n        if (!widened_argv_entries.back()) {\n            // A null here indicates a character-encoding failure or the python\n            // interpreter out of memory. Give up.\n            return;\n        }\n        widened_argv[ii] = widened_argv_entries.back().get();\n    }\n\n    auto *pysys_argv = widened_argv.get();\n\n    PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));\n#else\n    PyConfig config;\n    PyConfig_InitIsolatedConfig(&config);\n    config.isolated = 0;\n    config.use_environment = 1;\n    config.install_signal_handlers = init_signal_handlers ? 1 : 0;\n\n    PyStatus status = PyConfig_SetBytesArgv(&config, argc, const_cast<char *const *>(argv));\n    if (PyStatus_Exception(status)) {\n        // A failure here indicates a character-encoding failure or the python\n        // interpreter out of memory. Give up.\n        PyConfig_Clear(&config);\n        throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg\n                                                          : \"Failed to prepare CPython\");\n    }\n    status = Py_InitializeFromConfig(&config);\n    PyConfig_Clear(&config);\n    if (PyStatus_Exception(status)) {\n        throw std::runtime_error(PyStatus_IsError(status) ? status.err_msg\n                                                          : \"Failed to init CPython\");\n    }\n    if (add_program_dir_to_path) {\n        PyRun_SimpleString(\"import sys, os.path; \"\n                           \"sys.path.insert(0, \"\n                           \"os.path.abspath(os.path.dirname(sys.argv[0])) \"\n                           \"if sys.argv and os.path.exists(sys.argv[0]) else '')\");\n    }\n#endif\n}\n\n/** \\rst\n    Shut down the Python interpreter. No pybind11 or CPython API functions can be called\n    after this. In addition, pybind11 objects must not outlive the interpreter:\n\n    .. code-block:: cpp\n\n        { // BAD\n            py::initialize_interpreter();\n            auto hello = py::str(\"Hello, World!\");\n            py::finalize_interpreter();\n        } // <-- BOOM, hello's destructor is called after interpreter shutdown\n\n        { // GOOD\n            py::initialize_interpreter();\n            { // scoped\n                auto hello = py::str(\"Hello, World!\");\n            } // <-- OK, hello is cleaned up properly\n            py::finalize_interpreter();\n        }\n\n        { // BETTER\n            py::scoped_interpreter guard{};\n            auto hello = py::str(\"Hello, World!\");\n        }\n\n    .. warning::\n\n        The interpreter can be restarted by calling `initialize_interpreter` again.\n        Modules created using pybind11 can be safely re-initialized. However, Python\n        itself cannot completely unload binary extension modules and there are several\n        caveats with regard to interpreter restarting. All the details can be found\n        in the CPython documentation. In short, not all interpreter memory may be\n        freed, either due to reference cycles or user-created global data.\n\n \\endrst */\ninline void finalize_interpreter() {\n    handle builtins(PyEval_GetBuiltins());\n    const char *id = PYBIND11_INTERNALS_ID;\n\n    // Get the internals pointer (without creating it if it doesn't exist).  It's possible for the\n    // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()`\n    // during destruction), so we get the pointer-pointer here and check it after Py_Finalize().\n    detail::internals **internals_ptr_ptr = detail::get_internals_pp();\n    // It could also be stashed in builtins, so look there too:\n    if (builtins.contains(id) && isinstance<capsule>(builtins[id])) {\n        internals_ptr_ptr = capsule(builtins[id]);\n    }\n    // Local internals contains data managed by the current interpreter, so we must clear them to\n    // avoid undefined behaviors when initializing another interpreter\n    detail::get_local_internals().registered_types_cpp.clear();\n    detail::get_local_internals().registered_exception_translators.clear();\n\n    Py_Finalize();\n\n    if (internals_ptr_ptr) {\n        delete *internals_ptr_ptr;\n        *internals_ptr_ptr = nullptr;\n    }\n}\n\n/** \\rst\n    Scope guard version of `initialize_interpreter` and `finalize_interpreter`.\n    This a move-only guard and only a single instance can exist.\n\n    See `initialize_interpreter` for a discussion of its constructor arguments.\n\n    .. code-block:: cpp\n\n        #include <pybind11/embed.h>\n\n        int main() {\n            py::scoped_interpreter guard{};\n            py::print(Hello, World!);\n        } // <-- interpreter shutdown\n \\endrst */\nclass scoped_interpreter {\npublic:\n    explicit scoped_interpreter(bool init_signal_handlers = true,\n                                int argc = 0,\n                                const char *const *argv = nullptr,\n                                bool add_program_dir_to_path = true) {\n        initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);\n    }\n\n    scoped_interpreter(const scoped_interpreter &) = delete;\n    scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }\n    scoped_interpreter &operator=(const scoped_interpreter &) = delete;\n    scoped_interpreter &operator=(scoped_interpreter &&) = delete;\n\n    ~scoped_interpreter() {\n        if (is_valid) {\n            finalize_interpreter();\n        }\n    }\n\nprivate:\n    bool is_valid = true;\n};\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/eval.h",
    "content": "/*\n    pybind11/eval.h: Support for evaluating Python expressions and statements\n    from strings and files\n\n    Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <utility>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline void ensure_builtins_in_globals(object &global) {\n#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000\n    // Running exec and eval adds `builtins` module under `__builtins__` key to\n    // globals if not yet present.  Python 3.8 made PyRun_String behave\n    // similarly. Let's also do that for older versions, for consistency. This\n    // was missing from PyPy3.8 7.3.7.\n    if (!global.contains(\"__builtins__\"))\n        global[\"__builtins__\"] = module_::import(PYBIND11_BUILTINS_MODULE);\n#else\n    (void) global;\n#endif\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\nenum eval_mode {\n    /// Evaluate a string containing an isolated expression\n    eval_expr,\n\n    /// Evaluate a string containing a single statement. Returns \\c none\n    eval_single_statement,\n\n    /// Evaluate a string containing a sequence of statement. Returns \\c none\n    eval_statements\n};\n\ntemplate <eval_mode mode = eval_expr>\nobject eval(const str &expr, object global = globals(), object local = object()) {\n    if (!local) {\n        local = global;\n    }\n\n    detail::ensure_builtins_in_globals(global);\n\n    /* PyRun_String does not accept a PyObject / encoding specifier,\n       this seems to be the only alternative */\n    std::string buffer = \"# -*- coding: utf-8 -*-\\n\" + (std::string) expr;\n\n    int start = 0;\n    switch (mode) {\n        case eval_expr:\n            start = Py_eval_input;\n            break;\n        case eval_single_statement:\n            start = Py_single_input;\n            break;\n        case eval_statements:\n            start = Py_file_input;\n            break;\n        default:\n            pybind11_fail(\"invalid evaluation mode\");\n    }\n\n    PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ntemplate <eval_mode mode = eval_expr, size_t N>\nobject eval(const char (&s)[N], object global = globals(), object local = object()) {\n    /* Support raw string literals by removing common leading whitespace */\n    auto expr = (s[0] == '\\n') ? str(module_::import(\"textwrap\").attr(\"dedent\")(s)) : str(s);\n    return eval<mode>(expr, std::move(global), std::move(local));\n}\n\ninline void exec(const str &expr, object global = globals(), object local = object()) {\n    eval<eval_statements>(expr, std::move(global), std::move(local));\n}\n\ntemplate <size_t N>\nvoid exec(const char (&s)[N], object global = globals(), object local = object()) {\n    eval<eval_statements>(s, std::move(global), std::move(local));\n}\n\n#if defined(PYPY_VERSION)\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str, object, object) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str, object) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\n#else\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str fname, object global = globals(), object local = object()) {\n    if (!local) {\n        local = global;\n    }\n\n    detail::ensure_builtins_in_globals(global);\n\n    int start = 0;\n    switch (mode) {\n        case eval_expr:\n            start = Py_eval_input;\n            break;\n        case eval_single_statement:\n            start = Py_single_input;\n            break;\n        case eval_statements:\n            start = Py_file_input;\n            break;\n        default:\n            pybind11_fail(\"invalid evaluation mode\");\n    }\n\n    int closeFile = 1;\n    std::string fname_str = (std::string) fname;\n    FILE *f = _Py_fopen_obj(fname.ptr(), \"r\");\n    if (!f) {\n        PyErr_Clear();\n        pybind11_fail(\"File \\\"\" + fname_str + \"\\\" could not be opened!\");\n    }\n\n    if (!global.contains(\"__file__\")) {\n        global[\"__file__\"] = std::move(fname);\n    }\n\n    PyObject *result\n        = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);\n\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n#endif\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/functional.h",
    "content": "/*\n    pybind11/functional.h: std::function<> support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <functional>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename Return, typename... Args>\nstruct type_caster<std::function<Return(Args...)>> {\n    using type = std::function<Return(Args...)>;\n    using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;\n    using function_type = Return (*)(Args...);\n\npublic:\n    bool load(handle src, bool convert) {\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            return true;\n        }\n\n        if (!isinstance<function>(src)) {\n            return false;\n        }\n\n        auto func = reinterpret_borrow<function>(src);\n\n        /*\n           When passing a C++ function as an argument to another C++\n           function via Python, every function call would normally involve\n           a full C++ -> Python -> C++ roundtrip, which can be prohibitive.\n           Here, we try to at least detect the case where the function is\n           stateless (i.e. function pointer or lambda function without\n           captured variables), in which case the roundtrip can be avoided.\n         */\n        if (auto cfunc = func.cpp_function()) {\n            auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());\n            if (cfunc_self == nullptr) {\n                PyErr_Clear();\n            } else if (isinstance<capsule>(cfunc_self)) {\n                auto c = reinterpret_borrow<capsule>(cfunc_self);\n\n                function_record *rec = nullptr;\n                // Check that we can safely reinterpret the capsule into a function_record\n                if (detail::is_function_record_capsule(c)) {\n                    rec = c.get_pointer<function_record>();\n                }\n\n                while (rec != nullptr) {\n                    if (rec->is_stateless\n                        && same_type(typeid(function_type),\n                                     *reinterpret_cast<const std::type_info *>(rec->data[1]))) {\n                        struct capture {\n                            function_type f;\n                        };\n                        value = ((capture *) &rec->data)->f;\n                        return true;\n                    }\n                    rec = rec->next;\n                }\n            }\n            // PYPY segfaults here when passing builtin function like sum.\n            // Raising an fail exception here works to prevent the segfault, but only on gcc.\n            // See PR #1413 for full details\n        }\n\n        // ensure GIL is held during functor destruction\n        struct func_handle {\n            function f;\n#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))\n            // This triggers a syntax error under very special conditions (very weird indeed).\n            explicit\n#endif\n                func_handle(function &&f_) noexcept\n                : f(std::move(f_)) {\n            }\n            func_handle(const func_handle &f_) { operator=(f_); }\n            func_handle &operator=(const func_handle &f_) {\n                gil_scoped_acquire acq;\n                f = f_.f;\n                return *this;\n            }\n            ~func_handle() {\n                gil_scoped_acquire acq;\n                function kill_f(std::move(f));\n            }\n        };\n\n        // to emulate 'move initialization capture' in C++11\n        struct func_wrapper {\n            func_handle hfunc;\n            explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}\n            Return operator()(Args... args) const {\n                gil_scoped_acquire acq;\n                // casts the returned object as a rvalue to the return type\n                return hfunc.f(std::forward<Args>(args)...).template cast<Return>();\n            }\n        };\n\n        value = func_wrapper(func_handle(std::move(func)));\n        return true;\n    }\n\n    template <typename Func>\n    static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {\n        if (!f_) {\n            return none().release();\n        }\n\n        auto result = f_.template target<function_type>();\n        if (result) {\n            return cpp_function(*result, policy).release();\n        }\n        return cpp_function(std::forward<Func>(f_), policy).release();\n    }\n\n    PYBIND11_TYPE_CASTER(type,\n                         const_name(\"Callable[[\") + concat(make_caster<Args>::name...)\n                             + const_name(\"], \") + make_caster<retval_type>::name\n                             + const_name(\"]\"));\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/gil.h",
    "content": "/*\n    pybind11/gil.h: RAII helpers for managing the GIL\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n\n#if defined(WITH_THREAD) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n#    include \"detail/internals.h\"\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// forward declarations\nPyThreadState *get_thread_state_unchecked();\n\nPYBIND11_NAMESPACE_END(detail)\n\n#if defined(WITH_THREAD)\n\n#    if !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n\n/* The functions below essentially reproduce the PyGILState_* API using a RAII\n * pattern, but there are a few important differences:\n *\n * 1. When acquiring the GIL from an non-main thread during the finalization\n *    phase, the GILState API blindly terminates the calling thread, which\n *    is often not what is wanted. This API does not do this.\n *\n * 2. The gil_scoped_release function can optionally cut the relationship\n *    of a PyThreadState and its associated thread, which allows moving it to\n *    another thread (this is a fairly rare/advanced use case).\n *\n * 3. The reference count of an acquired thread state can be controlled. This\n *    can be handy to prevent cases where callbacks issued from an external\n *    thread would otherwise constantly construct and destroy thread state data\n *    structures.\n *\n * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an\n * example which uses features 2 and 3 to migrate the Python thread of\n * execution to another thread (to run the event loop on the original thread,\n * in this case).\n */\n\nclass gil_scoped_acquire {\npublic:\n    PYBIND11_NOINLINE gil_scoped_acquire() {\n        auto &internals = detail::get_internals();\n        tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate);\n\n        if (!tstate) {\n            /* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if\n               calling from a Python thread). Since we use a different key, this ensures\n               we don't create a new thread state and deadlock in PyEval_AcquireThread\n               below. Note we don't save this state with internals.tstate, since we don't\n               create it we would fail to clear it (its reference count should be > 0). */\n            tstate = PyGILState_GetThisThreadState();\n        }\n\n        if (!tstate) {\n            tstate = PyThreadState_New(internals.istate);\n#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            if (!tstate) {\n                pybind11_fail(\"scoped_acquire: could not create thread state!\");\n            }\n#        endif\n            tstate->gilstate_counter = 0;\n            PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate);\n        } else {\n            release = detail::get_thread_state_unchecked() != tstate;\n        }\n\n        if (release) {\n            PyEval_AcquireThread(tstate);\n        }\n\n        inc_ref();\n    }\n\n    gil_scoped_acquire(const gil_scoped_acquire &) = delete;\n    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;\n\n    void inc_ref() { ++tstate->gilstate_counter; }\n\n    PYBIND11_NOINLINE void dec_ref() {\n        --tstate->gilstate_counter;\n#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n        if (detail::get_thread_state_unchecked() != tstate) {\n            pybind11_fail(\"scoped_acquire::dec_ref(): thread state must be current!\");\n        }\n        if (tstate->gilstate_counter < 0) {\n            pybind11_fail(\"scoped_acquire::dec_ref(): reference count underflow!\");\n        }\n#        endif\n        if (tstate->gilstate_counter == 0) {\n#        if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n            if (!release) {\n                pybind11_fail(\"scoped_acquire::dec_ref(): internal error!\");\n            }\n#        endif\n            PyThreadState_Clear(tstate);\n            if (active) {\n                PyThreadState_DeleteCurrent();\n            }\n            PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate);\n            release = false;\n        }\n    }\n\n    /// This method will disable the PyThreadState_DeleteCurrent call and the\n    /// GIL won't be acquired. This method should be used if the interpreter\n    /// could be shutting down when this is called, as thread deletion is not\n    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and\n    /// protect subsequent code.\n    PYBIND11_NOINLINE void disarm() { active = false; }\n\n    PYBIND11_NOINLINE ~gil_scoped_acquire() {\n        dec_ref();\n        if (release) {\n            PyEval_SaveThread();\n        }\n    }\n\nprivate:\n    PyThreadState *tstate = nullptr;\n    bool release = true;\n    bool active = true;\n};\n\nclass gil_scoped_release {\npublic:\n    explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {\n        // `get_internals()` must be called here unconditionally in order to initialize\n        // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an\n        // initialization race could occur as multiple threads try `gil_scoped_acquire`.\n        auto &internals = detail::get_internals();\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        tstate = PyEval_SaveThread();\n        if (disassoc) {\n            // Python >= 3.7 can remove this, it's an int before 3.7\n            // NOLINTNEXTLINE(readability-qualified-auto)\n            auto key = internals.tstate;\n            PYBIND11_TLS_DELETE_VALUE(key);\n        }\n    }\n\n    gil_scoped_release(const gil_scoped_acquire &) = delete;\n    gil_scoped_release &operator=(const gil_scoped_acquire &) = delete;\n\n    /// This method will disable the PyThreadState_DeleteCurrent call and the\n    /// GIL won't be acquired. This method should be used if the interpreter\n    /// could be shutting down when this is called, as thread deletion is not\n    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and\n    /// protect subsequent code.\n    PYBIND11_NOINLINE void disarm() { active = false; }\n\n    ~gil_scoped_release() {\n        if (!tstate) {\n            return;\n        }\n        // `PyEval_RestoreThread()` should not be called if runtime is finalizing\n        if (active) {\n            PyEval_RestoreThread(tstate);\n        }\n        if (disassoc) {\n            // Python >= 3.7 can remove this, it's an int before 3.7\n            // NOLINTNEXTLINE(readability-qualified-auto)\n            auto key = detail::get_internals().tstate;\n            PYBIND11_TLS_REPLACE_VALUE(key, tstate);\n        }\n    }\n\nprivate:\n    PyThreadState *tstate;\n    bool disassoc;\n    bool active = true;\n};\n\n#    else // PYBIND11_SIMPLE_GIL_MANAGEMENT\n\nclass gil_scoped_acquire {\n    PyGILState_STATE state;\n\npublic:\n    gil_scoped_acquire() : state{PyGILState_Ensure()} {}\n    gil_scoped_acquire(const gil_scoped_acquire &) = delete;\n    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;\n    ~gil_scoped_acquire() { PyGILState_Release(state); }\n    void disarm() {}\n};\n\nclass gil_scoped_release {\n    PyThreadState *state;\n\npublic:\n    gil_scoped_release() : state{PyEval_SaveThread()} {}\n    gil_scoped_release(const gil_scoped_release &) = delete;\n    gil_scoped_release &operator=(const gil_scoped_acquire &) = delete;\n    ~gil_scoped_release() { PyEval_RestoreThread(state); }\n    void disarm() {}\n};\n\n#    endif // PYBIND11_SIMPLE_GIL_MANAGEMENT\n\n#else // WITH_THREAD\n\nclass gil_scoped_acquire {\npublic:\n    gil_scoped_acquire() {\n        // Trick to suppress `unused variable` error messages (at call sites).\n        (void) (this != (this + 1));\n    }\n    gil_scoped_acquire(const gil_scoped_acquire &) = delete;\n    gil_scoped_acquire &operator=(const gil_scoped_acquire &) = delete;\n    void disarm() {}\n};\n\nclass gil_scoped_release {\npublic:\n    gil_scoped_release() {\n        // Trick to suppress `unused variable` error messages (at call sites).\n        (void) (this != (this + 1));\n    }\n    gil_scoped_release(const gil_scoped_release &) = delete;\n    gil_scoped_release &operator=(const gil_scoped_acquire &) = delete;\n    void disarm() {}\n};\n\n#endif // WITH_THREAD\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/iostream.h",
    "content": "/*\n    pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python\n\n    Copyright (c) 2017 Henry F. Schreiner\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n\n    WARNING: The implementation in this file is NOT thread safe. Multiple\n    threads writing to a redirected ostream concurrently cause data races\n    and potentially buffer overflows. Therefore it is currently a requirement\n    that all (possibly) concurrent redirected ostream writes are protected by\n    a mutex.\n    #HelpAppreciated: Work on iostream.h thread safety.\n    For more background see the discussions under\n    https://github.com/pybind/pybind11/pull/2982 and\n    https://github.com/pybind/pybind11/pull/2995.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <iostream>\n#include <iterator>\n#include <memory>\n#include <ostream>\n#include <streambuf>\n#include <string>\n#include <utility>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Buffer that writes to Python instead of C++\nclass pythonbuf : public std::streambuf {\nprivate:\n    using traits_type = std::streambuf::traits_type;\n\n    const size_t buf_size;\n    std::unique_ptr<char[]> d_buffer;\n    object pywrite;\n    object pyflush;\n\n    int overflow(int c) override {\n        if (!traits_type::eq_int_type(c, traits_type::eof())) {\n            *pptr() = traits_type::to_char_type(c);\n            pbump(1);\n        }\n        return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();\n    }\n\n    // Computes how many bytes at the end of the buffer are part of an\n    // incomplete sequence of UTF-8 bytes.\n    // Precondition: pbase() < pptr()\n    size_t utf8_remainder() const {\n        const auto rbase = std::reverse_iterator<char *>(pbase());\n        const auto rpptr = std::reverse_iterator<char *>(pptr());\n        auto is_ascii = [](char c) { return (static_cast<unsigned char>(c) & 0x80) == 0x00; };\n        auto is_leading = [](char c) { return (static_cast<unsigned char>(c) & 0xC0) == 0xC0; };\n        auto is_leading_2b = [](char c) { return static_cast<unsigned char>(c) <= 0xDF; };\n        auto is_leading_3b = [](char c) { return static_cast<unsigned char>(c) <= 0xEF; };\n        // If the last character is ASCII, there are no incomplete code points\n        if (is_ascii(*rpptr)) {\n            return 0;\n        }\n        // Otherwise, work back from the end of the buffer and find the first\n        // UTF-8 leading byte\n        const auto rpend = rbase - rpptr >= 3 ? rpptr + 3 : rbase;\n        const auto leading = std::find_if(rpptr, rpend, is_leading);\n        if (leading == rbase) {\n            return 0;\n        }\n        const auto dist = static_cast<size_t>(leading - rpptr);\n        size_t remainder = 0;\n\n        if (dist == 0) {\n            remainder = 1; // 1-byte code point is impossible\n        } else if (dist == 1) {\n            remainder = is_leading_2b(*leading) ? 0 : dist + 1;\n        } else if (dist == 2) {\n            remainder = is_leading_3b(*leading) ? 0 : dist + 1;\n        }\n        // else if (dist >= 3), at least 4 bytes before encountering an UTF-8\n        // leading byte, either no remainder or invalid UTF-8.\n        // Invalid UTF-8 will cause an exception later when converting\n        // to a Python string, so that's not handled here.\n        return remainder;\n    }\n\n    // This function must be non-virtual to be called in a destructor.\n    int _sync() {\n        if (pbase() != pptr()) { // If buffer is not empty\n            gil_scoped_acquire tmp;\n            // This subtraction cannot be negative, so dropping the sign.\n            auto size = static_cast<size_t>(pptr() - pbase());\n            size_t remainder = utf8_remainder();\n\n            if (size > remainder) {\n                str line(pbase(), size - remainder);\n                pywrite(std::move(line));\n                pyflush();\n            }\n\n            // Copy the remainder at the end of the buffer to the beginning:\n            if (remainder > 0) {\n                std::memmove(pbase(), pptr() - remainder, remainder);\n            }\n            setp(pbase(), epptr());\n            pbump(static_cast<int>(remainder));\n        }\n        return 0;\n    }\n\n    int sync() override { return _sync(); }\n\npublic:\n    explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)\n        : buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr(\"write\")),\n          pyflush(pyostream.attr(\"flush\")) {\n        setp(d_buffer.get(), d_buffer.get() + buf_size - 1);\n    }\n\n    pythonbuf(pythonbuf &&) = default;\n\n    /// Sync before destroy\n    ~pythonbuf() override { _sync(); }\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    This a move-only guard that redirects output.\n\n    .. code-block:: cpp\n\n        #include <pybind11/iostream.h>\n\n        ...\n\n        {\n            py::scoped_ostream_redirect output;\n            std::cout << \"Hello, World!\"; // Python stdout\n        } // <-- return std::cout to normal\n\n    You can explicitly pass the c++ stream and the python object,\n    for example to guard stderr instead.\n\n    .. code-block:: cpp\n\n        {\n            py::scoped_ostream_redirect output{\n                std::cerr, py::module::import(\"sys\").attr(\"stderr\")};\n            std::cout << \"Hello, World!\";\n        }\n \\endrst */\nclass scoped_ostream_redirect {\nprotected:\n    std::streambuf *old;\n    std::ostream &costream;\n    detail::pythonbuf buffer;\n\npublic:\n    explicit scoped_ostream_redirect(std::ostream &costream = std::cout,\n                                     const object &pyostream\n                                     = module_::import(\"sys\").attr(\"stdout\"))\n        : costream(costream), buffer(pyostream) {\n        old = costream.rdbuf(&buffer);\n    }\n\n    ~scoped_ostream_redirect() { costream.rdbuf(old); }\n\n    scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;\n    scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;\n    scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete;\n    scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;\n};\n\n/** \\rst\n    Like `scoped_ostream_redirect`, but redirects cerr by default. This class\n    is provided primary to make ``py::call_guard`` easier to make.\n\n    .. code-block:: cpp\n\n     m.def(\"noisy_func\", &noisy_func,\n           py::call_guard<scoped_ostream_redirect,\n                          scoped_estream_redirect>());\n\n\\endrst */\nclass scoped_estream_redirect : public scoped_ostream_redirect {\npublic:\n    explicit scoped_estream_redirect(std::ostream &costream = std::cerr,\n                                     const object &pyostream\n                                     = module_::import(\"sys\").attr(\"stderr\"))\n        : scoped_ostream_redirect(costream, pyostream) {}\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Class to redirect output as a context manager. C++ backend.\nclass OstreamRedirect {\n    bool do_stdout_;\n    bool do_stderr_;\n    std::unique_ptr<scoped_ostream_redirect> redirect_stdout;\n    std::unique_ptr<scoped_estream_redirect> redirect_stderr;\n\npublic:\n    explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)\n        : do_stdout_(do_stdout), do_stderr_(do_stderr) {}\n\n    void enter() {\n        if (do_stdout_) {\n            redirect_stdout.reset(new scoped_ostream_redirect());\n        }\n        if (do_stderr_) {\n            redirect_stderr.reset(new scoped_estream_redirect());\n        }\n    }\n\n    void exit() {\n        redirect_stdout.reset();\n        redirect_stderr.reset();\n    }\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    This is a helper function to add a C++ redirect context manager to Python\n    instead of using a C++ guard. To use it, add the following to your binding code:\n\n    .. code-block:: cpp\n\n        #include <pybind11/iostream.h>\n\n        ...\n\n        py::add_ostream_redirect(m, \"ostream_redirect\");\n\n    You now have a Python context manager that redirects your output:\n\n    .. code-block:: python\n\n        with m.ostream_redirect():\n            m.print_to_cout_function()\n\n    This manager can optionally be told which streams to operate on:\n\n    .. code-block:: python\n\n        with m.ostream_redirect(stdout=true, stderr=true):\n            m.noisy_function_with_error_printing()\n\n \\endrst */\ninline class_<detail::OstreamRedirect>\nadd_ostream_redirect(module_ m, const std::string &name = \"ostream_redirect\") {\n    return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())\n        .def(init<bool, bool>(), arg(\"stdout\") = true, arg(\"stderr\") = true)\n        .def(\"__enter__\", &detail::OstreamRedirect::enter)\n        .def(\"__exit__\", [](detail::OstreamRedirect &self_, const args &) { self_.exit(); });\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/numpy.h",
    "content": "/*\n    pybind11/numpy.h: Basic NumPy support, vectorize() wrapper\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"complex.h\"\n\n#include <algorithm>\n#include <array>\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <functional>\n#include <numeric>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <utility>\n#include <vector>\n\n/* This will be true on all flat address space platforms and allows us to reduce the\n   whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size\n   and dimension types (e.g. shape, strides, indexing), instead of inflicting this\n   upon the library user. */\nstatic_assert(sizeof(::pybind11::ssize_t) == sizeof(Py_intptr_t), \"ssize_t != Py_intptr_t\");\nstatic_assert(std::is_signed<Py_intptr_t>::value, \"Py_intptr_t must be signed\");\n// We now can reinterpret_cast between py::ssize_t and Py_intptr_t (MSVC + PyPy cares)\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nclass array; // Forward declaration\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <>\nstruct handle_type_name<array> {\n    static constexpr auto name = const_name(\"numpy.ndarray\");\n};\n\ntemplate <typename type, typename SFINAE = void>\nstruct npy_format_descriptor;\n\nstruct PyArrayDescr_Proxy {\n    PyObject_HEAD\n    PyObject *typeobj;\n    char kind;\n    char type;\n    char byteorder;\n    char flags;\n    int type_num;\n    int elsize;\n    int alignment;\n    char *subarray;\n    PyObject *fields;\n    PyObject *names;\n};\n\nstruct PyArray_Proxy {\n    PyObject_HEAD\n    char *data;\n    int nd;\n    ssize_t *dimensions;\n    ssize_t *strides;\n    PyObject *base;\n    PyObject *descr;\n    int flags;\n};\n\nstruct PyVoidScalarObject_Proxy {\n    PyObject_VAR_HEAD char *obval;\n    PyArrayDescr_Proxy *descr;\n    int flags;\n    PyObject *base;\n};\n\nstruct numpy_type_info {\n    PyObject *dtype_ptr;\n    std::string format_str;\n};\n\nstruct numpy_internals {\n    std::unordered_map<std::type_index, numpy_type_info> registered_dtypes;\n\n    numpy_type_info *get_type_info(const std::type_info &tinfo, bool throw_if_missing = true) {\n        auto it = registered_dtypes.find(std::type_index(tinfo));\n        if (it != registered_dtypes.end()) {\n            return &(it->second);\n        }\n        if (throw_if_missing) {\n            pybind11_fail(std::string(\"NumPy type info missing for \") + tinfo.name());\n        }\n        return nullptr;\n    }\n\n    template <typename T>\n    numpy_type_info *get_type_info(bool throw_if_missing = true) {\n        return get_type_info(typeid(typename std::remove_cv<T>::type), throw_if_missing);\n    }\n};\n\nPYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr) {\n    ptr = &get_or_create_shared_data<numpy_internals>(\"_numpy_internals\");\n}\n\ninline numpy_internals &get_numpy_internals() {\n    static numpy_internals *ptr = nullptr;\n    if (!ptr) {\n        load_numpy_internals(ptr);\n    }\n    return *ptr;\n}\n\ntemplate <typename T>\nstruct same_size {\n    template <typename U>\n    using as = bool_constant<sizeof(T) == sizeof(U)>;\n};\n\ntemplate <typename Concrete>\nconstexpr int platform_lookup() {\n    return -1;\n}\n\n// Lookup a type according to its size, and return a value corresponding to the NumPy typenum.\ntemplate <typename Concrete, typename T, typename... Ts, typename... Ints>\nconstexpr int platform_lookup(int I, Ints... Is) {\n    return sizeof(Concrete) == sizeof(T) ? I : platform_lookup<Concrete, Ts...>(Is...);\n}\n\nstruct npy_api {\n    enum constants {\n        NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,\n        NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,\n        NPY_ARRAY_OWNDATA_ = 0x0004,\n        NPY_ARRAY_FORCECAST_ = 0x0010,\n        NPY_ARRAY_ENSUREARRAY_ = 0x0040,\n        NPY_ARRAY_ALIGNED_ = 0x0100,\n        NPY_ARRAY_WRITEABLE_ = 0x0400,\n        NPY_BOOL_ = 0,\n        NPY_BYTE_,\n        NPY_UBYTE_,\n        NPY_SHORT_,\n        NPY_USHORT_,\n        NPY_INT_,\n        NPY_UINT_,\n        NPY_LONG_,\n        NPY_ULONG_,\n        NPY_LONGLONG_,\n        NPY_ULONGLONG_,\n        NPY_FLOAT_,\n        NPY_DOUBLE_,\n        NPY_LONGDOUBLE_,\n        NPY_CFLOAT_,\n        NPY_CDOUBLE_,\n        NPY_CLONGDOUBLE_,\n        NPY_OBJECT_ = 17,\n        NPY_STRING_,\n        NPY_UNICODE_,\n        NPY_VOID_,\n        // Platform-dependent normalization\n        NPY_INT8_ = NPY_BYTE_,\n        NPY_UINT8_ = NPY_UBYTE_,\n        NPY_INT16_ = NPY_SHORT_,\n        NPY_UINT16_ = NPY_USHORT_,\n        // `npy_common.h` defines the integer aliases. In order, it checks:\n        // NPY_BITSOF_LONG, NPY_BITSOF_LONGLONG, NPY_BITSOF_INT, NPY_BITSOF_SHORT, NPY_BITSOF_CHAR\n        // and assigns the alias to the first matching size, so we should check in this order.\n        NPY_INT32_\n        = platform_lookup<std::int32_t, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),\n        NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(\n            NPY_ULONG_, NPY_UINT_, NPY_USHORT_),\n        NPY_INT64_\n        = platform_lookup<std::int64_t, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),\n        NPY_UINT64_\n        = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(\n            NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),\n    };\n\n    struct PyArray_Dims {\n        Py_intptr_t *ptr;\n        int len;\n    };\n\n    static npy_api &get() {\n        static npy_api api = lookup();\n        return api;\n    }\n\n    bool PyArray_Check_(PyObject *obj) const {\n        return PyObject_TypeCheck(obj, PyArray_Type_) != 0;\n    }\n    bool PyArrayDescr_Check_(PyObject *obj) const {\n        return PyObject_TypeCheck(obj, PyArrayDescr_Type_) != 0;\n    }\n\n    unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();\n    PyObject *(*PyArray_DescrFromType_)(int);\n    PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,\n                                       PyObject *,\n                                       int,\n                                       Py_intptr_t const *,\n                                       Py_intptr_t const *,\n                                       void *,\n                                       int,\n                                       PyObject *);\n    // Unused. Not removed because that affects ABI of the class.\n    PyObject *(*PyArray_DescrNewFromType_)(int);\n    int (*PyArray_CopyInto_)(PyObject *, PyObject *);\n    PyObject *(*PyArray_NewCopy_)(PyObject *, int);\n    PyTypeObject *PyArray_Type_;\n    PyTypeObject *PyVoidArrType_Type_;\n    PyTypeObject *PyArrayDescr_Type_;\n    PyObject *(*PyArray_DescrFromScalar_)(PyObject *);\n    PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int, int, int, PyObject *);\n    int (*PyArray_DescrConverter_)(PyObject *, PyObject **);\n    bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);\n    int (*PyArray_GetArrayParamsFromObject_)(PyObject *,\n                                             PyObject *,\n                                             unsigned char,\n                                             PyObject **,\n                                             int *,\n                                             Py_intptr_t *,\n                                             PyObject **,\n                                             PyObject *);\n    PyObject *(*PyArray_Squeeze_)(PyObject *);\n    // Unused. Not removed because that affects ABI of the class.\n    int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);\n    PyObject *(*PyArray_Resize_)(PyObject *, PyArray_Dims *, int, int);\n    PyObject *(*PyArray_Newshape_)(PyObject *, PyArray_Dims *, int);\n    PyObject *(*PyArray_View_)(PyObject *, PyObject *, PyObject *);\n\nprivate:\n    enum functions {\n        API_PyArray_GetNDArrayCFeatureVersion = 211,\n        API_PyArray_Type = 2,\n        API_PyArrayDescr_Type = 3,\n        API_PyVoidArrType_Type = 39,\n        API_PyArray_DescrFromType = 45,\n        API_PyArray_DescrFromScalar = 57,\n        API_PyArray_FromAny = 69,\n        API_PyArray_Resize = 80,\n        API_PyArray_CopyInto = 82,\n        API_PyArray_NewCopy = 85,\n        API_PyArray_NewFromDescr = 94,\n        API_PyArray_DescrNewFromType = 96,\n        API_PyArray_Newshape = 135,\n        API_PyArray_Squeeze = 136,\n        API_PyArray_View = 137,\n        API_PyArray_DescrConverter = 174,\n        API_PyArray_EquivTypes = 182,\n        API_PyArray_GetArrayParamsFromObject = 278,\n        API_PyArray_SetBaseObject = 282\n    };\n\n    static npy_api lookup() {\n        module_ m = module_::import(\"numpy.core.multiarray\");\n        auto c = m.attr(\"_ARRAY_API\");\n        void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);\n        npy_api api;\n#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];\n        DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);\n        if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7) {\n            pybind11_fail(\"pybind11 numpy support requires numpy >= 1.7.0\");\n        }\n        DECL_NPY_API(PyArray_Type);\n        DECL_NPY_API(PyVoidArrType_Type);\n        DECL_NPY_API(PyArrayDescr_Type);\n        DECL_NPY_API(PyArray_DescrFromType);\n        DECL_NPY_API(PyArray_DescrFromScalar);\n        DECL_NPY_API(PyArray_FromAny);\n        DECL_NPY_API(PyArray_Resize);\n        DECL_NPY_API(PyArray_CopyInto);\n        DECL_NPY_API(PyArray_NewCopy);\n        DECL_NPY_API(PyArray_NewFromDescr);\n        DECL_NPY_API(PyArray_DescrNewFromType);\n        DECL_NPY_API(PyArray_Newshape);\n        DECL_NPY_API(PyArray_Squeeze);\n        DECL_NPY_API(PyArray_View);\n        DECL_NPY_API(PyArray_DescrConverter);\n        DECL_NPY_API(PyArray_EquivTypes);\n        DECL_NPY_API(PyArray_GetArrayParamsFromObject);\n        DECL_NPY_API(PyArray_SetBaseObject);\n\n#undef DECL_NPY_API\n        return api;\n    }\n};\n\ninline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); }\n\ninline const PyArray_Proxy *array_proxy(const void *ptr) {\n    return reinterpret_cast<const PyArray_Proxy *>(ptr);\n}\n\ninline PyArrayDescr_Proxy *array_descriptor_proxy(PyObject *ptr) {\n    return reinterpret_cast<PyArrayDescr_Proxy *>(ptr);\n}\n\ninline const PyArrayDescr_Proxy *array_descriptor_proxy(const PyObject *ptr) {\n    return reinterpret_cast<const PyArrayDescr_Proxy *>(ptr);\n}\n\ninline bool check_flags(const void *ptr, int flag) {\n    return (flag == (array_proxy(ptr)->flags & flag));\n}\n\ntemplate <typename T>\nstruct is_std_array : std::false_type {};\ntemplate <typename T, size_t N>\nstruct is_std_array<std::array<T, N>> : std::true_type {};\ntemplate <typename T>\nstruct is_complex : std::false_type {};\ntemplate <typename T>\nstruct is_complex<std::complex<T>> : std::true_type {};\n\ntemplate <typename T>\nstruct array_info_scalar {\n    using type = T;\n    static constexpr bool is_array = false;\n    static constexpr bool is_empty = false;\n    static constexpr auto extents = const_name(\"\");\n    static void append_extents(list & /* shape */) {}\n};\n// Computes underlying type and a comma-separated list of extents for array\n// types (any mix of std::array and built-in arrays). An array of char is\n// treated as scalar because it gets special handling.\ntemplate <typename T>\nstruct array_info : array_info_scalar<T> {};\ntemplate <typename T, size_t N>\nstruct array_info<std::array<T, N>> {\n    using type = typename array_info<T>::type;\n    static constexpr bool is_array = true;\n    static constexpr bool is_empty = (N == 0) || array_info<T>::is_empty;\n    static constexpr size_t extent = N;\n\n    // appends the extents to shape\n    static void append_extents(list &shape) {\n        shape.append(N);\n        array_info<T>::append_extents(shape);\n    }\n\n    static constexpr auto extents = const_name<array_info<T>::is_array>(\n        concat(const_name<N>(), array_info<T>::extents), const_name<N>());\n};\n// For numpy we have special handling for arrays of characters, so we don't include\n// the size in the array extents.\ntemplate <size_t N>\nstruct array_info<char[N]> : array_info_scalar<char[N]> {};\ntemplate <size_t N>\nstruct array_info<std::array<char, N>> : array_info_scalar<std::array<char, N>> {};\ntemplate <typename T, size_t N>\nstruct array_info<T[N]> : array_info<std::array<T, N>> {};\ntemplate <typename T>\nusing remove_all_extents_t = typename array_info<T>::type;\n\ntemplate <typename T>\nusing is_pod_struct\n    = all_of<std::is_standard_layout<T>, // since we're accessing directly in memory\n                                         // we need a standard layout type\n#if defined(__GLIBCXX__)                                                                          \\\n    && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623              \\\n        || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)\n             // libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after\n             // 5) don't implement is_trivially_copyable, so approximate it\n             std::is_trivially_destructible<T>,\n             satisfies_any_of<T, std::has_trivial_copy_constructor, std::has_trivial_copy_assign>,\n#else\n             std::is_trivially_copyable<T>,\n#endif\n             satisfies_none_of<T,\n                               std::is_reference,\n                               std::is_array,\n                               is_std_array,\n                               std::is_arithmetic,\n                               is_complex,\n                               std::is_enum>>;\n\n// Replacement for std::is_pod (deprecated in C++20)\ntemplate <typename T>\nusing is_pod = all_of<std::is_standard_layout<T>, std::is_trivial<T>>;\n\ntemplate <ssize_t Dim = 0, typename Strides>\nssize_t byte_offset_unsafe(const Strides &) {\n    return 0;\n}\ntemplate <ssize_t Dim = 0, typename Strides, typename... Ix>\nssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) {\n    return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(strides, index...);\n}\n\n/**\n * Proxy class providing unsafe, unchecked const access to array data.  This is constructed through\n * the `unchecked<T, N>()` method of `array` or the `unchecked<N>()` method of `array_t<T>`. `Dims`\n * will be -1 for dimensions determined at runtime.\n */\ntemplate <typename T, ssize_t Dims>\nclass unchecked_reference {\nprotected:\n    static constexpr bool Dynamic = Dims < 0;\n    const unsigned char *data_;\n    // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to\n    // make large performance gains on big, nested loops, but requires compile-time dimensions\n    conditional_t<Dynamic, const ssize_t *, std::array<ssize_t, (size_t) Dims>> shape_, strides_;\n    const ssize_t dims_;\n\n    friend class pybind11::array;\n    // Constructor for compile-time dimensions:\n    template <bool Dyn = Dynamic>\n    unchecked_reference(const void *data,\n                        const ssize_t *shape,\n                        const ssize_t *strides,\n                        enable_if_t<!Dyn, ssize_t>)\n        : data_{reinterpret_cast<const unsigned char *>(data)}, dims_{Dims} {\n        for (size_t i = 0; i < (size_t) dims_; i++) {\n            shape_[i] = shape[i];\n            strides_[i] = strides[i];\n        }\n    }\n    // Constructor for runtime dimensions:\n    template <bool Dyn = Dynamic>\n    unchecked_reference(const void *data,\n                        const ssize_t *shape,\n                        const ssize_t *strides,\n                        enable_if_t<Dyn, ssize_t> dims)\n        : data_{reinterpret_cast<const unsigned char *>(data)}, shape_{shape}, strides_{strides},\n          dims_{dims} {}\n\npublic:\n    /**\n     * Unchecked const reference access to data at the given indices.  For a compile-time known\n     * number of dimensions, this requires the correct number of arguments; for run-time\n     * dimensionality, this is not checked (and so is up to the caller to use safely).\n     */\n    template <typename... Ix>\n    const T &operator()(Ix... index) const {\n        static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,\n                      \"Invalid number of indices for unchecked array reference\");\n        return *reinterpret_cast<const T *>(data_\n                                            + byte_offset_unsafe(strides_, ssize_t(index)...));\n    }\n    /**\n     * Unchecked const reference access to data; this operator only participates if the reference\n     * is to a 1-dimensional array.  When present, this is exactly equivalent to `obj(index)`.\n     */\n    template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>\n    const T &operator[](ssize_t index) const {\n        return operator()(index);\n    }\n\n    /// Pointer access to the data at the given indices.\n    template <typename... Ix>\n    const T *data(Ix... ix) const {\n        return &operator()(ssize_t(ix)...);\n    }\n\n    /// Returns the item size, i.e. sizeof(T)\n    constexpr static ssize_t itemsize() { return sizeof(T); }\n\n    /// Returns the shape (i.e. size) of dimension `dim`\n    ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; }\n\n    /// Returns the number of dimensions of the array\n    ssize_t ndim() const { return dims_; }\n\n    /// Returns the total number of elements in the referenced array, i.e. the product of the\n    /// shapes\n    template <bool Dyn = Dynamic>\n    enable_if_t<!Dyn, ssize_t> size() const {\n        return std::accumulate(\n            shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n    template <bool Dyn = Dynamic>\n    enable_if_t<Dyn, ssize_t> size() const {\n        return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n\n    /// Returns the total number of bytes used by the referenced data.  Note that the actual span\n    /// in memory may be larger if the referenced array has non-contiguous strides (e.g. for a\n    /// slice).\n    ssize_t nbytes() const { return size() * itemsize(); }\n};\n\ntemplate <typename T, ssize_t Dims>\nclass unchecked_mutable_reference : public unchecked_reference<T, Dims> {\n    friend class pybind11::array;\n    using ConstBase = unchecked_reference<T, Dims>;\n    using ConstBase::ConstBase;\n    using ConstBase::Dynamic;\n\npublic:\n    // Bring in const-qualified versions from base class\n    using ConstBase::operator();\n    using ConstBase::operator[];\n\n    /// Mutable, unchecked access to data at the given indices.\n    template <typename... Ix>\n    T &operator()(Ix... index) {\n        static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,\n                      \"Invalid number of indices for unchecked array reference\");\n        return const_cast<T &>(ConstBase::operator()(index...));\n    }\n    /**\n     * Mutable, unchecked access data at the given index; this operator only participates if the\n     * reference is to a 1-dimensional array (or has runtime dimensions).  When present, this is\n     * exactly equivalent to `obj(index)`.\n     */\n    template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>\n    T &operator[](ssize_t index) {\n        return operator()(index);\n    }\n\n    /// Mutable pointer access to the data at the given indices.\n    template <typename... Ix>\n    T *mutable_data(Ix... ix) {\n        return &operator()(ssize_t(ix)...);\n    }\n};\n\ntemplate <typename T, ssize_t Dim>\nstruct type_caster<unchecked_reference<T, Dim>> {\n    static_assert(Dim == 0 && Dim > 0 /* always fail */,\n                  \"unchecked array proxy object is not castable\");\n};\ntemplate <typename T, ssize_t Dim>\nstruct type_caster<unchecked_mutable_reference<T, Dim>>\n    : type_caster<unchecked_reference<T, Dim>> {};\n\nPYBIND11_NAMESPACE_END(detail)\n\nclass dtype : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_)\n\n    explicit dtype(const buffer_info &info) {\n        dtype descr(_dtype_from_pep3118()(pybind11::str(info.format)));\n        // If info.itemsize == 0, use the value calculated from the format string\n        m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())\n                    .release()\n                    .ptr();\n    }\n\n    explicit dtype(const pybind11::str &format) : dtype(from_args(format)) {}\n\n    explicit dtype(const std::string &format) : dtype(pybind11::str(format)) {}\n\n    explicit dtype(const char *format) : dtype(pybind11::str(format)) {}\n\n    dtype(list names, list formats, list offsets, ssize_t itemsize) {\n        dict args;\n        args[\"names\"] = std::move(names);\n        args[\"formats\"] = std::move(formats);\n        args[\"offsets\"] = std::move(offsets);\n        args[\"itemsize\"] = pybind11::int_(itemsize);\n        m_ptr = from_args(args).release().ptr();\n    }\n\n    explicit dtype(int typenum)\n        : object(detail::npy_api::get().PyArray_DescrFromType_(typenum), stolen_t{}) {\n        if (m_ptr == nullptr) {\n            throw error_already_set();\n        }\n    }\n\n    /// This is essentially the same as calling numpy.dtype(args) in Python.\n    static dtype from_args(const object &args) {\n        PyObject *ptr = nullptr;\n        if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<dtype>(ptr);\n    }\n\n    /// Return dtype associated with a C++ type.\n    template <typename T>\n    static dtype of() {\n        return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();\n    }\n\n    /// Size of the data type in bytes.\n    ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; }\n\n    /// Returns true for structured data types.\n    bool has_fields() const { return detail::array_descriptor_proxy(m_ptr)->names != nullptr; }\n\n    /// Single-character code for dtype's kind.\n    /// For example, floating point types are 'f' and integral types are 'i'.\n    char kind() const { return detail::array_descriptor_proxy(m_ptr)->kind; }\n\n    /// Single-character for dtype's type.\n    /// For example, ``float`` is 'f', ``double`` 'd', ``int`` 'i', and ``long`` 'l'.\n    char char_() const {\n        // Note: The signature, `dtype::char_` follows the naming of NumPy's\n        // public Python API (i.e., ``dtype.char``), rather than its internal\n        // C API (``PyArray_Descr::type``).\n        return detail::array_descriptor_proxy(m_ptr)->type;\n    }\n\n    /// type number of dtype.\n    int num() const {\n        // Note: The signature, `dtype::num` follows the naming of NumPy's public\n        // Python API (i.e., ``dtype.num``), rather than its internal\n        // C API (``PyArray_Descr::type_num``).\n        return detail::array_descriptor_proxy(m_ptr)->type_num;\n    }\n\n    /// Single character for byteorder\n    char byteorder() const { return detail::array_descriptor_proxy(m_ptr)->byteorder; }\n\n    /// Alignment of the data type\n    int alignment() const { return detail::array_descriptor_proxy(m_ptr)->alignment; }\n\n    /// Flags for the array descriptor\n    char flags() const { return detail::array_descriptor_proxy(m_ptr)->flags; }\n\nprivate:\n    static object _dtype_from_pep3118() {\n        static PyObject *obj = module_::import(\"numpy.core._internal\")\n                                   .attr(\"_dtype_from_pep3118\")\n                                   .cast<object>()\n                                   .release()\n                                   .ptr();\n        return reinterpret_borrow<object>(obj);\n    }\n\n    dtype strip_padding(ssize_t itemsize) {\n        // Recursively strip all void fields with empty names that are generated for\n        // padding fields (as of NumPy v1.11).\n        if (!has_fields()) {\n            return *this;\n        }\n\n        struct field_descr {\n            pybind11::str name;\n            object format;\n            pybind11::int_ offset;\n            field_descr(pybind11::str &&name, object &&format, pybind11::int_ &&offset)\n                : name{std::move(name)}, format{std::move(format)}, offset{std::move(offset)} {};\n        };\n        auto field_dict = attr(\"fields\").cast<dict>();\n        std::vector<field_descr> field_descriptors;\n        field_descriptors.reserve(field_dict.size());\n\n        for (auto field : field_dict.attr(\"items\")()) {\n            auto spec = field.cast<tuple>();\n            auto name = spec[0].cast<pybind11::str>();\n            auto spec_fo = spec[1].cast<tuple>();\n            auto format = spec_fo[0].cast<dtype>();\n            auto offset = spec_fo[1].cast<pybind11::int_>();\n            if ((len(name) == 0u) && format.kind() == 'V') {\n                continue;\n            }\n            field_descriptors.emplace_back(\n                std::move(name), format.strip_padding(format.itemsize()), std::move(offset));\n        }\n\n        std::sort(field_descriptors.begin(),\n                  field_descriptors.end(),\n                  [](const field_descr &a, const field_descr &b) {\n                      return a.offset.cast<int>() < b.offset.cast<int>();\n                  });\n\n        list names, formats, offsets;\n        for (auto &descr : field_descriptors) {\n            names.append(std::move(descr.name));\n            formats.append(std::move(descr.format));\n            offsets.append(std::move(descr.offset));\n        }\n        return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);\n    }\n};\n\nclass array : public buffer {\npublic:\n    PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array)\n\n    enum {\n        c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_,\n        f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_,\n        forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_\n    };\n\n    array() : array(0, static_cast<const double *>(nullptr)) {}\n\n    using ShapeContainer = detail::any_container<ssize_t>;\n    using StridesContainer = detail::any_container<ssize_t>;\n\n    // Constructs an array taking shape/strides from arbitrary container types\n    array(const pybind11::dtype &dt,\n          ShapeContainer shape,\n          StridesContainer strides,\n          const void *ptr = nullptr,\n          handle base = handle()) {\n\n        if (strides->empty()) {\n            *strides = detail::c_strides(*shape, dt.itemsize());\n        }\n\n        auto ndim = shape->size();\n        if (ndim != strides->size()) {\n            pybind11_fail(\"NumPy: shape ndim doesn't match strides ndim\");\n        }\n        auto descr = dt;\n\n        int flags = 0;\n        if (base && ptr) {\n            if (isinstance<array>(base)) {\n                /* Copy flags from base (except ownership bit) */\n                flags = reinterpret_borrow<array>(base).flags()\n                        & ~detail::npy_api::NPY_ARRAY_OWNDATA_;\n            } else {\n                /* Writable by default, easy to downgrade later on if needed */\n                flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;\n            }\n        }\n\n        auto &api = detail::npy_api::get();\n        auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(\n            api.PyArray_Type_,\n            descr.release().ptr(),\n            (int) ndim,\n            // Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)\n            reinterpret_cast<Py_intptr_t *>(shape->data()),\n            reinterpret_cast<Py_intptr_t *>(strides->data()),\n            const_cast<void *>(ptr),\n            flags,\n            nullptr));\n        if (!tmp) {\n            throw error_already_set();\n        }\n        if (ptr) {\n            if (base) {\n                api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr());\n            } else {\n                tmp = reinterpret_steal<object>(\n                    api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */));\n            }\n        }\n        m_ptr = tmp.release().ptr();\n    }\n\n    array(const pybind11::dtype &dt,\n          ShapeContainer shape,\n          const void *ptr = nullptr,\n          handle base = handle())\n        : array(dt, std::move(shape), {}, ptr, base) {}\n\n    template <typename T,\n              typename\n              = detail::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>>\n    array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle())\n        : array(dt, {{count}}, ptr, base) {}\n\n    template <typename T>\n    array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())\n        : array(pybind11::dtype::of<T>(), std::move(shape), std::move(strides), ptr, base) {}\n\n    template <typename T>\n    array(ShapeContainer shape, const T *ptr, handle base = handle())\n        : array(std::move(shape), {}, ptr, base) {}\n\n    template <typename T>\n    explicit array(ssize_t count, const T *ptr, handle base = handle())\n        : array({count}, {}, ptr, base) {}\n\n    explicit array(const buffer_info &info, handle base = handle())\n        : array(pybind11::dtype(info), info.shape, info.strides, info.ptr, base) {}\n\n    /// Array descriptor (dtype)\n    pybind11::dtype dtype() const {\n        return reinterpret_borrow<pybind11::dtype>(detail::array_proxy(m_ptr)->descr);\n    }\n\n    /// Total number of elements\n    ssize_t size() const {\n        return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n\n    /// Byte size of a single element\n    ssize_t itemsize() const {\n        return detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize;\n    }\n\n    /// Total number of bytes\n    ssize_t nbytes() const { return size() * itemsize(); }\n\n    /// Number of dimensions\n    ssize_t ndim() const { return detail::array_proxy(m_ptr)->nd; }\n\n    /// Base object\n    object base() const { return reinterpret_borrow<object>(detail::array_proxy(m_ptr)->base); }\n\n    /// Dimensions of the array\n    const ssize_t *shape() const { return detail::array_proxy(m_ptr)->dimensions; }\n\n    /// Dimension along a given axis\n    ssize_t shape(ssize_t dim) const {\n        if (dim >= ndim()) {\n            fail_dim_check(dim, \"invalid axis\");\n        }\n        return shape()[dim];\n    }\n\n    /// Strides of the array\n    const ssize_t *strides() const { return detail::array_proxy(m_ptr)->strides; }\n\n    /// Stride along a given axis\n    ssize_t strides(ssize_t dim) const {\n        if (dim >= ndim()) {\n            fail_dim_check(dim, \"invalid axis\");\n        }\n        return strides()[dim];\n    }\n\n    /// Return the NumPy array flags\n    int flags() const { return detail::array_proxy(m_ptr)->flags; }\n\n    /// If set, the array is writeable (otherwise the buffer is read-only)\n    bool writeable() const {\n        return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_);\n    }\n\n    /// If set, the array owns the data (will be freed when the array is deleted)\n    bool owndata() const {\n        return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_);\n    }\n\n    /// Pointer to the contained data. If index is not provided, points to the\n    /// beginning of the buffer. May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    const void *data(Ix... index) const {\n        return static_cast<const void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));\n    }\n\n    /// Mutable pointer to the contained data. If index is not provided, points to the\n    /// beginning of the buffer. May throw if the index would lead to out of bounds access.\n    /// May throw if the array is not writeable.\n    template <typename... Ix>\n    void *mutable_data(Ix... index) {\n        check_writeable();\n        return static_cast<void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));\n    }\n\n    /// Byte offset from beginning of the array to a given index (full or partial).\n    /// May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    ssize_t offset_at(Ix... index) const {\n        if ((ssize_t) sizeof...(index) > ndim()) {\n            fail_dim_check(sizeof...(index), \"too many indices for an array\");\n        }\n        return byte_offset(ssize_t(index)...);\n    }\n\n    ssize_t offset_at() const { return 0; }\n\n    /// Item count from beginning of the array to a given index (full or partial).\n    /// May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    ssize_t index_at(Ix... index) const {\n        return offset_at(index...) / itemsize();\n    }\n\n    /**\n     * Returns a proxy object that provides access to the array's data without bounds or\n     * dimensionality checking.  Will throw if the array is missing the `writeable` flag.  Use with\n     * care: the array must not be destroyed or reshaped for the duration of the returned object,\n     * and the caller must take care not to access invalid dimensions or dimension indices.\n     */\n    template <typename T, ssize_t Dims = -1>\n    detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {\n        if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {\n            throw std::domain_error(\"array has incorrect number of dimensions: \"\n                                    + std::to_string(ndim()) + \"; expected \"\n                                    + std::to_string(Dims));\n        }\n        return detail::unchecked_mutable_reference<T, Dims>(\n            mutable_data(), shape(), strides(), ndim());\n    }\n\n    /**\n     * Returns a proxy object that provides const access to the array's data without bounds or\n     * dimensionality checking.  Unlike `mutable_unchecked()`, this does not require that the\n     * underlying array have the `writable` flag.  Use with care: the array must not be destroyed\n     * or reshaped for the duration of the returned object, and the caller must take care not to\n     * access invalid dimensions or dimension indices.\n     */\n    template <typename T, ssize_t Dims = -1>\n    detail::unchecked_reference<T, Dims> unchecked() const & {\n        if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {\n            throw std::domain_error(\"array has incorrect number of dimensions: \"\n                                    + std::to_string(ndim()) + \"; expected \"\n                                    + std::to_string(Dims));\n        }\n        return detail::unchecked_reference<T, Dims>(data(), shape(), strides(), ndim());\n    }\n\n    /// Return a new view with all of the dimensions of length 1 removed\n    array squeeze() {\n        auto &api = detail::npy_api::get();\n        return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));\n    }\n\n    /// Resize array to given shape\n    /// If refcheck is true and more that one reference exist to this array\n    /// then resize will succeed only if it makes a reshape, i.e. original size doesn't change\n    void resize(ShapeContainer new_shape, bool refcheck = true) {\n        detail::npy_api::PyArray_Dims d\n            = {// Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)\n               reinterpret_cast<Py_intptr_t *>(new_shape->data()),\n               int(new_shape->size())};\n        // try to resize, set ordering param to -1 cause it's not used anyway\n        auto new_array = reinterpret_steal<object>(\n            detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1));\n        if (!new_array) {\n            throw error_already_set();\n        }\n        if (isinstance<array>(new_array)) {\n            *this = std::move(new_array);\n        }\n    }\n\n    /// Optional `order` parameter omitted, to be added as needed.\n    array reshape(ShapeContainer new_shape) {\n        detail::npy_api::PyArray_Dims d\n            = {reinterpret_cast<Py_intptr_t *>(new_shape->data()), int(new_shape->size())};\n        auto new_array\n            = reinterpret_steal<array>(detail::npy_api::get().PyArray_Newshape_(m_ptr, &d, 0));\n        if (!new_array) {\n            throw error_already_set();\n        }\n        return new_array;\n    }\n\n    /// Create a view of an array in a different data type.\n    /// This function may fundamentally reinterpret the data in the array.\n    /// It is the responsibility of the caller to ensure that this is safe.\n    /// Only supports the `dtype` argument, the `type` argument is omitted,\n    /// to be added as needed.\n    array view(const std::string &dtype) {\n        auto &api = detail::npy_api::get();\n        auto new_view = reinterpret_steal<array>(api.PyArray_View_(\n            m_ptr, dtype::from_args(pybind11::str(dtype)).release().ptr(), nullptr));\n        if (!new_view) {\n            throw error_already_set();\n        }\n        return new_view;\n    }\n\n    /// Ensure that the argument is a NumPy array\n    /// In case of an error, nullptr is returned and the Python error is cleared.\n    static array ensure(handle h, int ExtraFlags = 0) {\n        auto result = reinterpret_steal<array>(raw_array(h.ptr(), ExtraFlags));\n        if (!result) {\n            PyErr_Clear();\n        }\n        return result;\n    }\n\nprotected:\n    template <typename, typename>\n    friend struct detail::npy_format_descriptor;\n\n    void fail_dim_check(ssize_t dim, const std::string &msg) const {\n        throw index_error(msg + \": \" + std::to_string(dim) + \" (ndim = \" + std::to_string(ndim())\n                          + ')');\n    }\n\n    template <typename... Ix>\n    ssize_t byte_offset(Ix... index) const {\n        check_dimensions(index...);\n        return detail::byte_offset_unsafe(strides(), ssize_t(index)...);\n    }\n\n    void check_writeable() const {\n        if (!writeable()) {\n            throw std::domain_error(\"array is not writeable\");\n        }\n    }\n\n    template <typename... Ix>\n    void check_dimensions(Ix... index) const {\n        check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...);\n    }\n\n    void check_dimensions_impl(ssize_t, const ssize_t *) const {}\n\n    template <typename... Ix>\n    void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix... index) const {\n        if (i >= *shape) {\n            throw index_error(std::string(\"index \") + std::to_string(i)\n                              + \" is out of bounds for axis \" + std::to_string(axis)\n                              + \" with size \" + std::to_string(*shape));\n        }\n        check_dimensions_impl(axis + 1, shape + 1, index...);\n    }\n\n    /// Create array from any object -- always returns a new reference\n    static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) {\n        if (ptr == nullptr) {\n            PyErr_SetString(PyExc_ValueError, \"cannot create a pybind11::array from a nullptr\");\n            return nullptr;\n        }\n        return detail::npy_api::get().PyArray_FromAny_(\n            ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);\n    }\n};\n\ntemplate <typename T, int ExtraFlags = array::forcecast>\nclass array_t : public array {\nprivate:\n    struct private_ctor {};\n    // Delegating constructor needed when both moving and accessing in the same constructor\n    array_t(private_ctor,\n            ShapeContainer &&shape,\n            StridesContainer &&strides,\n            const T *ptr,\n            handle base)\n        : array(std::move(shape), std::move(strides), ptr, base) {}\n\npublic:\n    static_assert(!detail::array_info<T>::is_array, \"Array types cannot be used with array_t\");\n\n    using value_type = T;\n\n    array_t() : array(0, static_cast<const T *>(nullptr)) {}\n    array_t(handle h, borrowed_t) : array(h, borrowed_t{}) {}\n    array_t(handle h, stolen_t) : array(h, stolen_t{}) {}\n\n    PYBIND11_DEPRECATED(\"Use array_t<T>::ensure() instead\")\n    array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            PyErr_Clear();\n        }\n        if (!is_borrowed) {\n            Py_XDECREF(h.ptr());\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    explicit array_t(const buffer_info &info, handle base = handle()) : array(info, base) {}\n\n    array_t(ShapeContainer shape,\n            StridesContainer strides,\n            const T *ptr = nullptr,\n            handle base = handle())\n        : array(std::move(shape), std::move(strides), ptr, base) {}\n\n    explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())\n        : array_t(private_ctor{},\n                  std::move(shape),\n                  (ExtraFlags & f_style) != 0 ? detail::f_strides(*shape, itemsize())\n                                              : detail::c_strides(*shape, itemsize()),\n                  ptr,\n                  base) {}\n\n    explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle())\n        : array({count}, {}, ptr, base) {}\n\n    constexpr ssize_t itemsize() const { return sizeof(T); }\n\n    template <typename... Ix>\n    ssize_t index_at(Ix... index) const {\n        return offset_at(index...) / itemsize();\n    }\n\n    template <typename... Ix>\n    const T *data(Ix... index) const {\n        return static_cast<const T *>(array::data(index...));\n    }\n\n    template <typename... Ix>\n    T *mutable_data(Ix... index) {\n        return static_cast<T *>(array::mutable_data(index...));\n    }\n\n    // Reference to element at a given index\n    template <typename... Ix>\n    const T &at(Ix... index) const {\n        if ((ssize_t) sizeof...(index) != ndim()) {\n            fail_dim_check(sizeof...(index), \"index dimension mismatch\");\n        }\n        return *(static_cast<const T *>(array::data())\n                 + byte_offset(ssize_t(index)...) / itemsize());\n    }\n\n    // Mutable reference to element at a given index\n    template <typename... Ix>\n    T &mutable_at(Ix... index) {\n        if ((ssize_t) sizeof...(index) != ndim()) {\n            fail_dim_check(sizeof...(index), \"index dimension mismatch\");\n        }\n        return *(static_cast<T *>(array::mutable_data())\n                 + byte_offset(ssize_t(index)...) / itemsize());\n    }\n\n    /**\n     * Returns a proxy object that provides access to the array's data without bounds or\n     * dimensionality checking.  Will throw if the array is missing the `writeable` flag.  Use with\n     * care: the array must not be destroyed or reshaped for the duration of the returned object,\n     * and the caller must take care not to access invalid dimensions or dimension indices.\n     */\n    template <ssize_t Dims = -1>\n    detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {\n        return array::mutable_unchecked<T, Dims>();\n    }\n\n    /**\n     * Returns a proxy object that provides const access to the array's data without bounds or\n     * dimensionality checking.  Unlike `unchecked()`, this does not require that the underlying\n     * array have the `writable` flag.  Use with care: the array must not be destroyed or reshaped\n     * for the duration of the returned object, and the caller must take care not to access invalid\n     * dimensions or dimension indices.\n     */\n    template <ssize_t Dims = -1>\n    detail::unchecked_reference<T, Dims> unchecked() const & {\n        return array::unchecked<T, Dims>();\n    }\n\n    /// Ensure that the argument is a NumPy array of the correct dtype (and if not, try to convert\n    /// it).  In case of an error, nullptr is returned and the Python error is cleared.\n    static array_t ensure(handle h) {\n        auto result = reinterpret_steal<array_t>(raw_array_t(h.ptr()));\n        if (!result) {\n            PyErr_Clear();\n        }\n        return result;\n    }\n\n    static bool check_(handle h) {\n        const auto &api = detail::npy_api::get();\n        return api.PyArray_Check_(h.ptr())\n               && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr,\n                                          dtype::of<T>().ptr())\n               && detail::check_flags(h.ptr(), ExtraFlags & (array::c_style | array::f_style));\n    }\n\nprotected:\n    /// Create array from any object -- always returns a new reference\n    static PyObject *raw_array_t(PyObject *ptr) {\n        if (ptr == nullptr) {\n            PyErr_SetString(PyExc_ValueError, \"cannot create a pybind11::array_t from a nullptr\");\n            return nullptr;\n        }\n        return detail::npy_api::get().PyArray_FromAny_(ptr,\n                                                       dtype::of<T>().release().ptr(),\n                                                       0,\n                                                       0,\n                                                       detail::npy_api::NPY_ARRAY_ENSUREARRAY_\n                                                           | ExtraFlags,\n                                                       nullptr);\n    }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {\n    static std::string format() {\n        return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::format();\n    }\n};\n\ntemplate <size_t N>\nstruct format_descriptor<char[N]> {\n    static std::string format() { return std::to_string(N) + 's'; }\n};\ntemplate <size_t N>\nstruct format_descriptor<std::array<char, N>> {\n    static std::string format() { return std::to_string(N) + 's'; }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<std::is_enum<T>::value>> {\n    static std::string format() {\n        return format_descriptor<\n            typename std::remove_cv<typename std::underlying_type<T>::type>::type>::format();\n    }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<detail::array_info<T>::is_array>> {\n    static std::string format() {\n        using namespace detail;\n        static constexpr auto extents = const_name(\"(\") + array_info<T>::extents + const_name(\")\");\n        return extents.text + format_descriptor<remove_all_extents_t<T>>::format();\n    }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename T, int ExtraFlags>\nstruct pyobject_caster<array_t<T, ExtraFlags>> {\n    using type = array_t<T, ExtraFlags>;\n\n    bool load(handle src, bool convert) {\n        if (!convert && !type::check_(src)) {\n            return false;\n        }\n        value = type::ensure(src);\n        return static_cast<bool>(value);\n    }\n\n    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {\n        return src.inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);\n};\n\ntemplate <typename T>\nstruct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {\n    static bool compare(const buffer_info &b) {\n        return npy_api::get().PyArray_EquivTypes_(dtype::of<T>().ptr(), dtype(b).ptr());\n    }\n};\n\ntemplate <typename T, typename = void>\nstruct npy_format_descriptor_name;\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {\n    static constexpr auto name = const_name<std::is_same<T, bool>::value>(\n        const_name(\"bool\"),\n        const_name<std::is_signed<T>::value>(\"numpy.int\", \"numpy.uint\")\n            + const_name<sizeof(T) * 8>());\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr auto name = const_name < std::is_same<T, float>::value\n                                 || std::is_same<T, const float>::value\n                                 || std::is_same<T, double>::value\n                                 || std::is_same<T, const double>::value\n                                        > (const_name(\"numpy.float\") + const_name<sizeof(T) * 8>(),\n                                           const_name(\"numpy.longdouble\"));\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {\n    static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value\n                                 || std::is_same<typename T::value_type, const float>::value\n                                 || std::is_same<typename T::value_type, double>::value\n                                 || std::is_same<typename T::value_type, const double>::value\n                                        > (const_name(\"numpy.complex\")\n                                               + const_name<sizeof(typename T::value_type) * 16>(),\n                                           const_name(\"numpy.longcomplex\"));\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor<\n    T,\n    enable_if_t<satisfies_any_of<T, std::is_arithmetic, is_complex>::value>>\n    : npy_format_descriptor_name<T> {\nprivate:\n    // NB: the order here must match the one in common.h\n    constexpr static const int values[15] = {npy_api::NPY_BOOL_,\n                                             npy_api::NPY_BYTE_,\n                                             npy_api::NPY_UBYTE_,\n                                             npy_api::NPY_INT16_,\n                                             npy_api::NPY_UINT16_,\n                                             npy_api::NPY_INT32_,\n                                             npy_api::NPY_UINT32_,\n                                             npy_api::NPY_INT64_,\n                                             npy_api::NPY_UINT64_,\n                                             npy_api::NPY_FLOAT_,\n                                             npy_api::NPY_DOUBLE_,\n                                             npy_api::NPY_LONGDOUBLE_,\n                                             npy_api::NPY_CFLOAT_,\n                                             npy_api::NPY_CDOUBLE_,\n                                             npy_api::NPY_CLONGDOUBLE_};\n\npublic:\n    static constexpr int value = values[detail::is_fmt_numeric<T>::index];\n\n    static pybind11::dtype dtype() {\n        if (auto *ptr = npy_api::get().PyArray_DescrFromType_(value)) {\n            return reinterpret_steal<pybind11::dtype>(ptr);\n        }\n        pybind11_fail(\"Unsupported buffer format!\");\n    }\n};\n\n#define PYBIND11_DECL_CHAR_FMT                                                                    \\\n    static constexpr auto name = const_name(\"S\") + const_name<N>();                               \\\n    static pybind11::dtype dtype() {                                                              \\\n        return pybind11::dtype(std::string(\"S\") + std::to_string(N));                             \\\n    }\ntemplate <size_t N>\nstruct npy_format_descriptor<char[N]> {\n    PYBIND11_DECL_CHAR_FMT\n};\ntemplate <size_t N>\nstruct npy_format_descriptor<std::array<char, N>> {\n    PYBIND11_DECL_CHAR_FMT\n};\n#undef PYBIND11_DECL_CHAR_FMT\n\ntemplate <typename T>\nstruct npy_format_descriptor<T, enable_if_t<array_info<T>::is_array>> {\nprivate:\n    using base_descr = npy_format_descriptor<typename array_info<T>::type>;\n\npublic:\n    static_assert(!array_info<T>::is_empty, \"Zero-sized arrays are not supported\");\n\n    static constexpr auto name\n        = const_name(\"(\") + array_info<T>::extents + const_name(\")\") + base_descr::name;\n    static pybind11::dtype dtype() {\n        list shape;\n        array_info<T>::append_extents(shape);\n        return pybind11::dtype::from_args(\n            pybind11::make_tuple(base_descr::dtype(), std::move(shape)));\n    }\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor<T, enable_if_t<std::is_enum<T>::value>> {\nprivate:\n    using base_descr = npy_format_descriptor<typename std::underlying_type<T>::type>;\n\npublic:\n    static constexpr auto name = base_descr::name;\n    static pybind11::dtype dtype() { return base_descr::dtype(); }\n};\n\nstruct field_descriptor {\n    const char *name;\n    ssize_t offset;\n    ssize_t size;\n    std::string format;\n    dtype descr;\n};\n\nPYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor> fields,\n                                                 const std::type_info &tinfo,\n                                                 ssize_t itemsize,\n                                                 bool (*direct_converter)(PyObject *, void *&)) {\n\n    auto &numpy_internals = get_numpy_internals();\n    if (numpy_internals.get_type_info(tinfo, false)) {\n        pybind11_fail(\"NumPy: dtype is already registered\");\n    }\n\n    // Use ordered fields because order matters as of NumPy 1.14:\n    // https://docs.scipy.org/doc/numpy/release.html#multiple-field-indexing-assignment-of-structured-arrays\n    std::vector<field_descriptor> ordered_fields(std::move(fields));\n    std::sort(\n        ordered_fields.begin(),\n        ordered_fields.end(),\n        [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });\n\n    list names, formats, offsets;\n    for (auto &field : ordered_fields) {\n        if (!field.descr) {\n            pybind11_fail(std::string(\"NumPy: unsupported field dtype: `\") + field.name + \"` @ \"\n                          + tinfo.name());\n        }\n        names.append(pybind11::str(field.name));\n        formats.append(field.descr);\n        offsets.append(pybind11::int_(field.offset));\n    }\n    auto *dtype_ptr\n        = pybind11::dtype(std::move(names), std::move(formats), std::move(offsets), itemsize)\n              .release()\n              .ptr();\n\n    // There is an existing bug in NumPy (as of v1.11): trailing bytes are\n    // not encoded explicitly into the format string. This will supposedly\n    // get fixed in v1.12; for further details, see these:\n    // - https://github.com/numpy/numpy/issues/7797\n    // - https://github.com/numpy/numpy/pull/7798\n    // Because of this, we won't use numpy's logic to generate buffer format\n    // strings and will just do it ourselves.\n    ssize_t offset = 0;\n    std::ostringstream oss;\n    // mark the structure as unaligned with '^', because numpy and C++ don't\n    // always agree about alignment (particularly for complex), and we're\n    // explicitly listing all our padding. This depends on none of the fields\n    // overriding the endianness. Putting the ^ in front of individual fields\n    // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049\n    oss << \"^T{\";\n    for (auto &field : ordered_fields) {\n        if (field.offset > offset) {\n            oss << (field.offset - offset) << 'x';\n        }\n        oss << field.format << ':' << field.name << ':';\n        offset = field.offset + field.size;\n    }\n    if (itemsize > offset) {\n        oss << (itemsize - offset) << 'x';\n    }\n    oss << '}';\n    auto format_str = oss.str();\n\n    // Smoke test: verify that NumPy properly parses our buffer format string\n    auto &api = npy_api::get();\n    auto arr = array(buffer_info(nullptr, itemsize, format_str, 1));\n    if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) {\n        pybind11_fail(\"NumPy: invalid buffer descriptor!\");\n    }\n\n    auto tindex = std::type_index(tinfo);\n    numpy_internals.registered_dtypes[tindex] = {dtype_ptr, std::move(format_str)};\n    get_internals().direct_conversions[tindex].push_back(direct_converter);\n}\n\ntemplate <typename T, typename SFINAE>\nstruct npy_format_descriptor {\n    static_assert(is_pod_struct<T>::value,\n                  \"Attempt to use a non-POD or unimplemented POD type as a numpy dtype\");\n\n    static constexpr auto name = make_caster<T>::name;\n\n    static pybind11::dtype dtype() { return reinterpret_borrow<pybind11::dtype>(dtype_ptr()); }\n\n    static std::string format() {\n        static auto format_str = get_numpy_internals().get_type_info<T>(true)->format_str;\n        return format_str;\n    }\n\n    static void register_dtype(any_container<field_descriptor> fields) {\n        register_structured_dtype(std::move(fields),\n                                  typeid(typename std::remove_cv<T>::type),\n                                  sizeof(T),\n                                  &direct_converter);\n    }\n\nprivate:\n    static PyObject *dtype_ptr() {\n        static PyObject *ptr = get_numpy_internals().get_type_info<T>(true)->dtype_ptr;\n        return ptr;\n    }\n\n    static bool direct_converter(PyObject *obj, void *&value) {\n        auto &api = npy_api::get();\n        if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) {\n            return false;\n        }\n        if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {\n            if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {\n                value = ((PyVoidScalarObject_Proxy *) obj)->obval;\n                return true;\n            }\n        }\n        return false;\n    }\n};\n\n#ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code)\n#    define PYBIND11_NUMPY_DTYPE(Type, ...) ((void) 0)\n#    define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void) 0)\n#else\n\n#    define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name)                                          \\\n        ::pybind11::detail::field_descriptor {                                                    \\\n            Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)),                  \\\n                ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(),       \\\n                ::pybind11::detail::npy_format_descriptor<                                        \\\n                    decltype(std::declval<T>().Field)>::dtype()                                   \\\n        }\n\n// Extract name, offset and format descriptor for a struct field\n#    define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #    Field)\n\n// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro\n// (C) William Swanson, Paul Fultz\n#    define PYBIND11_EVAL0(...) __VA_ARGS__\n#    define PYBIND11_EVAL1(...) PYBIND11_EVAL0(PYBIND11_EVAL0(PYBIND11_EVAL0(__VA_ARGS__)))\n#    define PYBIND11_EVAL2(...) PYBIND11_EVAL1(PYBIND11_EVAL1(PYBIND11_EVAL1(__VA_ARGS__)))\n#    define PYBIND11_EVAL3(...) PYBIND11_EVAL2(PYBIND11_EVAL2(PYBIND11_EVAL2(__VA_ARGS__)))\n#    define PYBIND11_EVAL4(...) PYBIND11_EVAL3(PYBIND11_EVAL3(PYBIND11_EVAL3(__VA_ARGS__)))\n#    define PYBIND11_EVAL(...) PYBIND11_EVAL4(PYBIND11_EVAL4(PYBIND11_EVAL4(__VA_ARGS__)))\n#    define PYBIND11_MAP_END(...)\n#    define PYBIND11_MAP_OUT\n#    define PYBIND11_MAP_COMMA ,\n#    define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END\n#    define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT\n#    define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0(test, next, 0)\n#    define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    if defined(_MSC_VER)                                                                         \\\n        && !defined(__clang__) // MSVC is not as eager to expand macros, hence this workaround\n#        define PYBIND11_MAP_LIST_NEXT1(test, next)                                               \\\n            PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))\n#    else\n#        define PYBIND11_MAP_LIST_NEXT1(test, next)                                               \\\n            PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)\n#    endif\n#    define PYBIND11_MAP_LIST_NEXT(test, next)                                                    \\\n        PYBIND11_MAP_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    define PYBIND11_MAP_LIST0(f, t, x, peek, ...)                                                \\\n        f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST1)(f, t, peek, __VA_ARGS__)\n#    define PYBIND11_MAP_LIST1(f, t, x, peek, ...)                                                \\\n        f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST0)(f, t, peek, __VA_ARGS__)\n// PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ...\n#    define PYBIND11_MAP_LIST(f, t, ...)                                                          \\\n        PYBIND11_EVAL(PYBIND11_MAP_LIST1(f, t, __VA_ARGS__, (), 0))\n\n#    define PYBIND11_NUMPY_DTYPE(Type, ...)                                                       \\\n        ::pybind11::detail::npy_format_descriptor<Type>::register_dtype(                          \\\n            ::std::vector<::pybind11::detail::field_descriptor>{                                  \\\n                PYBIND11_MAP_LIST(PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)})\n\n#    if defined(_MSC_VER) && !defined(__clang__)\n#        define PYBIND11_MAP2_LIST_NEXT1(test, next)                                              \\\n            PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))\n#    else\n#        define PYBIND11_MAP2_LIST_NEXT1(test, next)                                              \\\n            PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)\n#    endif\n#    define PYBIND11_MAP2_LIST_NEXT(test, next)                                                   \\\n        PYBIND11_MAP2_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...)                                          \\\n        f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST1)(f, t, peek, __VA_ARGS__)\n#    define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...)                                          \\\n        f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST0)(f, t, peek, __VA_ARGS__)\n// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ...\n#    define PYBIND11_MAP2_LIST(f, t, ...)                                                         \\\n        PYBIND11_EVAL(PYBIND11_MAP2_LIST1(f, t, __VA_ARGS__, (), 0))\n\n#    define PYBIND11_NUMPY_DTYPE_EX(Type, ...)                                                    \\\n        ::pybind11::detail::npy_format_descriptor<Type>::register_dtype(                          \\\n            ::std::vector<::pybind11::detail::field_descriptor>{                                  \\\n                PYBIND11_MAP2_LIST(PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)})\n\n#endif // __CLION_IDE__\n\nclass common_iterator {\npublic:\n    using container_type = std::vector<ssize_t>;\n    using value_type = container_type::value_type;\n    using size_type = container_type::size_type;\n\n    common_iterator() : m_strides() {}\n\n    common_iterator(void *ptr, const container_type &strides, const container_type &shape)\n        : p_ptr(reinterpret_cast<char *>(ptr)), m_strides(strides.size()) {\n        m_strides.back() = static_cast<value_type>(strides.back());\n        for (size_type i = m_strides.size() - 1; i != 0; --i) {\n            size_type j = i - 1;\n            auto s = static_cast<value_type>(shape[i]);\n            m_strides[j] = strides[j] + m_strides[i] - strides[i] * s;\n        }\n    }\n\n    void increment(size_type dim) { p_ptr += m_strides[dim]; }\n\n    void *data() const { return p_ptr; }\n\nprivate:\n    char *p_ptr{nullptr};\n    container_type m_strides;\n};\n\ntemplate <size_t N>\nclass multi_array_iterator {\npublic:\n    using container_type = std::vector<ssize_t>;\n\n    multi_array_iterator(const std::array<buffer_info, N> &buffers, const container_type &shape)\n        : m_shape(shape.size()), m_index(shape.size(), 0), m_common_iterator() {\n\n        // Manual copy to avoid conversion warning if using std::copy\n        for (size_t i = 0; i < shape.size(); ++i) {\n            m_shape[i] = shape[i];\n        }\n\n        container_type strides(shape.size());\n        for (size_t i = 0; i < N; ++i) {\n            init_common_iterator(buffers[i], shape, m_common_iterator[i], strides);\n        }\n    }\n\n    multi_array_iterator &operator++() {\n        for (size_t j = m_index.size(); j != 0; --j) {\n            size_t i = j - 1;\n            if (++m_index[i] != m_shape[i]) {\n                increment_common_iterator(i);\n                break;\n            }\n            m_index[i] = 0;\n        }\n        return *this;\n    }\n\n    template <size_t K, class T = void>\n    T *data() const {\n        return reinterpret_cast<T *>(m_common_iterator[K].data());\n    }\n\nprivate:\n    using common_iter = common_iterator;\n\n    void init_common_iterator(const buffer_info &buffer,\n                              const container_type &shape,\n                              common_iter &iterator,\n                              container_type &strides) {\n        auto buffer_shape_iter = buffer.shape.rbegin();\n        auto buffer_strides_iter = buffer.strides.rbegin();\n        auto shape_iter = shape.rbegin();\n        auto strides_iter = strides.rbegin();\n\n        while (buffer_shape_iter != buffer.shape.rend()) {\n            if (*shape_iter == *buffer_shape_iter) {\n                *strides_iter = *buffer_strides_iter;\n            } else {\n                *strides_iter = 0;\n            }\n\n            ++buffer_shape_iter;\n            ++buffer_strides_iter;\n            ++shape_iter;\n            ++strides_iter;\n        }\n\n        std::fill(strides_iter, strides.rend(), 0);\n        iterator = common_iter(buffer.ptr, strides, shape);\n    }\n\n    void increment_common_iterator(size_t dim) {\n        for (auto &iter : m_common_iterator) {\n            iter.increment(dim);\n        }\n    }\n\n    container_type m_shape;\n    container_type m_index;\n    std::array<common_iter, N> m_common_iterator;\n};\n\nenum class broadcast_trivial { non_trivial, c_trivial, f_trivial };\n\n// Populates the shape and number of dimensions for the set of buffers.  Returns a\n// broadcast_trivial enum value indicating whether the broadcast is \"trivial\"--that is, has each\n// buffer being either a singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous\n// (`f_trivial`) storage buffer; returns `non_trivial` otherwise.\ntemplate <size_t N>\nbroadcast_trivial\nbroadcast(const std::array<buffer_info, N> &buffers, ssize_t &ndim, std::vector<ssize_t> &shape) {\n    ndim = std::accumulate(\n        buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) {\n            return std::max(res, buf.ndim);\n        });\n\n    shape.clear();\n    shape.resize((size_t) ndim, 1);\n\n    // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1\n    // or the full size).\n    for (size_t i = 0; i < N; ++i) {\n        auto res_iter = shape.rbegin();\n        auto end = buffers[i].shape.rend();\n        for (auto shape_iter = buffers[i].shape.rbegin(); shape_iter != end;\n             ++shape_iter, ++res_iter) {\n            const auto &dim_size_in = *shape_iter;\n            auto &dim_size_out = *res_iter;\n\n            // Each input dimension can either be 1 or `n`, but `n` values must match across\n            // buffers\n            if (dim_size_out == 1) {\n                dim_size_out = dim_size_in;\n            } else if (dim_size_in != 1 && dim_size_in != dim_size_out) {\n                pybind11_fail(\"pybind11::vectorize: incompatible size/dimension of inputs!\");\n            }\n        }\n    }\n\n    bool trivial_broadcast_c = true;\n    bool trivial_broadcast_f = true;\n    for (size_t i = 0; i < N && (trivial_broadcast_c || trivial_broadcast_f); ++i) {\n        if (buffers[i].size == 1) {\n            continue;\n        }\n\n        // Require the same number of dimensions:\n        if (buffers[i].ndim != ndim) {\n            return broadcast_trivial::non_trivial;\n        }\n\n        // Require all dimensions be full-size:\n        if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin())) {\n            return broadcast_trivial::non_trivial;\n        }\n\n        // Check for C contiguity (but only if previous inputs were also C contiguous)\n        if (trivial_broadcast_c) {\n            ssize_t expect_stride = buffers[i].itemsize;\n            auto end = buffers[i].shape.crend();\n            for (auto shape_iter = buffers[i].shape.crbegin(),\n                      stride_iter = buffers[i].strides.crbegin();\n                 trivial_broadcast_c && shape_iter != end;\n                 ++shape_iter, ++stride_iter) {\n                if (expect_stride == *stride_iter) {\n                    expect_stride *= *shape_iter;\n                } else {\n                    trivial_broadcast_c = false;\n                }\n            }\n        }\n\n        // Check for Fortran contiguity (if previous inputs were also F contiguous)\n        if (trivial_broadcast_f) {\n            ssize_t expect_stride = buffers[i].itemsize;\n            auto end = buffers[i].shape.cend();\n            for (auto shape_iter = buffers[i].shape.cbegin(),\n                      stride_iter = buffers[i].strides.cbegin();\n                 trivial_broadcast_f && shape_iter != end;\n                 ++shape_iter, ++stride_iter) {\n                if (expect_stride == *stride_iter) {\n                    expect_stride *= *shape_iter;\n                } else {\n                    trivial_broadcast_f = false;\n                }\n            }\n        }\n    }\n\n    return trivial_broadcast_c   ? broadcast_trivial::c_trivial\n           : trivial_broadcast_f ? broadcast_trivial::f_trivial\n                                 : broadcast_trivial::non_trivial;\n}\n\ntemplate <typename T>\nstruct vectorize_arg {\n    static_assert(!std::is_rvalue_reference<T>::value,\n                  \"Functions with rvalue reference arguments cannot be vectorized\");\n    // The wrapped function gets called with this type:\n    using call_type = remove_reference_t<T>;\n    // Is this a vectorized argument?\n    static constexpr bool vectorize\n        = satisfies_any_of<call_type, std::is_arithmetic, is_complex, is_pod>::value\n          && satisfies_none_of<call_type,\n                               std::is_pointer,\n                               std::is_array,\n                               is_std_array,\n                               std::is_enum>::value\n          && (!std::is_reference<T>::value\n              || (std::is_lvalue_reference<T>::value && std::is_const<call_type>::value));\n    // Accept this type: an array for vectorized types, otherwise the type as-is:\n    using type = conditional_t<vectorize, array_t<remove_cv_t<call_type>, array::forcecast>, T>;\n};\n\n// py::vectorize when a return type is present\ntemplate <typename Func, typename Return, typename... Args>\nstruct vectorize_returned_array {\n    using Type = array_t<Return>;\n\n    static Type create(broadcast_trivial trivial, const std::vector<ssize_t> &shape) {\n        if (trivial == broadcast_trivial::f_trivial) {\n            return array_t<Return, array::f_style>(shape);\n        }\n        return array_t<Return>(shape);\n    }\n\n    static Return *mutable_data(Type &array) { return array.mutable_data(); }\n\n    static Return call(Func &f, Args &...args) { return f(args...); }\n\n    static void call(Return *out, size_t i, Func &f, Args &...args) { out[i] = f(args...); }\n};\n\n// py::vectorize when a return type is not present\ntemplate <typename Func, typename... Args>\nstruct vectorize_returned_array<Func, void, Args...> {\n    using Type = none;\n\n    static Type create(broadcast_trivial, const std::vector<ssize_t> &) { return none(); }\n\n    static void *mutable_data(Type &) { return nullptr; }\n\n    static detail::void_type call(Func &f, Args &...args) {\n        f(args...);\n        return {};\n    }\n\n    static void call(void *, size_t, Func &f, Args &...args) { f(args...); }\n};\n\ntemplate <typename Func, typename Return, typename... Args>\nstruct vectorize_helper {\n\n// NVCC for some reason breaks if NVectorized is private\n#ifdef __CUDACC__\npublic:\n#else\nprivate:\n#endif\n\n    static constexpr size_t N = sizeof...(Args);\n    static constexpr size_t NVectorized = constexpr_sum(vectorize_arg<Args>::vectorize...);\n    static_assert(\n        NVectorized >= 1,\n        \"pybind11::vectorize(...) requires a function with at least one vectorizable argument\");\n\npublic:\n    template <typename T,\n              // SFINAE to prevent shadowing the copy constructor.\n              typename = detail::enable_if_t<\n                  !std::is_same<vectorize_helper, typename std::decay<T>::type>::value>>\n    explicit vectorize_helper(T &&f) : f(std::forward<T>(f)) {}\n\n    object operator()(typename vectorize_arg<Args>::type... args) {\n        return run(args...,\n                   make_index_sequence<N>(),\n                   select_indices<vectorize_arg<Args>::vectorize...>(),\n                   make_index_sequence<NVectorized>());\n    }\n\nprivate:\n    remove_reference_t<Func> f;\n\n    // Internal compiler error in MSVC 19.16.27025.1 (Visual Studio 2017 15.9.4), when compiling\n    // with \"/permissive-\" flag when arg_call_types is manually inlined.\n    using arg_call_types = std::tuple<typename vectorize_arg<Args>::call_type...>;\n    template <size_t Index>\n    using param_n_t = typename std::tuple_element<Index, arg_call_types>::type;\n\n    using returned_array = vectorize_returned_array<Func, Return, Args...>;\n\n    // Runs a vectorized function given arguments tuple and three index sequences:\n    //     - Index is the full set of 0 ... (N-1) argument indices;\n    //     - VIndex is the subset of argument indices with vectorized parameters, letting us access\n    //       vectorized arguments (anything not in this sequence is passed through)\n    //     - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that\n    //       we can store vectorized buffer_infos in an array (argument VIndex has its buffer at\n    //       index BIndex in the array).\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    object run(typename vectorize_arg<Args>::type &...args,\n               index_sequence<Index...> i_seq,\n               index_sequence<VIndex...> vi_seq,\n               index_sequence<BIndex...> bi_seq) {\n\n        // Pointers to values the function was called with; the vectorized ones set here will start\n        // out as array_t<T> pointers, but they will be changed them to T pointers before we make\n        // call the wrapped function.  Non-vectorized pointers are left as-is.\n        std::array<void *, N> params{{&args...}};\n\n        // The array of `buffer_info`s of vectorized arguments:\n        std::array<buffer_info, NVectorized> buffers{\n            {reinterpret_cast<array *>(params[VIndex])->request()...}};\n\n        /* Determine dimensions parameters of output array */\n        ssize_t nd = 0;\n        std::vector<ssize_t> shape(0);\n        auto trivial = broadcast(buffers, nd, shape);\n        auto ndim = (size_t) nd;\n\n        size_t size\n            = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>());\n\n        // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e.\n        // not wrapped in an array).\n        if (size == 1 && ndim == 0) {\n            PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr);\n            return cast(\n                returned_array::call(f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...));\n        }\n\n        auto result = returned_array::create(trivial, shape);\n#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wreturn-std-move\"\n#endif\n\n        if (size == 0) {\n            return result;\n        }\n\n        /* Call the function */\n        auto *mutable_data = returned_array::mutable_data(result);\n        if (trivial == broadcast_trivial::non_trivial) {\n            apply_broadcast(buffers, params, mutable_data, size, shape, i_seq, vi_seq, bi_seq);\n        } else {\n            apply_trivial(buffers, params, mutable_data, size, i_seq, vi_seq, bi_seq);\n        }\n\n        return result;\n#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING\n#    pragma clang diagnostic pop\n#endif\n    }\n\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    void apply_trivial(std::array<buffer_info, NVectorized> &buffers,\n                       std::array<void *, N> &params,\n                       Return *out,\n                       size_t size,\n                       index_sequence<Index...>,\n                       index_sequence<VIndex...>,\n                       index_sequence<BIndex...>) {\n\n        // Initialize an array of mutable byte references and sizes with references set to the\n        // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size\n        // (except for singletons, which get an increment of 0).\n        std::array<std::pair<unsigned char *&, const size_t>, NVectorized> vecparams{\n            {std::pair<unsigned char *&, const size_t>(\n                reinterpret_cast<unsigned char *&>(params[VIndex] = buffers[BIndex].ptr),\n                buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t<VIndex>))...}};\n\n        for (size_t i = 0; i < size; ++i) {\n            returned_array::call(\n                out, i, f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...);\n            for (auto &x : vecparams) {\n                x.first += x.second;\n            }\n        }\n    }\n\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    void apply_broadcast(std::array<buffer_info, NVectorized> &buffers,\n                         std::array<void *, N> &params,\n                         Return *out,\n                         size_t size,\n                         const std::vector<ssize_t> &output_shape,\n                         index_sequence<Index...>,\n                         index_sequence<VIndex...>,\n                         index_sequence<BIndex...>) {\n\n        multi_array_iterator<NVectorized> input_iter(buffers, output_shape);\n\n        for (size_t i = 0; i < size; ++i, ++input_iter) {\n            PYBIND11_EXPAND_SIDE_EFFECTS((params[VIndex] = input_iter.template data<BIndex>()));\n            returned_array::call(\n                out, i, f, *reinterpret_cast<param_n_t<Index> *>(std::get<Index>(params))...);\n        }\n    }\n};\n\ntemplate <typename Func, typename Return, typename... Args>\nvectorize_helper<Func, Return, Args...> vectorize_extractor(const Func &f, Return (*)(Args...)) {\n    return detail::vectorize_helper<Func, Return, Args...>(f);\n}\n\ntemplate <typename T, int Flags>\nstruct handle_type_name<array_t<T, Flags>> {\n    static constexpr auto name\n        = const_name(\"numpy.ndarray[\") + npy_format_descriptor<T>::name + const_name(\"]\");\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n// Vanilla pointer vectorizer:\ntemplate <typename Return, typename... Args>\ndetail::vectorize_helper<Return (*)(Args...), Return, Args...> vectorize(Return (*f)(Args...)) {\n    return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(f);\n}\n\n// lambda vectorizer:\ntemplate <typename Func, detail::enable_if_t<detail::is_lambda<Func>::value, int> = 0>\nauto vectorize(Func &&f)\n    -> decltype(detail::vectorize_extractor(std::forward<Func>(f),\n                                            (detail::function_signature_t<Func> *) nullptr)) {\n    return detail::vectorize_extractor(std::forward<Func>(f),\n                                       (detail::function_signature_t<Func> *) nullptr);\n}\n\n// Vectorize a class method (non-const):\ntemplate <typename Return,\n          typename Class,\n          typename... Args,\n          typename Helper = detail::vectorize_helper<\n              decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)>())),\n              Return,\n              Class *,\n              Args...>>\nHelper vectorize(Return (Class::*f)(Args...)) {\n    return Helper(std::mem_fn(f));\n}\n\n// Vectorize a class method (const):\ntemplate <typename Return,\n          typename Class,\n          typename... Args,\n          typename Helper = detail::vectorize_helper<\n              decltype(std::mem_fn(std::declval<Return (Class::*)(Args...) const>())),\n              Return,\n              const Class *,\n              Args...>>\nHelper vectorize(Return (Class::*f)(Args...) const) {\n    return Helper(std::mem_fn(f));\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/operators.h",
    "content": "/*\n    pybind11/operator.h: Metatemplates for operator overloading\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Enumeration with all supported operator types\nenum op_id : int {\n    op_add,\n    op_sub,\n    op_mul,\n    op_div,\n    op_mod,\n    op_divmod,\n    op_pow,\n    op_lshift,\n    op_rshift,\n    op_and,\n    op_xor,\n    op_or,\n    op_neg,\n    op_pos,\n    op_abs,\n    op_invert,\n    op_int,\n    op_long,\n    op_float,\n    op_str,\n    op_cmp,\n    op_gt,\n    op_ge,\n    op_lt,\n    op_le,\n    op_eq,\n    op_ne,\n    op_iadd,\n    op_isub,\n    op_imul,\n    op_idiv,\n    op_imod,\n    op_ilshift,\n    op_irshift,\n    op_iand,\n    op_ixor,\n    op_ior,\n    op_complex,\n    op_bool,\n    op_nonzero,\n    op_repr,\n    op_truediv,\n    op_itruediv,\n    op_hash\n};\n\nenum op_type : int {\n    op_l, /* base type on left */\n    op_r, /* base type on right */\n    op_u  /* unary operator */\n};\n\nstruct self_t {};\nstatic const self_t self = self_t();\n\n/// Type for an unused type slot\nstruct undefined_t {};\n\n/// Don't warn about an unused variable\ninline self_t __self() { return self; }\n\n/// base template of operator implementations\ntemplate <op_id, op_type, typename B, typename L, typename R>\nstruct op_impl {};\n\n/// Operator implementation generator\ntemplate <op_id id, op_type ot, typename L, typename R>\nstruct op_ {\n    static constexpr bool op_enable_if_hook = true;\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) const {\n        using Base = typename Class::type;\n        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;\n        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;\n        using op = op_impl<id, ot, Base, L_type, R_type>;\n        cl.def(op::name(), &op::execute, is_operator(), extra...);\n    }\n    template <typename Class, typename... Extra>\n    void execute_cast(Class &cl, const Extra &...extra) const {\n        using Base = typename Class::type;\n        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;\n        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;\n        using op = op_impl<id, ot, Base, L_type, R_type>;\n        cl.def(op::name(), &op::execute_cast, is_operator(), extra...);\n    }\n};\n\n#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr)                                               \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_l, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); }          \\\n        static B execute_cast(const L &l, const R &r) { return B(expr); }                         \\\n    };                                                                                            \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_r, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #rid \"__\"; }                                      \\\n        static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); }          \\\n        static B execute_cast(const R &r, const L &l) { return B(expr); }                         \\\n    };                                                                                            \\\n    inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) {                \\\n        return op_<op_##id, op_l, self_t, self_t>();                                              \\\n    }                                                                                             \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \\\n        return op_<op_##id, op_l, self_t, T>();                                                   \\\n    }                                                                                             \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) {                                 \\\n        return op_<op_##id, op_r, T, self_t>();                                                   \\\n    }\n\n#define PYBIND11_INPLACE_OPERATOR(id, op, expr)                                                   \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_l, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(L &l, const R &r) -> decltype(expr) { return expr; }                  \\\n        static B execute_cast(L &l, const R &r) { return B(expr); }                               \\\n    };                                                                                            \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \\\n        return op_<op_##id, op_l, self_t, T>();                                                   \\\n    }\n\n#define PYBIND11_UNARY_OPERATOR(id, op, expr)                                                     \\\n    template <typename B, typename L>                                                             \\\n    struct op_impl<op_##id, op_u, B, L, undefined_t> {                                            \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(const L &l) -> decltype(expr) { return expr; }                        \\\n        static B execute_cast(const L &l) { return B(expr); }                                     \\\n    };                                                                                            \\\n    inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) {                           \\\n        return op_<op_##id, op_u, self_t, undefined_t>();                                         \\\n    }\n\nPYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)\nPYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)\nPYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)\nPYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)\nPYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)\nPYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)\nPYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)\nPYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)\nPYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)\nPYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)\nPYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)\nPYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)\nPYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)\nPYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)\nPYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)\nPYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)\n// PYBIND11_BINARY_OPERATOR(pow,       rpow,         pow,          std::pow(l,  r))\nPYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)\nPYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)\nPYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)\nPYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)\nPYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)\nPYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)\nPYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)\nPYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)\nPYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)\nPYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)\nPYBIND11_UNARY_OPERATOR(neg, operator-, -l)\nPYBIND11_UNARY_OPERATOR(pos, operator+, +l)\n// WARNING: This usage of `abs` should only be done for existing STL overloads.\n// Adding overloads directly in to the `std::` namespace is advised against:\n// https://en.cppreference.com/w/cpp/language/extending_std\nPYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))\nPYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))\nPYBIND11_UNARY_OPERATOR(invert, operator~, (~l))\nPYBIND11_UNARY_OPERATOR(bool, operator!, !!l)\nPYBIND11_UNARY_OPERATOR(int, int_, (int) l)\nPYBIND11_UNARY_OPERATOR(float, float_, (double) l)\n\n#undef PYBIND11_BINARY_OPERATOR\n#undef PYBIND11_INPLACE_OPERATOR\n#undef PYBIND11_UNARY_OPERATOR\nPYBIND11_NAMESPACE_END(detail)\n\nusing detail::self;\n// Add named operators so that they are accessible via `py::`.\nusing detail::hash;\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/options.h",
    "content": "/*\n    pybind11/options.h: global settings that are configurable at runtime.\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nclass options {\npublic:\n    // Default RAII constructor, which leaves settings as they currently are.\n    options() : previous_state(global_state()) {}\n\n    // Class is non-copyable.\n    options(const options &) = delete;\n    options &operator=(const options &) = delete;\n\n    // Destructor, which restores settings that were in effect before.\n    ~options() { global_state() = previous_state; }\n\n    // Setter methods (affect the global state):\n\n    options &disable_user_defined_docstrings() & {\n        global_state().show_user_defined_docstrings = false;\n        return *this;\n    }\n\n    options &enable_user_defined_docstrings() & {\n        global_state().show_user_defined_docstrings = true;\n        return *this;\n    }\n\n    options &disable_function_signatures() & {\n        global_state().show_function_signatures = false;\n        return *this;\n    }\n\n    options &enable_function_signatures() & {\n        global_state().show_function_signatures = true;\n        return *this;\n    }\n\n    options& disable_enum_members_docstring() & { global_state().show_enum_members_docstring = false; return *this; }\n\n    options& enable_enum_members_docstring() & { global_state().show_enum_members_docstring = true; return *this; }\n\n    // Getter methods (return the global state):\n\n    static bool show_user_defined_docstrings() {\n        return global_state().show_user_defined_docstrings;\n    }\n\n    static bool show_function_signatures() { return global_state().show_function_signatures; }\n\n    static bool show_enum_members_docstring() { return global_state().show_enum_members_docstring; }\n\n    // This type is not meant to be allocated on the heap.\n    void *operator new(size_t) = delete;\n\nprivate:\n    struct state {\n        bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.\n        bool show_function_signatures = true;     //< Include auto-generated function signatures\n                                                  //  in docstrings.\n        bool show_enum_members_docstring = true;  //< Include auto-generated member list in enum\n                                                  //  docstrings.\n    };\n\n    static state &global_state() {\n        static state instance;\n        return instance;\n    }\n\n    state previous_state;\n};\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/pybind11.h",
    "content": "/*\n    pybind11/pybind11.h: Main header file of the C++11 python\n    binding generator library\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/class.h\"\n#include \"detail/init.h\"\n#include \"attr.h\"\n#include \"gil.h\"\n#include \"options.h\"\n\n#include <cstdlib>\n#include <cstring>\n#include <memory>\n#include <new>\n#include <string>\n#include <utility>\n#include <vector>\n\n#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))\n#    define PYBIND11_STD_LAUNDER std::launder\n#    define PYBIND11_HAS_STD_LAUNDER 1\n#else\n#    define PYBIND11_STD_LAUNDER\n#    define PYBIND11_HAS_STD_LAUNDER 0\n#endif\n#if defined(__GNUG__) && !defined(__clang__)\n#    include <cxxabi.h>\n#endif\n\n/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning\n   This warning is about ABI compatibility, not code health.\n   It is only actually needed in a couple places, but apparently GCC 7 \"generates this warning if\n   and only if the first template instantiation ... involves noexcept\" [stackoverflow], therefore\n   it could get triggered from seemingly random places, depending on user code.\n   No other GCC version generates this warning.\n */\n#if defined(__GNUC__) && __GNUC__ == 7\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wnoexcept-type\"\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Apply all the extensions translators from a list\n// Return true if one of the translators completed without raising an exception\n// itself. Return of false indicates that if there are other translators\n// available, they should be tried.\ninline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {\n    auto last_exception = std::current_exception();\n\n    for (auto &translator : translators) {\n        try {\n            translator(last_exception);\n            return true;\n        } catch (...) {\n            last_exception = std::current_exception();\n        }\n    }\n    return false;\n}\n\n#if defined(_MSC_VER)\n#    define PYBIND11_COMPAT_STRDUP _strdup\n#else\n#    define PYBIND11_COMPAT_STRDUP strdup\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object\nclass cpp_function : public function {\npublic:\n    cpp_function() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(std::nullptr_t) {}\n\n    /// Construct a cpp_function from a vanilla function pointer\n    template <typename Return, typename... Args, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (*f)(Args...), const Extra &...extra) {\n        initialize(f, f, extra...);\n    }\n\n    /// Construct a cpp_function from a lambda function (possibly with internal state)\n    template <typename Func,\n              typename... Extra,\n              typename = detail::enable_if_t<detail::is_lambda<Func>::value>>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Func &&f, const Extra &...extra) {\n        initialize(\n            std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...);\n    }\n\n    /// Construct a cpp_function from a class method (non-const, no ref-qualifier)\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) {\n        initialize(\n            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n            (Return(*)(Class *, Arg...)) nullptr,\n            extra...);\n    }\n\n    /// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier)\n    /// A copy of the overload for non-const functions without explicit ref-qualifier\n    /// but with an added `&`.\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) {\n        initialize(\n            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n            (Return(*)(Class *, Arg...)) nullptr,\n            extra...);\n    }\n\n    /// Construct a cpp_function from a class method (const, no ref-qualifier)\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) {\n        initialize([f](const Class *c,\n                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n                   (Return(*)(const Class *, Arg...)) nullptr,\n                   extra...);\n    }\n\n    /// Construct a cpp_function from a class method (const, lvalue ref-qualifier)\n    /// A copy of the overload for const functions without explicit ref-qualifier\n    /// but with an added `&`.\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) const &, const Extra &...extra) {\n        initialize([f](const Class *c,\n                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n                   (Return(*)(const Class *, Arg...)) nullptr,\n                   extra...);\n    }\n\n    /// Return the function name\n    object name() const { return attr(\"__name__\"); }\n\nprotected:\n    struct InitializingFunctionRecordDeleter {\n        // `destruct(function_record, false)`: `initialize_generic` copies strings and\n        // takes care of cleaning up in case of exceptions. So pass `false` to `free_strings`.\n        void operator()(detail::function_record *rec) { destruct(rec, false); }\n    };\n    using unique_function_record\n        = std::unique_ptr<detail::function_record, InitializingFunctionRecordDeleter>;\n\n    /// Space optimization: don't inline this frequently instantiated fragment\n    PYBIND11_NOINLINE unique_function_record make_function_record() {\n        return unique_function_record(new detail::function_record());\n    }\n\n    /// Special internal constructor for functors, lambda functions, etc.\n    template <typename Func, typename Return, typename... Args, typename... Extra>\n    void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {\n        using namespace detail;\n        struct capture {\n            remove_reference_t<Func> f;\n        };\n\n        /* Store the function including any extra state it might have (e.g. a lambda capture\n         * object) */\n        // The unique_ptr makes sure nothing is leaked in case of an exception.\n        auto unique_rec = make_function_record();\n        auto *rec = unique_rec.get();\n\n        /* Store the capture object directly in the function record if there is enough space */\n        if (PYBIND11_SILENCE_MSVC_C4127(sizeof(capture) <= sizeof(rec->data))) {\n            /* Without these pragmas, GCC warns that there might not be\n               enough space to use the placement new operator. However, the\n               'if' statement above ensures that this is the case. */\n#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wplacement-new\"\n#endif\n            new ((capture *) &rec->data) capture{std::forward<Func>(f)};\n#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n#endif\n            // UB without std::launder, but without breaking ABI and/or\n            // a significant refactoring it's \"impossible\" to solve.\n            if (!std::is_trivially_destructible<capture>::value) {\n                rec->free_data = [](function_record *r) {\n                    auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);\n                    (void) data;\n                    data->~capture();\n                };\n            }\n#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n        } else {\n            rec->data[0] = new capture{std::forward<Func>(f)};\n            rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };\n        }\n\n        /* Type casters for the function arguments and return value */\n        using cast_in = argument_loader<Args...>;\n        using cast_out\n            = make_caster<conditional_t<std::is_void<Return>::value, void_type, Return>>;\n\n        static_assert(\n            expected_num_args<Extra...>(\n                sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),\n            \"The number of argument annotations does not match the number of function arguments\");\n\n        /* Dispatch code which converts function arguments and performs the actual function call */\n        rec->impl = [](function_call &call) -> handle {\n            cast_in args_converter;\n\n            /* Try to cast the function arguments into the C++ domain */\n            if (!args_converter.load_args(call)) {\n                return PYBIND11_TRY_NEXT_OVERLOAD;\n            }\n\n            /* Invoke call policy pre-call hook */\n            process_attributes<Extra...>::precall(call);\n\n            /* Get a pointer to the capture object */\n            const auto *data = (sizeof(capture) <= sizeof(call.func.data) ? &call.func.data\n                                                                          : call.func.data[0]);\n            auto *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));\n\n            /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */\n            return_value_policy policy\n                = return_value_policy_override<Return>::policy(call.func.policy);\n\n            /* Function scope guard -- defaults to the compile-to-nothing `void_type` */\n            using Guard = extract_guard_t<Extra...>;\n\n            /* Perform the function call */\n            handle result\n                = cast_out::cast(std::move(args_converter).template call<Return, Guard>(cap->f),\n                                 policy,\n                                 call.parent);\n\n            /* Invoke call policy post-call hook */\n            process_attributes<Extra...>::postcall(call, result);\n\n            return result;\n        };\n\n        rec->nargs_pos = cast_in::args_pos >= 0\n                             ? static_cast<std::uint16_t>(cast_in::args_pos)\n                             : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if\n                                                                      // we have a kw_only\n        rec->has_args = cast_in::args_pos >= 0;\n        rec->has_kwargs = cast_in::has_kwargs;\n\n        /* Process any user-provided function attributes */\n        process_attributes<Extra...>::init(extra..., rec);\n\n        {\n            constexpr bool has_kw_only_args = any_of<std::is_same<kw_only, Extra>...>::value,\n                           has_pos_only_args = any_of<std::is_same<pos_only, Extra>...>::value,\n                           has_arg_annotations = any_of<is_keyword<Extra>...>::value;\n            static_assert(has_arg_annotations || !has_kw_only_args,\n                          \"py::kw_only requires the use of argument annotations\");\n            static_assert(has_arg_annotations || !has_pos_only_args,\n                          \"py::pos_only requires the use of argument annotations (for docstrings \"\n                          \"and aligning the annotations to the argument)\");\n\n            static_assert(constexpr_sum(is_kw_only<Extra>::value...) <= 1,\n                          \"py::kw_only may be specified only once\");\n            static_assert(constexpr_sum(is_pos_only<Extra>::value...) <= 1,\n                          \"py::pos_only may be specified only once\");\n            constexpr auto kw_only_pos = constexpr_first<is_kw_only, Extra...>();\n            constexpr auto pos_only_pos = constexpr_first<is_pos_only, Extra...>();\n            static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos,\n                          \"py::pos_only must come before py::kw_only\");\n        }\n\n        /* Generate a readable signature describing the function's arguments and return\n           value types */\n        static constexpr auto signature\n            = const_name(\"(\") + cast_in::arg_names + const_name(\") -> \") + cast_out::name;\n        PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();\n\n        /* Register the function with Python from generic (non-templated) code */\n        // Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.\n        initialize_generic(std::move(unique_rec), signature.text, types.data(), sizeof...(Args));\n\n        /* Stash some additional information used by an important optimization in 'functional.h' */\n        using FunctionType = Return (*)(Args...);\n        constexpr bool is_function_ptr\n            = std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);\n        if (is_function_ptr) {\n            rec->is_stateless = true;\n            rec->data[1]\n                = const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));\n        }\n    }\n\n    // Utility class that keeps track of all duplicated strings, and cleans them up in its\n    // destructor, unless they are released. Basically a RAII-solution to deal with exceptions\n    // along the way.\n    class strdup_guard {\n    public:\n        strdup_guard() = default;\n        strdup_guard(const strdup_guard &) = delete;\n        strdup_guard &operator=(const strdup_guard &) = delete;\n\n        ~strdup_guard() {\n            for (auto *s : strings) {\n                std::free(s);\n            }\n        }\n        char *operator()(const char *s) {\n            auto *t = PYBIND11_COMPAT_STRDUP(s);\n            strings.push_back(t);\n            return t;\n        }\n        void release() { strings.clear(); }\n\n    private:\n        std::vector<char *> strings;\n    };\n\n    /// Register a function call with Python (generic non-templated code goes here)\n    void initialize_generic(unique_function_record &&unique_rec,\n                            const char *text,\n                            const std::type_info *const *types,\n                            size_t args) {\n        // Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr,\n        // we do not want this to destruct the pointer. `initialize` (the caller) still relies on\n        // the pointee being alive after this call. Only move out if a `capsule` is going to keep\n        // it alive.\n        auto *rec = unique_rec.get();\n\n        // Keep track of strdup'ed strings, and clean them up as long as the function's capsule\n        // has not taken ownership yet (when `unique_rec.release()` is called).\n        // Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the\n        // strings are only referenced before strdup'ing. So only *after* the following block could\n        // `destruct` safely be called, but even then, `repr` could still throw in the middle of\n        // copying all strings.\n        strdup_guard guarded_strdup;\n\n        /* Create copies of all referenced C-style strings */\n        rec->name = guarded_strdup(rec->name ? rec->name : \"\");\n        if (rec->doc) {\n            rec->doc = guarded_strdup(rec->doc);\n        }\n        for (auto &a : rec->args) {\n            if (a.name) {\n                a.name = guarded_strdup(a.name);\n            }\n            if (a.descr) {\n                a.descr = guarded_strdup(a.descr);\n            } else if (a.value) {\n                a.descr = guarded_strdup(repr(a.value).cast<std::string>().c_str());\n            }\n        }\n\n        rec->is_constructor = (std::strcmp(rec->name, \"__init__\") == 0)\n                              || (std::strcmp(rec->name, \"__setstate__\") == 0);\n\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)\n        if (rec->is_constructor && !rec->is_new_style_constructor) {\n            const auto class_name\n                = detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());\n            const auto func_name = std::string(rec->name);\n            PyErr_WarnEx(PyExc_FutureWarning,\n                         (\"pybind11-bound class '\" + class_name\n                          + \"' is using an old-style \"\n                            \"placement-new '\"\n                          + func_name\n                          + \"' which has been deprecated. See \"\n                            \"the upgrade guide in pybind11's docs. This message is only visible \"\n                            \"when compiled in debug mode.\")\n                             .c_str(),\n                         0);\n        }\n#endif\n\n        /* Generate a proper function signature */\n        std::string signature;\n        size_t type_index = 0, arg_index = 0;\n        bool is_starred = false;\n        for (const auto *pc = text; *pc != '\\0'; ++pc) {\n            const auto c = *pc;\n\n            if (c == '{') {\n                // Write arg name for everything except *args and **kwargs.\n                is_starred = *(pc + 1) == '*';\n                if (is_starred) {\n                    continue;\n                }\n                // Separator for keyword-only arguments, placed before the kw\n                // arguments start (unless we are already putting an *args)\n                if (!rec->has_args && arg_index == rec->nargs_pos) {\n                    signature += \"*, \";\n                }\n                if (arg_index < rec->args.size() && rec->args[arg_index].name) {\n                    signature += rec->args[arg_index].name;\n                } else if (arg_index == 0 && rec->is_method) {\n                    signature += \"self\";\n                } else {\n                    signature += \"arg\" + std::to_string(arg_index - (rec->is_method ? 1 : 0));\n                }\n                signature += \": \";\n            } else if (c == '}') {\n                // Write default value if available.\n                if (!is_starred && arg_index < rec->args.size() && rec->args[arg_index].descr) {\n                    signature += \" = \";\n                    signature += rec->args[arg_index].descr;\n                }\n                // Separator for positional-only arguments (placed after the\n                // argument, rather than before like *\n                if (rec->nargs_pos_only > 0 && (arg_index + 1) == rec->nargs_pos_only) {\n                    signature += \", /\";\n                }\n                if (!is_starred) {\n                    arg_index++;\n                }\n            } else if (c == '%') {\n                const std::type_info *t = types[type_index++];\n                if (!t) {\n                    pybind11_fail(\"Internal error while parsing type signature (1)\");\n                }\n                if (auto *tinfo = detail::get_type_info(*t)) {\n                    handle th((PyObject *) tinfo->type);\n                    signature += th.attr(\"__module__\").cast<std::string>() + \".\"\n                                 + th.attr(\"__qualname__\").cast<std::string>();\n                } else if (rec->is_new_style_constructor && arg_index == 0) {\n                    // A new-style `__init__` takes `self` as `value_and_holder`.\n                    // Rewrite it to the proper class type.\n                    signature += rec->scope.attr(\"__module__\").cast<std::string>() + \".\"\n                                 + rec->scope.attr(\"__qualname__\").cast<std::string>();\n                } else {\n                    std::string tname(t->name());\n                    detail::clean_type_id(tname);\n                    signature += tname;\n                }\n            } else {\n                signature += c;\n            }\n        }\n\n        if (arg_index != args - rec->has_args - rec->has_kwargs || types[type_index] != nullptr) {\n            pybind11_fail(\"Internal error while parsing type signature (2)\");\n        }\n\n        rec->signature = guarded_strdup(signature.c_str());\n        rec->args.shrink_to_fit();\n        rec->nargs = (std::uint16_t) args;\n\n        if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) {\n            rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr());\n        }\n\n        detail::function_record *chain = nullptr, *chain_start = rec;\n        if (rec->sibling) {\n            if (PyCFunction_Check(rec->sibling.ptr())) {\n                auto *self = PyCFunction_GET_SELF(rec->sibling.ptr());\n                if (!isinstance<capsule>(self)) {\n                    chain = nullptr;\n                } else {\n                    auto rec_capsule = reinterpret_borrow<capsule>(self);\n                    if (detail::is_function_record_capsule(rec_capsule)) {\n                        chain = rec_capsule.get_pointer<detail::function_record>();\n                        /* Never append a method to an overload chain of a parent class;\n                           instead, hide the parent's overloads in this case */\n                        if (!chain->scope.is(rec->scope)) {\n                            chain = nullptr;\n                        }\n                    } else {\n                        chain = nullptr;\n                    }\n                }\n            }\n            // Don't trigger for things like the default __init__, which are wrapper_descriptors\n            // that we are intentionally replacing\n            else if (!rec->sibling.is_none() && rec->name[0] != '_') {\n                pybind11_fail(\"Cannot overload existing non-function object \\\"\"\n                              + std::string(rec->name) + \"\\\" with a function of the same name\");\n            }\n        }\n\n        if (!chain) {\n            /* No existing overload was found, create a new function object */\n            rec->def = new PyMethodDef();\n            std::memset(rec->def, 0, sizeof(PyMethodDef));\n            rec->def->ml_name = rec->name;\n            rec->def->ml_meth\n                = reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(dispatcher));\n            rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;\n\n            capsule rec_capsule(unique_rec.release(),\n                                [](void *ptr) { destruct((detail::function_record *) ptr); });\n            rec_capsule.set_name(detail::get_function_record_capsule_name());\n            guarded_strdup.release();\n\n            object scope_module;\n            if (rec->scope) {\n                if (hasattr(rec->scope, \"__module__\")) {\n                    scope_module = rec->scope.attr(\"__module__\");\n                } else if (hasattr(rec->scope, \"__name__\")) {\n                    scope_module = rec->scope.attr(\"__name__\");\n                }\n            }\n\n            m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr());\n            if (!m_ptr) {\n                pybind11_fail(\"cpp_function::cpp_function(): Could not allocate function object\");\n            }\n        } else {\n            /* Append at the beginning or end of the overload chain */\n            m_ptr = rec->sibling.ptr();\n            inc_ref();\n            if (chain->is_method != rec->is_method) {\n                pybind11_fail(\n                    \"overloading a method with both static and instance methods is not supported; \"\n#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                    \"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more \"\n                    \"details\"\n#else\n                    \"error while attempting to bind \"\n                    + std::string(rec->is_method ? \"instance\" : \"static\") + \" method \"\n                    + std::string(pybind11::str(rec->scope.attr(\"__name__\"))) + \".\"\n                    + std::string(rec->name) + signature\n#endif\n                );\n            }\n\n            if (rec->prepend) {\n                // Beginning of chain; we need to replace the capsule's current head-of-the-chain\n                // pointer with this one, then make this one point to the previous head of the\n                // chain.\n                chain_start = rec;\n                rec->next = chain;\n                auto rec_capsule\n                    = reinterpret_borrow<capsule>(((PyCFunctionObject *) m_ptr)->m_self);\n                rec_capsule.set_pointer(unique_rec.release());\n                guarded_strdup.release();\n            } else {\n                // Or end of chain (normal behavior)\n                chain_start = chain;\n                while (chain->next) {\n                    chain = chain->next;\n                }\n                chain->next = unique_rec.release();\n                guarded_strdup.release();\n            }\n        }\n\n        std::string signatures;\n        int index = 0;\n        /* Create a nice pydoc rec including all signatures and\n           docstrings of the functions in the overload chain */\n        if (chain && options::show_function_signatures()) {\n            // First a generic signature\n            signatures += rec->name;\n            signatures += \"(*args, **kwargs)\\n\";\n            signatures += \"Overloaded function.\\n\\n\";\n        }\n        // Then specific overload signatures\n        bool first_user_def = true;\n        for (auto *it = chain_start; it != nullptr; it = it->next) {\n            if (options::show_function_signatures()) {\n                if (index > 0) {\n                    signatures += '\\n';\n                }\n                if (chain) {\n                    signatures += std::to_string(++index) + \". \";\n                }\n                signatures += rec->name;\n                signatures += it->signature;\n                signatures += '\\n';\n            }\n            if (it->doc && it->doc[0] != '\\0' && options::show_user_defined_docstrings()) {\n                // If we're appending another docstring, and aren't printing function signatures,\n                // we need to append a newline first:\n                if (!options::show_function_signatures()) {\n                    if (first_user_def) {\n                        first_user_def = false;\n                    } else {\n                        signatures += '\\n';\n                    }\n                }\n                if (options::show_function_signatures()) {\n                    signatures += '\\n';\n                }\n                signatures += it->doc;\n                if (options::show_function_signatures()) {\n                    signatures += '\\n';\n                }\n            }\n        }\n\n        /* Install docstring */\n        auto *func = (PyCFunctionObject *) m_ptr;\n        std::free(const_cast<char *>(func->m_ml->ml_doc));\n        // Install docstring if it's non-empty (when at least one option is enabled)\n        func->m_ml->ml_doc\n            = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());\n\n        if (rec->is_method) {\n            m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr());\n            if (!m_ptr) {\n                pybind11_fail(\n                    \"cpp_function::cpp_function(): Could not allocate instance method object\");\n            }\n            Py_DECREF(func);\n        }\n    }\n\n    /// When a cpp_function is GCed, release any memory allocated by pybind11\n    static void destruct(detail::function_record *rec, bool free_strings = true) {\n// If on Python 3.9, check the interpreter \"MICRO\" (patch) version.\n// If this is running on 3.9.0, we have to work around a bug.\n#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9\n        static bool is_zero = Py_GetVersion()[4] == '0';\n#endif\n\n        while (rec) {\n            detail::function_record *next = rec->next;\n            if (rec->free_data) {\n                rec->free_data(rec);\n            }\n            // During initialization, these strings might not have been copied yet,\n            // so they cannot be freed. Once the function has been created, they can.\n            // Check `make_function_record` for more details.\n            if (free_strings) {\n                std::free((char *) rec->name);\n                std::free((char *) rec->doc);\n                std::free((char *) rec->signature);\n                for (auto &arg : rec->args) {\n                    std::free(const_cast<char *>(arg.name));\n                    std::free(const_cast<char *>(arg.descr));\n                }\n            }\n            for (auto &arg : rec->args) {\n                arg.value.dec_ref();\n            }\n            if (rec->def) {\n                std::free(const_cast<char *>(rec->def->ml_doc));\n// Python 3.9.0 decref's these in the wrong order; rec->def\n// If loaded on 3.9.0, let these leak (use Python 3.9.1 at runtime to fix)\n// See https://github.com/python/cpython/pull/22670\n#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9\n                if (!is_zero) {\n                    delete rec->def;\n                }\n#else\n                delete rec->def;\n#endif\n            }\n            delete rec;\n            rec = next;\n        }\n    }\n\n    /// Main dispatch logic for calls to functions bound using pybind11\n    static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) {\n        using namespace detail;\n        assert(isinstance<capsule>(self));\n\n        /* Iterator over the list of potentially admissible overloads */\n        const function_record *overloads = reinterpret_cast<function_record *>(\n                                  PyCapsule_GetPointer(self, get_function_record_capsule_name())),\n                              *it = overloads;\n        assert(overloads != nullptr);\n\n        /* Need to know how many arguments + keyword arguments there are to pick the right\n           overload */\n        const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in);\n\n        handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,\n               result = PYBIND11_TRY_NEXT_OVERLOAD;\n\n        auto self_value_and_holder = value_and_holder();\n        if (overloads->is_constructor) {\n            if (!parent\n                || !PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {\n                PyErr_SetString(\n                    PyExc_TypeError,\n                    \"__init__(self, ...) called with invalid or missing `self` argument\");\n                return nullptr;\n            }\n\n            auto *const tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr());\n            auto *const pi = reinterpret_cast<instance *>(parent.ptr());\n            self_value_and_holder = pi->get_value_and_holder(tinfo, true);\n\n            // If this value is already registered it must mean __init__ is invoked multiple times;\n            // we really can't support that in C++, so just ignore the second __init__.\n            if (self_value_and_holder.instance_registered()) {\n                return none().release().ptr();\n            }\n        }\n\n        try {\n            // We do this in two passes: in the first pass, we load arguments with `convert=false`;\n            // in the second, we allow conversion (except for arguments with an explicit\n            // py::arg().noconvert()).  This lets us prefer calls without conversion, with\n            // conversion as a fallback.\n            std::vector<function_call> second_pass;\n\n            // However, if there are no overloads, we can just skip the no-convert pass entirely\n            const bool overloaded = it != nullptr && it->next != nullptr;\n\n            for (; it != nullptr; it = it->next) {\n\n                /* For each overload:\n                   1. Copy all positional arguments we were given, also checking to make sure that\n                      named positional arguments weren't *also* specified via kwarg.\n                   2. If we weren't given enough, try to make up the omitted ones by checking\n                      whether they were provided by a kwarg matching the `py::arg(\"name\")` name. If\n                      so, use it (and remove it from kwargs); if not, see if the function binding\n                      provided a default that we can use.\n                   3. Ensure that either all keyword arguments were \"consumed\", or that the\n                   function takes a kwargs argument to accept unconsumed kwargs.\n                   4. Any positional arguments still left get put into a tuple (for args), and any\n                      leftover kwargs get put into a dict.\n                   5. Pack everything into a vector; if we have py::args or py::kwargs, they are an\n                      extra tuple or dict at the end of the positional arguments.\n                   6. Call the function call dispatcher (function_record::impl)\n\n                   If one of these fail, move on to the next overload and keep trying until we get\n                   a result other than PYBIND11_TRY_NEXT_OVERLOAD.\n                 */\n\n                const function_record &func = *it;\n                size_t num_args = func.nargs; // Number of positional arguments that we need\n                if (func.has_args) {\n                    --num_args; // (but don't count py::args\n                }\n                if (func.has_kwargs) {\n                    --num_args; //  or py::kwargs)\n                }\n                size_t pos_args = func.nargs_pos;\n\n                if (!func.has_args && n_args_in > pos_args) {\n                    continue; // Too many positional arguments for this overload\n                }\n\n                if (n_args_in < pos_args && func.args.size() < pos_args) {\n                    continue; // Not enough positional arguments given, and not enough defaults to\n                              // fill in the blanks\n                }\n\n                function_call call(func, parent);\n\n                // Protect std::min with parentheses\n                size_t args_to_copy = (std::min)(pos_args, n_args_in);\n                size_t args_copied = 0;\n\n                // 0. Inject new-style `self` argument\n                if (func.is_new_style_constructor) {\n                    // The `value` may have been preallocated by an old-style `__init__`\n                    // if it was a preceding candidate for overload resolution.\n                    if (self_value_and_holder) {\n                        self_value_and_holder.type->dealloc(self_value_and_holder);\n                    }\n\n                    call.init_self = PyTuple_GET_ITEM(args_in, 0);\n                    call.args.emplace_back(reinterpret_cast<PyObject *>(&self_value_and_holder));\n                    call.args_convert.push_back(false);\n                    ++args_copied;\n                }\n\n                // 1. Copy any position arguments given.\n                bool bad_arg = false;\n                for (; args_copied < args_to_copy; ++args_copied) {\n                    const argument_record *arg_rec\n                        = args_copied < func.args.size() ? &func.args[args_copied] : nullptr;\n                    if (kwargs_in && arg_rec && arg_rec->name\n                        && dict_getitemstring(kwargs_in, arg_rec->name)) {\n                        bad_arg = true;\n                        break;\n                    }\n\n                    handle arg(PyTuple_GET_ITEM(args_in, args_copied));\n                    if (arg_rec && !arg_rec->none && arg.is_none()) {\n                        bad_arg = true;\n                        break;\n                    }\n                    call.args.push_back(arg);\n                    call.args_convert.push_back(arg_rec ? arg_rec->convert : true);\n                }\n                if (bad_arg) {\n                    continue; // Maybe it was meant for another overload (issue #688)\n                }\n\n                // Keep track of how many position args we copied out in case we need to come back\n                // to copy the rest into a py::args argument.\n                size_t positional_args_copied = args_copied;\n\n                // We'll need to copy this if we steal some kwargs for defaults\n                dict kwargs = reinterpret_borrow<dict>(kwargs_in);\n\n                // 1.5. Fill in any missing pos_only args from defaults if they exist\n                if (args_copied < func.nargs_pos_only) {\n                    for (; args_copied < func.nargs_pos_only; ++args_copied) {\n                        const auto &arg_rec = func.args[args_copied];\n                        handle value;\n\n                        if (arg_rec.value) {\n                            value = arg_rec.value;\n                        }\n                        if (value) {\n                            call.args.push_back(value);\n                            call.args_convert.push_back(arg_rec.convert);\n                        } else {\n                            break;\n                        }\n                    }\n\n                    if (args_copied < func.nargs_pos_only) {\n                        continue; // Not enough defaults to fill the positional arguments\n                    }\n                }\n\n                // 2. Check kwargs and, failing that, defaults that may help complete the list\n                if (args_copied < num_args) {\n                    bool copied_kwargs = false;\n\n                    for (; args_copied < num_args; ++args_copied) {\n                        const auto &arg_rec = func.args[args_copied];\n\n                        handle value;\n                        if (kwargs_in && arg_rec.name) {\n                            value = dict_getitemstring(kwargs.ptr(), arg_rec.name);\n                        }\n\n                        if (value) {\n                            // Consume a kwargs value\n                            if (!copied_kwargs) {\n                                kwargs = reinterpret_steal<dict>(PyDict_Copy(kwargs.ptr()));\n                                copied_kwargs = true;\n                            }\n                            if (PyDict_DelItemString(kwargs.ptr(), arg_rec.name) == -1) {\n                                throw error_already_set();\n                            }\n                        } else if (arg_rec.value) {\n                            value = arg_rec.value;\n                        }\n\n                        if (!arg_rec.none && value.is_none()) {\n                            break;\n                        }\n\n                        if (value) {\n                            // If we're at the py::args index then first insert a stub for it to be\n                            // replaced later\n                            if (func.has_args && call.args.size() == func.nargs_pos) {\n                                call.args.push_back(none());\n                            }\n\n                            call.args.push_back(value);\n                            call.args_convert.push_back(arg_rec.convert);\n                        } else {\n                            break;\n                        }\n                    }\n\n                    if (args_copied < num_args) {\n                        continue; // Not enough arguments, defaults, or kwargs to fill the\n                                  // positional arguments\n                    }\n                }\n\n                // 3. Check everything was consumed (unless we have a kwargs arg)\n                if (kwargs && !kwargs.empty() && !func.has_kwargs) {\n                    continue; // Unconsumed kwargs, but no py::kwargs argument to accept them\n                }\n\n                // 4a. If we have a py::args argument, create a new tuple with leftovers\n                if (func.has_args) {\n                    tuple extra_args;\n                    if (args_to_copy == 0) {\n                        // We didn't copy out any position arguments from the args_in tuple, so we\n                        // can reuse it directly without copying:\n                        extra_args = reinterpret_borrow<tuple>(args_in);\n                    } else if (positional_args_copied >= n_args_in) {\n                        extra_args = tuple(0);\n                    } else {\n                        size_t args_size = n_args_in - positional_args_copied;\n                        extra_args = tuple(args_size);\n                        for (size_t i = 0; i < args_size; ++i) {\n                            extra_args[i] = PyTuple_GET_ITEM(args_in, positional_args_copied + i);\n                        }\n                    }\n                    if (call.args.size() <= func.nargs_pos) {\n                        call.args.push_back(extra_args);\n                    } else {\n                        call.args[func.nargs_pos] = extra_args;\n                    }\n                    call.args_convert.push_back(false);\n                    call.args_ref = std::move(extra_args);\n                }\n\n                // 4b. If we have a py::kwargs, pass on any remaining kwargs\n                if (func.has_kwargs) {\n                    if (!kwargs.ptr()) {\n                        kwargs = dict(); // If we didn't get one, send an empty one\n                    }\n                    call.args.push_back(kwargs);\n                    call.args_convert.push_back(false);\n                    call.kwargs_ref = std::move(kwargs);\n                }\n\n// 5. Put everything in a vector.  Not technically step 5, we've been building it\n// in `call.args` all along.\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n                if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {\n                    pybind11_fail(\"Internal error: function call dispatcher inserted wrong number \"\n                                  \"of arguments!\");\n                }\n#endif\n\n                std::vector<bool> second_pass_convert;\n                if (overloaded) {\n                    // We're in the first no-convert pass, so swap out the conversion flags for a\n                    // set of all-false flags.  If the call fails, we'll swap the flags back in for\n                    // the conversion-allowed call below.\n                    second_pass_convert.resize(func.nargs, false);\n                    call.args_convert.swap(second_pass_convert);\n                }\n\n                // 6. Call the function.\n                try {\n                    loader_life_support guard{};\n                    result = func.impl(call);\n                } catch (reference_cast_error &) {\n                    result = PYBIND11_TRY_NEXT_OVERLOAD;\n                }\n\n                if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {\n                    break;\n                }\n\n                if (overloaded) {\n                    // The (overloaded) call failed; if the call has at least one argument that\n                    // permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`)\n                    // then add this call to the list of second pass overloads to try.\n                    for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) {\n                        if (second_pass_convert[i]) {\n                            // Found one: swap the converting flags back in and store the call for\n                            // the second pass.\n                            call.args_convert.swap(second_pass_convert);\n                            second_pass.push_back(std::move(call));\n                            break;\n                        }\n                    }\n                }\n            }\n\n            if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {\n                // The no-conversion pass finished without success, try again with conversion\n                // allowed\n                for (auto &call : second_pass) {\n                    try {\n                        loader_life_support guard{};\n                        result = call.func.impl(call);\n                    } catch (reference_cast_error &) {\n                        result = PYBIND11_TRY_NEXT_OVERLOAD;\n                    }\n\n                    if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {\n                        // The error reporting logic below expects 'it' to be valid, as it would be\n                        // if we'd encountered this failure in the first-pass loop.\n                        if (!result) {\n                            it = &call.func;\n                        }\n                        break;\n                    }\n                }\n            }\n        } catch (error_already_set &e) {\n            e.restore();\n            return nullptr;\n#ifdef __GLIBCXX__\n        } catch (abi::__forced_unwind &) {\n            throw;\n#endif\n        } catch (...) {\n            /* When an exception is caught, give each registered exception\n               translator a chance to translate it to a Python exception. First\n               all module-local translators will be tried in reverse order of\n               registration. If none of the module-locale translators handle\n               the exception (or there are no module-locale translators) then\n               the global translators will be tried, also in reverse order of\n               registration.\n\n               A translator may choose to do one of the following:\n\n                - catch the exception and call PyErr_SetString or PyErr_SetObject\n                  to set a standard (or custom) Python exception, or\n                - do nothing and let the exception fall through to the next translator, or\n                - delegate translation to the next translator by throwing a new type of exception.\n             */\n\n            auto &local_exception_translators\n                = get_local_internals().registered_exception_translators;\n            if (detail::apply_exception_translators(local_exception_translators)) {\n                return nullptr;\n            }\n            auto &exception_translators = get_internals().registered_exception_translators;\n            if (detail::apply_exception_translators(exception_translators)) {\n                return nullptr;\n            }\n\n            PyErr_SetString(PyExc_SystemError,\n                            \"Exception escaped from default exception translator!\");\n            return nullptr;\n        }\n\n        auto append_note_if_missing_header_is_suspected = [](std::string &msg) {\n            if (msg.find(\"std::\") != std::string::npos) {\n                msg += \"\\n\\n\"\n                       \"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\\n\"\n                       \"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\\n\"\n                       \"conversions are optional and require extra headers to be included\\n\"\n                       \"when compiling your pybind11 module.\";\n            }\n        };\n\n        if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {\n            if (overloads->is_operator) {\n                return handle(Py_NotImplemented).inc_ref().ptr();\n            }\n\n            std::string msg = std::string(overloads->name) + \"(): incompatible \"\n                              + std::string(overloads->is_constructor ? \"constructor\" : \"function\")\n                              + \" arguments. The following argument types are supported:\\n\";\n\n            int ctr = 0;\n            for (const function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) {\n                msg += \"    \" + std::to_string(++ctr) + \". \";\n\n                bool wrote_sig = false;\n                if (overloads->is_constructor) {\n                    // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as\n                    // `Object(arg0, ...)`\n                    std::string sig = it2->signature;\n                    size_t start = sig.find('(') + 7; // skip \"(self: \"\n                    if (start < sig.size()) {\n                        // End at the , for the next argument\n                        size_t end = sig.find(\", \"), next = end + 2;\n                        size_t ret = sig.rfind(\" -> \");\n                        // Or the ), if there is no comma:\n                        if (end >= sig.size()) {\n                            next = end = sig.find(')');\n                        }\n                        if (start < end && next < sig.size()) {\n                            msg.append(sig, start, end - start);\n                            msg += '(';\n                            msg.append(sig, next, ret - next);\n                            wrote_sig = true;\n                        }\n                    }\n                }\n                if (!wrote_sig) {\n                    msg += it2->signature;\n                }\n\n                msg += '\\n';\n            }\n            msg += \"\\nInvoked with: \";\n            auto args_ = reinterpret_borrow<tuple>(args_in);\n            bool some_args = false;\n            for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {\n                if (!some_args) {\n                    some_args = true;\n                } else {\n                    msg += \", \";\n                }\n                try {\n                    msg += pybind11::repr(args_[ti]);\n                } catch (const error_already_set &) {\n                    msg += \"<repr raised Error>\";\n                }\n            }\n            if (kwargs_in) {\n                auto kwargs = reinterpret_borrow<dict>(kwargs_in);\n                if (!kwargs.empty()) {\n                    if (some_args) {\n                        msg += \"; \";\n                    }\n                    msg += \"kwargs: \";\n                    bool first = true;\n                    for (auto kwarg : kwargs) {\n                        if (first) {\n                            first = false;\n                        } else {\n                            msg += \", \";\n                        }\n                        msg += pybind11::str(\"{}=\").format(kwarg.first);\n                        try {\n                            msg += pybind11::repr(kwarg.second);\n                        } catch (const error_already_set &) {\n                            msg += \"<repr raised Error>\";\n                        }\n                    }\n                }\n            }\n\n            append_note_if_missing_header_is_suspected(msg);\n            // Attach additional error info to the exception if supported\n            if (PyErr_Occurred()) {\n                // #HelpAppreciated: unit test coverage for this branch.\n                raise_from(PyExc_TypeError, msg.c_str());\n                return nullptr;\n            }\n            PyErr_SetString(PyExc_TypeError, msg.c_str());\n            return nullptr;\n        }\n        if (!result) {\n            std::string msg = \"Unable to convert function return value to a \"\n                              \"Python type! The signature was\\n\\t\";\n            msg += it->signature;\n            append_note_if_missing_header_is_suspected(msg);\n            // Attach additional error info to the exception if supported\n            if (PyErr_Occurred()) {\n                raise_from(PyExc_TypeError, msg.c_str());\n                return nullptr;\n            }\n            PyErr_SetString(PyExc_TypeError, msg.c_str());\n            return nullptr;\n        }\n        if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {\n            auto *pi = reinterpret_cast<instance *>(parent.ptr());\n            self_value_and_holder.type->init_instance(pi, nullptr);\n        }\n        return result.ptr();\n    }\n};\n\n/// Wrapper for Python extension modules\nclass module_ : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)\n\n    /// Create a new top-level Python module with the given name and docstring\n    PYBIND11_DEPRECATED(\"Use PYBIND11_MODULE or module_::create_extension_module instead\")\n    explicit module_(const char *name, const char *doc = nullptr) {\n        *this = create_extension_module(name, doc, new PyModuleDef());\n    }\n\n    /** \\rst\n        Create Python binding for a new function within the module scope. ``Func``\n        can be a plain C++ function, a function pointer, or a lambda function. For\n        details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.\n    \\endrst */\n    template <typename Func, typename... Extra>\n    module_ &def(const char *name_, Func &&f, const Extra &...extra) {\n        cpp_function func(std::forward<Func>(f),\n                          name(name_),\n                          scope(*this),\n                          sibling(getattr(*this, name_, none())),\n                          extra...);\n        // NB: allow overwriting here because cpp_function sets up a chain with the intention of\n        // overwriting (and has already checked internally that it isn't overwriting\n        // non-functions).\n        add_object(name_, func, true /* overwrite */);\n        return *this;\n    }\n\n    /** \\rst\n        Create and return a new Python submodule with the given name and docstring.\n        This also works recursively, i.e.\n\n        .. code-block:: cpp\n\n            py::module_ m(\"example\", \"pybind11 example plugin\");\n            py::module_ m2 = m.def_submodule(\"sub\", \"A submodule of 'example'\");\n            py::module_ m3 = m2.def_submodule(\"subsub\", \"A submodule of 'example.sub'\");\n    \\endrst */\n    module_ def_submodule(const char *name, const char *doc = nullptr) {\n        const char *this_name = PyModule_GetName(m_ptr);\n        if (this_name == nullptr) {\n            throw error_already_set();\n        }\n        std::string full_name = std::string(this_name) + '.' + name;\n        handle submodule = PyImport_AddModule(full_name.c_str());\n        if (!submodule) {\n            throw error_already_set();\n        }\n        auto result = reinterpret_borrow<module_>(submodule);\n        if (doc && options::show_user_defined_docstrings()) {\n            result.attr(\"__doc__\") = pybind11::str(doc);\n        }\n        attr(name) = result;\n        return result;\n    }\n\n    /// Import and return a module or throws `error_already_set`.\n    static module_ import(const char *name) {\n        PyObject *obj = PyImport_ImportModule(name);\n        if (!obj) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<module_>(obj);\n    }\n\n    /// Reload the module or throws `error_already_set`.\n    void reload() {\n        PyObject *obj = PyImport_ReloadModule(ptr());\n        if (!obj) {\n            throw error_already_set();\n        }\n        *this = reinterpret_steal<module_>(obj);\n    }\n\n    /** \\rst\n        Adds an object to the module using the given name.  Throws if an object with the given name\n        already exists.\n\n        ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11\n        has established will, in most cases, break things.\n    \\endrst */\n    PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) {\n        if (!overwrite && hasattr(*this, name)) {\n            pybind11_fail(\n                \"Error during initialization: multiple incompatible definitions with name \\\"\"\n                + std::string(name) + \"\\\"\");\n        }\n\n        PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */);\n    }\n\n    using module_def = PyModuleDef; // TODO: Can this be removed (it was needed only for Python 2)?\n\n    /** \\rst\n        Create a new top-level module that can be used as the main module of a C extension.\n\n        ``def`` should point to a statically allocated module_def.\n    \\endrst */\n    static module_ create_extension_module(const char *name, const char *doc, module_def *def) {\n        // module_def is PyModuleDef\n        // Placement new (not an allocation).\n        def = new (def)\n            PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,\n                        /* m_name */ name,\n                        /* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,\n                        /* m_size */ -1,\n                        /* m_methods */ nullptr,\n                        /* m_slots */ nullptr,\n                        /* m_traverse */ nullptr,\n                        /* m_clear */ nullptr,\n                        /* m_free */ nullptr};\n        auto *m = PyModule_Create(def);\n        if (m == nullptr) {\n            if (PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            pybind11_fail(\"Internal error in module_::create_extension_module()\");\n        }\n        // TODO: Should be reinterpret_steal for Python 3, but Python also steals it again when\n        //       returned from PyInit_...\n        //       For Python 2, reinterpret_borrow was correct.\n        return reinterpret_borrow<module_>(m);\n    }\n};\n\n// When inside a namespace (or anywhere as long as it's not the first item on a line),\n// C++20 allows \"module\" to be used. This is provided for backward compatibility, and for\n// simplicity, if someone wants to use py::module for example, that is perfectly safe.\nusing module = module_;\n\n/// \\ingroup python_builtins\n/// Return a dictionary representing the global variables in the current execution frame,\n/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded).\ninline dict globals() {\n    PyObject *p = PyEval_GetGlobals();\n    return reinterpret_borrow<dict>(p ? p : module_::import(\"__main__\").attr(\"__dict__\").ptr());\n}\n\ntemplate <typename... Args, typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>>\nPYBIND11_DEPRECATED(\"make_simple_namespace should be replaced with \"\n                    \"py::module_::import(\\\"types\\\").attr(\\\"SimpleNamespace\\\") \")\nobject make_simple_namespace(Args &&...args_) {\n    return module_::import(\"types\").attr(\"SimpleNamespace\")(std::forward<Args>(args_)...);\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n/// Generic support for creating new Python heap types\nclass generic_type : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check)\nprotected:\n    void initialize(const type_record &rec) {\n        if (rec.scope && hasattr(rec.scope, \"__dict__\")\n            && rec.scope.attr(\"__dict__\").contains(rec.name)) {\n            pybind11_fail(\"generic_type: cannot initialize type \\\"\" + std::string(rec.name)\n                          + \"\\\": an object with that name is already defined\");\n        }\n\n        if ((rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type))\n            != nullptr) {\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(rec.name)\n                          + \"\\\" is already registered!\");\n        }\n\n        m_ptr = make_new_python_type(rec);\n\n        /* Register supplemental type information in C++ dict */\n        auto *tinfo = new detail::type_info();\n        tinfo->type = (PyTypeObject *) m_ptr;\n        tinfo->cpptype = rec.type;\n        tinfo->type_size = rec.type_size;\n        tinfo->type_align = rec.type_align;\n        tinfo->operator_new = rec.operator_new;\n        tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size);\n        tinfo->init_instance = rec.init_instance;\n        tinfo->dealloc = rec.dealloc;\n        tinfo->simple_type = true;\n        tinfo->simple_ancestors = true;\n        tinfo->default_holder = rec.default_holder;\n        tinfo->module_local = rec.module_local;\n\n        auto &internals = get_internals();\n        auto tindex = std::type_index(*rec.type);\n        tinfo->direct_conversions = &internals.direct_conversions[tindex];\n        if (rec.module_local) {\n            get_local_internals().registered_types_cpp[tindex] = tinfo;\n        } else {\n            internals.registered_types_cpp[tindex] = tinfo;\n        }\n        internals.registered_types_py[(PyTypeObject *) m_ptr] = {tinfo};\n\n        if (rec.bases.size() > 1 || rec.multiple_inheritance) {\n            mark_parents_nonsimple(tinfo->type);\n            tinfo->simple_ancestors = false;\n        } else if (rec.bases.size() == 1) {\n            auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());\n            assert(parent_tinfo != nullptr);\n            bool parent_simple_ancestors = parent_tinfo->simple_ancestors;\n            tinfo->simple_ancestors = parent_simple_ancestors;\n            // The parent can no longer be a simple type if it has MI and has a child\n            parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;\n        }\n\n        if (rec.module_local) {\n            // Stash the local typeinfo and loader so that external modules can access it.\n            tinfo->module_local_load = &type_caster_generic::local_load;\n            setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo));\n        }\n    }\n\n    /// Helper function which tags all parents of a type using mult. inheritance\n    void mark_parents_nonsimple(PyTypeObject *value) {\n        auto t = reinterpret_borrow<tuple>(value->tp_bases);\n        for (handle h : t) {\n            auto *tinfo2 = get_type_info((PyTypeObject *) h.ptr());\n            if (tinfo2) {\n                tinfo2->simple_type = false;\n            }\n            mark_parents_nonsimple((PyTypeObject *) h.ptr());\n        }\n    }\n\n    void install_buffer_funcs(buffer_info *(*get_buffer)(PyObject *, void *),\n                              void *get_buffer_data) {\n        auto *type = (PyHeapTypeObject *) m_ptr;\n        auto *tinfo = detail::get_type_info(&type->ht_type);\n\n        if (!type->ht_type.tp_as_buffer) {\n            pybind11_fail(\"To be able to register buffer protocol support for the type '\"\n                          + get_fully_qualified_tp_name(tinfo->type)\n                          + \"' the associated class<>(..) invocation must \"\n                            \"include the pybind11::buffer_protocol() annotation!\");\n        }\n\n        tinfo->get_buffer = get_buffer;\n        tinfo->get_buffer_data = get_buffer_data;\n    }\n\n    // rec_func must be set for either fget or fset.\n    void def_property_static_impl(const char *name,\n                                  handle fget,\n                                  handle fset,\n                                  detail::function_record *rec_func) {\n        const auto is_static = (rec_func != nullptr) && !(rec_func->is_method && rec_func->scope);\n        const auto has_doc = (rec_func != nullptr) && (rec_func->doc != nullptr)\n                             && pybind11::options::show_user_defined_docstrings();\n        auto property = handle(\n            (PyObject *) (is_static ? get_internals().static_property_type : &PyProperty_Type));\n        attr(name) = property(fget.ptr() ? fget : none(),\n                              fset.ptr() ? fset : none(),\n                              /*deleter*/ none(),\n                              pybind11::str(has_doc ? rec_func->doc : \"\"));\n    }\n};\n\n/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded.\ntemplate <typename T,\n          typename = void_t<decltype(static_cast<void *(*) (size_t)>(T::operator new))>>\nvoid set_operator_new(type_record *r) {\n    r->operator_new = &T::operator new;\n}\n\ntemplate <typename>\nvoid set_operator_new(...) {}\n\ntemplate <typename T, typename SFINAE = void>\nstruct has_operator_delete : std::false_type {};\ntemplate <typename T>\nstruct has_operator_delete<T, void_t<decltype(static_cast<void (*)(void *)>(T::operator delete))>>\n    : std::true_type {};\ntemplate <typename T, typename SFINAE = void>\nstruct has_operator_delete_size : std::false_type {};\ntemplate <typename T>\nstruct has_operator_delete_size<\n    T,\n    void_t<decltype(static_cast<void (*)(void *, size_t)>(T::operator delete))>> : std::true_type {\n};\n/// Call class-specific delete if it exists or global otherwise. Can also be an overload set.\ntemplate <typename T, enable_if_t<has_operator_delete<T>::value, int> = 0>\nvoid call_operator_delete(T *p, size_t, size_t) {\n    T::operator delete(p);\n}\ntemplate <\n    typename T,\n    enable_if_t<!has_operator_delete<T>::value && has_operator_delete_size<T>::value, int> = 0>\nvoid call_operator_delete(T *p, size_t s, size_t) {\n    T::operator delete(p, s);\n}\n\ninline void call_operator_delete(void *p, size_t s, size_t a) {\n    (void) s;\n    (void) a;\n#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n    if (a > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {\n#    ifdef __cpp_sized_deallocation\n        ::operator delete(p, s, std::align_val_t(a));\n#    else\n        ::operator delete(p, std::align_val_t(a));\n#    endif\n        return;\n    }\n#endif\n#ifdef __cpp_sized_deallocation\n    ::operator delete(p, s);\n#else\n    ::operator delete(p);\n#endif\n}\n\ninline void add_class_method(object &cls, const char *name_, const cpp_function &cf) {\n    cls.attr(cf.name()) = cf;\n    if (std::strcmp(name_, \"__eq__\") == 0 && !cls.attr(\"__dict__\").contains(\"__hash__\")) {\n        cls.attr(\"__hash__\") = none();\n    }\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Given a pointer to a member function, cast it to its `Derived` version.\n/// Forward everything else unchanged.\ntemplate <typename /*Derived*/, typename F>\nauto method_adaptor(F &&f) -> decltype(std::forward<F>(f)) {\n    return std::forward<F>(f);\n}\n\ntemplate <typename Derived, typename Return, typename Class, typename... Args>\nauto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) {\n    static_assert(\n        detail::is_accessible_base_of<Class, Derived>::value,\n        \"Cannot bind an inaccessible base class method; use a lambda definition instead\");\n    return pmf;\n}\n\ntemplate <typename Derived, typename Return, typename Class, typename... Args>\nauto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const {\n    static_assert(\n        detail::is_accessible_base_of<Class, Derived>::value,\n        \"Cannot bind an inaccessible base class method; use a lambda definition instead\");\n    return pmf;\n}\n\ntemplate <typename type_, typename... options>\nclass class_ : public detail::generic_type {\n    template <typename T>\n    using is_holder = detail::is_holder_type<type_, T>;\n    template <typename T>\n    using is_subtype = detail::is_strict_base_of<type_, T>;\n    template <typename T>\n    using is_base = detail::is_strict_base_of<T, type_>;\n    // struct instead of using here to help MSVC:\n    template <typename T>\n    struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};\n\npublic:\n    using type = type_;\n    using type_alias = detail::exactly_one_t<is_subtype, void, options...>;\n    constexpr static bool has_alias = !std::is_void<type_alias>::value;\n    using holder_type = detail::exactly_one_t<is_holder, std::unique_ptr<type>, options...>;\n\n    static_assert(detail::all_of<is_valid_class_option<options>...>::value,\n                  \"Unknown/invalid class_ template parameters provided\");\n\n    static_assert(!has_alias || std::is_polymorphic<type>::value,\n                  \"Cannot use an alias class with a non-polymorphic type\");\n\n    PYBIND11_OBJECT(class_, generic_type, PyType_Check)\n\n    template <typename... Extra>\n    class_(handle scope, const char *name, const Extra &...extra) {\n        using namespace detail;\n\n        // MI can only be specified via class_ template options, not constructor parameters\n        static_assert(\n            none_of<is_pyobject<Extra>...>::value || // no base class arguments, or:\n                (constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base\n                 constexpr_sum(is_base<options>::value...) == 0 &&   // no template option bases\n                 // no multiple_inheritance attr\n                 none_of<std::is_same<multiple_inheritance, Extra>...>::value),\n            \"Error: multiple inheritance bases must be specified via class_ template options\");\n\n        type_record record;\n        record.scope = scope;\n        record.name = name;\n        record.type = &typeid(type);\n        record.type_size = sizeof(conditional_t<has_alias, type_alias, type>);\n        record.type_align = alignof(conditional_t<has_alias, type_alias, type> &);\n        record.holder_size = sizeof(holder_type);\n        record.init_instance = init_instance;\n        record.dealloc = dealloc;\n        record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;\n\n        set_operator_new<type>(&record);\n\n        /* Register base classes specified via template arguments to class_, if any */\n        PYBIND11_EXPAND_SIDE_EFFECTS(add_base<options>(record));\n\n        /* Process optional arguments, if any */\n        process_attributes<Extra...>::init(extra..., &record);\n\n        generic_type::initialize(record);\n\n        if (has_alias) {\n            auto &instances = record.module_local ? get_local_internals().registered_types_cpp\n                                                  : get_internals().registered_types_cpp;\n            instances[std::type_index(typeid(type_alias))]\n                = instances[std::type_index(typeid(type))];\n        }\n    }\n\n    template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0>\n    static void add_base(detail::type_record &rec) {\n        rec.add_base(typeid(Base), [](void *src) -> void * {\n            return static_cast<Base *>(reinterpret_cast<type *>(src));\n        });\n    }\n\n    template <typename Base, detail::enable_if_t<!is_base<Base>::value, int> = 0>\n    static void add_base(detail::type_record &) {}\n\n    template <typename Func, typename... Extra>\n    class_ &def(const char *name_, Func &&f, const Extra &...extra) {\n        cpp_function cf(method_adaptor<type>(std::forward<Func>(f)),\n                        name(name_),\n                        is_method(*this),\n                        sibling(getattr(*this, name_, none())),\n                        extra...);\n        add_class_method(*this, name_, cf);\n        return *this;\n    }\n\n    template <typename Func, typename... Extra>\n    class_ &def_static(const char *name_, Func &&f, const Extra &...extra) {\n        static_assert(!std::is_member_function_pointer<Func>::value,\n                      \"def_static(...) called with a non-static member function pointer\");\n        cpp_function cf(std::forward<Func>(f),\n                        name(name_),\n                        scope(*this),\n                        sibling(getattr(*this, name_, none())),\n                        extra...);\n        auto cf_name = cf.name();\n        attr(std::move(cf_name)) = staticmethod(std::move(cf));\n        return *this;\n    }\n\n    template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>\n    class_ &def(const T &op, const Extra &...extra) {\n        op.execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename T, typename... Extra, detail::enable_if_t<T::op_enable_if_hook, int> = 0>\n    class_ &def_cast(const T &op, const Extra &...extra) {\n        op.execute_cast(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(const detail::initimpl::constructor<Args...> &init, const Extra &...extra) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);\n        init.execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(const detail::initimpl::alias_constructor<Args...> &init, const Extra &...extra) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);\n        init.execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(detail::initimpl::factory<Args...> &&init, const Extra &...extra) {\n        std::move(init).execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, const Extra &...extra) {\n        std::move(pf).execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename Func>\n    class_ &def_buffer(Func &&func) {\n        struct capture {\n            Func func;\n        };\n        auto *ptr = new capture{std::forward<Func>(func)};\n        install_buffer_funcs(\n            [](PyObject *obj, void *ptr) -> buffer_info * {\n                detail::make_caster<type> caster;\n                if (!caster.load(obj, false)) {\n                    return nullptr;\n                }\n                return new buffer_info(((capture *) ptr)->func(std::move(caster)));\n            },\n            ptr);\n        weakref(m_ptr, cpp_function([ptr](handle wr) {\n                    delete ptr;\n                    wr.dec_ref();\n                }))\n            .release();\n        return *this;\n    }\n\n    template <typename Return, typename Class, typename... Args>\n    class_ &def_buffer(Return (Class::*func)(Args...)) {\n        return def_buffer([func](type &obj) { return (obj.*func)(); });\n    }\n\n    template <typename Return, typename Class, typename... Args>\n    class_ &def_buffer(Return (Class::*func)(Args...) const) {\n        return def_buffer([func](const type &obj) { return (obj.*func)(); });\n    }\n\n    template <typename C, typename D, typename... Extra>\n    class_ &def_readwrite(const char *name, D C::*pm, const Extra &...extra) {\n        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,\n                      \"def_readwrite() requires a class member (or base class member)\");\n        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this)),\n            fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));\n        def_property(name, fget, fset, return_value_policy::reference_internal, extra...);\n        return *this;\n    }\n\n    template <typename C, typename D, typename... Extra>\n    class_ &def_readonly(const char *name, const D C::*pm, const Extra &...extra) {\n        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,\n                      \"def_readonly() requires a class member (or base class member)\");\n        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this));\n        def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);\n        return *this;\n    }\n\n    template <typename D, typename... Extra>\n    class_ &def_readwrite_static(const char *name, D *pm, const Extra &...extra) {\n        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),\n            fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));\n        def_property_static(name, fget, fset, return_value_policy::reference, extra...);\n        return *this;\n    }\n\n    template <typename D, typename... Extra>\n    class_ &def_readonly_static(const char *name, const D *pm, const Extra &...extra) {\n        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));\n        def_property_readonly_static(name, fget, return_value_policy::reference, extra...);\n        return *this;\n    }\n\n    /// Uses return_value_policy::reference_internal by default\n    template <typename Getter, typename... Extra>\n    class_ &def_property_readonly(const char *name, const Getter &fget, const Extra &...extra) {\n        return def_property_readonly(name,\n                                     cpp_function(method_adaptor<type>(fget)),\n                                     return_value_policy::reference_internal,\n                                     extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &\n    def_property_readonly(const char *name, const cpp_function &fget, const Extra &...extra) {\n        return def_property(name, fget, nullptr, extra...);\n    }\n\n    /// Uses return_value_policy::reference by default\n    template <typename Getter, typename... Extra>\n    class_ &\n    def_property_readonly_static(const char *name, const Getter &fget, const Extra &...extra) {\n        return def_property_readonly_static(\n            name, cpp_function(fget), return_value_policy::reference, extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property_readonly_static(const char *name,\n                                         const cpp_function &fget,\n                                         const Extra &...extra) {\n        return def_property_static(name, fget, nullptr, extra...);\n    }\n\n    /// Uses return_value_policy::reference_internal by default\n    template <typename Getter, typename Setter, typename... Extra>\n    class_ &\n    def_property(const char *name, const Getter &fget, const Setter &fset, const Extra &...extra) {\n        return def_property(name, fget, cpp_function(method_adaptor<type>(fset)), extra...);\n    }\n    template <typename Getter, typename... Extra>\n    class_ &def_property(const char *name,\n                         const Getter &fget,\n                         const cpp_function &fset,\n                         const Extra &...extra) {\n        return def_property(name,\n                            cpp_function(method_adaptor<type>(fget)),\n                            fset,\n                            return_value_policy::reference_internal,\n                            extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property(const char *name,\n                         const cpp_function &fget,\n                         const cpp_function &fset,\n                         const Extra &...extra) {\n        return def_property_static(name, fget, fset, is_method(*this), extra...);\n    }\n\n    /// Uses return_value_policy::reference by default\n    template <typename Getter, typename... Extra>\n    class_ &def_property_static(const char *name,\n                                const Getter &fget,\n                                const cpp_function &fset,\n                                const Extra &...extra) {\n        return def_property_static(\n            name, cpp_function(fget), fset, return_value_policy::reference, extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property_static(const char *name,\n                                const cpp_function &fget,\n                                const cpp_function &fset,\n                                const Extra &...extra) {\n        static_assert(0 == detail::constexpr_sum(std::is_base_of<arg, Extra>::value...),\n                      \"Argument annotations are not allowed for properties\");\n        auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset);\n        auto *rec_active = rec_fget;\n        if (rec_fget) {\n            char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific\n                                               documentation string */\n            detail::process_attributes<Extra...>::init(extra..., rec_fget);\n            if (rec_fget->doc && rec_fget->doc != doc_prev) {\n                std::free(doc_prev);\n                rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);\n            }\n        }\n        if (rec_fset) {\n            char *doc_prev = rec_fset->doc;\n            detail::process_attributes<Extra...>::init(extra..., rec_fset);\n            if (rec_fset->doc && rec_fset->doc != doc_prev) {\n                std::free(doc_prev);\n                rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc);\n            }\n            if (!rec_active) {\n                rec_active = rec_fset;\n            }\n        }\n        def_property_static_impl(name, fget, fset, rec_active);\n        return *this;\n    }\n\nprivate:\n    /// Initialize holder object, variant 1: object derives from enable_shared_from_this\n    template <typename T>\n    static void init_holder(detail::instance *inst,\n                            detail::value_and_holder &v_h,\n                            const holder_type * /* unused */,\n                            const std::enable_shared_from_this<T> * /* dummy */) {\n\n        auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(\n            detail::try_get_shared_from_this(v_h.value_ptr<type>()));\n        if (sh) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));\n            v_h.set_holder_constructed();\n        }\n\n        if (!v_h.holder_constructed() && inst->owned) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());\n            v_h.set_holder_constructed();\n        }\n    }\n\n    static void init_holder_from_existing(const detail::value_and_holder &v_h,\n                                          const holder_type *holder_ptr,\n                                          std::true_type /*is_copy_constructible*/) {\n        new (std::addressof(v_h.holder<holder_type>()))\n            holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));\n    }\n\n    static void init_holder_from_existing(const detail::value_and_holder &v_h,\n                                          const holder_type *holder_ptr,\n                                          std::false_type /*is_copy_constructible*/) {\n        new (std::addressof(v_h.holder<holder_type>()))\n            holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));\n    }\n\n    /// Initialize holder object, variant 2: try to construct from existing holder object, if\n    /// possible\n    static void init_holder(detail::instance *inst,\n                            detail::value_and_holder &v_h,\n                            const holder_type *holder_ptr,\n                            const void * /* dummy -- not enable_shared_from_this<T>) */) {\n        if (holder_ptr) {\n            init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());\n            v_h.set_holder_constructed();\n        } else if (PYBIND11_SILENCE_MSVC_C4127(detail::always_construct_holder<holder_type>::value)\n                   || inst->owned) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());\n            v_h.set_holder_constructed();\n        }\n    }\n\n    /// Performs instance initialization including constructing a holder and registering the known\n    /// instance.  Should be called as soon as the `type` value_ptr is set for an instance.  Takes\n    /// an optional pointer to an existing holder to use; if not specified and the instance is\n    /// `.owned`, a new holder will be constructed to manage the value pointer.\n    static void init_instance(detail::instance *inst, const void *holder_ptr) {\n        auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));\n        if (!v_h.instance_registered()) {\n            register_instance(inst, v_h.value_ptr(), v_h.type);\n            v_h.set_instance_registered();\n        }\n        init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());\n    }\n\n    /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.\n    static void dealloc(detail::value_and_holder &v_h) {\n        // We could be deallocating because we are cleaning up after a Python exception.\n        // If so, the Python error indicator will be set. We need to clear that before\n        // running the destructor, in case the destructor code calls more Python.\n        // If we don't, the Python API will exit with an exception, and pybind11 will\n        // throw error_already_set from the C++ destructor which is forbidden and triggers\n        // std::terminate().\n        error_scope scope;\n        if (v_h.holder_constructed()) {\n            v_h.holder<holder_type>().~holder_type();\n            v_h.set_holder_constructed(false);\n        } else {\n            detail::call_operator_delete(\n                v_h.value_ptr<type>(), v_h.type->type_size, v_h.type->type_align);\n        }\n        v_h.value_ptr() = nullptr;\n    }\n\n    static detail::function_record *get_function_record(handle h) {\n        h = detail::get_function(h);\n        if (!h) {\n            return nullptr;\n        }\n\n        handle func_self = PyCFunction_GET_SELF(h.ptr());\n        if (!func_self) {\n            throw error_already_set();\n        }\n        if (!isinstance<capsule>(func_self)) {\n            return nullptr;\n        }\n        auto cap = reinterpret_borrow<capsule>(func_self);\n        if (!detail::is_function_record_capsule(cap)) {\n            return nullptr;\n        }\n        return cap.get_pointer<detail::function_record>();\n    }\n};\n\n/// Binds an existing constructor taking arguments Args...\ntemplate <typename... Args>\ndetail::initimpl::constructor<Args...> init() {\n    return {};\n}\n/// Like `init<Args...>()`, but the instance is always constructed through the alias class (even\n/// when not inheriting on the Python side).\ntemplate <typename... Args>\ndetail::initimpl::alias_constructor<Args...> init_alias() {\n    return {};\n}\n\n/// Binds a factory function as a constructor\ntemplate <typename Func, typename Ret = detail::initimpl::factory<Func>>\nRet init(Func &&f) {\n    return {std::forward<Func>(f)};\n}\n\n/// Dual-argument factory function: the first function is called when no alias is needed, the\n/// second when an alias is needed (i.e. due to python-side inheritance).  Arguments must be\n/// identical.\ntemplate <typename CFunc, typename AFunc, typename Ret = detail::initimpl::factory<CFunc, AFunc>>\nRet init(CFunc &&c, AFunc &&a) {\n    return {std::forward<CFunc>(c), std::forward<AFunc>(a)};\n}\n\n/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type\n/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`.\ntemplate <typename GetState, typename SetState>\ndetail::initimpl::pickle_factory<GetState, SetState> pickle(GetState &&g, SetState &&s) {\n    return {std::forward<GetState>(g), std::forward<SetState>(s)};\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline str enum_name(handle arg) {\n    dict entries = arg.get_type().attr(\"__entries\");\n    for (auto kv : entries) {\n        if (handle(kv.second[int_(0)]).equal(arg)) {\n            return pybind11::str(kv.first);\n        }\n    }\n    return \"???\";\n}\n\nstruct enum_base {\n    enum_base(const handle &base, const handle &parent) : m_base(base), m_parent(parent) {}\n\n    PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) {\n        m_base.attr(\"__entries\") = dict();\n        auto property = handle((PyObject *) &PyProperty_Type);\n        auto static_property = handle((PyObject *) get_internals().static_property_type);\n\n        m_base.attr(\"__repr__\") = cpp_function(\n            [](const object &arg) -> str {\n                handle type = type::handle_of(arg);\n                object type_name = type.attr(\"__name__\");\n                return pybind11::str(\"<{}.{}: {}>\")\n                    .format(std::move(type_name), enum_name(arg), int_(arg));\n            },\n            name(\"__repr__\"),\n            is_method(m_base));\n\n        m_base.attr(\"name\") = property(cpp_function(&enum_name, name(\"name\"), is_method(m_base)));\n\n        m_base.attr(\"__str__\") = cpp_function(\n            [](handle arg) -> str {\n                object type_name = type::handle_of(arg).attr(\"__name__\");\n                return pybind11::str(\"{}.{}\").format(std::move(type_name), enum_name(arg));\n            },\n            name(\"name\"),\n            is_method(m_base));\n\n        if (options::show_enum_members_docstring()) {\n            m_base.attr(\"__doc__\") = static_property(\n                cpp_function(\n                    [](handle arg) -> std::string {\n                        std::string docstring;\n                        dict entries = arg.attr(\"__entries\");\n                        if (((PyTypeObject *) arg.ptr())->tp_doc) {\n                            docstring += std::string(((PyTypeObject *) arg.ptr())->tp_doc) + \"\\n\\n\";\n                        }\n                        docstring += \"Members:\";\n                        for (auto kv : entries) {\n                            auto key = std::string(pybind11::str(kv.first));\n                            auto comment = kv.second[int_(1)];\n                            docstring += \"\\n\\n  \" + key;\n                            if (!comment.is_none()) {\n                                docstring += \" : \" + (std::string) pybind11::str(comment);\n                            }\n                        }\n                        return docstring;\n                    },\n                    name(\"__doc__\")),\n                none(),\n                none(),\n                \"\");\n        }\n\n        m_base.attr(\"__members__\") = static_property(cpp_function(\n                                                         [](handle arg) -> dict {\n                                                             dict entries = arg.attr(\"__entries\"),\n                                                                  m;\n                                                             for (auto kv : entries) {\n                                                                 m[kv.first] = kv.second[int_(0)];\n                                                             }\n                                                             return m;\n                                                         },\n                                                         name(\"__members__\")),\n                                                     none(),\n                                                     none(),\n                                                     \"\");\n\n#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior)                                        \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a, const object &b) {                                                    \\\n            if (!type::handle_of(a).is(type::handle_of(b)))                                       \\\n                strict_behavior; /* NOLINT(bugprone-macro-parentheses) */                         \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n#define PYBIND11_ENUM_OP_CONV(op, expr)                                                           \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a_, const object &b_) {                                                  \\\n            int_ a(a_), b(b_);                                                                    \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n#define PYBIND11_ENUM_OP_CONV_LHS(op, expr)                                                       \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a_, const object &b) {                                                   \\\n            int_ a(a_);                                                                           \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n        if (is_convertible) {\n            PYBIND11_ENUM_OP_CONV_LHS(\"__eq__\", !b.is_none() && a.equal(b));\n            PYBIND11_ENUM_OP_CONV_LHS(\"__ne__\", b.is_none() || !a.equal(b));\n\n            if (is_arithmetic) {\n                PYBIND11_ENUM_OP_CONV(\"__lt__\", a < b);\n                PYBIND11_ENUM_OP_CONV(\"__gt__\", a > b);\n                PYBIND11_ENUM_OP_CONV(\"__le__\", a <= b);\n                PYBIND11_ENUM_OP_CONV(\"__ge__\", a >= b);\n                PYBIND11_ENUM_OP_CONV(\"__and__\", a & b);\n                PYBIND11_ENUM_OP_CONV(\"__rand__\", a & b);\n                PYBIND11_ENUM_OP_CONV(\"__or__\", a | b);\n                PYBIND11_ENUM_OP_CONV(\"__ror__\", a | b);\n                PYBIND11_ENUM_OP_CONV(\"__xor__\", a ^ b);\n                PYBIND11_ENUM_OP_CONV(\"__rxor__\", a ^ b);\n                m_base.attr(\"__invert__\")\n                    = cpp_function([](const object &arg) { return ~(int_(arg)); },\n                                   name(\"__invert__\"),\n                                   is_method(m_base));\n            }\n        } else {\n            PYBIND11_ENUM_OP_STRICT(\"__eq__\", int_(a).equal(int_(b)), return false);\n            PYBIND11_ENUM_OP_STRICT(\"__ne__\", !int_(a).equal(int_(b)), return true);\n\n            if (is_arithmetic) {\n#define PYBIND11_THROW throw type_error(\"Expected an enumeration of matching type!\");\n                PYBIND11_ENUM_OP_STRICT(\"__lt__\", int_(a) < int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__gt__\", int_(a) > int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__le__\", int_(a) <= int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__ge__\", int_(a) >= int_(b), PYBIND11_THROW);\n#undef PYBIND11_THROW\n            }\n        }\n\n#undef PYBIND11_ENUM_OP_CONV_LHS\n#undef PYBIND11_ENUM_OP_CONV\n#undef PYBIND11_ENUM_OP_STRICT\n\n        m_base.attr(\"__getstate__\") = cpp_function(\n            [](const object &arg) { return int_(arg); }, name(\"__getstate__\"), is_method(m_base));\n\n        m_base.attr(\"__hash__\") = cpp_function(\n            [](const object &arg) { return int_(arg); }, name(\"__hash__\"), is_method(m_base));\n    }\n\n    PYBIND11_NOINLINE void value(char const *name_, object value, const char *doc = nullptr) {\n        dict entries = m_base.attr(\"__entries\");\n        str name(name_);\n        if (entries.contains(name)) {\n            std::string type_name = (std::string) str(m_base.attr(\"__name__\"));\n            throw value_error(std::move(type_name) + \": element \\\"\" + std::string(name_)\n                              + \"\\\" already exists!\");\n        }\n\n        entries[name] = pybind11::make_tuple(value, doc);\n        m_base.attr(std::move(name)) = std::move(value);\n    }\n\n    PYBIND11_NOINLINE void export_values() {\n        dict entries = m_base.attr(\"__entries\");\n        for (auto kv : entries) {\n            m_parent.attr(kv.first) = kv.second[int_(0)];\n        }\n    }\n\n    handle m_base;\n    handle m_parent;\n};\n\ntemplate <bool is_signed, size_t length>\nstruct equivalent_integer {};\ntemplate <>\nstruct equivalent_integer<true, 1> {\n    using type = int8_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 1> {\n    using type = uint8_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 2> {\n    using type = int16_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 2> {\n    using type = uint16_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 4> {\n    using type = int32_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 4> {\n    using type = uint32_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 8> {\n    using type = int64_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 8> {\n    using type = uint64_t;\n};\n\ntemplate <typename IntLike>\nusing equivalent_integer_t =\n    typename equivalent_integer<std::is_signed<IntLike>::value, sizeof(IntLike)>::type;\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Binds C++ enumerations and enumeration classes to Python\ntemplate <typename Type>\nclass enum_ : public class_<Type> {\npublic:\n    using Base = class_<Type>;\n    using Base::attr;\n    using Base::def;\n    using Base::def_property_readonly;\n    using Base::def_property_readonly_static;\n    using Underlying = typename std::underlying_type<Type>::type;\n    // Scalar is the integer representation of underlying type\n    using Scalar = detail::conditional_t<detail::any_of<detail::is_std_char_type<Underlying>,\n                                                        std::is_same<Underlying, bool>>::value,\n                                         detail::equivalent_integer_t<Underlying>,\n                                         Underlying>;\n\n    template <typename... Extra>\n    enum_(const handle &scope, const char *name, const Extra &...extra)\n        : class_<Type>(scope, name, extra...), m_base(*this, scope) {\n        constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;\n        constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;\n        m_base.init(is_arithmetic, is_convertible);\n\n        def(init([](Scalar i) { return static_cast<Type>(i); }), arg(\"value\"));\n        def_property_readonly(\"value\", [](Type value) { return (Scalar) value; });\n        def(\"__int__\", [](Type value) { return (Scalar) value; });\n        def(\"__index__\", [](Type value) { return (Scalar) value; });\n        attr(\"__setstate__\") = cpp_function(\n            [](detail::value_and_holder &v_h, Scalar arg) {\n                detail::initimpl::setstate<Base>(\n                    v_h, static_cast<Type>(arg), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            detail::is_new_style_constructor(),\n            pybind11::name(\"__setstate__\"),\n            is_method(*this),\n            arg(\"state\"));\n    }\n\n    /// Export enumeration entries into the parent scope\n    enum_ &export_values() {\n        m_base.export_values();\n        return *this;\n    }\n\n    /// Add an enumeration entry\n    enum_ &value(char const *name, Type value, const char *doc = nullptr) {\n        m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc);\n        return *this;\n    }\n\nprivate:\n    detail::enum_base m_base;\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\nPYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) {\n    if (!nurse || !patient) {\n        pybind11_fail(\"Could not activate keep_alive!\");\n    }\n\n    if (patient.is_none() || nurse.is_none()) {\n        return; /* Nothing to keep alive or nothing to be kept alive by */\n    }\n\n    auto tinfo = all_type_info(Py_TYPE(nurse.ptr()));\n    if (!tinfo.empty()) {\n        /* It's a pybind-registered type, so we can store the patient in the\n         * internal list. */\n        add_patient(nurse.ptr(), patient.ptr());\n    } else {\n        /* Fall back to clever approach based on weak references taken from\n         * Boost.Python. This is not used for pybind-registered types because\n         * the objects can be destroyed out-of-order in a GC pass. */\n        cpp_function disable_lifesupport([patient](handle weakref) {\n            patient.dec_ref();\n            weakref.dec_ref();\n        });\n\n        weakref wr(nurse, disable_lifesupport);\n\n        patient.inc_ref(); /* reference patient and leak the weak reference */\n        (void) wr.release();\n    }\n}\n\nPYBIND11_NOINLINE void\nkeep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) {\n    auto get_arg = [&](size_t n) {\n        if (n == 0) {\n            return ret;\n        }\n        if (n == 1 && call.init_self) {\n            return call.init_self;\n        }\n        if (n <= call.args.size()) {\n            return call.args[n - 1];\n        }\n        return handle();\n    };\n\n    keep_alive_impl(get_arg(Nurse), get_arg(Patient));\n}\n\ninline std::pair<decltype(internals::registered_types_py)::iterator, bool>\nall_type_info_get_cache(PyTypeObject *type) {\n    auto res = get_internals()\n                   .registered_types_py\n#ifdef __cpp_lib_unordered_map_try_emplace\n                   .try_emplace(type);\n#else\n                   .emplace(type, std::vector<detail::type_info *>());\n#endif\n    if (res.second) {\n        // New cache entry created; set up a weak reference to automatically remove it if the type\n        // gets destroyed:\n        weakref((PyObject *) type, cpp_function([type](handle wr) {\n                    get_internals().registered_types_py.erase(type);\n\n                    // TODO consolidate the erasure code in pybind11_meta_dealloc() in class.h\n                    auto &cache = get_internals().inactive_override_cache;\n                    for (auto it = cache.begin(), last = cache.end(); it != last;) {\n                        if (it->first == reinterpret_cast<PyObject *>(type)) {\n                            it = cache.erase(it);\n                        } else {\n                            ++it;\n                        }\n                    }\n\n                    wr.dec_ref();\n                }))\n            .release();\n    }\n\n    return res;\n}\n\n/* There are a large number of apparently unused template arguments because\n * each combination requires a separate py::class_ registration.\n */\ntemplate <typename Access,\n          return_value_policy Policy,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType,\n          typename... Extra>\nstruct iterator_state {\n    Iterator it;\n    Sentinel end;\n    bool first_or_done;\n};\n\n// Note: these helpers take the iterator by non-const reference because some\n// iterators in the wild can't be dereferenced when const. The & after Iterator\n// is required for MSVC < 16.9. SFINAE cannot be reused for result_type due to\n// bugs in ICC, NVCC, and PGI compilers. See PR #3293.\ntemplate <typename Iterator, typename SFINAE = decltype(*std::declval<Iterator &>())>\nstruct iterator_access {\n    using result_type = decltype(*std::declval<Iterator &>());\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    result_type operator()(Iterator &it) const { return *it; }\n};\n\ntemplate <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).first)>\nclass iterator_key_access {\nprivate:\n    using pair_type = decltype(*std::declval<Iterator &>());\n\npublic:\n    /* If either the pair itself or the element of the pair is a reference, we\n     * want to return a reference, otherwise a value. When the decltype\n     * expression is parenthesized it is based on the value category of the\n     * expression; otherwise it is the declared type of the pair member.\n     * The use of declval<pair_type> in the second branch rather than directly\n     * using *std::declval<Iterator &>() is a workaround for nvcc\n     * (it's not used in the first branch because going via decltype and back\n     * through declval does not perfectly preserve references).\n     */\n    using result_type\n        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,\n                        decltype(((*std::declval<Iterator &>()).first)),\n                        decltype(std::declval<pair_type>().first)>;\n    result_type operator()(Iterator &it) const { return (*it).first; }\n};\n\ntemplate <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).second)>\nclass iterator_value_access {\nprivate:\n    using pair_type = decltype(*std::declval<Iterator &>());\n\npublic:\n    using result_type\n        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,\n                        decltype(((*std::declval<Iterator &>()).second)),\n                        decltype(std::declval<pair_type>().second)>;\n    result_type operator()(Iterator &it) const { return (*it).second; }\n};\n\ntemplate <typename Access,\n          return_value_policy Policy,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType,\n          typename... Extra>\niterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {\n    using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;\n    // TODO: state captures only the types of Extra, not the values\n\n    if (!detail::get_type_info(typeid(state), false)) {\n        class_<state>(handle(), \"iterator\", pybind11::module_local())\n            .def(\"__iter__\", [](state &s) -> state & { return s; })\n            .def(\n                \"__next__\",\n                [](state &s) -> ValueType {\n                    if (!s.first_or_done) {\n                        ++s.it;\n                    } else {\n                        s.first_or_done = false;\n                    }\n                    if (s.it == s.end) {\n                        s.first_or_done = true;\n                        throw stop_iteration();\n                    }\n                    return Access()(s.it);\n                    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n                },\n                std::forward<Extra>(extra)...,\n                Policy);\n    }\n\n    return cast(state{first, last, true});\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Makes a python iterator from a first and past-the-end C++ InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType = typename detail::iterator_access<Iterator>::result_type,\n          typename... Extra>\niterator make_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      ValueType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a\n/// first and past-the-end InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,\n          typename... Extra>\niterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      KeyType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a\n/// first and past-the-end InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,\n          typename... Extra>\niterator make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      ValueType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes an iterator over values of an stl container or other container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_iterator(Type &value, Extra &&...extra) {\n    return make_iterator<Policy>(\n        std::begin(value), std::end(value), std::forward<Extra>(extra)...);\n}\n\n/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_key_iterator(Type &value, Extra &&...extra) {\n    return make_key_iterator<Policy>(\n        std::begin(value), std::end(value), std::forward<Extra>(extra)...);\n}\n\n/// Makes an iterator over the values (`.second`) of a stl map-like container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_value_iterator(Type &value, Extra &&...extra) {\n    return make_value_iterator<Policy>(\n        std::begin(value), std::end(value), std::forward<Extra>(extra)...);\n}\n\ntemplate <typename InputType, typename OutputType>\nvoid implicitly_convertible() {\n    struct set_flag {\n        bool &flag;\n        explicit set_flag(bool &flag_) : flag(flag_) { flag_ = true; }\n        ~set_flag() { flag = false; }\n    };\n    auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * {\n        static bool currently_used = false;\n        if (currently_used) { // implicit conversions are non-reentrant\n            return nullptr;\n        }\n        set_flag flag_helper(currently_used);\n        if (!detail::make_caster<InputType>().load(obj, false)) {\n            return nullptr;\n        }\n        tuple args(1);\n        args[0] = obj;\n        PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr);\n        if (result == nullptr) {\n            PyErr_Clear();\n        }\n        return result;\n    };\n\n    if (auto *tinfo = detail::get_type_info(typeid(OutputType))) {\n        tinfo->implicit_conversions.emplace_back(std::move(implicit_caster));\n    } else {\n        pybind11_fail(\"implicitly_convertible: Unable to find type \" + type_id<OutputType>());\n    }\n}\n\ninline void register_exception_translator(ExceptionTranslator &&translator) {\n    detail::get_internals().registered_exception_translators.push_front(\n        std::forward<ExceptionTranslator>(translator));\n}\n\n/**\n * Add a new module-local exception translator. Locally registered functions\n * will be tried before any globally registered exception translators, which\n * will only be invoked if the module-local handlers do not deal with\n * the exception.\n */\ninline void register_local_exception_translator(ExceptionTranslator &&translator) {\n    detail::get_local_internals().registered_exception_translators.push_front(\n        std::forward<ExceptionTranslator>(translator));\n}\n\n/**\n * Wrapper to generate a new Python exception type.\n *\n * This should only be used with PyErr_SetString for now.\n * It is not (yet) possible to use as a py::base.\n * Template type argument is reserved for future use.\n */\ntemplate <typename type>\nclass exception : public object {\npublic:\n    exception() = default;\n    exception(handle scope, const char *name, handle base = PyExc_Exception) {\n        std::string full_name\n            = scope.attr(\"__name__\").cast<std::string>() + std::string(\".\") + name;\n        m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), nullptr);\n        if (hasattr(scope, \"__dict__\") && scope.attr(\"__dict__\").contains(name)) {\n            pybind11_fail(\"Error during initialization: multiple incompatible \"\n                          \"definitions with name \\\"\"\n                          + std::string(name) + \"\\\"\");\n        }\n        scope.attr(name) = *this;\n    }\n\n    // Sets the current python exception to this exception object with the given message\n    void operator()(const char *message) { PyErr_SetString(m_ptr, message); }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Returns a reference to a function-local static exception object used in the simple\n// register_exception approach below.  (It would be simpler to have the static local variable\n// directly in register_exception, but that makes clang <3.5 segfault - issue #1349).\ntemplate <typename CppException>\nexception<CppException> &get_exception_object() {\n    static exception<CppException> ex;\n    return ex;\n}\n\n// Helper function for register_exception and register_local_exception\ntemplate <typename CppException>\nexception<CppException> &\nregister_exception_impl(handle scope, const char *name, handle base, bool isLocal) {\n    auto &ex = detail::get_exception_object<CppException>();\n    if (!ex) {\n        ex = exception<CppException>(scope, name, base);\n    }\n\n    auto register_func\n        = isLocal ? &register_local_exception_translator : &register_exception_translator;\n\n    register_func([](std::exception_ptr p) {\n        if (!p) {\n            return;\n        }\n        try {\n            std::rethrow_exception(p);\n        } catch (const CppException &e) {\n            detail::get_exception_object<CppException>()(e.what());\n        }\n    });\n    return ex;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/**\n * Registers a Python exception in `m` of the given `name` and installs a translator to\n * translate the C++ exception to the created Python exception using the what() method.\n * This is intended for simple exception translations; for more complex translation, register the\n * exception object and translator directly.\n */\ntemplate <typename CppException>\nexception<CppException> &\nregister_exception(handle scope, const char *name, handle base = PyExc_Exception) {\n    return detail::register_exception_impl<CppException>(scope, name, base, false /* isLocal */);\n}\n\n/**\n * Registers a Python exception in `m` of the given `name` and installs a translator to\n * translate the C++ exception to the created Python exception using the what() method.\n * This translator will only be used for exceptions that are thrown in this module and will be\n * tried before global exception translators, including those registered with register_exception.\n * This is intended for simple exception translations; for more complex translation, register the\n * exception object and translator directly.\n */\ntemplate <typename CppException>\nexception<CppException> &\nregister_local_exception(handle scope, const char *name, handle base = PyExc_Exception) {\n    return detail::register_exception_impl<CppException>(scope, name, base, true /* isLocal */);\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\nPYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) {\n    auto strings = tuple(args.size());\n    for (size_t i = 0; i < args.size(); ++i) {\n        strings[i] = str(args[i]);\n    }\n    auto sep = kwargs.contains(\"sep\") ? kwargs[\"sep\"] : str(\" \");\n    auto line = sep.attr(\"join\")(std::move(strings));\n\n    object file;\n    if (kwargs.contains(\"file\")) {\n        file = kwargs[\"file\"].cast<object>();\n    } else {\n        try {\n            file = module_::import(\"sys\").attr(\"stdout\");\n        } catch (const error_already_set &) {\n            /* If print() is called from code that is executed as\n               part of garbage collection during interpreter shutdown,\n               importing 'sys' can fail. Give up rather than crashing the\n               interpreter in this case. */\n            return;\n        }\n    }\n\n    auto write = file.attr(\"write\");\n    write(std::move(line));\n    write(kwargs.contains(\"end\") ? kwargs[\"end\"] : str(\"\\n\"));\n\n    if (kwargs.contains(\"flush\") && kwargs[\"flush\"].cast<bool>()) {\n        file.attr(\"flush\")();\n    }\n}\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>\nvoid print(Args &&...args) {\n    auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...);\n    detail::print(c.args(), c.kwargs());\n}\n\ninline void\nerror_already_set::m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr) {\n    gil_scoped_acquire gil;\n    error_scope scope;\n    delete raw_ptr;\n}\n\ninline const char *error_already_set::what() const noexcept {\n    gil_scoped_acquire gil;\n    error_scope scope;\n    return m_fetched_error->error_string().c_str();\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline function\nget_type_override(const void *this_ptr, const type_info *this_type, const char *name) {\n    handle self = get_object_handle(this_ptr, this_type);\n    if (!self) {\n        return function();\n    }\n    handle type = type::handle_of(self);\n    auto key = std::make_pair(type.ptr(), name);\n\n    /* Cache functions that aren't overridden in Python to avoid\n       many costly Python dictionary lookups below */\n    auto &cache = get_internals().inactive_override_cache;\n    if (cache.find(key) != cache.end()) {\n        return function();\n    }\n\n    function override = getattr(self, name, function());\n    if (override.is_cpp_function()) {\n        cache.insert(std::move(key));\n        return function();\n    }\n\n    /* Don't call dispatch code if invoked from overridden function.\n       Unfortunately this doesn't work on PyPy. */\n#if !defined(PYPY_VERSION)\n#    if PY_VERSION_HEX >= 0x03090000\n    PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());\n    if (frame != nullptr) {\n        PyCodeObject *f_code = PyFrame_GetCode(frame);\n        // f_code is guaranteed to not be NULL\n        if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {\n            PyObject *locals = PyEval_GetLocals();\n            if (locals != nullptr) {\n                PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, \"co_varnames\");\n                PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0);\n                Py_DECREF(co_varnames);\n                PyObject *self_caller = dict_getitem(locals, self_arg);\n                if (self_caller == self.ptr()) {\n                    Py_DECREF(f_code);\n                    Py_DECREF(frame);\n                    return function();\n                }\n            }\n        }\n        Py_DECREF(f_code);\n        Py_DECREF(frame);\n    }\n#    else\n    PyFrameObject *frame = PyThreadState_Get()->frame;\n    if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name\n        && frame->f_code->co_argcount > 0) {\n        PyFrame_FastToLocals(frame);\n        PyObject *self_caller\n            = dict_getitem(frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0));\n        if (self_caller == self.ptr()) {\n            return function();\n        }\n    }\n#    endif\n\n#else\n    /* PyPy currently doesn't provide a detailed cpyext emulation of\n       frame objects, so we have to emulate this using Python. This\n       is going to be slow..*/\n    dict d;\n    d[\"self\"] = self;\n    d[\"name\"] = pybind11::str(name);\n    PyObject *result\n        = PyRun_String(\"import inspect\\n\"\n                       \"frame = inspect.currentframe()\\n\"\n                       \"if frame is not None:\\n\"\n                       \"    frame = frame.f_back\\n\"\n                       \"    if frame is not None and str(frame.f_code.co_name) == name and \"\n                       \"frame.f_code.co_argcount > 0:\\n\"\n                       \"        self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\\n\"\n                       \"        if self_caller == self:\\n\"\n                       \"            self = None\\n\",\n                       Py_file_input,\n                       d.ptr(),\n                       d.ptr());\n    if (result == nullptr)\n        throw error_already_set();\n    Py_DECREF(result);\n    if (d[\"self\"].is_none())\n        return function();\n#endif\n\n    return override;\n}\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n  Try to retrieve a python method by the provided name from the instance pointed to by the\n  this_ptr.\n\n  :this_ptr: The pointer to the object the overridden method should be retrieved for. This should\n             be the first non-trampoline class encountered in the inheritance chain.\n  :name: The name of the overridden Python method to retrieve.\n  :return: The Python method by this name from the object or an empty function wrapper.\n \\endrst */\ntemplate <class T>\nfunction get_override(const T *this_ptr, const char *name) {\n    auto *tinfo = detail::get_type_info(typeid(T));\n    return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();\n}\n\n#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...)                                        \\\n    do {                                                                                          \\\n        pybind11::gil_scoped_acquire gil;                                                         \\\n        pybind11::function override                                                               \\\n            = pybind11::get_override(static_cast<const cname *>(this), name);                     \\\n        if (override) {                                                                           \\\n            auto o = override(__VA_ARGS__);                                                       \\\n            if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) {           \\\n                static pybind11::detail::override_caster_t<ret_type> caster;                      \\\n                return pybind11::detail::cast_ref<ret_type>(std::move(o), caster);                \\\n            }                                                                                     \\\n            return pybind11::detail::cast_safe<ret_type>(std::move(o));                           \\\n        }                                                                                         \\\n    } while (false)\n\n/** \\rst\n    Macro to populate the virtual method in the trampoline class. This macro tries to look up a\n    method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument\n    conversions to call this method and return the appropriate type.\n    See :ref:`overriding_virtuals` for more information. This macro should be used when the method\n    name in C is not the same as the method name in Python. For example with `__str__`.\n\n    .. code-block:: cpp\n\n      std::string toString() override {\n        PYBIND11_OVERRIDE_NAME(\n            std::string, // Return type (ret_type)\n            Animal,      // Parent class (cname)\n            \"__str__\",   // Name of method in Python (name)\n            toString,    // Name of function in C++ (fn)\n        );\n      }\n\\endrst */\n#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...)                                    \\\n    do {                                                                                          \\\n        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \\\n        return cname::fn(__VA_ARGS__);                                                            \\\n    } while (false)\n\n/** \\rst\n    Macro for pure virtual functions, this function is identical to\n    :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found.\n\\endrst */\n#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...)                               \\\n    do {                                                                                          \\\n        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \\\n        pybind11::pybind11_fail(                                                                  \\\n            \"Tried to call pure virtual function \\\"\" PYBIND11_STRINGIFY(cname) \"::\" name \"\\\"\");   \\\n    } while (false)\n\n/** \\rst\n    Macro to populate the virtual method in the trampoline class. This macro tries to look up the\n    method from the Python side, deals with the :ref:`gil` and necessary argument conversions to\n    call this method and return the appropriate type. This macro should be used if the method name\n    in C and in Python are identical.\n    See :ref:`overriding_virtuals` for more information.\n\n    .. code-block:: cpp\n\n      class PyAnimal : public Animal {\n      public:\n          // Inherit the constructors\n          using Animal::Animal;\n\n          // Trampoline (need one for each virtual function)\n          std::string go(int n_times) override {\n              PYBIND11_OVERRIDE_PURE(\n                  std::string, // Return type (ret_type)\n                  Animal,      // Parent class (cname)\n                  go,          // Name of function in C++ (must match Python name) (fn)\n                  n_times      // Argument(s) (...)\n              );\n          }\n      };\n\\endrst */\n#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...)                                               \\\n    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)\n\n/** \\rst\n    Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`,\n    except that it throws if no override can be found.\n\\endrst */\n#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...)                                          \\\n    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \\\n        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)\n\n// Deprecated versions\n\nPYBIND11_DEPRECATED(\"get_type_overload has been deprecated\")\ninline function\nget_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {\n    return detail::get_type_override(this_ptr, this_type, name);\n}\n\ntemplate <class T>\ninline function get_overload(const T *this_ptr, const char *name) {\n    return get_override(this_ptr, name);\n}\n\n#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...)                                         \\\n    PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...)                                    \\\n    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...)                               \\\n    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \\\n        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);\n#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...)                                               \\\n    PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...)                                          \\\n    PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n\n#if defined(__GNUC__) && __GNUC__ == 7\n#    pragma GCC diagnostic pop // -Wnoexcept-type\n#endif\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/pytypes.h",
    "content": "/*\n    pybind11/pytypes.h: Convenience wrapper classes for basic Python types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"buffer_info.h\"\n\n#include <assert.h>\n#include <cstddef>\n#include <exception>\n#include <frameobject.h>\n#include <iterator>\n#include <memory>\n#include <string>\n#include <type_traits>\n#include <typeinfo>\n#include <utility>\n\n#if defined(PYBIND11_HAS_OPTIONAL)\n#    include <optional>\n#endif\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n#    include <string_view>\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n/* A few forward declarations */\nclass handle;\nclass object;\nclass str;\nclass iterator;\nclass type;\nstruct arg;\nstruct arg_v;\n\nPYBIND11_NAMESPACE_BEGIN(detail)\nclass args_proxy;\nbool isinstance_generic(handle obj, const std::type_info &tp);\n\n// Accessor forward declarations\ntemplate <typename Policy>\nclass accessor;\nnamespace accessor_policies {\nstruct obj_attr;\nstruct str_attr;\nstruct generic_item;\nstruct sequence_item;\nstruct list_item;\nstruct tuple_item;\n} // namespace accessor_policies\nusing obj_attr_accessor = accessor<accessor_policies::obj_attr>;\nusing str_attr_accessor = accessor<accessor_policies::str_attr>;\nusing item_accessor = accessor<accessor_policies::generic_item>;\nusing sequence_accessor = accessor<accessor_policies::sequence_item>;\nusing list_accessor = accessor<accessor_policies::list_item>;\nusing tuple_accessor = accessor<accessor_policies::tuple_item>;\n\n/// Tag and check to identify a class which implements the Python object API\nclass pyobject_tag {};\ntemplate <typename T>\nusing is_pyobject = std::is_base_of<pyobject_tag, remove_reference_t<T>>;\n\n/** \\rst\n    A mixin class which adds common functions to `handle`, `object` and various accessors.\n    The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``.\n\\endrst */\ntemplate <typename Derived>\nclass object_api : public pyobject_tag {\n    const Derived &derived() const { return static_cast<const Derived &>(*this); }\n\npublic:\n    /** \\rst\n        Return an iterator equivalent to calling ``iter()`` in Python. The object\n        must be a collection which supports the iteration protocol.\n    \\endrst */\n    iterator begin() const;\n    /// Return a sentinel which ends iteration.\n    iterator end() const;\n\n    /** \\rst\n        Return an internal functor to invoke the object's sequence protocol. Casting\n        the returned ``detail::item_accessor`` instance to a `handle` or `object`\n        subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`\n        or `object` subclass causes a call to ``__setitem__``.\n    \\endrst */\n    item_accessor operator[](handle key) const;\n    /// See above (the only difference is that the key's reference is stolen)\n    item_accessor operator[](object &&key) const;\n    /// See above (the only difference is that the key is provided as a string literal)\n    item_accessor operator[](const char *key) const;\n\n    /** \\rst\n        Return an internal functor to access the object's attributes. Casting the\n        returned ``detail::obj_attr_accessor`` instance to a `handle` or `object`\n        subclass causes a corresponding call to ``getattr``. Assigning a `handle`\n        or `object` subclass causes a call to ``setattr``.\n    \\endrst */\n    obj_attr_accessor attr(handle key) const;\n    /// See above (the only difference is that the key's reference is stolen)\n    obj_attr_accessor attr(object &&key) const;\n    /// See above (the only difference is that the key is provided as a string literal)\n    str_attr_accessor attr(const char *key) const;\n\n    /** \\rst\n        Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple``\n        or ``list`` for a function call. Applying another * to the result yields\n        ** unpacking, e.g. to unpack a dict as function keyword arguments.\n        See :ref:`calling_python_functions`.\n    \\endrst */\n    args_proxy operator*() const;\n\n    /// Check if the given item is contained within this object, i.e. ``item in obj``.\n    template <typename T>\n    bool contains(T &&item) const;\n\n    /** \\rst\n        Assuming the Python object is a function or implements the ``__call__``\n        protocol, ``operator()`` invokes the underlying function, passing an\n        arbitrary set of parameters. The result is returned as a `object` and\n        may need to be converted back into a Python object using `handle::cast()`.\n\n        When some of the arguments cannot be converted to Python objects, the\n        function will throw a `cast_error` exception. When the Python function\n        call fails, a `error_already_set` exception is thrown.\n    \\endrst */\n    template <return_value_policy policy = return_value_policy::automatic_reference,\n              typename... Args>\n    object operator()(Args &&...args) const;\n    template <return_value_policy policy = return_value_policy::automatic_reference,\n              typename... Args>\n    PYBIND11_DEPRECATED(\"call(...) was deprecated in favor of operator()(...)\")\n    object call(Args &&...args) const;\n\n    /// Equivalent to ``obj is other`` in Python.\n    bool is(object_api const &other) const { return derived().ptr() == other.derived().ptr(); }\n    /// Equivalent to ``obj is None`` in Python.\n    bool is_none() const { return derived().ptr() == Py_None; }\n    /// Equivalent to obj == other in Python\n    bool equal(object_api const &other) const { return rich_compare(other, Py_EQ); }\n    bool not_equal(object_api const &other) const { return rich_compare(other, Py_NE); }\n    bool operator<(object_api const &other) const { return rich_compare(other, Py_LT); }\n    bool operator<=(object_api const &other) const { return rich_compare(other, Py_LE); }\n    bool operator>(object_api const &other) const { return rich_compare(other, Py_GT); }\n    bool operator>=(object_api const &other) const { return rich_compare(other, Py_GE); }\n\n    object operator-() const;\n    object operator~() const;\n    object operator+(object_api const &other) const;\n    object operator+=(object_api const &other);\n    object operator-(object_api const &other) const;\n    object operator-=(object_api const &other);\n    object operator*(object_api const &other) const;\n    object operator*=(object_api const &other);\n    object operator/(object_api const &other) const;\n    object operator/=(object_api const &other);\n    object operator|(object_api const &other) const;\n    object operator|=(object_api const &other);\n    object operator&(object_api const &other) const;\n    object operator&=(object_api const &other);\n    object operator^(object_api const &other) const;\n    object operator^=(object_api const &other);\n    object operator<<(object_api const &other) const;\n    object operator<<=(object_api const &other);\n    object operator>>(object_api const &other) const;\n    object operator>>=(object_api const &other);\n\n    PYBIND11_DEPRECATED(\"Use py::str(obj) instead\")\n    pybind11::str str() const;\n\n    /// Get or set the object's docstring, i.e. ``obj.__doc__``.\n    str_attr_accessor doc() const;\n\n    /// Return the object's current reference count\n    int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }\n\n    // TODO PYBIND11_DEPRECATED(\n    //     \"Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()\")\n    handle get_type() const;\n\nprivate:\n    bool rich_compare(object_api const &other, int value) const;\n};\n\ntemplate <typename T>\nusing is_pyobj_ptr_or_nullptr_t = detail::any_of<std::is_same<T, PyObject *>,\n                                                 std::is_same<T, PyObject *const>,\n                                                 std::is_same<T, std::nullptr_t>>;\n\nPYBIND11_NAMESPACE_END(detail)\n\n#if !defined(PYBIND11_HANDLE_REF_DEBUG) && !defined(NDEBUG)\n#    define PYBIND11_HANDLE_REF_DEBUG\n#endif\n\n/** \\rst\n    Holds a reference to a Python object (no reference counting)\n\n    The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a\n    ``PyObject *`` in Python's C API). It does not perform any automatic reference\n    counting and merely provides a basic C++ interface to various Python API functions.\n\n    .. seealso::\n        The `object` class inherits from `handle` and adds automatic reference\n        counting features.\n\\endrst */\nclass handle : public detail::object_api<handle> {\npublic:\n    /// The default constructor creates a handle with a ``nullptr``-valued pointer\n    handle() = default;\n\n    /// Enable implicit conversion from ``PyObject *`` and ``nullptr``.\n    /// Not using ``handle(PyObject *ptr)`` to avoid implicit conversion from ``0``.\n    template <typename T,\n              detail::enable_if_t<detail::is_pyobj_ptr_or_nullptr_t<T>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    handle(T ptr) : m_ptr(ptr) {}\n\n    /// Enable implicit conversion through ``T::operator PyObject *()``.\n    template <\n        typename T,\n        detail::enable_if_t<detail::all_of<detail::none_of<std::is_base_of<handle, T>,\n                                                           detail::is_pyobj_ptr_or_nullptr_t<T>>,\n                                           std::is_convertible<T, PyObject *>>::value,\n                            int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    handle(T &obj) : m_ptr(obj) {}\n\n    /// Return the underlying ``PyObject *`` pointer\n    PyObject *ptr() const { return m_ptr; }\n    PyObject *&ptr() { return m_ptr; }\n\n    /** \\rst\n        Manually increase the reference count of the Python object. Usually, it is\n        preferable to use the `object` class which derives from `handle` and calls\n        this function automatically. Returns a reference to itself.\n    \\endrst */\n    const handle &inc_ref() const & {\n#ifdef PYBIND11_HANDLE_REF_DEBUG\n        inc_ref_counter(1);\n#endif\n        Py_XINCREF(m_ptr);\n        return *this;\n    }\n\n    /** \\rst\n        Manually decrease the reference count of the Python object. Usually, it is\n        preferable to use the `object` class which derives from `handle` and calls\n        this function automatically. Returns a reference to itself.\n    \\endrst */\n    const handle &dec_ref() const & {\n        Py_XDECREF(m_ptr);\n        return *this;\n    }\n\n    /** \\rst\n        Attempt to cast the Python object into the given C++ type. A `cast_error`\n        will be throw upon failure.\n    \\endrst */\n    template <typename T>\n    T cast() const;\n    /// Return ``true`` when the `handle` wraps a valid Python object\n    explicit operator bool() const { return m_ptr != nullptr; }\n    /** \\rst\n        Deprecated: Check that the underlying pointers are the same.\n        Equivalent to ``obj1 is obj2`` in Python.\n    \\endrst */\n    PYBIND11_DEPRECATED(\"Use obj1.is(obj2) instead\")\n    bool operator==(const handle &h) const { return m_ptr == h.m_ptr; }\n    PYBIND11_DEPRECATED(\"Use !obj1.is(obj2) instead\")\n    bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; }\n    PYBIND11_DEPRECATED(\"Use handle::operator bool() instead\")\n    bool check() const { return m_ptr != nullptr; }\n\nprotected:\n    PyObject *m_ptr = nullptr;\n\n#ifdef PYBIND11_HANDLE_REF_DEBUG\nprivate:\n    static std::size_t inc_ref_counter(std::size_t add) {\n        thread_local std::size_t counter = 0;\n        counter += add;\n        return counter;\n    }\n\npublic:\n    static std::size_t inc_ref_counter() { return inc_ref_counter(0); }\n#endif\n};\n\n/** \\rst\n    Holds a reference to a Python object (with reference counting)\n\n    Like `handle`, the `object` class is a thin wrapper around an arbitrary Python\n    object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it\n    optionally increases the object's reference count upon construction, and it\n    *always* decreases the reference count when the `object` instance goes out of\n    scope and is destructed. When using `object` instances consistently, it is much\n    easier to get reference counting right at the first attempt.\n\\endrst */\nclass object : public handle {\npublic:\n    object() = default;\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<object>() or reinterpret_steal<object>()\")\n    object(handle h, bool is_borrowed) : handle(h) {\n        if (is_borrowed) {\n            inc_ref();\n        }\n    }\n    /// Copy constructor; always increases the reference count\n    object(const object &o) : handle(o) { inc_ref(); }\n    /// Move constructor; steals the object from ``other`` and preserves its reference count\n    object(object &&other) noexcept : handle(other) { other.m_ptr = nullptr; }\n    /// Destructor; automatically calls `handle::dec_ref()`\n    ~object() { dec_ref(); }\n\n    /** \\rst\n        Resets the internal pointer to ``nullptr`` without decreasing the\n        object's reference count. The function returns a raw handle to the original\n        Python object.\n    \\endrst */\n    handle release() {\n        PyObject *tmp = m_ptr;\n        m_ptr = nullptr;\n        return handle(tmp);\n    }\n\n    object &operator=(const object &other) {\n        // Skip inc_ref and dec_ref if both objects are the same\n        if (!this->is(other)) {\n            other.inc_ref();\n            // Use temporary variable to ensure `*this` remains valid while\n            // `Py_XDECREF` executes, in case `*this` is accessible from Python.\n            handle temp(m_ptr);\n            m_ptr = other.m_ptr;\n            temp.dec_ref();\n        }\n        return *this;\n    }\n\n    object &operator=(object &&other) noexcept {\n        if (this != &other) {\n            handle temp(m_ptr);\n            m_ptr = other.m_ptr;\n            other.m_ptr = nullptr;\n            temp.dec_ref();\n        }\n        return *this;\n    }\n\n#define PYBIND11_INPLACE_OP(iop)                                                                  \\\n    object iop(object_api const &other) { return operator=(handle::iop(other)); }\n\n    PYBIND11_INPLACE_OP(operator+=)\n    PYBIND11_INPLACE_OP(operator-=)\n    PYBIND11_INPLACE_OP(operator*=)\n    PYBIND11_INPLACE_OP(operator/=)\n    PYBIND11_INPLACE_OP(operator|=)\n    PYBIND11_INPLACE_OP(operator&=)\n    PYBIND11_INPLACE_OP(operator^=)\n    PYBIND11_INPLACE_OP(operator<<=)\n    PYBIND11_INPLACE_OP(operator>>=)\n#undef PYBIND11_INPLACE_OP\n\n    // Calling cast() on an object lvalue just copies (via handle::cast)\n    template <typename T>\n    T cast() const &;\n    // Calling on an object rvalue does a move, if needed and/or possible\n    template <typename T>\n    T cast() &&;\n\nprotected:\n    // Tags for choosing constructors from raw PyObject *\n    struct borrowed_t {};\n    struct stolen_t {};\n\n    /// @cond BROKEN\n    template <typename T>\n    friend T reinterpret_borrow(handle);\n    template <typename T>\n    friend T reinterpret_steal(handle);\n    /// @endcond\n\npublic:\n    // Only accessible from derived classes and the reinterpret_* functions\n    object(handle h, borrowed_t) : handle(h) { inc_ref(); }\n    object(handle h, stolen_t) : handle(h) {}\n};\n\n/** \\rst\n    Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference.\n    The target type ``T`` must be `object` or one of its derived classes. The function\n    doesn't do any conversions or checks. It's up to the user to make sure that the\n    target type is correct.\n\n    .. code-block:: cpp\n\n        PyObject *p = PyList_GetItem(obj, index);\n        py::object o = reinterpret_borrow<py::object>(p);\n        // or\n        py::tuple t = reinterpret_borrow<py::tuple>(p); // <-- `p` must be already be a `tuple`\n\\endrst */\ntemplate <typename T>\nT reinterpret_borrow(handle h) {\n    return {h, object::borrowed_t{}};\n}\n\n/** \\rst\n    Like `reinterpret_borrow`, but steals the reference.\n\n     .. code-block:: cpp\n\n        PyObject *p = PyObject_Str(obj);\n        py::str s = reinterpret_steal<py::str>(p); // <-- `p` must be already be a `str`\n\\endrst */\ntemplate <typename T>\nT reinterpret_steal(handle h) {\n    return {h, object::stolen_t{}};\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Equivalent to obj.__class__.__name__ (or obj.__name__ if obj is a class).\ninline const char *obj_class_name(PyObject *obj) {\n    if (Py_TYPE(obj) == &PyType_Type) {\n        return reinterpret_cast<PyTypeObject *>(obj)->tp_name;\n    }\n    return Py_TYPE(obj)->tp_name;\n}\n\nstd::string error_string();\n\nstruct error_fetch_and_normalize {\n    // Immediate normalization is long-established behavior (starting with\n    // https://github.com/pybind/pybind11/commit/135ba8deafb8bf64a15b24d1513899eb600e2011\n    // from Sep 2016) and safest. Normalization could be deferred, but this could mask\n    // errors elsewhere, the performance gain is very minor in typical situations\n    // (usually the dominant bottleneck is EH unwinding), and the implementation here\n    // would be more complex.\n    explicit error_fetch_and_normalize(const char *called) {\n        PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());\n        if (!m_type) {\n            pybind11_fail(\"Internal error: \" + std::string(called)\n                          + \" called while \"\n                            \"Python error indicator not set.\");\n        }\n        const char *exc_type_name_orig = detail::obj_class_name(m_type.ptr());\n        if (exc_type_name_orig == nullptr) {\n            pybind11_fail(\"Internal error: \" + std::string(called)\n                          + \" failed to obtain the name \"\n                            \"of the original active exception type.\");\n        }\n        m_lazy_error_string = exc_type_name_orig;\n        // PyErr_NormalizeException() may change the exception type if there are cascading\n        // failures. This can potentially be extremely confusing.\n        PyErr_NormalizeException(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());\n        if (m_type.ptr() == nullptr) {\n            pybind11_fail(\"Internal error: \" + std::string(called)\n                          + \" failed to normalize the \"\n                            \"active exception.\");\n        }\n        const char *exc_type_name_norm = detail::obj_class_name(m_type.ptr());\n        if (exc_type_name_orig == nullptr) {\n            pybind11_fail(\"Internal error: \" + std::string(called)\n                          + \" failed to obtain the name \"\n                            \"of the normalized active exception type.\");\n        }\n#if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x07030a00\n        // This behavior runs the risk of masking errors in the error handling, but avoids a\n        // conflict with PyPy, which relies on the normalization here to change OSError to\n        // FileNotFoundError (https://github.com/pybind/pybind11/issues/4075).\n        m_lazy_error_string = exc_type_name_norm;\n#else\n        if (exc_type_name_norm != m_lazy_error_string) {\n            std::string msg = std::string(called)\n                              + \": MISMATCH of original and normalized \"\n                                \"active exception types: \";\n            msg += \"ORIGINAL \";\n            msg += m_lazy_error_string;\n            msg += \" REPLACED BY \";\n            msg += exc_type_name_norm;\n            msg += \": \" + format_value_and_trace();\n            pybind11_fail(msg);\n        }\n#endif\n    }\n\n    error_fetch_and_normalize(const error_fetch_and_normalize &) = delete;\n    error_fetch_and_normalize(error_fetch_and_normalize &&) = delete;\n\n    std::string format_value_and_trace() const {\n        std::string result;\n        std::string message_error_string;\n        if (m_value) {\n            auto value_str = reinterpret_steal<object>(PyObject_Str(m_value.ptr()));\n            constexpr const char *message_unavailable_exc\n                = \"<MESSAGE UNAVAILABLE DUE TO ANOTHER EXCEPTION>\";\n            if (!value_str) {\n                message_error_string = detail::error_string();\n                result = message_unavailable_exc;\n            } else {\n                // Not using `value_str.cast<std::string>()`, to not potentially throw a secondary\n                // error_already_set that will then result in process termination (#4288).\n                auto value_bytes = reinterpret_steal<object>(\n                    PyUnicode_AsEncodedString(value_str.ptr(), \"utf-8\", \"backslashreplace\"));\n                if (!value_bytes) {\n                    message_error_string = detail::error_string();\n                    result = message_unavailable_exc;\n                } else {\n                    char *buffer = nullptr;\n                    Py_ssize_t length = 0;\n                    if (PyBytes_AsStringAndSize(value_bytes.ptr(), &buffer, &length) == -1) {\n                        message_error_string = detail::error_string();\n                        result = message_unavailable_exc;\n                    } else {\n                        result = std::string(buffer, static_cast<std::size_t>(length));\n                    }\n                }\n            }\n        } else {\n            result = \"<MESSAGE UNAVAILABLE>\";\n        }\n        if (result.empty()) {\n            result = \"<EMPTY MESSAGE>\";\n        }\n\n        bool have_trace = false;\n        if (m_trace) {\n#if !defined(PYPY_VERSION)\n            auto *tb = reinterpret_cast<PyTracebackObject *>(m_trace.ptr());\n\n            // Get the deepest trace possible.\n            while (tb->tb_next) {\n                tb = tb->tb_next;\n            }\n\n            PyFrameObject *frame = tb->tb_frame;\n            Py_XINCREF(frame);\n            result += \"\\n\\nAt:\\n\";\n            while (frame) {\n#    if PY_VERSION_HEX >= 0x030900B1\n                PyCodeObject *f_code = PyFrame_GetCode(frame);\n#    else\n                PyCodeObject *f_code = frame->f_code;\n                Py_INCREF(f_code);\n#    endif\n                int lineno = PyFrame_GetLineNumber(frame);\n                result += \"  \";\n                result += handle(f_code->co_filename).cast<std::string>();\n                result += '(';\n                result += std::to_string(lineno);\n                result += \"): \";\n                result += handle(f_code->co_name).cast<std::string>();\n                result += '\\n';\n                Py_DECREF(f_code);\n#    if PY_VERSION_HEX >= 0x030900B1\n                auto *b_frame = PyFrame_GetBack(frame);\n#    else\n                auto *b_frame = frame->f_back;\n                Py_XINCREF(b_frame);\n#    endif\n                Py_DECREF(frame);\n                frame = b_frame;\n            }\n\n            have_trace = true;\n#endif //! defined(PYPY_VERSION)\n        }\n\n        if (!message_error_string.empty()) {\n            if (!have_trace) {\n                result += '\\n';\n            }\n            result += \"\\nMESSAGE UNAVAILABLE DUE TO EXCEPTION: \" + message_error_string;\n        }\n\n        return result;\n    }\n\n    std::string const &error_string() const {\n        if (!m_lazy_error_string_completed) {\n            m_lazy_error_string += \": \" + format_value_and_trace();\n            m_lazy_error_string_completed = true;\n        }\n        return m_lazy_error_string;\n    }\n\n    void restore() {\n        if (m_restore_called) {\n            pybind11_fail(\"Internal error: pybind11::detail::error_fetch_and_normalize::restore() \"\n                          \"called a second time. ORIGINAL ERROR: \"\n                          + error_string());\n        }\n        PyErr_Restore(m_type.inc_ref().ptr(), m_value.inc_ref().ptr(), m_trace.inc_ref().ptr());\n        m_restore_called = true;\n    }\n\n    bool matches(handle exc) const {\n        return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0);\n    }\n\n    // Not protecting these for simplicity.\n    object m_type, m_value, m_trace;\n\nprivate:\n    // Only protecting invariants.\n    mutable std::string m_lazy_error_string;\n    mutable bool m_lazy_error_string_completed = false;\n    mutable bool m_restore_called = false;\n};\n\ninline std::string error_string() {\n    return error_fetch_and_normalize(\"pybind11::detail::error_string\").error_string();\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Fetch and hold an error which was already set in Python.  An instance of this is typically\n/// thrown to propagate python-side errors back through C++ which can either be caught manually or\n/// else falls back to the function dispatcher (which then raises the captured error back to\n/// python).\nclass PYBIND11_EXPORT_EXCEPTION error_already_set : public std::exception {\npublic:\n    /// Fetches the current Python exception (using PyErr_Fetch()), which will clear the\n    /// current Python error indicator.\n    error_already_set()\n        : m_fetched_error{new detail::error_fetch_and_normalize(\"pybind11::error_already_set\"),\n                          m_fetched_error_deleter} {}\n\n    /// The what() result is built lazily on demand.\n    /// WARNING: This member function needs to acquire the Python GIL. This can lead to\n    ///          crashes (undefined behavior) if the Python interpreter is finalizing.\n    const char *what() const noexcept override;\n\n    /// Restores the currently-held Python error (which will clear the Python error indicator first\n    /// if already set).\n    /// NOTE: This member function will always restore the normalized exception, which may or may\n    ///       not be the original Python exception.\n    /// WARNING: The GIL must be held when this member function is called!\n    void restore() { m_fetched_error->restore(); }\n\n    /// If it is impossible to raise the currently-held error, such as in a destructor, we can\n    /// write it out using Python's unraisable hook (`sys.unraisablehook`). The error context\n    /// should be some object whose `repr()` helps identify the location of the error. Python\n    /// already knows the type and value of the error, so there is no need to repeat that.\n    void discard_as_unraisable(object err_context) {\n        restore();\n        PyErr_WriteUnraisable(err_context.ptr());\n    }\n    /// An alternate version of `discard_as_unraisable()`, where a string provides information on\n    /// the location of the error. For example, `__func__` could be helpful.\n    /// WARNING: The GIL must be held when this member function is called!\n    void discard_as_unraisable(const char *err_context) {\n        discard_as_unraisable(reinterpret_steal<object>(PYBIND11_FROM_STRING(err_context)));\n    }\n\n    // Does nothing; provided for backwards compatibility.\n    PYBIND11_DEPRECATED(\"Use of error_already_set.clear() is deprecated\")\n    void clear() {}\n\n    /// Check if the currently trapped error type matches the given Python exception class (or a\n    /// subclass thereof).  May also be passed a tuple to search for any exception class matches in\n    /// the given tuple.\n    bool matches(handle exc) const { return m_fetched_error->matches(exc); }\n\n    const object &type() const { return m_fetched_error->m_type; }\n    const object &value() const { return m_fetched_error->m_value; }\n    const object &trace() const { return m_fetched_error->m_trace; }\n\nprivate:\n    std::shared_ptr<detail::error_fetch_and_normalize> m_fetched_error;\n\n    /// WARNING: This custom deleter needs to acquire the Python GIL. This can lead to\n    ///          crashes (undefined behavior) if the Python interpreter is finalizing.\n    static void m_fetched_error_deleter(detail::error_fetch_and_normalize *raw_ptr);\n};\n\n/// Replaces the current Python error indicator with the chosen error, performing a\n/// 'raise from' to indicate that the chosen error was caused by the original error.\ninline void raise_from(PyObject *type, const char *message) {\n    // Based on _PyErr_FormatVFromCause:\n    // https://github.com/python/cpython/blob/467ab194fc6189d9f7310c89937c51abeac56839/Python/errors.c#L405\n    // See https://github.com/pybind/pybind11/pull/2112 for details.\n    PyObject *exc = nullptr, *val = nullptr, *val2 = nullptr, *tb = nullptr;\n\n    assert(PyErr_Occurred());\n    PyErr_Fetch(&exc, &val, &tb);\n    PyErr_NormalizeException(&exc, &val, &tb);\n    if (tb != nullptr) {\n        PyException_SetTraceback(val, tb);\n        Py_DECREF(tb);\n    }\n    Py_DECREF(exc);\n    assert(!PyErr_Occurred());\n\n    PyErr_SetString(type, message);\n\n    PyErr_Fetch(&exc, &val2, &tb);\n    PyErr_NormalizeException(&exc, &val2, &tb);\n    Py_INCREF(val);\n    PyException_SetCause(val2, val);\n    PyException_SetContext(val2, val);\n    PyErr_Restore(exc, val2, tb);\n}\n\n/// Sets the current Python error indicator with the chosen error, performing a 'raise from'\n/// from the error contained in error_already_set to indicate that the chosen error was\n/// caused by the original error.\ninline void raise_from(error_already_set &err, PyObject *type, const char *message) {\n    err.restore();\n    raise_from(type, message);\n}\n\n/** \\defgroup python_builtins const_name\n    Unless stated otherwise, the following C++ functions behave the same\n    as their Python counterparts.\n */\n\n/** \\ingroup python_builtins\n    \\rst\n    Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of\n    `object` or a class which was exposed to Python as ``py::class_<T>``.\n\\endrst */\ntemplate <typename T, detail::enable_if_t<std::is_base_of<object, T>::value, int> = 0>\nbool isinstance(handle obj) {\n    return T::check_(obj);\n}\n\ntemplate <typename T, detail::enable_if_t<!std::is_base_of<object, T>::value, int> = 0>\nbool isinstance(handle obj) {\n    return detail::isinstance_generic(obj, typeid(T));\n}\n\ntemplate <>\ninline bool isinstance<handle>(handle) = delete;\ntemplate <>\ninline bool isinstance<object>(handle obj) {\n    return obj.ptr() != nullptr;\n}\n\n/// \\ingroup python_builtins\n/// Return true if ``obj`` is an instance of the ``type``.\ninline bool isinstance(handle obj, handle type) {\n    const auto result = PyObject_IsInstance(obj.ptr(), type.ptr());\n    if (result == -1) {\n        throw error_already_set();\n    }\n    return result != 0;\n}\n\n/// \\addtogroup python_builtins\n/// @{\ninline bool hasattr(handle obj, handle name) {\n    return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;\n}\n\ninline bool hasattr(handle obj, const char *name) {\n    return PyObject_HasAttrString(obj.ptr(), name) == 1;\n}\n\ninline void delattr(handle obj, handle name) {\n    if (PyObject_DelAttr(obj.ptr(), name.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline void delattr(handle obj, const char *name) {\n    if (PyObject_DelAttrString(obj.ptr(), name) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline object getattr(handle obj, handle name) {\n    PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ninline object getattr(handle obj, const char *name) {\n    PyObject *result = PyObject_GetAttrString(obj.ptr(), name);\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ninline object getattr(handle obj, handle name, handle default_) {\n    if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {\n        return reinterpret_steal<object>(result);\n    }\n    PyErr_Clear();\n    return reinterpret_borrow<object>(default_);\n}\n\ninline object getattr(handle obj, const char *name, handle default_) {\n    if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {\n        return reinterpret_steal<object>(result);\n    }\n    PyErr_Clear();\n    return reinterpret_borrow<object>(default_);\n}\n\ninline void setattr(handle obj, handle name, handle value) {\n    if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline void setattr(handle obj, const char *name, handle value) {\n    if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline ssize_t hash(handle obj) {\n    auto h = PyObject_Hash(obj.ptr());\n    if (h == -1) {\n        throw error_already_set();\n    }\n    return h;\n}\n\n/// @} python_builtins\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ninline handle get_function(handle value) {\n    if (value) {\n        if (PyInstanceMethod_Check(value.ptr())) {\n            value = PyInstanceMethod_GET_FUNCTION(value.ptr());\n        } else if (PyMethod_Check(value.ptr())) {\n            value = PyMethod_GET_FUNCTION(value.ptr());\n        }\n    }\n    return value;\n}\n\n// Reimplementation of python's dict helper functions to ensure that exceptions\n// aren't swallowed (see #2862)\n\n// copied from cpython _PyDict_GetItemStringWithError\ninline PyObject *dict_getitemstring(PyObject *v, const char *key) {\n    PyObject *kv = nullptr, *rv = nullptr;\n    kv = PyUnicode_FromString(key);\n    if (kv == nullptr) {\n        throw error_already_set();\n    }\n\n    rv = PyDict_GetItemWithError(v, kv);\n    Py_DECREF(kv);\n    if (rv == nullptr && PyErr_Occurred()) {\n        throw error_already_set();\n    }\n    return rv;\n}\n\ninline PyObject *dict_getitem(PyObject *v, PyObject *key) {\n    PyObject *rv = PyDict_GetItemWithError(v, key);\n    if (rv == nullptr && PyErr_Occurred()) {\n        throw error_already_set();\n    }\n    return rv;\n}\n\n// Helper aliases/functions to support implicit casting of values given to python\n// accessors/methods. When given a pyobject, this simply returns the pyobject as-is; for other C++\n// type, the value goes through pybind11::cast(obj) to convert it to an `object`.\ntemplate <typename T, enable_if_t<is_pyobject<T>::value, int> = 0>\nauto object_or_cast(T &&o) -> decltype(std::forward<T>(o)) {\n    return std::forward<T>(o);\n}\n// The following casting version is implemented in cast.h:\ntemplate <typename T, enable_if_t<!is_pyobject<T>::value, int> = 0>\nobject object_or_cast(T &&o);\n// Match a PyObject*, which we want to convert directly to handle via its converting constructor\ninline handle object_or_cast(PyObject *ptr) { return ptr; }\n\n#if defined(_MSC_VER) && _MSC_VER < 1920\n#    pragma warning(push)\n#    pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified\n#endif\ntemplate <typename Policy>\nclass accessor : public object_api<accessor<Policy>> {\n    using key_type = typename Policy::key_type;\n\npublic:\n    accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) {}\n    accessor(const accessor &) = default;\n    accessor(accessor &&) noexcept = default;\n\n    // accessor overload required to override default assignment operator (templates are not\n    // allowed to replace default compiler-generated assignments).\n    void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); }\n    void operator=(const accessor &a) & { operator=(handle(a)); }\n\n    template <typename T>\n    void operator=(T &&value) && {\n        Policy::set(obj, key, object_or_cast(std::forward<T>(value)));\n    }\n    template <typename T>\n    void operator=(T &&value) & {\n        get_cache() = ensure_object(object_or_cast(std::forward<T>(value)));\n    }\n\n    template <typename T = Policy>\n    PYBIND11_DEPRECATED(\n        \"Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)\")\n    explicit\n    operator enable_if_t<std::is_same<T, accessor_policies::str_attr>::value\n                             || std::is_same<T, accessor_policies::obj_attr>::value,\n                         bool>() const {\n        return hasattr(obj, key);\n    }\n    template <typename T = Policy>\n    PYBIND11_DEPRECATED(\"Use of obj[key] as bool is deprecated in favor of obj.contains(key)\")\n    explicit\n    operator enable_if_t<std::is_same<T, accessor_policies::generic_item>::value, bool>() const {\n        return obj.contains(key);\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator object() const { return get_cache(); }\n    PyObject *ptr() const { return get_cache().ptr(); }\n    template <typename T>\n    T cast() const {\n        return get_cache().template cast<T>();\n    }\n\nprivate:\n    static object ensure_object(object &&o) { return std::move(o); }\n    static object ensure_object(handle h) { return reinterpret_borrow<object>(h); }\n\n    object &get_cache() const {\n        if (!cache) {\n            cache = Policy::get(obj, key);\n        }\n        return cache;\n    }\n\nprivate:\n    handle obj;\n    key_type key;\n    mutable object cache;\n};\n#if defined(_MSC_VER) && _MSC_VER < 1920\n#    pragma warning(pop)\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(accessor_policies)\nstruct obj_attr {\n    using key_type = object;\n    static object get(handle obj, handle key) { return getattr(obj, key); }\n    static void set(handle obj, handle key, handle val) { setattr(obj, key, val); }\n};\n\nstruct str_attr {\n    using key_type = const char *;\n    static object get(handle obj, const char *key) { return getattr(obj, key); }\n    static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); }\n};\n\nstruct generic_item {\n    using key_type = object;\n\n    static object get(handle obj, handle key) {\n        PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\n    static void set(handle obj, handle key, handle val) {\n        if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct sequence_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PySequence_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PySequence_SetItem does not steal a reference to 'val'\n        if (PySequence_SetItem(obj.ptr(), ssize_t_cast(index), val.ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct list_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PyList_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_borrow<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PyList_SetItem steals a reference to 'val'\n        if (PyList_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct tuple_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PyTuple_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_borrow<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PyTuple_SetItem steals a reference to 'val'\n        if (PyTuple_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\nPYBIND11_NAMESPACE_END(accessor_policies)\n\n/// STL iterator template used for tuple, list, sequence and dict\ntemplate <typename Policy>\nclass generic_iterator : public Policy {\n    using It = generic_iterator;\n\npublic:\n    using difference_type = ssize_t;\n    using iterator_category = typename Policy::iterator_category;\n    using value_type = typename Policy::value_type;\n    using reference = typename Policy::reference;\n    using pointer = typename Policy::pointer;\n\n    generic_iterator() = default;\n    generic_iterator(handle seq, ssize_t index) : Policy(seq, index) {}\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator*() const { return Policy::dereference(); }\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator[](difference_type n) const { return *(*this + n); }\n    pointer operator->() const { return **this; }\n\n    It &operator++() {\n        Policy::increment();\n        return *this;\n    }\n    It operator++(int) {\n        auto copy = *this;\n        Policy::increment();\n        return copy;\n    }\n    It &operator--() {\n        Policy::decrement();\n        return *this;\n    }\n    It operator--(int) {\n        auto copy = *this;\n        Policy::decrement();\n        return copy;\n    }\n    It &operator+=(difference_type n) {\n        Policy::advance(n);\n        return *this;\n    }\n    It &operator-=(difference_type n) {\n        Policy::advance(-n);\n        return *this;\n    }\n\n    friend It operator+(const It &a, difference_type n) {\n        auto copy = a;\n        return copy += n;\n    }\n    friend It operator+(difference_type n, const It &b) { return b + n; }\n    friend It operator-(const It &a, difference_type n) {\n        auto copy = a;\n        return copy -= n;\n    }\n    friend difference_type operator-(const It &a, const It &b) { return a.distance_to(b); }\n\n    friend bool operator==(const It &a, const It &b) { return a.equal(b); }\n    friend bool operator!=(const It &a, const It &b) { return !(a == b); }\n    friend bool operator<(const It &a, const It &b) { return b - a > 0; }\n    friend bool operator>(const It &a, const It &b) { return b < a; }\n    friend bool operator>=(const It &a, const It &b) { return !(a < b); }\n    friend bool operator<=(const It &a, const It &b) { return !(a > b); }\n};\n\nPYBIND11_NAMESPACE_BEGIN(iterator_policies)\n/// Quick proxy class needed to implement ``operator->`` for iterators which can't return pointers\ntemplate <typename T>\nstruct arrow_proxy {\n    T value;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    arrow_proxy(T &&value) noexcept : value(std::move(value)) {}\n    T *operator->() const { return &value; }\n};\n\n/// Lightweight iterator policy using just a simple pointer: see ``PySequence_Fast_ITEMS``\nclass sequence_fast_readonly {\nprotected:\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = handle;\n    using reference = const handle; // PR #3263\n    using pointer = arrow_proxy<const handle>;\n\n    sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) {}\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference dereference() const { return *ptr; }\n    void increment() { ++ptr; }\n    void decrement() { --ptr; }\n    void advance(ssize_t n) { ptr += n; }\n    bool equal(const sequence_fast_readonly &b) const { return ptr == b.ptr; }\n    ssize_t distance_to(const sequence_fast_readonly &b) const { return ptr - b.ptr; }\n\nprivate:\n    PyObject **ptr;\n};\n\n/// Full read and write access using the sequence protocol: see ``detail::sequence_accessor``\nclass sequence_slow_readwrite {\nprotected:\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = object;\n    using reference = sequence_accessor;\n    using pointer = arrow_proxy<const sequence_accessor>;\n\n    sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) {}\n\n    reference dereference() const { return {obj, static_cast<size_t>(index)}; }\n    void increment() { ++index; }\n    void decrement() { --index; }\n    void advance(ssize_t n) { index += n; }\n    bool equal(const sequence_slow_readwrite &b) const { return index == b.index; }\n    ssize_t distance_to(const sequence_slow_readwrite &b) const { return index - b.index; }\n\nprivate:\n    handle obj;\n    ssize_t index;\n};\n\n/// Python's dictionary protocol permits this to be a forward iterator\nclass dict_readonly {\nprotected:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = std::pair<handle, handle>;\n    using reference = const value_type; // PR #3263\n    using pointer = arrow_proxy<const value_type>;\n\n    dict_readonly() = default;\n    dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); }\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference dereference() const { return {key, value}; }\n    void increment() {\n        if (PyDict_Next(obj.ptr(), &pos, &key, &value) == 0) {\n            pos = -1;\n        }\n    }\n    bool equal(const dict_readonly &b) const { return pos == b.pos; }\n\nprivate:\n    handle obj;\n    PyObject *key = nullptr, *value = nullptr;\n    ssize_t pos = -1;\n};\nPYBIND11_NAMESPACE_END(iterator_policies)\n\n#if !defined(PYPY_VERSION)\nusing tuple_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;\nusing list_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;\n#else\nusing tuple_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\nusing list_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\n#endif\n\nusing sequence_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\nusing dict_iterator = generic_iterator<iterator_policies::dict_readonly>;\n\ninline bool PyIterable_Check(PyObject *obj) {\n    PyObject *iter = PyObject_GetIter(obj);\n    if (iter) {\n        Py_DECREF(iter);\n        return true;\n    }\n    PyErr_Clear();\n    return false;\n}\n\ninline bool PyNone_Check(PyObject *o) { return o == Py_None; }\ninline bool PyEllipsis_Check(PyObject *o) { return o == Py_Ellipsis; }\n\n#ifdef PYBIND11_STR_LEGACY_PERMISSIVE\ninline bool PyUnicode_Check_Permissive(PyObject *o) {\n    return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o);\n}\n#    define PYBIND11_STR_CHECK_FUN detail::PyUnicode_Check_Permissive\n#else\n#    define PYBIND11_STR_CHECK_FUN PyUnicode_Check\n#endif\n\ninline bool PyStaticMethod_Check(PyObject *o) { return o->ob_type == &PyStaticMethod_Type; }\n\nclass kwargs_proxy : public handle {\npublic:\n    explicit kwargs_proxy(handle h) : handle(h) {}\n};\n\nclass args_proxy : public handle {\npublic:\n    explicit args_proxy(handle h) : handle(h) {}\n    kwargs_proxy operator*() const { return kwargs_proxy(*this); }\n};\n\n/// Python argument categories (using PEP 448 terms)\ntemplate <typename T>\nusing is_keyword = std::is_base_of<arg, T>;\ntemplate <typename T>\nusing is_s_unpacking = std::is_same<args_proxy, T>; // * unpacking\ntemplate <typename T>\nusing is_ds_unpacking = std::is_same<kwargs_proxy, T>; // ** unpacking\ntemplate <typename T>\nusing is_positional = satisfies_none_of<T, is_keyword, is_s_unpacking, is_ds_unpacking>;\ntemplate <typename T>\nusing is_keyword_or_ds = satisfies_any_of<T, is_keyword, is_ds_unpacking>;\n\n// Call argument collector forward declarations\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\nclass simple_collector;\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\nclass unpacking_collector;\n\nPYBIND11_NAMESPACE_END(detail)\n\n// TODO: After the deprecated constructors are removed, this macro can be simplified by\n//       inheriting ctors: `using Parent::Parent`. It's not an option right now because\n//       the `using` statement triggers the parent deprecation warning even if the ctor\n//       isn't even used.\n#define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                            \\\npublic:                                                                                           \\\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<\" #Name \">() or reinterpret_steal<\" #Name \">()\")  \\\n    Name(handle h, bool is_borrowed)                                                              \\\n        : Parent(is_borrowed ? Parent(h, borrowed_t{}) : Parent(h, stolen_t{})) {}                \\\n    Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) {}                                       \\\n    Name(handle h, stolen_t) : Parent(h, stolen_t{}) {}                                           \\\n    PYBIND11_DEPRECATED(\"Use py::isinstance<py::python_type>(obj) instead\")                       \\\n    bool check() const { return m_ptr != nullptr && (CheckFun(m_ptr) != 0); }                     \\\n    static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); }              \\\n    template <typename Policy_> /* NOLINTNEXTLINE(google-explicit-constructor) */                 \\\n    Name(const ::pybind11::detail::accessor<Policy_> &a) : Name(object(a)) {}\n\n#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)                                   \\\n    PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                                \\\n    /* This is deliberately not 'explicit' to allow implicit conversion from object: */           \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(const object &o)                                                                         \\\n        : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) {               \\\n        if (!m_ptr)                                                                               \\\n            throw ::pybind11::error_already_set();                                                \\\n    }                                                                                             \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) {  \\\n        if (!m_ptr)                                                                               \\\n            throw ::pybind11::error_already_set();                                                \\\n    }\n\n#define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun)                           \\\n    PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)                                       \\\n    Name() = default;\n\n#define PYBIND11_OBJECT_CHECK_FAILED(Name, o_ptr)                                                 \\\n    ::pybind11::type_error(\"Object of type '\"                                                     \\\n                           + ::pybind11::detail::get_fully_qualified_tp_name(Py_TYPE(o_ptr))      \\\n                           + \"' is not an instance of '\" #Name \"'\")\n\n#define PYBIND11_OBJECT(Name, Parent, CheckFun)                                                   \\\n    PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                                \\\n    /* This is deliberately not 'explicit' to allow implicit conversion from object: */           \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(const object &o) : Parent(o) {                                                           \\\n        if (m_ptr && !check_(m_ptr))                                                              \\\n            throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr);                                      \\\n    }                                                                                             \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(object &&o) : Parent(std::move(o)) {                                                     \\\n        if (m_ptr && !check_(m_ptr))                                                              \\\n            throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr);                                      \\\n    }\n\n#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun)                                           \\\n    PYBIND11_OBJECT(Name, Parent, CheckFun)                                                       \\\n    Name() = default;\n\n/// \\addtogroup pytypes\n/// @{\n\n/** \\rst\n    Wraps a Python iterator so that it can also be used as a C++ input iterator\n\n    Caveat: copying an iterator does not (and cannot) clone the internal\n    state of the Python iterable. This also applies to the post-increment\n    operator. This iterator should only be used to retrieve the current\n    value using ``operator*()``.\n\\endrst */\nclass iterator : public object {\npublic:\n    using iterator_category = std::input_iterator_tag;\n    using difference_type = ssize_t;\n    using value_type = handle;\n    using reference = const handle; // PR #3263\n    using pointer = const handle *;\n\n    PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check)\n\n    iterator &operator++() {\n        advance();\n        return *this;\n    }\n\n    iterator operator++(int) {\n        auto rv = *this;\n        advance();\n        return rv;\n    }\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator*() const {\n        if (m_ptr && !value.ptr()) {\n            auto &self = const_cast<iterator &>(*this);\n            self.advance();\n        }\n        return value;\n    }\n\n    pointer operator->() const {\n        operator*();\n        return &value;\n    }\n\n    /** \\rst\n         The value which marks the end of the iteration. ``it == iterator::sentinel()``\n         is equivalent to catching ``StopIteration`` in Python.\n\n         .. code-block:: cpp\n\n             void foo(py::iterator it) {\n                 while (it != py::iterator::sentinel()) {\n                    // use `*it`\n                    ++it;\n                 }\n             }\n    \\endrst */\n    static iterator sentinel() { return {}; }\n\n    friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); }\n    friend bool operator!=(const iterator &a, const iterator &b) { return a->ptr() != b->ptr(); }\n\nprivate:\n    void advance() {\n        value = reinterpret_steal<object>(PyIter_Next(m_ptr));\n        if (value.ptr() == nullptr && PyErr_Occurred()) {\n            throw error_already_set();\n        }\n    }\n\nprivate:\n    object value = {};\n};\n\nclass type : public object {\npublic:\n    PYBIND11_OBJECT(type, object, PyType_Check)\n\n    /// Return a type handle from a handle or an object\n    static handle handle_of(handle h) { return handle((PyObject *) Py_TYPE(h.ptr())); }\n\n    /// Return a type object from a handle or an object\n    static type of(handle h) { return type(type::handle_of(h), borrowed_t{}); }\n\n    // Defined in pybind11/cast.h\n    /// Convert C++ type to handle if previously registered. Does not convert\n    /// standard types, like int, float. etc. yet.\n    /// See https://github.com/pybind/pybind11/issues/2486\n    template <typename T>\n    static handle handle_of();\n\n    /// Convert C++ type to type if previously registered. Does not convert\n    /// standard types, like int, float. etc. yet.\n    /// See https://github.com/pybind/pybind11/issues/2486\n    template <typename T>\n    static type of() {\n        return type(type::handle_of<T>(), borrowed_t{});\n    }\n};\n\nclass iterable : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check)\n};\n\nclass bytes;\n\nclass str : public object {\npublic:\n    PYBIND11_OBJECT_CVT(str, object, PYBIND11_STR_CHECK_FUN, raw_str)\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    str(const char *c, const SzType &n)\n        : object(PyUnicode_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            if (PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            pybind11_fail(\"Could not allocate string object!\");\n        }\n    }\n\n    // 'explicit' is explicitly omitted from the following constructors to allow implicit\n    // conversion to py::str from C++ string-like objects\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(const char *c = \"\") : object(PyUnicode_FromString(c), stolen_t{}) {\n        if (!m_ptr) {\n            if (PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            pybind11_fail(\"Could not allocate string object!\");\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(const std::string &s) : str(s.data(), s.size()) {}\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n    // enable_if is needed to avoid \"ambiguous conversion\" errors (see PR #3521).\n    template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(T s) : str(s.data(), s.size()) {}\n\n#    ifdef PYBIND11_HAS_U8STRING\n    // reinterpret_cast here is safe (C++20 guarantees char8_t has the same size/alignment as char)\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(std::u8string_view s) : str(reinterpret_cast<const char *>(s.data()), s.size()) {}\n#    endif\n\n#endif\n\n    explicit str(const bytes &b);\n\n    /** \\rst\n        Return a string representation of the object. This is analogous to\n        the ``str()`` function in Python.\n    \\endrst */\n    explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string() const {\n        object temp = *this;\n        if (PyUnicode_Check(m_ptr)) {\n            temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(m_ptr));\n            if (!temp) {\n                throw error_already_set();\n            }\n        }\n        char *buffer = nullptr;\n        ssize_t length = 0;\n        if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {\n            throw error_already_set();\n        }\n        return std::string(buffer, (size_t) length);\n    }\n\n    template <typename... Args>\n    str format(Args &&...args) const {\n        return attr(\"format\")(std::forward<Args>(args)...);\n    }\n\nprivate:\n    /// Return string representation -- always returns a new reference, even if already a str\n    static PyObject *raw_str(PyObject *op) {\n        PyObject *str_value = PyObject_Str(op);\n        return str_value;\n    }\n};\n/// @} pytypes\n\ninline namespace literals {\n/** \\rst\n    String literal version of `str`\n \\endrst */\ninline str operator\"\" _s(const char *s, size_t size) { return {s, size}; }\n} // namespace literals\n\n/// \\addtogroup pytypes\n/// @{\nclass bytes : public object {\npublic:\n    PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK)\n\n    // Allow implicit conversion:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(const char *c = \"\") : object(PYBIND11_BYTES_FROM_STRING(c), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytes object!\");\n        }\n    }\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    bytes(const char *c, const SzType &n)\n        : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytes object!\");\n        }\n    }\n\n    // Allow implicit conversion:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(const std::string &s) : bytes(s.data(), s.size()) {}\n\n    explicit bytes(const pybind11::str &s);\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string() const { return string_op<std::string>(); }\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n    // enable_if is needed to avoid \"ambiguous conversion\" errors (see PR #3521).\n    template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(T s) : bytes(s.data(), s.size()) {}\n\n    // Obtain a string view that views the current `bytes` buffer value.  Note that this is only\n    // valid so long as the `bytes` instance remains alive and so generally should not outlive the\n    // lifetime of the `bytes` instance.\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string_view() const { return string_op<std::string_view>(); }\n#endif\nprivate:\n    template <typename T>\n    T string_op() const {\n        char *buffer = nullptr;\n        ssize_t length = 0;\n        if (PyBytes_AsStringAndSize(m_ptr, &buffer, &length) != 0) {\n            throw error_already_set();\n        }\n        return {buffer, static_cast<size_t>(length)};\n    }\n};\n// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors\n// are included in the doxygen group; close here and reopen after as a workaround\n/// @} pytypes\n\ninline bytes::bytes(const pybind11::str &s) {\n    object temp = s;\n    if (PyUnicode_Check(s.ptr())) {\n        temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(s.ptr()));\n        if (!temp) {\n            throw error_already_set();\n        }\n    }\n    char *buffer = nullptr;\n    ssize_t length = 0;\n    if (PyBytes_AsStringAndSize(temp.ptr(), &buffer, &length) != 0) {\n        throw error_already_set();\n    }\n    auto obj = reinterpret_steal<object>(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length));\n    if (!obj) {\n        pybind11_fail(\"Could not allocate bytes object!\");\n    }\n    m_ptr = obj.release().ptr();\n}\n\ninline str::str(const bytes &b) {\n    char *buffer = nullptr;\n    ssize_t length = 0;\n    if (PyBytes_AsStringAndSize(b.ptr(), &buffer, &length) != 0) {\n        throw error_already_set();\n    }\n    auto obj = reinterpret_steal<object>(PyUnicode_FromStringAndSize(buffer, length));\n    if (!obj) {\n        if (PyErr_Occurred()) {\n            throw error_already_set();\n        }\n        pybind11_fail(\"Could not allocate string object!\");\n    }\n    m_ptr = obj.release().ptr();\n}\n\n/// \\addtogroup pytypes\n/// @{\nclass bytearray : public object {\npublic:\n    PYBIND11_OBJECT_CVT(bytearray, object, PyByteArray_Check, PyByteArray_FromObject)\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    bytearray(const char *c, const SzType &n)\n        : object(PyByteArray_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytearray object!\");\n        }\n    }\n\n    bytearray() : bytearray(\"\", 0) {}\n\n    explicit bytearray(const std::string &s) : bytearray(s.data(), s.size()) {}\n\n    size_t size() const { return static_cast<size_t>(PyByteArray_Size(m_ptr)); }\n\n    explicit operator std::string() const {\n        char *buffer = PyByteArray_AS_STRING(m_ptr);\n        ssize_t size = PyByteArray_GET_SIZE(m_ptr);\n        return std::string(buffer, static_cast<size_t>(size));\n    }\n};\n// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors\n// are included in the doxygen group; close here and reopen after as a workaround\n/// @} pytypes\n\n/// \\addtogroup pytypes\n/// @{\nclass none : public object {\npublic:\n    PYBIND11_OBJECT(none, object, detail::PyNone_Check)\n    none() : object(Py_None, borrowed_t{}) {}\n};\n\nclass ellipsis : public object {\npublic:\n    PYBIND11_OBJECT(ellipsis, object, detail::PyEllipsis_Check)\n    ellipsis() : object(Py_Ellipsis, borrowed_t{}) {}\n};\n\nclass bool_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool)\n    bool_() : object(Py_False, borrowed_t{}) {}\n    // Allow implicit conversion from and to `bool`:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) {}\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator bool() const { return (m_ptr != nullptr) && PyLong_AsLong(m_ptr) != 0; }\n\nprivate:\n    /// Return the truth value of an object -- always returns a new reference\n    static PyObject *raw_bool(PyObject *op) {\n        const auto value = PyObject_IsTrue(op);\n        if (value == -1) {\n            return nullptr;\n        }\n        return handle(value != 0 ? Py_True : Py_False).inc_ref().ptr();\n    }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Converts a value to the given unsigned type.  If an error occurs, you get back (Unsigned) -1;\n// otherwise you get back the unsigned long or unsigned long long value cast to (Unsigned).\n// (The distinction is critically important when casting a returned -1 error value to some other\n// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).\ntemplate <typename Unsigned>\nUnsigned as_unsigned(PyObject *o) {\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))) {\n        unsigned long v = PyLong_AsUnsignedLong(o);\n        return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;\n    }\n    unsigned long long v = PyLong_AsUnsignedLongLong(o);\n    return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;\n}\nPYBIND11_NAMESPACE_END(detail)\n\nclass int_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long)\n    int_() : object(PyLong_FromLong(0), stolen_t{}) {}\n    // Allow implicit conversion from C++ integral types:\n    template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    int_(T value) {\n        if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {\n            if (std::is_signed<T>::value) {\n                m_ptr = PyLong_FromLong((long) value);\n            } else {\n                m_ptr = PyLong_FromUnsignedLong((unsigned long) value);\n            }\n        } else {\n            if (std::is_signed<T>::value) {\n                m_ptr = PyLong_FromLongLong((long long) value);\n            } else {\n                m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value);\n            }\n        }\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate int object!\");\n        }\n    }\n\n    template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator T() const {\n        return std::is_unsigned<T>::value  ? detail::as_unsigned<T>(m_ptr)\n               : sizeof(T) <= sizeof(long) ? (T) PyLong_AsLong(m_ptr)\n                                           : (T) PYBIND11_LONG_AS_LONGLONG(m_ptr);\n    }\n};\n\nclass float_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float)\n    // Allow implicit conversion from float/double:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    float_(float value) : object(PyFloat_FromDouble((double) value), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate float object!\");\n        }\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate float object!\");\n        }\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator float() const { return (float) PyFloat_AsDouble(m_ptr); }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator double() const { return (double) PyFloat_AsDouble(m_ptr); }\n};\n\nclass weakref : public object {\npublic:\n    PYBIND11_OBJECT_CVT_DEFAULT(weakref, object, PyWeakref_Check, raw_weakref)\n    explicit weakref(handle obj, handle callback = {})\n        : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            if (PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            pybind11_fail(\"Could not allocate weak reference!\");\n        }\n    }\n\nprivate:\n    static PyObject *raw_weakref(PyObject *o) { return PyWeakref_NewRef(o, nullptr); }\n};\n\nclass slice : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check)\n    slice(handle start, handle stop, handle step)\n        : object(PySlice_New(start.ptr(), stop.ptr(), step.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate slice object!\");\n        }\n    }\n\n#ifdef PYBIND11_HAS_OPTIONAL\n    slice(std::optional<ssize_t> start, std::optional<ssize_t> stop, std::optional<ssize_t> step)\n        : slice(index_to_object(start), index_to_object(stop), index_to_object(step)) {}\n#else\n    slice(ssize_t start_, ssize_t stop_, ssize_t step_)\n        : slice(int_(start_), int_(stop_), int_(step_)) {}\n#endif\n\n    bool\n    compute(size_t length, size_t *start, size_t *stop, size_t *step, size_t *slicelength) const {\n        return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr,\n                                    (ssize_t) length,\n                                    (ssize_t *) start,\n                                    (ssize_t *) stop,\n                                    (ssize_t *) step,\n                                    (ssize_t *) slicelength)\n               == 0;\n    }\n    bool compute(\n        ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {\n        return PySlice_GetIndicesEx(\n                   (PYBIND11_SLICE_OBJECT *) m_ptr, length, start, stop, step, slicelength)\n               == 0;\n    }\n\nprivate:\n    template <typename T>\n    static object index_to_object(T index) {\n        return index ? object(int_(*index)) : object(none());\n    }\n};\n\nclass capsule : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact)\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<capsule>() or reinterpret_steal<capsule>()\")\n    capsule(PyObject *ptr, bool is_borrowed)\n        : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) {}\n\n    explicit capsule(const void *value,\n                     const char *name = nullptr,\n                     PyCapsule_Destructor destructor = nullptr)\n        : object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    PYBIND11_DEPRECATED(\"Please use the ctor with value, name, destructor args\")\n    capsule(const void *value, PyCapsule_Destructor destructor)\n        : object(PyCapsule_New(const_cast<void *>(value), nullptr, destructor), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    capsule(const void *value, void (*destructor)(void *)) {\n        m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {\n            // guard if destructor called while err indicator is set\n            error_scope error_guard;\n            auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));\n            if (destructor == nullptr && PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            const char *name = get_name_in_error_scope(o);\n            void *ptr = PyCapsule_GetPointer(o, name);\n            if (ptr == nullptr) {\n                throw error_already_set();\n            }\n\n            if (destructor != nullptr) {\n                destructor(ptr);\n            }\n        });\n\n        if (!m_ptr || PyCapsule_SetContext(m_ptr, reinterpret_cast<void *>(destructor)) != 0) {\n            throw error_already_set();\n        }\n    }\n\n    explicit capsule(void (*destructor)()) {\n        m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {\n            const char *name = get_name_in_error_scope(o);\n            auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, name));\n            if (destructor == nullptr) {\n                throw error_already_set();\n            }\n            destructor();\n        });\n\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    template <typename T>\n    operator T *() const { // NOLINT(google-explicit-constructor)\n        return get_pointer<T>();\n    }\n\n    /// Get the pointer the capsule holds.\n    template <typename T = void>\n    T *get_pointer() const {\n        const auto *name = this->name();\n        T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));\n        if (!result) {\n            throw error_already_set();\n        }\n        return result;\n    }\n\n    /// Replaces a capsule's pointer *without* calling the destructor on the existing one.\n    void set_pointer(const void *value) {\n        if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {\n            throw error_already_set();\n        }\n    }\n\n    const char *name() const {\n        const char *name = PyCapsule_GetName(m_ptr);\n        if ((name == nullptr) && PyErr_Occurred()) {\n            throw error_already_set();\n        }\n        return name;\n    }\n\n    /// Replaces a capsule's name *without* calling the destructor on the existing one.\n    void set_name(const char *new_name) {\n        if (PyCapsule_SetName(m_ptr, new_name) != 0) {\n            throw error_already_set();\n        }\n    }\n\nprivate:\n    static const char *get_name_in_error_scope(PyObject *o) {\n        error_scope error_guard;\n\n        const char *name = PyCapsule_GetName(o);\n        if ((name == nullptr) && PyErr_Occurred()) {\n            // write out and consume error raised by call to PyCapsule_GetName\n            PyErr_WriteUnraisable(o);\n        }\n\n        return name;\n    }\n};\n\nclass tuple : public object {\npublic:\n    PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple)\n    template <typename SzType = ssize_t,\n              detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    // Some compilers generate link errors when using `const SzType &` here:\n    explicit tuple(SzType size = 0) : object(PyTuple_New(ssize_t_cast(size)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate tuple object!\");\n        }\n    }\n    size_t size() const { return (size_t) PyTuple_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }\n    template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>\n    detail::item_accessor operator[](T &&o) const {\n        return object::operator[](std::forward<T>(o));\n    }\n    detail::tuple_iterator begin() const { return {*this, 0}; }\n    detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }\n};\n\n// We need to put this into a separate function because the Intel compiler\n// fails to compile enable_if_t<all_of<is_keyword_or_ds<Args>...>::value> part below\n// (tested with ICC 2021.1 Beta 20200827).\ntemplate <typename... Args>\nconstexpr bool args_are_all_keyword_or_ds() {\n    return detail::all_of<detail::is_keyword_or_ds<Args>...>::value;\n}\n\nclass dict : public object {\npublic:\n    PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict)\n    dict() : object(PyDict_New(), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate dict object!\");\n        }\n    }\n    template <typename... Args,\n              typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>,\n              // MSVC workaround: it can't compile an out-of-line definition, so defer the\n              // collector\n              typename collector = detail::deferred_t<detail::unpacking_collector<>, Args...>>\n    explicit dict(Args &&...args) : dict(collector(std::forward<Args>(args)...).kwargs()) {}\n\n    size_t size() const { return (size_t) PyDict_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::dict_iterator begin() const { return {*this, 0}; }\n    detail::dict_iterator end() const { return {}; }\n    void clear() /* py-non-const */ { PyDict_Clear(ptr()); }\n    template <typename T>\n    bool contains(T &&key) const {\n        auto result = PyDict_Contains(m_ptr, detail::object_or_cast(std::forward<T>(key)).ptr());\n        if (result == -1) {\n            throw error_already_set();\n        }\n        return result == 1;\n    }\n\nprivate:\n    /// Call the `dict` Python type -- always returns a new reference\n    static PyObject *raw_dict(PyObject *op) {\n        if (PyDict_Check(op)) {\n            return handle(op).inc_ref().ptr();\n        }\n        return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr);\n    }\n};\n\nclass sequence : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check)\n    size_t size() const {\n        ssize_t result = PySequence_Size(m_ptr);\n        if (result == -1) {\n            throw error_already_set();\n        }\n        return (size_t) result;\n    }\n    bool empty() const { return size() == 0; }\n    detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }\n    template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>\n    detail::item_accessor operator[](T &&o) const {\n        return object::operator[](std::forward<T>(o));\n    }\n    detail::sequence_iterator begin() const { return {*this, 0}; }\n    detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }\n};\n\nclass list : public object {\npublic:\n    PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List)\n    template <typename SzType = ssize_t,\n              detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    // Some compilers generate link errors when using `const SzType &` here:\n    explicit list(SzType size = 0) : object(PyList_New(ssize_t_cast(size)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate list object!\");\n        }\n    }\n    size_t size() const { return (size_t) PyList_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::list_accessor operator[](size_t index) const { return {*this, index}; }\n    template <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>\n    detail::item_accessor operator[](T &&o) const {\n        return object::operator[](std::forward<T>(o));\n    }\n    detail::list_iterator begin() const { return {*this, 0}; }\n    detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }\n    template <typename T>\n    void append(T &&val) /* py-non-const */ {\n        if (PyList_Append(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n    template <typename IdxType,\n              typename ValType,\n              detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    void insert(const IdxType &index, ValType &&val) /* py-non-const */ {\n        if (PyList_Insert(m_ptr,\n                          ssize_t_cast(index),\n                          detail::object_or_cast(std::forward<ValType>(val)).ptr())\n            != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nclass args : public tuple {\n    PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check)\n};\nclass kwargs : public dict {\n    PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check)\n};\n\nclass anyset : public object {\npublic:\n    PYBIND11_OBJECT(anyset, object, PyAnySet_Check)\n    size_t size() const { return static_cast<size_t>(PySet_Size(m_ptr)); }\n    bool empty() const { return size() == 0; }\n    template <typename T>\n    bool contains(T &&val) const {\n        auto result = PySet_Contains(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr());\n        if (result == -1) {\n            throw error_already_set();\n        }\n        return result == 1;\n    }\n};\n\nclass set : public anyset {\npublic:\n    PYBIND11_OBJECT_CVT(set, anyset, PySet_Check, PySet_New)\n    set() : anyset(PySet_New(nullptr), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate set object!\");\n        }\n    }\n    template <typename T>\n    bool add(T &&val) /* py-non-const */ {\n        return PySet_Add(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) == 0;\n    }\n    void clear() /* py-non-const */ { PySet_Clear(m_ptr); }\n};\n\nclass frozenset : public anyset {\npublic:\n    PYBIND11_OBJECT_CVT(frozenset, anyset, PyFrozenSet_Check, PyFrozenSet_New)\n};\n\nclass function : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check)\n    handle cpp_function() const {\n        handle fun = detail::get_function(m_ptr);\n        if (fun && PyCFunction_Check(fun.ptr())) {\n            return fun;\n        }\n        return handle();\n    }\n    bool is_cpp_function() const { return (bool) cpp_function(); }\n};\n\nclass staticmethod : public object {\npublic:\n    PYBIND11_OBJECT_CVT(staticmethod, object, detail::PyStaticMethod_Check, PyStaticMethod_New)\n};\n\nclass buffer : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer)\n\n    buffer_info request(bool writable = false) const {\n        int flags = PyBUF_STRIDES | PyBUF_FORMAT;\n        if (writable) {\n            flags |= PyBUF_WRITABLE;\n        }\n        auto *view = new Py_buffer();\n        if (PyObject_GetBuffer(m_ptr, view, flags) != 0) {\n            delete view;\n            throw error_already_set();\n        }\n        return buffer_info(view);\n    }\n};\n\nclass memoryview : public object {\npublic:\n    PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject)\n\n    /** \\rst\n        Creates ``memoryview`` from ``buffer_info``.\n\n        ``buffer_info`` must be created from ``buffer::request()``. Otherwise\n        throws an exception.\n\n        For creating a ``memoryview`` from objects that support buffer protocol,\n        use ``memoryview(const object& obj)`` instead of this constructor.\n     \\endrst */\n    explicit memoryview(const buffer_info &info) {\n        if (!info.view()) {\n            pybind11_fail(\"Prohibited to create memoryview without Py_buffer\");\n        }\n        // Note: PyMemoryView_FromBuffer never increments obj reference.\n        m_ptr = (info.view()->obj) ? PyMemoryView_FromObject(info.view()->obj)\n                                   : PyMemoryView_FromBuffer(info.view());\n        if (!m_ptr) {\n            pybind11_fail(\"Unable to create memoryview from buffer descriptor\");\n        }\n    }\n\n    /** \\rst\n        Creates ``memoryview`` from static buffer.\n\n        This method is meant for providing a ``memoryview`` for C/C++ buffer not\n        managed by Python. The caller is responsible for managing the lifetime\n        of ``ptr`` and ``format``, which MUST outlive the memoryview constructed\n        here.\n\n        See also: Python C API documentation for `PyMemoryView_FromBuffer`_.\n\n        .. _PyMemoryView_FromBuffer:\n           https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer\n\n        :param ptr: Pointer to the buffer.\n        :param itemsize: Byte size of an element.\n        :param format: Pointer to the null-terminated format string. For\n            homogeneous Buffers, this should be set to\n            ``format_descriptor<T>::value``.\n        :param shape: Shape of the tensor (1 entry per dimension).\n        :param strides: Number of bytes between adjacent entries (for each\n            per dimension).\n        :param readonly: Flag to indicate if the underlying storage may be\n            written to.\n     \\endrst */\n    static memoryview from_buffer(void *ptr,\n                                  ssize_t itemsize,\n                                  const char *format,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides,\n                                  bool readonly = false);\n\n    static memoryview from_buffer(const void *ptr,\n                                  ssize_t itemsize,\n                                  const char *format,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides) {\n        return memoryview::from_buffer(\n            const_cast<void *>(ptr), itemsize, format, std::move(shape), std::move(strides), true);\n    }\n\n    template <typename T>\n    static memoryview from_buffer(T *ptr,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides,\n                                  bool readonly = false) {\n        return memoryview::from_buffer(reinterpret_cast<void *>(ptr),\n                                       sizeof(T),\n                                       format_descriptor<T>::value,\n                                       std::move(shape),\n                                       std::move(strides),\n                                       readonly);\n    }\n\n    template <typename T>\n    static memoryview from_buffer(const T *ptr,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides) {\n        return memoryview::from_buffer(\n            const_cast<T *>(ptr), std::move(shape), std::move(strides), true);\n    }\n\n    /** \\rst\n        Creates ``memoryview`` from static memory.\n\n        This method is meant for providing a ``memoryview`` for C/C++ buffer not\n        managed by Python. The caller is responsible for managing the lifetime\n        of ``mem``, which MUST outlive the memoryview constructed here.\n\n        See also: Python C API documentation for `PyMemoryView_FromBuffer`_.\n\n        .. _PyMemoryView_FromMemory:\n           https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory\n     \\endrst */\n    static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) {\n        PyObject *ptr = PyMemoryView_FromMemory(\n            reinterpret_cast<char *>(mem), size, (readonly) ? PyBUF_READ : PyBUF_WRITE);\n        if (!ptr) {\n            pybind11_fail(\"Could not allocate memoryview object!\");\n        }\n        return memoryview(object(ptr, stolen_t{}));\n    }\n\n    static memoryview from_memory(const void *mem, ssize_t size) {\n        return memoryview::from_memory(const_cast<void *>(mem), size, true);\n    }\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n    static memoryview from_memory(std::string_view mem) {\n        return from_memory(const_cast<char *>(mem.data()), static_cast<ssize_t>(mem.size()), true);\n    }\n#endif\n};\n\n/// @cond DUPLICATE\ninline memoryview memoryview::from_buffer(void *ptr,\n                                          ssize_t itemsize,\n                                          const char *format,\n                                          detail::any_container<ssize_t> shape,\n                                          detail::any_container<ssize_t> strides,\n                                          bool readonly) {\n    size_t ndim = shape->size();\n    if (ndim != strides->size()) {\n        pybind11_fail(\"memoryview: shape length doesn't match strides length\");\n    }\n    ssize_t size = ndim != 0u ? 1 : 0;\n    for (size_t i = 0; i < ndim; ++i) {\n        size *= (*shape)[i];\n    }\n    Py_buffer view;\n    view.buf = ptr;\n    view.obj = nullptr;\n    view.len = size * itemsize;\n    view.readonly = static_cast<int>(readonly);\n    view.itemsize = itemsize;\n    view.format = const_cast<char *>(format);\n    view.ndim = static_cast<int>(ndim);\n    view.shape = shape->data();\n    view.strides = strides->data();\n    view.suboffsets = nullptr;\n    view.internal = nullptr;\n    PyObject *obj = PyMemoryView_FromBuffer(&view);\n    if (!obj) {\n        throw error_already_set();\n    }\n    return memoryview(object(obj, stolen_t{}));\n}\n/// @endcond\n/// @} pytypes\n\n/// \\addtogroup python_builtins\n/// @{\n\n/// Get the length of a Python object.\ninline size_t len(handle h) {\n    ssize_t result = PyObject_Length(h.ptr());\n    if (result < 0) {\n        throw error_already_set();\n    }\n    return (size_t) result;\n}\n\n/// Get the length hint of a Python object.\n/// Returns 0 when this cannot be determined.\ninline size_t len_hint(handle h) {\n    ssize_t result = PyObject_LengthHint(h.ptr(), 0);\n    if (result < 0) {\n        // Sometimes a length can't be determined at all (eg generators)\n        // In which case simply return 0\n        PyErr_Clear();\n        return 0;\n    }\n    return (size_t) result;\n}\n\ninline str repr(handle h) {\n    PyObject *str_value = PyObject_Repr(h.ptr());\n    if (!str_value) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<str>(str_value);\n}\n\ninline iterator iter(handle obj) {\n    PyObject *result = PyObject_GetIter(obj.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<iterator>(result);\n}\n/// @} python_builtins\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename D>\niterator object_api<D>::begin() const {\n    return iter(derived());\n}\ntemplate <typename D>\niterator object_api<D>::end() const {\n    return iterator::sentinel();\n}\ntemplate <typename D>\nitem_accessor object_api<D>::operator[](handle key) const {\n    return {derived(), reinterpret_borrow<object>(key)};\n}\ntemplate <typename D>\nitem_accessor object_api<D>::operator[](object &&key) const {\n    return {derived(), std::move(key)};\n}\ntemplate <typename D>\nitem_accessor object_api<D>::operator[](const char *key) const {\n    return {derived(), pybind11::str(key)};\n}\ntemplate <typename D>\nobj_attr_accessor object_api<D>::attr(handle key) const {\n    return {derived(), reinterpret_borrow<object>(key)};\n}\ntemplate <typename D>\nobj_attr_accessor object_api<D>::attr(object &&key) const {\n    return {derived(), std::move(key)};\n}\ntemplate <typename D>\nstr_attr_accessor object_api<D>::attr(const char *key) const {\n    return {derived(), key};\n}\ntemplate <typename D>\nargs_proxy object_api<D>::operator*() const {\n    return args_proxy(derived().ptr());\n}\ntemplate <typename D>\ntemplate <typename T>\nbool object_api<D>::contains(T &&item) const {\n    return attr(\"__contains__\")(std::forward<T>(item)).template cast<bool>();\n}\n\ntemplate <typename D>\npybind11::str object_api<D>::str() const {\n    return pybind11::str(derived());\n}\n\ntemplate <typename D>\nstr_attr_accessor object_api<D>::doc() const {\n    return attr(\"__doc__\");\n}\n\ntemplate <typename D>\nhandle object_api<D>::get_type() const {\n    return type::handle_of(derived());\n}\n\ntemplate <typename D>\nbool object_api<D>::rich_compare(object_api const &other, int value) const {\n    int rv = PyObject_RichCompareBool(derived().ptr(), other.derived().ptr(), value);\n    if (rv == -1) {\n        throw error_already_set();\n    }\n    return rv == 1;\n}\n\n#define PYBIND11_MATH_OPERATOR_UNARY(op, fn)                                                      \\\n    template <typename D>                                                                         \\\n    object object_api<D>::op() const {                                                            \\\n        object result = reinterpret_steal<object>(fn(derived().ptr()));                           \\\n        if (!result.ptr())                                                                        \\\n            throw error_already_set();                                                            \\\n        return result;                                                                            \\\n    }\n\n#define PYBIND11_MATH_OPERATOR_BINARY(op, fn)                                                     \\\n    template <typename D>                                                                         \\\n    object object_api<D>::op(object_api const &other) const {                                     \\\n        object result = reinterpret_steal<object>(fn(derived().ptr(), other.derived().ptr()));    \\\n        if (!result.ptr())                                                                        \\\n            throw error_already_set();                                                            \\\n        return result;                                                                            \\\n    }\n\n#define PYBIND11_MATH_OPERATOR_BINARY_INPLACE(iop, fn)                                            \\\n    template <typename D>                                                                         \\\n    object object_api<D>::iop(object_api const &other) {                                          \\\n        object result = reinterpret_steal<object>(fn(derived().ptr(), other.derived().ptr()));    \\\n        if (!result.ptr())                                                                        \\\n            throw error_already_set();                                                            \\\n        return result;                                                                            \\\n    }\n\nPYBIND11_MATH_OPERATOR_UNARY(operator~, PyNumber_Invert)\nPYBIND11_MATH_OPERATOR_UNARY(operator-, PyNumber_Negative)\nPYBIND11_MATH_OPERATOR_BINARY(operator+, PyNumber_Add)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator+=, PyNumber_InPlaceAdd)\nPYBIND11_MATH_OPERATOR_BINARY(operator-, PyNumber_Subtract)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator-=, PyNumber_InPlaceSubtract)\nPYBIND11_MATH_OPERATOR_BINARY(operator*, PyNumber_Multiply)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator*=, PyNumber_InPlaceMultiply)\nPYBIND11_MATH_OPERATOR_BINARY(operator/, PyNumber_TrueDivide)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator/=, PyNumber_InPlaceTrueDivide)\nPYBIND11_MATH_OPERATOR_BINARY(operator|, PyNumber_Or)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator|=, PyNumber_InPlaceOr)\nPYBIND11_MATH_OPERATOR_BINARY(operator&, PyNumber_And)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator&=, PyNumber_InPlaceAnd)\nPYBIND11_MATH_OPERATOR_BINARY(operator^, PyNumber_Xor)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator^=, PyNumber_InPlaceXor)\nPYBIND11_MATH_OPERATOR_BINARY(operator<<, PyNumber_Lshift)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator<<=, PyNumber_InPlaceLshift)\nPYBIND11_MATH_OPERATOR_BINARY(operator>>, PyNumber_Rshift)\nPYBIND11_MATH_OPERATOR_BINARY_INPLACE(operator>>=, PyNumber_InPlaceRshift)\n\n#undef PYBIND11_MATH_OPERATOR_UNARY\n#undef PYBIND11_MATH_OPERATOR_BINARY\n#undef PYBIND11_MATH_OPERATOR_BINARY_INPLACE\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/stl/filesystem.h",
    "content": "// Copyright (c) 2021 The Pybind Development Team.\n// All rights reserved. Use of this source code is governed by a\n// BSD-style license that can be found in the LICENSE file.\n\n#pragma once\n\n#include \"../pybind11.h\"\n#include \"../detail/common.h\"\n#include \"../detail/descr.h\"\n#include \"../cast.h\"\n#include \"../pytypes.h\"\n\n#include <string>\n\n#ifdef __has_include\n#    if defined(PYBIND11_CPP17)\n#        if __has_include(<filesystem>) && \\\n          PY_VERSION_HEX >= 0x03060000\n#            include <filesystem>\n#            define PYBIND11_HAS_FILESYSTEM 1\n#        elif __has_include(<experimental/filesystem>)\n#            include <experimental/filesystem>\n#            define PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM 1\n#        endif\n#    endif\n#endif\n\n#if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)           \\\n    && !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)\n#    error                                                                                        \\\n        \"Neither #include <filesystem> nor #include <experimental/filesystem is available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)\"\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if defined(PYBIND11_HAS_FILESYSTEM) || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)\ntemplate <typename T>\nstruct path_caster {\n\nprivate:\n    static PyObject *unicode_from_fs_native(const std::string &w) {\n#    if !defined(PYPY_VERSION)\n        return PyUnicode_DecodeFSDefaultAndSize(w.c_str(), ssize_t(w.size()));\n#    else\n        // PyPy mistakenly declares the first parameter as non-const.\n        return PyUnicode_DecodeFSDefaultAndSize(const_cast<char *>(w.c_str()), ssize_t(w.size()));\n#    endif\n    }\n\n    static PyObject *unicode_from_fs_native(const std::wstring &w) {\n        return PyUnicode_FromWideChar(w.c_str(), ssize_t(w.size()));\n    }\n\npublic:\n    static handle cast(const T &path, return_value_policy, handle) {\n        if (auto py_str = unicode_from_fs_native(path.native())) {\n            return module_::import(\"pathlib\")\n                .attr(\"Path\")(reinterpret_steal<object>(py_str))\n                .release();\n        }\n        return nullptr;\n    }\n\n    bool load(handle handle, bool) {\n        // PyUnicode_FSConverter and PyUnicode_FSDecoder normally take care of\n        // calling PyOS_FSPath themselves, but that's broken on PyPy (PyPy\n        // issue #3168) so we do it ourselves instead.\n        PyObject *buf = PyOS_FSPath(handle.ptr());\n        if (!buf) {\n            PyErr_Clear();\n            return false;\n        }\n        PyObject *native = nullptr;\n        if constexpr (std::is_same_v<typename T::value_type, char>) {\n            if (PyUnicode_FSConverter(buf, &native) != 0) {\n                if (auto *c_str = PyBytes_AsString(native)) {\n                    // AsString returns a pointer to the internal buffer, which\n                    // must not be free'd.\n                    value = c_str;\n                }\n            }\n        } else if constexpr (std::is_same_v<typename T::value_type, wchar_t>) {\n            if (PyUnicode_FSDecoder(buf, &native) != 0) {\n                if (auto *c_str = PyUnicode_AsWideCharString(native, nullptr)) {\n                    // AsWideCharString returns a new string that must be free'd.\n                    value = c_str; // Copies the string.\n                    PyMem_Free(c_str);\n                }\n            }\n        }\n        Py_XDECREF(native);\n        Py_DECREF(buf);\n        if (PyErr_Occurred()) {\n            PyErr_Clear();\n            return false;\n        }\n        return true;\n    }\n\n    PYBIND11_TYPE_CASTER(T, const_name(\"os.PathLike\"));\n};\n\n#endif // PYBIND11_HAS_FILESYSTEM || defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)\n\n#if defined(PYBIND11_HAS_FILESYSTEM)\ntemplate <>\nstruct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};\n#elif defined(PYBIND11_HAS_EXPERIMENTAL_FILESYSTEM)\ntemplate <>\nstruct type_caster<std::experimental::filesystem::path>\n    : public path_caster<std::experimental::filesystem::path> {};\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/stl.h",
    "content": "/*\n    pybind11/stl.h: Transparent conversion for STL data types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"detail/common.h\"\n\n#include <deque>\n#include <list>\n#include <map>\n#include <ostream>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n\n// See `detail/common.h` for implementation of these guards.\n#if defined(PYBIND11_HAS_OPTIONAL)\n#    include <optional>\n#elif defined(PYBIND11_HAS_EXP_OPTIONAL)\n#    include <experimental/optional>\n#endif\n\n#if defined(PYBIND11_HAS_VARIANT)\n#    include <variant>\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for\n/// forwarding a container element).  Typically used indirect via forwarded_type(), below.\ntemplate <typename T, typename U>\nusing forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,\n                                     remove_reference_t<U> &,\n                                     remove_reference_t<U> &&>;\n\n/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically\n/// used for forwarding a container's elements.\ntemplate <typename T, typename U>\nconstexpr forwarded_type<T, U> forward_like(U &&u) {\n    return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));\n}\n\n// Checks if a container has a STL style reserve method.\n// This will only return true for a `reserve()` with a `void` return.\ntemplate <typename C>\nusing has_reserve_method = std::is_same<decltype(std::declval<C>().reserve(0)), void>;\n\ntemplate <typename Type, typename Key>\nstruct set_caster {\n    using type = Type;\n    using key_conv = make_caster<Key>;\n\nprivate:\n    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>\n    void reserve_maybe(const anyset &s, Type *) {\n        value.reserve(s.size());\n    }\n    void reserve_maybe(const anyset &, void *) {}\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<anyset>(src)) {\n            return false;\n        }\n        auto s = reinterpret_borrow<anyset>(src);\n        value.clear();\n        reserve_maybe(s, &value);\n        for (auto entry : s) {\n            key_conv conv;\n            if (!conv.load(entry, convert)) {\n                return false;\n            }\n            value.insert(cast_op<Key &&>(std::move(conv)));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Key>::policy(policy);\n        }\n        pybind11::set s;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                key_conv::cast(detail::forward_like<T>(value), policy, parent));\n            if (!value_ || !s.add(std::move(value_))) {\n                return handle();\n            }\n        }\n        return s.release();\n    }\n\n    PYBIND11_TYPE_CASTER(type, const_name(\"Set[\") + key_conv::name + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Key, typename Value>\nstruct map_caster {\n    using key_conv = make_caster<Key>;\n    using value_conv = make_caster<Value>;\n\nprivate:\n    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>\n    void reserve_maybe(const dict &d, Type *) {\n        value.reserve(d.size());\n    }\n    void reserve_maybe(const dict &, void *) {}\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<dict>(src)) {\n            return false;\n        }\n        auto d = reinterpret_borrow<dict>(src);\n        value.clear();\n        reserve_maybe(d, &value);\n        for (auto it : d) {\n            key_conv kconv;\n            value_conv vconv;\n            if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {\n                return false;\n            }\n            value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        dict d;\n        return_value_policy policy_key = policy;\n        return_value_policy policy_value = policy;\n        if (!std::is_lvalue_reference<T>::value) {\n            policy_key = return_value_policy_override<Key>::policy(policy_key);\n            policy_value = return_value_policy_override<Value>::policy(policy_value);\n        }\n        for (auto &&kv : src) {\n            auto key = reinterpret_steal<object>(\n                key_conv::cast(detail::forward_like<T>(kv.first), policy_key, parent));\n            auto value = reinterpret_steal<object>(\n                value_conv::cast(detail::forward_like<T>(kv.second), policy_value, parent));\n            if (!key || !value) {\n                return handle();\n            }\n            d[std::move(key)] = std::move(value);\n        }\n        return d.release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name(\"Dict[\") + key_conv::name + const_name(\", \") + value_conv::name\n                             + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Value>\nstruct list_caster {\n    using value_conv = make_caster<Value>;\n\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {\n            return false;\n        }\n        auto s = reinterpret_borrow<sequence>(src);\n        value.clear();\n        reserve_maybe(s, &value);\n        for (auto it : s) {\n            value_conv conv;\n            if (!conv.load(it, convert)) {\n                return false;\n            }\n            value.push_back(cast_op<Value &&>(std::move(conv)));\n        }\n        return true;\n    }\n\nprivate:\n    template <typename T = Type, enable_if_t<has_reserve_method<T>::value, int> = 0>\n    void reserve_maybe(const sequence &s, Type *) {\n        value.reserve(s.size());\n    }\n    void reserve_maybe(const sequence &, void *) {}\n\npublic:\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Value>::policy(policy);\n        }\n        list l(src.size());\n        ssize_t index = 0;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                value_conv::cast(detail::forward_like<T>(value), policy, parent));\n            if (!value_) {\n                return handle();\n            }\n            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference\n        }\n        return l.release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type, const_name(\"List[\") + value_conv::name + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};\n\ntemplate <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>\nstruct array_caster {\n    using value_conv = make_caster<Value>;\n\nprivate:\n    template <bool R = Resizable>\n    bool require_size(enable_if_t<R, size_t> size) {\n        if (value.size() != size) {\n            value.resize(size);\n        }\n        return true;\n    }\n    template <bool R = Resizable>\n    bool require_size(enable_if_t<!R, size_t> size) {\n        return size == Size;\n    }\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src)) {\n            return false;\n        }\n        auto l = reinterpret_borrow<sequence>(src);\n        if (!require_size(l.size())) {\n            return false;\n        }\n        size_t ctr = 0;\n        for (auto it : l) {\n            value_conv conv;\n            if (!conv.load(it, convert)) {\n                return false;\n            }\n            value[ctr++] = cast_op<Value &&>(std::move(conv));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        list l(src.size());\n        ssize_t index = 0;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                value_conv::cast(detail::forward_like<T>(value), policy, parent));\n            if (!value_) {\n                return handle();\n            }\n            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference\n        }\n        return l.release();\n    }\n\n    PYBIND11_TYPE_CASTER(ArrayType,\n                         const_name(\"List[\") + value_conv::name\n                             + const_name<Resizable>(const_name(\"\"),\n                                                     const_name(\"[\") + const_name<Size>()\n                                                         + const_name(\"]\"))\n                             + const_name(\"]\"));\n};\n\ntemplate <typename Type, size_t Size>\nstruct type_caster<std::array<Type, Size>>\n    : array_caster<std::array<Type, Size>, Type, false, Size> {};\n\ntemplate <typename Type>\nstruct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};\n\ntemplate <typename Key, typename Compare, typename Alloc>\nstruct type_caster<std::set<Key, Compare, Alloc>>\n    : set_caster<std::set<Key, Compare, Alloc>, Key> {};\n\ntemplate <typename Key, typename Hash, typename Equal, typename Alloc>\nstruct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>\n    : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};\n\ntemplate <typename Key, typename Value, typename Compare, typename Alloc>\nstruct type_caster<std::map<Key, Value, Compare, Alloc>>\n    : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};\n\ntemplate <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>\nstruct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>\n    : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};\n\n// This type caster is intended to be used for std::optional and std::experimental::optional\ntemplate <typename Type, typename Value = typename Type::value_type>\nstruct optional_caster {\n    using value_conv = make_caster<Value>;\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().release();\n        }\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Value>::policy(policy);\n        }\n        return value_conv::cast(*std::forward<T>(src), policy, parent);\n    }\n\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.is_none()) {\n            return true; // default-constructed value is already empty\n        }\n        value_conv inner_caster;\n        if (!inner_caster.load(src, convert)) {\n            return false;\n        }\n\n        value.emplace(cast_op<Value &&>(std::move(inner_caster)));\n        return true;\n    }\n\n    PYBIND11_TYPE_CASTER(Type, const_name(\"Optional[\") + value_conv::name + const_name(\"]\"));\n};\n\n#if defined(PYBIND11_HAS_OPTIONAL)\ntemplate <typename T>\nstruct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};\n\ntemplate <>\nstruct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};\n#endif\n\n#if defined(PYBIND11_HAS_EXP_OPTIONAL)\ntemplate <typename T>\nstruct type_caster<std::experimental::optional<T>>\n    : public optional_caster<std::experimental::optional<T>> {};\n\ntemplate <>\nstruct type_caster<std::experimental::nullopt_t>\n    : public void_caster<std::experimental::nullopt_t> {};\n#endif\n\n/// Visit a variant and cast any found type to Python\nstruct variant_caster_visitor {\n    return_value_policy policy;\n    handle parent;\n\n    using result_type = handle; // required by boost::variant in C++11\n\n    template <typename T>\n    result_type operator()(T &&src) const {\n        return make_caster<T>::cast(std::forward<T>(src), policy, parent);\n    }\n};\n\n/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar\n/// `namespace::variant` types which provide a `namespace::visit()` function are handled here\n/// automatically using argument-dependent lookup. Users can provide specializations for other\n/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.\ntemplate <template <typename...> class Variant>\nstruct visit_helper {\n    template <typename... Args>\n    static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {\n        return visit(std::forward<Args>(args)...);\n    }\n};\n\n/// Generic variant caster\ntemplate <typename Variant>\nstruct variant_caster;\n\ntemplate <template <typename...> class V, typename... Ts>\nstruct variant_caster<V<Ts...>> {\n    static_assert(sizeof...(Ts) > 0, \"Variant must consist of at least one alternative.\");\n\n    template <typename U, typename... Us>\n    bool load_alternative(handle src, bool convert, type_list<U, Us...>) {\n        auto caster = make_caster<U>();\n        if (caster.load(src, convert)) {\n            value = cast_op<U>(std::move(caster));\n            return true;\n        }\n        return load_alternative(src, convert, type_list<Us...>{});\n    }\n\n    bool load_alternative(handle, bool, type_list<>) { return false; }\n\n    bool load(handle src, bool convert) {\n        // Do a first pass without conversions to improve constructor resolution.\n        // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`\n        // slot of the variant. Without two-pass loading `double` would be filled\n        // because it appears first and a conversion is possible.\n        if (convert && load_alternative(src, false, type_list<Ts...>{})) {\n            return true;\n        }\n        return load_alternative(src, convert, type_list<Ts...>{});\n    }\n\n    template <typename Variant>\n    static handle cast(Variant &&src, return_value_policy policy, handle parent) {\n        return visit_helper<V>::call(variant_caster_visitor{policy, parent},\n                                     std::forward<Variant>(src));\n    }\n\n    using Type = V<Ts...>;\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name(\"Union[\") + detail::concat(make_caster<Ts>::name...)\n                             + const_name(\"]\"));\n};\n\n#if defined(PYBIND11_HAS_VARIANT)\ntemplate <typename... Ts>\nstruct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};\n\ntemplate <>\nstruct type_caster<std::monostate> : public void_caster<std::monostate> {};\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\ninline std::ostream &operator<<(std::ostream &os, const handle &obj) {\n#ifdef PYBIND11_HAS_STRING_VIEW\n    os << str(obj).cast<std::string_view>();\n#else\n    os << (std::string) str(obj);\n#endif\n    return os;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/include/pybind11/stl_bind.h",
    "content": "/*\n    pybind11/std_bind.h: Binding generators for STL data types\n\n    Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"operators.h\"\n\n#include <algorithm>\n#include <sstream>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/* SFINAE helper class used by 'is_comparable */\ntemplate <typename T>\nstruct container_traits {\n    template <typename T2>\n    static std::true_type\n    test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);\n    template <typename T2>\n    static std::false_type test_comparable(...);\n    template <typename T2>\n    static std::true_type test_value(typename T2::value_type *);\n    template <typename T2>\n    static std::false_type test_value(...);\n    template <typename T2>\n    static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);\n    template <typename T2>\n    static std::false_type test_pair(...);\n\n    static constexpr const bool is_comparable\n        = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;\n    static constexpr const bool is_pair\n        = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;\n    static constexpr const bool is_vector\n        = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;\n    static constexpr const bool is_element = !is_pair && !is_vector;\n};\n\n/* Default: is_comparable -> std::false_type */\ntemplate <typename T, typename SFINAE = void>\nstruct is_comparable : std::false_type {};\n\n/* For non-map data structures, check whether operator== can be instantiated */\ntemplate <typename T>\nstruct is_comparable<\n    T,\n    enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>\n    : std::true_type {};\n\n/* For a vector/map data structure, recursively check the value type\n   (which is std::pair for maps) */\ntemplate <typename T>\nstruct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {\n    static constexpr const bool value = is_comparable<typename T::value_type>::value;\n};\n\n/* For pairs, recursively check the two data types */\ntemplate <typename T>\nstruct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {\n    static constexpr const bool value = is_comparable<typename T::first_type>::value\n                                        && is_comparable<typename T::second_type>::value;\n};\n\n/* Fallback functions */\ntemplate <typename, typename, typename... Args>\nvoid vector_if_copy_constructible(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_if_equal_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_if_insertion_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_modifiers(const Args &...) {}\n\ntemplate <typename Vector, typename Class_>\nvoid vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {\n    cl.def(init<const Vector &>(), \"Copy constructor\");\n}\n\ntemplate <typename Vector, typename Class_>\nvoid vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n\n    cl.def(self == self);\n    cl.def(self != self);\n\n    cl.def(\n        \"count\",\n        [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },\n        arg(\"x\"),\n        \"Return the number of times ``x`` appears in the list\");\n\n    cl.def(\n        \"remove\",\n        [](Vector &v, const T &x) {\n            auto p = std::find(v.begin(), v.end(), x);\n            if (p != v.end()) {\n                v.erase(p);\n            } else {\n                throw value_error();\n            }\n        },\n        arg(\"x\"),\n        \"Remove the first item from the list whose value is x. \"\n        \"It is an error if there is no such item.\");\n\n    cl.def(\n        \"__contains__\",\n        [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },\n        arg(\"x\"),\n        \"Return true the container contains ``x``\");\n}\n\n// Vector modifiers -- requires a copyable vector_type:\n// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it\n// seems silly to allow deletion but not insertion, so include them here too.)\ntemplate <typename Vector, typename Class_>\nvoid vector_modifiers(\n    enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n\n    auto wrap_i = [](DiffType i, SizeType n) {\n        if (i < 0) {\n            i += n;\n        }\n        if (i < 0 || (SizeType) i >= n) {\n            throw index_error();\n        }\n        return i;\n    };\n\n    cl.def(\n        \"append\",\n        [](Vector &v, const T &value) { v.push_back(value); },\n        arg(\"x\"),\n        \"Add an item to the end of the list\");\n\n    cl.def(init([](const iterable &it) {\n        auto v = std::unique_ptr<Vector>(new Vector());\n        v->reserve(len_hint(it));\n        for (handle h : it) {\n            v->push_back(h.cast<T>());\n        }\n        return v.release();\n    }));\n\n    cl.def(\n        \"clear\", [](Vector &v) { v.clear(); }, \"Clear the contents\");\n\n    cl.def(\n        \"extend\",\n        [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },\n        arg(\"L\"),\n        \"Extend the list by appending all the items in the given list\");\n\n    cl.def(\n        \"extend\",\n        [](Vector &v, const iterable &it) {\n            const size_t old_size = v.size();\n            v.reserve(old_size + len_hint(it));\n            try {\n                for (handle h : it) {\n                    v.push_back(h.cast<T>());\n                }\n            } catch (const cast_error &) {\n                v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),\n                        v.end());\n                try {\n                    v.shrink_to_fit();\n                } catch (const std::exception &) {\n                    // Do nothing\n                }\n                throw;\n            }\n        },\n        arg(\"L\"),\n        \"Extend the list by appending all the items in the given list\");\n\n    cl.def(\n        \"insert\",\n        [](Vector &v, DiffType i, const T &x) {\n            // Can't use wrap_i; i == v.size() is OK\n            if (i < 0) {\n                i += v.size();\n            }\n            if (i < 0 || (SizeType) i > v.size()) {\n                throw index_error();\n            }\n            v.insert(v.begin() + i, x);\n        },\n        arg(\"i\"),\n        arg(\"x\"),\n        \"Insert an item at a given position.\");\n\n    cl.def(\n        \"pop\",\n        [](Vector &v) {\n            if (v.empty()) {\n                throw index_error();\n            }\n            T t = std::move(v.back());\n            v.pop_back();\n            return t;\n        },\n        \"Remove and return the last item\");\n\n    cl.def(\n        \"pop\",\n        [wrap_i](Vector &v, DiffType i) {\n            i = wrap_i(i, v.size());\n            T t = std::move(v[(SizeType) i]);\n            v.erase(std::next(v.begin(), i));\n            return t;\n        },\n        arg(\"i\"),\n        \"Remove and return the item at index ``i``\");\n\n    cl.def(\"__setitem__\", [wrap_i](Vector &v, DiffType i, const T &t) {\n        i = wrap_i(i, v.size());\n        v[(SizeType) i] = t;\n    });\n\n    /// Slicing protocol\n    cl.def(\n        \"__getitem__\",\n        [](const Vector &v, const slice &slice) -> Vector * {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            auto *seq = new Vector();\n            seq->reserve((size_t) slicelength);\n\n            for (size_t i = 0; i < slicelength; ++i) {\n                seq->push_back(v[start]);\n                start += step;\n            }\n            return seq;\n        },\n        arg(\"s\"),\n        \"Retrieve list elements using a slice object\");\n\n    cl.def(\n        \"__setitem__\",\n        [](Vector &v, const slice &slice, const Vector &value) {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            if (slicelength != value.size()) {\n                throw std::runtime_error(\n                    \"Left and right hand size of slice assignment have different sizes!\");\n            }\n\n            for (size_t i = 0; i < slicelength; ++i) {\n                v[start] = value[i];\n                start += step;\n            }\n        },\n        \"Assign list elements using a slice object\");\n\n    cl.def(\n        \"__delitem__\",\n        [wrap_i](Vector &v, DiffType i) {\n            i = wrap_i(i, v.size());\n            v.erase(v.begin() + i);\n        },\n        \"Delete the list elements at index ``i``\");\n\n    cl.def(\n        \"__delitem__\",\n        [](Vector &v, const slice &slice) {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            if (step == 1 && false) {\n                v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));\n            } else {\n                for (size_t i = 0; i < slicelength; ++i) {\n                    v.erase(v.begin() + DiffType(start));\n                    start += step - 1;\n                }\n            }\n        },\n        \"Delete list elements using a slice object\");\n}\n\n// If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),\n// we have to access by copying; otherwise we return by reference.\ntemplate <typename Vector>\nusing vector_needs_copy\n    = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),\n                            typename Vector::value_type &>>;\n\n// The usual case: access and iterate by reference\ntemplate <typename Vector, typename Class_>\nvoid vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n    using ItType = typename Vector::iterator;\n\n    auto wrap_i = [](DiffType i, SizeType n) {\n        if (i < 0) {\n            i += n;\n        }\n        if (i < 0 || (SizeType) i >= n) {\n            throw index_error();\n        }\n        return i;\n    };\n\n    cl.def(\n        \"__getitem__\",\n        [wrap_i](Vector &v, DiffType i) -> T & {\n            i = wrap_i(i, v.size());\n            return v[(SizeType) i];\n        },\n        return_value_policy::reference_internal // ref + keepalive\n    );\n\n    cl.def(\n        \"__iter__\",\n        [](Vector &v) {\n            return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(\n                v.begin(), v.end());\n        },\n        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */\n    );\n}\n\n// The case for special objects, like std::vector<bool>, that have to be returned-by-copy:\ntemplate <typename Vector, typename Class_>\nvoid vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n    using ItType = typename Vector::iterator;\n    cl.def(\"__getitem__\", [](const Vector &v, DiffType i) -> T {\n        if (i < 0 && (i += v.size()) < 0) {\n            throw index_error();\n        }\n        if ((SizeType) i >= v.size()) {\n            throw index_error();\n        }\n        return v[(SizeType) i];\n    });\n\n    cl.def(\n        \"__iter__\",\n        [](Vector &v) {\n            return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());\n        },\n        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */\n    );\n}\n\ntemplate <typename Vector, typename Class_>\nauto vector_if_insertion_operator(Class_ &cl, std::string const &name)\n    -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),\n                void()) {\n    using size_type = typename Vector::size_type;\n\n    cl.def(\n        \"__repr__\",\n        [name](Vector &v) {\n            std::ostringstream s;\n            s << name << '[';\n            for (size_type i = 0; i < v.size(); ++i) {\n                s << v[i];\n                if (i != v.size() - 1) {\n                    s << \", \";\n                }\n            }\n            s << ']';\n            return s.str();\n        },\n        \"Return the canonical string representation of this list.\");\n}\n\n// Provide the buffer interface for vectors if we have data() and we have a format for it\n// GCC seems to have \"void std::vector<bool>::data()\" - doing SFINAE on the existence of data()\n// is insufficient, we need to check it returns an appropriate pointer\ntemplate <typename Vector, typename = void>\nstruct vector_has_data_and_format : std::false_type {};\ntemplate <typename Vector>\nstruct vector_has_data_and_format<\n    Vector,\n    enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),\n                                      std::declval<Vector>().data()),\n                             typename Vector::value_type *>::value>> : std::true_type {};\n\n// [workaround(intel)] Separate function required here\n// Workaround as the Intel compiler does not compile the enable_if_t part below\n// (tested with icc (ICC) 2021.1 Beta 20200827)\ntemplate <typename... Args>\nconstexpr bool args_any_are_buffer() {\n    return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;\n}\n\n// [workaround(intel)] Separate function required here\n// [workaround(msvc)] Can't use constexpr bool in return type\n\n// Add the buffer interface to a vector\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer_impl(Class_ &cl, std::true_type) {\n    using T = typename Vector::value_type;\n\n    static_assert(vector_has_data_and_format<Vector>::value,\n                  \"There is not an appropriate format descriptor for this vector\");\n\n    // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard\n    // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here\n    format_descriptor<T>::format();\n\n    cl.def_buffer([](Vector &v) -> buffer_info {\n        return buffer_info(v.data(),\n                           static_cast<ssize_t>(sizeof(T)),\n                           format_descriptor<T>::format(),\n                           1,\n                           {v.size()},\n                           {sizeof(T)});\n    });\n\n    cl.def(init([](const buffer &buf) {\n        auto info = buf.request();\n        if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {\n            throw type_error(\"Only valid 1D buffers can be copied to a vector\");\n        }\n        if (!detail::compare_buffer_info<T>::compare(info)\n            || (ssize_t) sizeof(T) != info.itemsize) {\n            throw type_error(\"Format mismatch (Python: \" + info.format\n                             + \" C++: \" + format_descriptor<T>::format() + \")\");\n        }\n\n        T *p = static_cast<T *>(info.ptr);\n        ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));\n        T *end = p + info.shape[0] * step;\n        if (step == 1) {\n            return Vector(p, end);\n        }\n        Vector vec;\n        vec.reserve((size_t) info.shape[0]);\n        for (; p != end; p += step) {\n            vec.push_back(*p);\n        }\n        return vec;\n    }));\n\n    return;\n}\n\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer_impl(Class_ &, std::false_type) {}\n\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer(Class_ &cl) {\n    vector_buffer_impl<Vector, Class_, Args...>(\n        cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n//\n// std::vector\n//\ntemplate <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>\nclass_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {\n    using Class_ = class_<Vector, holder_type>;\n\n    // If the value_type is unregistered (e.g. a converting type) or is itself registered\n    // module-local then make the vector binding module-local as well:\n    using vtype = typename Vector::value_type;\n    auto *vtype_info = detail::get_type_info(typeid(vtype));\n    bool local = !vtype_info || vtype_info->module_local;\n\n    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);\n\n    // Declare the buffer interface if a buffer_protocol() is passed in\n    detail::vector_buffer<Vector, Class_, Args...>(cl);\n\n    cl.def(init<>());\n\n    // Register copy constructor (if possible)\n    detail::vector_if_copy_constructible<Vector, Class_>(cl);\n\n    // Register comparison-related operators and functions (if possible)\n    detail::vector_if_equal_operator<Vector, Class_>(cl);\n\n    // Register stream insertion operator (if possible)\n    detail::vector_if_insertion_operator<Vector, Class_>(cl, name);\n\n    // Modifiers require copyable vector value type\n    detail::vector_modifiers<Vector, Class_>(cl);\n\n    // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive\n    detail::vector_accessor<Vector, Class_>(cl);\n\n    cl.def(\n        \"__bool__\",\n        [](const Vector &v) -> bool { return !v.empty(); },\n        \"Check whether the list is nonempty\");\n\n    cl.def(\"__len__\", &Vector::size);\n\n#if 0\n    // C++ style functions deprecated, leaving it here as an example\n    cl.def(init<size_type>());\n\n    cl.def(\"resize\",\n         (void (Vector::*) (size_type count)) & Vector::resize,\n         \"changes the number of elements stored\");\n\n    cl.def(\"erase\",\n        [](Vector &v, SizeType i) {\n        if (i >= v.size())\n            throw index_error();\n        v.erase(v.begin() + i);\n    }, \"erases element at index ``i``\");\n\n    cl.def(\"empty\",         &Vector::empty,         \"checks whether the container is empty\");\n    cl.def(\"size\",          &Vector::size,          \"returns the number of elements\");\n    cl.def(\"push_back\", (void (Vector::*)(const T&)) &Vector::push_back, \"adds an element to the end\");\n    cl.def(\"pop_back\",                               &Vector::pop_back, \"removes the last element\");\n\n    cl.def(\"max_size\",      &Vector::max_size,      \"returns the maximum possible number of elements\");\n    cl.def(\"reserve\",       &Vector::reserve,       \"reserves storage\");\n    cl.def(\"capacity\",      &Vector::capacity,      \"returns the number of elements that can be held in currently allocated storage\");\n    cl.def(\"shrink_to_fit\", &Vector::shrink_to_fit, \"reduces memory usage by freeing unused memory\");\n\n    cl.def(\"clear\", &Vector::clear, \"clears the contents\");\n    cl.def(\"swap\",   &Vector::swap, \"swaps the contents\");\n\n    cl.def(\"front\", [](Vector &v) {\n        if (v.size()) return v.front();\n        else throw index_error();\n    }, \"access the first element\");\n\n    cl.def(\"back\", [](Vector &v) {\n        if (v.size()) return v.back();\n        else throw index_error();\n    }, \"access the last element \");\n\n#endif\n\n    return cl;\n}\n\n//\n// std::map, std::unordered_map\n//\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/* Fallback functions */\ntemplate <typename, typename, typename... Args>\nvoid map_if_insertion_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid map_assignment(const Args &...) {}\n\n// Map assignment when copy-assignable: just copy the value\ntemplate <typename Map, typename Class_>\nvoid map_assignment(\n    enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n\n    cl.def(\"__setitem__\", [](Map &m, const KeyType &k, const MappedType &v) {\n        auto it = m.find(k);\n        if (it != m.end()) {\n            it->second = v;\n        } else {\n            m.emplace(k, v);\n        }\n    });\n}\n\n// Not copy-assignable, but still copy-constructible: we can update the value by erasing and\n// reinserting\ntemplate <typename Map, typename Class_>\nvoid map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value\n                                    && is_copy_constructible<typename Map::mapped_type>::value,\n                                Class_> &cl) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n\n    cl.def(\"__setitem__\", [](Map &m, const KeyType &k, const MappedType &v) {\n        // We can't use m[k] = v; because value type might not be default constructable\n        auto r = m.emplace(k, v);\n        if (!r.second) {\n            // value type is not copy assignable so the only way to insert it is to erase it\n            // first...\n            m.erase(r.first);\n            m.emplace(k, v);\n        }\n    });\n}\n\ntemplate <typename Map, typename Class_>\nauto map_if_insertion_operator(Class_ &cl, std::string const &name)\n    -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()\n                                               << std::declval<typename Map::mapped_type>(),\n                void()) {\n\n    cl.def(\n        \"__repr__\",\n        [name](Map &m) {\n            std::ostringstream s;\n            s << name << '{';\n            bool f = false;\n            for (auto const &kv : m) {\n                if (f) {\n                    s << \", \";\n                }\n                s << kv.first << \": \" << kv.second;\n                f = true;\n            }\n            s << '}';\n            return s.str();\n        },\n        \"Return the canonical string representation of this map.\");\n}\n\ntemplate <typename Map>\nstruct keys_view {\n    Map &map;\n};\n\ntemplate <typename Map>\nstruct values_view {\n    Map &map;\n};\n\ntemplate <typename Map>\nstruct items_view {\n    Map &map;\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>\nclass_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n    using KeysView = detail::keys_view<Map>;\n    using ValuesView = detail::values_view<Map>;\n    using ItemsView = detail::items_view<Map>;\n    using Class_ = class_<Map, holder_type>;\n\n    // If either type is a non-module-local bound type then make the map binding non-local as well;\n    // otherwise (e.g. both types are either module-local or converting) the map will be\n    // module-local.\n    auto *tinfo = detail::get_type_info(typeid(MappedType));\n    bool local = !tinfo || tinfo->module_local;\n    if (local) {\n        tinfo = detail::get_type_info(typeid(KeyType));\n        local = !tinfo || tinfo->module_local;\n    }\n\n    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);\n    class_<KeysView> keys_view(\n        scope, (\"KeysView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n    class_<ValuesView> values_view(\n        scope, (\"ValuesView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n    class_<ItemsView> items_view(\n        scope, (\"ItemsView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n\n    cl.def(init<>());\n\n    // Register stream insertion operator (if possible)\n    detail::map_if_insertion_operator<Map, Class_>(cl, name);\n\n    cl.def(\n        \"__bool__\",\n        [](const Map &m) -> bool { return !m.empty(); },\n        \"Check whether the map is nonempty\");\n\n    cl.def(\n        \"__iter__\",\n        [](Map &m) { return make_key_iterator(m.begin(), m.end()); },\n        keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */\n    );\n\n    cl.def(\n        \"keys\",\n        [](Map &m) { return KeysView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"values\",\n        [](Map &m) { return ValuesView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"items\",\n        [](Map &m) { return ItemsView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"__getitem__\",\n        [](Map &m, const KeyType &k) -> MappedType & {\n            auto it = m.find(k);\n            if (it == m.end()) {\n                throw key_error();\n            }\n            return it->second;\n        },\n        return_value_policy::reference_internal // ref + keepalive\n    );\n\n    cl.def(\"__contains__\", [](Map &m, const KeyType &k) -> bool {\n        auto it = m.find(k);\n        if (it == m.end()) {\n            return false;\n        }\n        return true;\n    });\n    // Fallback for when the object is not of the key type\n    cl.def(\"__contains__\", [](Map &, const object &) -> bool { return false; });\n\n    // Assignment provided only if the type is copyable\n    detail::map_assignment<Map, Class_>(cl);\n\n    cl.def(\"__delitem__\", [](Map &m, const KeyType &k) {\n        auto it = m.find(k);\n        if (it == m.end()) {\n            throw key_error();\n        }\n        m.erase(it);\n    });\n\n    cl.def(\"__len__\", &Map::size);\n\n    keys_view.def(\"__len__\", [](KeysView &view) { return view.map.size(); });\n    keys_view.def(\n        \"__iter__\",\n        [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n    keys_view.def(\"__contains__\", [](KeysView &view, const KeyType &k) -> bool {\n        auto it = view.map.find(k);\n        if (it == view.map.end()) {\n            return false;\n        }\n        return true;\n    });\n    // Fallback for when the object is not of the key type\n    keys_view.def(\"__contains__\", [](KeysView &, const object &) -> bool { return false; });\n\n    values_view.def(\"__len__\", [](ValuesView &view) { return view.map.size(); });\n    values_view.def(\n        \"__iter__\",\n        [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n\n    items_view.def(\"__len__\", [](ItemsView &view) { return view.map.size(); });\n    items_view.def(\n        \"__iter__\",\n        [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n\n    return cl;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/noxfile.py",
    "content": "import os\n\nimport nox\n\nnox.needs_version = \">=2022.1.7\"\nnox.options.sessions = [\"lint\", \"tests\", \"tests_packaging\"]\n\nPYTHON_VERSIONS = [\n    \"3.6\",\n    \"3.7\",\n    \"3.8\",\n    \"3.9\",\n    \"3.10\",\n    \"3.11\",\n    \"pypy3.7\",\n    \"pypy3.8\",\n    \"pypy3.9\",\n]\n\nif os.environ.get(\"CI\", None):\n    nox.options.error_on_missing_interpreters = True\n\n\n@nox.session(reuse_venv=True)\ndef lint(session: nox.Session) -> None:\n    \"\"\"\n    Lint the codebase (except for clang-format/tidy).\n    \"\"\"\n    session.install(\"pre-commit\")\n    session.run(\"pre-commit\", \"run\", \"-a\", *session.posargs)\n\n\n@nox.session(python=PYTHON_VERSIONS)\ndef tests(session: nox.Session) -> None:\n    \"\"\"\n    Run the tests (requires a compiler).\n    \"\"\"\n    tmpdir = session.create_tmp()\n    session.install(\"cmake\")\n    session.install(\"-r\", \"tests/requirements.txt\")\n    session.run(\n        \"cmake\",\n        \"-S.\",\n        f\"-B{tmpdir}\",\n        \"-DPYBIND11_WERROR=ON\",\n        \"-DDOWNLOAD_CATCH=ON\",\n        \"-DDOWNLOAD_EIGEN=ON\",\n        *session.posargs,\n    )\n    session.run(\"cmake\", \"--build\", tmpdir)\n    session.run(\"cmake\", \"--build\", tmpdir, \"--config=Release\", \"--target\", \"check\")\n\n\n@nox.session\ndef tests_packaging(session: nox.Session) -> None:\n    \"\"\"\n    Run the packaging tests.\n    \"\"\"\n\n    session.install(\"-r\", \"tests/requirements.txt\", \"--prefer-binary\")\n    session.run(\"pytest\", \"tests/extra_python_package\", *session.posargs)\n\n\n@nox.session(reuse_venv=True)\ndef docs(session: nox.Session) -> None:\n    \"\"\"\n    Build the docs. Pass \"serve\" to serve.\n    \"\"\"\n\n    session.install(\"-r\", \"docs/requirements.txt\")\n    session.chdir(\"docs\")\n\n    if \"pdf\" in session.posargs:\n        session.run(\"sphinx-build\", \"-M\", \"latexpdf\", \".\", \"_build\")\n        return\n\n    session.run(\"sphinx-build\", \"-M\", \"html\", \".\", \"_build\")\n\n    if \"serve\" in session.posargs:\n        session.log(\"Launching docs at http://localhost:8000/ - use Ctrl-C to quit\")\n        session.run(\"python\", \"-m\", \"http.server\", \"8000\", \"-d\", \"_build/html\")\n    elif session.posargs:\n        session.error(\"Unsupported argument to docs\")\n\n\n@nox.session(reuse_venv=True)\ndef make_changelog(session: nox.Session) -> None:\n    \"\"\"\n    Inspect the closed issues and make entries for a changelog.\n    \"\"\"\n    session.install(\"ghapi\", \"rich\")\n    session.run(\"python\", \"tools/make_changelog.py\")\n\n\n@nox.session(reuse_venv=True)\ndef build(session: nox.Session) -> None:\n    \"\"\"\n    Build SDists and wheels.\n    \"\"\"\n\n    session.install(\"build\")\n    session.log(\"Building normal files\")\n    session.run(\"python\", \"-m\", \"build\", *session.posargs)\n    session.log(\"Building pybind11-global files (PYBIND11_GLOBAL_SDIST=1)\")\n    session.run(\n        \"python\", \"-m\", \"build\", *session.posargs, env={\"PYBIND11_GLOBAL_SDIST\": \"1\"}\n    )\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/__init__.py",
    "content": "import sys\n\nif sys.version_info < (3, 6):\n    msg = \"pybind11 does not support Python < 3.6. 2.9 was the last release supporting Python 2.7 and 3.5.\"\n    raise ImportError(msg)\n\n\nfrom ._version import __version__, version_info\nfrom .commands import get_cmake_dir, get_include, get_pkgconfig_dir\n\n__all__ = (\n    \"version_info\",\n    \"__version__\",\n    \"get_include\",\n    \"get_cmake_dir\",\n    \"get_pkgconfig_dir\",\n)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/__main__.py",
    "content": "# pylint: disable=missing-function-docstring\n\nimport argparse\nimport sys\nimport sysconfig\n\nfrom .commands import get_cmake_dir, get_include, get_pkgconfig_dir\n\n\ndef print_includes() -> None:\n    dirs = [\n        sysconfig.get_path(\"include\"),\n        sysconfig.get_path(\"platinclude\"),\n        get_include(),\n    ]\n\n    # Make unique but preserve order\n    unique_dirs = []\n    for d in dirs:\n        if d and d not in unique_dirs:\n            unique_dirs.append(d)\n\n    print(\" \".join(\"-I\" + d for d in unique_dirs))\n\n\ndef main() -> None:\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        \"--includes\",\n        action=\"store_true\",\n        help=\"Include flags for both pybind11 and Python headers.\",\n    )\n    parser.add_argument(\n        \"--cmakedir\",\n        action=\"store_true\",\n        help=\"Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.\",\n    )\n    parser.add_argument(\n        \"--pkgconfigdir\",\n        action=\"store_true\",\n        help=\"Print the pkgconfig directory, ideal for setting $PKG_CONFIG_PATH.\",\n    )\n    args = parser.parse_args()\n    if not sys.argv[1:]:\n        parser.print_help()\n    if args.includes:\n        print_includes()\n    if args.cmakedir:\n        print(get_cmake_dir())\n    if args.pkgconfigdir:\n        print(get_pkgconfig_dir())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/_version.py",
    "content": "from typing import Union\n\n\ndef _to_int(s: str) -> Union[int, str]:\n    try:\n        return int(s)\n    except ValueError:\n        return s\n\n\n__version__ = \"2.11.0.dev1\"\nversion_info = tuple(_to_int(s) for s in __version__.split(\".\"))\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/commands.py",
    "content": "import os\n\nDIR = os.path.abspath(os.path.dirname(__file__))\n\n\ndef get_include(user: bool = False) -> str:  # pylint: disable=unused-argument\n    \"\"\"\n    Return the path to the pybind11 include directory. The historical \"user\"\n    argument is unused, and may be removed.\n    \"\"\"\n    installed_path = os.path.join(DIR, \"include\")\n    source_path = os.path.join(os.path.dirname(DIR), \"include\")\n    return installed_path if os.path.exists(installed_path) else source_path\n\n\ndef get_cmake_dir() -> str:\n    \"\"\"\n    Return the path to the pybind11 CMake module directory.\n    \"\"\"\n    cmake_installed_path = os.path.join(DIR, \"share\", \"cmake\", \"pybind11\")\n    if os.path.exists(cmake_installed_path):\n        return cmake_installed_path\n\n    msg = \"pybind11 not installed, installation required to access the CMake files\"\n    raise ImportError(msg)\n\n\ndef get_pkgconfig_dir() -> str:\n    \"\"\"\n    Return the path to the pybind11 pkgconfig directory.\n    \"\"\"\n    pkgconfig_installed_path = os.path.join(DIR, \"share\", \"pkgconfig\")\n    if os.path.exists(pkgconfig_installed_path):\n        return pkgconfig_installed_path\n\n    msg = \"pybind11 not installed, installation required to access the pkgconfig files\"\n    raise ImportError(msg)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/py.typed",
    "content": ""
  },
  {
    "path": "external/pybind11_2.11_dev1/pybind11/setup_helpers.py",
    "content": "\"\"\"\nThis module provides helpers for C++11+ projects using pybind11.\n\nLICENSE:\n\nCopyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n   may be used to endorse or promote products derived from this software\n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\"\"\"\n\n# IMPORTANT: If you change this file in the pybind11 repo, also review\n# setup_helpers.pyi for matching changes.\n#\n# If you copy this file in, you don't\n# need the .pyi file; it's just an interface file for static type checkers.\n\nimport contextlib\nimport os\nimport platform\nimport shlex\nimport shutil\nimport sys\nimport sysconfig\nimport tempfile\nimport threading\nimport warnings\nfrom functools import lru_cache\nfrom pathlib import Path\nfrom typing import (\n    Any,\n    Callable,\n    Dict,\n    Iterable,\n    Iterator,\n    List,\n    Optional,\n    Tuple,\n    TypeVar,\n    Union,\n)\n\ntry:\n    from setuptools import Extension as _Extension\n    from setuptools.command.build_ext import build_ext as _build_ext\nexcept ImportError:\n    from distutils.command.build_ext import build_ext as _build_ext\n    from distutils.extension import Extension as _Extension\n\nimport distutils.ccompiler\nimport distutils.errors\n\nWIN = sys.platform.startswith(\"win32\") and \"mingw\" not in sysconfig.get_platform()\nMACOS = sys.platform.startswith(\"darwin\")\nSTD_TMPL = \"/std:c++{}\" if WIN else \"-std=c++{}\"\n\n\n# It is recommended to use PEP 518 builds if using this module. However, this\n# file explicitly supports being copied into a user's project directory\n# standalone, and pulling pybind11 with the deprecated setup_requires feature.\n# If you copy the file, remember to add it to your MANIFEST.in, and add the current\n# directory into your path if it sits beside your setup.py.\n\n\nclass Pybind11Extension(_Extension):  # type: ignore[misc]\n    \"\"\"\n    Build a C++11+ Extension module with pybind11. This automatically adds the\n    recommended flags when you init the extension and assumes C++ sources - you\n    can further modify the options yourself.\n\n    The customizations are:\n\n    * ``/EHsc`` and ``/bigobj`` on Windows\n    * ``stdlib=libc++`` on macOS\n    * ``visibility=hidden`` and ``-g0`` on Unix\n\n    Finally, you can set ``cxx_std`` via constructor or afterwards to enable\n    flags for C++ std, and a few extra helper flags related to the C++ standard\n    level. It is _highly_ recommended you either set this, or use the provided\n    ``build_ext``, which will search for the highest supported extension for\n    you if the ``cxx_std`` property is not set. Do not set the ``cxx_std``\n    property more than once, as flags are added when you set it. Set the\n    property to None to disable the addition of C++ standard flags.\n\n    If you want to add pybind11 headers manually, for example for an exact\n    git checkout, then set ``include_pybind11=False``.\n    \"\"\"\n\n    # flags are prepended, so that they can be further overridden, e.g. by\n    # ``extra_compile_args=[\"-g\"]``.\n\n    def _add_cflags(self, flags: List[str]) -> None:\n        self.extra_compile_args[:0] = flags\n\n    def _add_ldflags(self, flags: List[str]) -> None:\n        self.extra_link_args[:0] = flags\n\n    def __init__(self, *args: Any, **kwargs: Any) -> None:\n\n        self._cxx_level = 0\n        cxx_std = kwargs.pop(\"cxx_std\", 0)\n\n        if \"language\" not in kwargs:\n            kwargs[\"language\"] = \"c++\"\n\n        include_pybind11 = kwargs.pop(\"include_pybind11\", True)\n\n        super().__init__(*args, **kwargs)\n\n        # Include the installed package pybind11 headers\n        if include_pybind11:\n            # If using setup_requires, this fails the first time - that's okay\n            try:\n                import pybind11\n\n                pyinc = pybind11.get_include()\n\n                if pyinc not in self.include_dirs:\n                    self.include_dirs.append(pyinc)\n            except ModuleNotFoundError:\n                pass\n\n        self.cxx_std = cxx_std\n\n        cflags = []\n        ldflags = []\n        if WIN:\n            cflags += [\"/EHsc\", \"/bigobj\"]\n        else:\n            cflags += [\"-fvisibility=hidden\"]\n            env_cflags = os.environ.get(\"CFLAGS\", \"\")\n            env_cppflags = os.environ.get(\"CPPFLAGS\", \"\")\n            c_cpp_flags = shlex.split(env_cflags) + shlex.split(env_cppflags)\n            if not any(opt.startswith(\"-g\") for opt in c_cpp_flags):\n                cflags += [\"-g0\"]\n            if MACOS:\n                cflags += [\"-stdlib=libc++\"]\n                ldflags += [\"-stdlib=libc++\"]\n        self._add_cflags(cflags)\n        self._add_ldflags(ldflags)\n\n    @property\n    def cxx_std(self) -> int:\n        \"\"\"\n        The CXX standard level. If set, will add the required flags. If left at\n        0, it will trigger an automatic search when pybind11's build_ext is\n        used. If None, will have no effect.  Besides just the flags, this may\n        add a macos-min 10.9 or 10.14 flag if MACOSX_DEPLOYMENT_TARGET is\n        unset.\n        \"\"\"\n        return self._cxx_level\n\n    @cxx_std.setter\n    def cxx_std(self, level: int) -> None:\n\n        if self._cxx_level:\n            warnings.warn(\"You cannot safely change the cxx_level after setting it!\")\n\n        # MSVC 2015 Update 3 and later only have 14 (and later 17) modes, so\n        # force a valid flag here.\n        if WIN and level == 11:\n            level = 14\n\n        self._cxx_level = level\n\n        if not level:\n            return\n\n        cflags = [STD_TMPL.format(level)]\n        ldflags = []\n\n        if MACOS and \"MACOSX_DEPLOYMENT_TARGET\" not in os.environ:\n            # C++17 requires a higher min version of macOS. An earlier version\n            # (10.12 or 10.13) can be set manually via environment variable if\n            # you are careful in your feature usage, but 10.14 is the safest\n            # setting for general use. However, never set higher than the\n            # current macOS version!\n            current_macos = tuple(int(x) for x in platform.mac_ver()[0].split(\".\")[:2])\n            desired_macos = (10, 9) if level < 17 else (10, 14)\n            macos_string = \".\".join(str(x) for x in min(current_macos, desired_macos))\n            macosx_min = f\"-mmacosx-version-min={macos_string}\"\n            cflags += [macosx_min]\n            ldflags += [macosx_min]\n\n        self._add_cflags(cflags)\n        self._add_ldflags(ldflags)\n\n\n# Just in case someone clever tries to multithread\ntmp_chdir_lock = threading.Lock()\n\n\n@contextlib.contextmanager\ndef tmp_chdir() -> Iterator[str]:\n    \"Prepare and enter a temporary directory, cleanup when done\"\n\n    # Threadsafe\n    with tmp_chdir_lock:\n        olddir = os.getcwd()\n        try:\n            tmpdir = tempfile.mkdtemp()\n            os.chdir(tmpdir)\n            yield tmpdir\n        finally:\n            os.chdir(olddir)\n            shutil.rmtree(tmpdir)\n\n\n# cf http://bugs.python.org/issue26689\ndef has_flag(compiler: Any, flag: str) -> bool:\n    \"\"\"\n    Return the flag if a flag name is supported on the\n    specified compiler, otherwise None (can be used as a boolean).\n    If multiple flags are passed, return the first that matches.\n    \"\"\"\n\n    with tmp_chdir():\n        fname = Path(\"flagcheck.cpp\")\n        # Don't trigger -Wunused-parameter.\n        fname.write_text(\"int main (int, char **) { return 0; }\", encoding=\"utf-8\")\n\n        try:\n            compiler.compile([str(fname)], extra_postargs=[flag])\n        except distutils.errors.CompileError:\n            return False\n        return True\n\n\n# Every call will cache the result\ncpp_flag_cache = None\n\n\n@lru_cache()\ndef auto_cpp_level(compiler: Any) -> Union[str, int]:\n    \"\"\"\n    Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows.\n    \"\"\"\n\n    if WIN:\n        return \"latest\"\n\n    levels = [17, 14, 11]\n\n    for level in levels:\n        if has_flag(compiler, STD_TMPL.format(level)):\n            return level\n\n    msg = \"Unsupported compiler -- at least C++11 support is needed!\"\n    raise RuntimeError(msg)\n\n\nclass build_ext(_build_ext):  # type: ignore[misc] # noqa: N801\n    \"\"\"\n    Customized build_ext that allows an auto-search for the highest supported\n    C++ level for Pybind11Extension. This is only needed for the auto-search\n    for now, and is completely optional otherwise.\n    \"\"\"\n\n    def build_extensions(self) -> None:\n        \"\"\"\n        Build extensions, injecting C++ std for Pybind11Extension if needed.\n        \"\"\"\n\n        for ext in self.extensions:\n            if hasattr(ext, \"_cxx_level\") and ext._cxx_level == 0:\n                ext.cxx_std = auto_cpp_level(self.compiler)\n\n        super().build_extensions()\n\n\ndef intree_extensions(\n    paths: Iterable[str], package_dir: Optional[Dict[str, str]] = None\n) -> List[Pybind11Extension]:\n    \"\"\"\n    Generate Pybind11Extensions from source files directly located in a Python\n    source tree.\n\n    ``package_dir`` behaves as in ``setuptools.setup``.  If unset, the Python\n    package root parent is determined as the first parent directory that does\n    not contain an ``__init__.py`` file.\n    \"\"\"\n    exts = []\n\n    if package_dir is None:\n        for path in paths:\n            parent, _ = os.path.split(path)\n            while os.path.exists(os.path.join(parent, \"__init__.py\")):\n                parent, _ = os.path.split(parent)\n            relname, _ = os.path.splitext(os.path.relpath(path, parent))\n            qualified_name = relname.replace(os.path.sep, \".\")\n            exts.append(Pybind11Extension(qualified_name, [path]))\n        return exts\n\n    for path in paths:\n        for prefix, parent in package_dir.items():\n            if path.startswith(parent):\n                relname, _ = os.path.splitext(os.path.relpath(path, parent))\n                qualified_name = relname.replace(os.path.sep, \".\")\n                if prefix:\n                    qualified_name = prefix + \".\" + qualified_name\n                exts.append(Pybind11Extension(qualified_name, [path]))\n                break\n        else:\n            msg = (\n                f\"path {path} is not a child of any of the directories listed \"\n                f\"in 'package_dir' ({package_dir})\"\n            )\n            raise ValueError(msg)\n\n    return exts\n\n\ndef naive_recompile(obj: str, src: str) -> bool:\n    \"\"\"\n    This will recompile only if the source file changes. It does not check\n    header files, so a more advanced function or Ccache is better if you have\n    editable header files in your package.\n    \"\"\"\n    return os.stat(obj).st_mtime < os.stat(src).st_mtime\n\n\ndef no_recompile(obg: str, src: str) -> bool:  # pylint: disable=unused-argument\n    \"\"\"\n    This is the safest but slowest choice (and is the default) - will always\n    recompile sources.\n    \"\"\"\n    return True\n\n\nS = TypeVar(\"S\", bound=\"ParallelCompile\")\n\nCCompilerMethod = Callable[\n    [\n        distutils.ccompiler.CCompiler,\n        List[str],\n        Optional[str],\n        Optional[Union[Tuple[str], Tuple[str, Optional[str]]]],\n        Optional[List[str]],\n        bool,\n        Optional[List[str]],\n        Optional[List[str]],\n        Optional[List[str]],\n    ],\n    List[str],\n]\n\n\n# Optional parallel compile utility\n# inspired by: http://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils\n# and: https://github.com/tbenthompson/cppimport/blob/stable/cppimport/build_module.py\n# and NumPy's parallel distutils module:\n#              https://github.com/numpy/numpy/blob/master/numpy/distutils/ccompiler.py\nclass ParallelCompile:\n    \"\"\"\n    Make a parallel compile function. Inspired by\n    numpy.distutils.ccompiler.CCompiler.compile and cppimport.\n\n    This takes several arguments that allow you to customize the compile\n    function created:\n\n    envvar:\n        Set an environment variable to control the compilation threads, like\n        NPY_NUM_BUILD_JOBS\n    default:\n        0 will automatically multithread, or 1 will only multithread if the\n        envvar is set.\n    max:\n        The limit for automatic multithreading if non-zero\n    needs_recompile:\n        A function of (obj, src) that returns True when recompile is needed.  No\n        effect in isolated mode; use ccache instead, see\n        https://github.com/matplotlib/matplotlib/issues/1507/\n\n    To use::\n\n        ParallelCompile(\"NPY_NUM_BUILD_JOBS\").install()\n\n    or::\n\n        with ParallelCompile(\"NPY_NUM_BUILD_JOBS\"):\n            setup(...)\n\n    By default, this assumes all files need to be recompiled. A smarter\n    function can be provided via needs_recompile.  If the output has not yet\n    been generated, the compile will always run, and this function is not\n    called.\n    \"\"\"\n\n    __slots__ = (\"envvar\", \"default\", \"max\", \"_old\", \"needs_recompile\")\n\n    def __init__(\n        self,\n        envvar: Optional[str] = None,\n        default: int = 0,\n        max: int = 0,  # pylint: disable=redefined-builtin\n        needs_recompile: Callable[[str, str], bool] = no_recompile,\n    ) -> None:\n        self.envvar = envvar\n        self.default = default\n        self.max = max\n        self.needs_recompile = needs_recompile\n        self._old: List[CCompilerMethod] = []\n\n    def function(self) -> CCompilerMethod:\n        \"\"\"\n        Builds a function object usable as distutils.ccompiler.CCompiler.compile.\n        \"\"\"\n\n        def compile_function(\n            compiler: distutils.ccompiler.CCompiler,\n            sources: List[str],\n            output_dir: Optional[str] = None,\n            macros: Optional[Union[Tuple[str], Tuple[str, Optional[str]]]] = None,\n            include_dirs: Optional[List[str]] = None,\n            debug: bool = False,\n            extra_preargs: Optional[List[str]] = None,\n            extra_postargs: Optional[List[str]] = None,\n            depends: Optional[List[str]] = None,\n        ) -> Any:\n\n            # These lines are directly from distutils.ccompiler.CCompiler\n            macros, objects, extra_postargs, pp_opts, build = compiler._setup_compile(  # type: ignore[attr-defined]\n                output_dir, macros, include_dirs, sources, depends, extra_postargs\n            )\n            cc_args = compiler._get_cc_args(pp_opts, debug, extra_preargs)  # type: ignore[attr-defined]\n\n            # The number of threads; start with default.\n            threads = self.default\n\n            # Determine the number of compilation threads, unless set by an environment variable.\n            if self.envvar is not None:\n                threads = int(os.environ.get(self.envvar, self.default))\n\n            def _single_compile(obj: Any) -> None:\n                try:\n                    src, ext = build[obj]\n                except KeyError:\n                    return\n\n                if not os.path.exists(obj) or self.needs_recompile(obj, src):\n                    compiler._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)  # type: ignore[attr-defined]\n\n            try:\n                # Importing .synchronize checks for platforms that have some multiprocessing\n                # capabilities but lack semaphores, such as AWS Lambda and Android Termux.\n                import multiprocessing.synchronize\n                from multiprocessing.pool import ThreadPool\n            except ImportError:\n                threads = 1\n\n            if threads == 0:\n                try:\n                    threads = multiprocessing.cpu_count()\n                    threads = self.max if self.max and self.max < threads else threads\n                except NotImplementedError:\n                    threads = 1\n\n            if threads > 1:\n                with ThreadPool(threads) as pool:\n                    for _ in pool.imap_unordered(_single_compile, objects):\n                        pass\n            else:\n                for ob in objects:\n                    _single_compile(ob)\n\n            return objects\n\n        return compile_function\n\n    def install(self: S) -> S:\n        \"\"\"\n        Installs the compile function into distutils.ccompiler.CCompiler.compile.\n        \"\"\"\n        distutils.ccompiler.CCompiler.compile = self.function()  # type: ignore[assignment]\n        return self\n\n    def __enter__(self: S) -> S:\n        self._old.append(distutils.ccompiler.CCompiler.compile)\n        return self.install()\n\n    def __exit__(self, *args: Any) -> None:\n        distutils.ccompiler.CCompiler.compile = self._old.pop()  # type: ignore[assignment]\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=42\", \"cmake>=3.18\", \"ninja\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.check-manifest]\nignore = [\n    \"tests/**\",\n    \"docs/**\",\n    \"tools/**\",\n    \"include/**\",\n    \".*\",\n    \"pybind11/include/**\",\n    \"pybind11/share/**\",\n    \"CMakeLists.txt\",\n    \"noxfile.py\",\n]\n\n[tool.isort]\n# Needs the compiled .so modules and env.py from tests\nknown_first_party = \"env,pybind11_cross_module_tests,pybind11_tests,\"\n# For black compatibility\nprofile = \"black\"\n\n[tool.mypy]\nfiles = [\"pybind11\"]\npython_version = \"3.6\"\nstrict = true\nshow_error_codes = true\nenable_error_code = [\"ignore-without-code\", \"redundant-expr\", \"truthy-bool\"]\nwarn_unreachable = true\n\n[[tool.mypy.overrides]]\nmodule = [\"ghapi.*\", \"setuptools.*\"]\nignore_missing_imports = true\n\n\n[tool.pytest.ini_options]\nminversion = \"6.0\"\naddopts = [\"-ra\", \"--showlocals\", \"--strict-markers\", \"--strict-config\"]\nxfail_strict = true\nfilterwarnings = [\"error\"]\nlog_cli_level = \"info\"\ntestpaths = [\n    \"tests\",\n]\ntimeout=300\n\n\n[tool.pylint]\nmaster.py-version = \"3.6\"\nreports.output-format = \"colorized\"\nmessages_control.disable = [\n  \"design\",\n  \"fixme\",\n  \"imports\",\n  \"line-too-long\",\n  \"imports\",\n  \"invalid-name\",\n  \"protected-access\",\n  \"missing-module-docstring\",\n]\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/setup.cfg",
    "content": "[metadata]\nlong_description = file: README.rst\nlong_description_content_type = text/x-rst\ndescription = Seamless operability between C++11 and Python\nauthor = Wenzel Jakob\nauthor_email = wenzel.jakob@epfl.ch\nurl = https://github.com/pybind/pybind11\nlicense = BSD\n\nclassifiers =\n    Development Status :: 5 - Production/Stable\n    Intended Audience :: Developers\n    Topic :: Software Development :: Libraries :: Python Modules\n    Topic :: Utilities\n    Programming Language :: C++\n    Programming Language :: Python :: 3 :: Only\n    Programming Language :: Python :: 3.6\n    Programming Language :: Python :: 3.7\n    Programming Language :: Python :: 3.8\n    Programming Language :: Python :: 3.9\n    Programming Language :: Python :: 3.10\n    Programming Language :: Python :: 3.11\n    License :: OSI Approved :: BSD License\n    Programming Language :: Python :: Implementation :: PyPy\n    Programming Language :: Python :: Implementation :: CPython\n    Programming Language :: C++\n    Topic :: Software Development :: Libraries :: Python Modules\n\nkeywords =\n    C++11\n    Python bindings\n\nproject_urls =\n    Documentation = https://pybind11.readthedocs.io/\n    Bug Tracker = https://github.com/pybind/pybind11/issues\n    Discussions = https://github.com/pybind/pybind11/discussions\n    Changelog = https://pybind11.readthedocs.io/en/latest/changelog.html\n    Chat = https://gitter.im/pybind/Lobby\n\n[options]\npython_requires = >=3.6\nzip_safe = False\n\n\n[flake8]\nmax-line-length = 120\nshow_source = True\nexclude = .git, __pycache__, build, dist, docs, tools, venv\nextend-ignore = E203, E722, B903, B950\nextend-select = B9\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/setup.py",
    "content": "#!/usr/bin/env python3\n\n# Setup script for PyPI; use CMakeFile.txt to build extension modules\n\nimport contextlib\nimport os\nimport re\nimport shutil\nimport string\nimport subprocess\nimport sys\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom typing import Dict, Iterator, List, Union\n\nimport setuptools.command.sdist\n\nDIR = Path(__file__).parent.absolute()\nVERSION_REGEX = re.compile(\n    r\"^\\s*#\\s*define\\s+PYBIND11_VERSION_([A-Z]+)\\s+(.*)$\", re.MULTILINE\n)\nVERSION_FILE = Path(\"pybind11/_version.py\")\nCOMMON_FILE = Path(\"include/pybind11/detail/common.h\")\n\n\ndef build_expected_version_hex(matches: Dict[str, str]) -> str:\n    patch_level_serial = matches[\"PATCH\"]\n    serial = None\n    major = int(matches[\"MAJOR\"])\n    minor = int(matches[\"MINOR\"])\n    flds = patch_level_serial.split(\".\")\n    if flds:\n        patch = int(flds[0])\n        if len(flds) == 1:\n            level = \"0\"\n            serial = 0\n        elif len(flds) == 2:\n            level_serial = flds[1]\n            for level in (\"a\", \"b\", \"c\", \"dev\"):\n                if level_serial.startswith(level):\n                    serial = int(level_serial[len(level) :])\n                    break\n    if serial is None:\n        msg = f'Invalid PYBIND11_VERSION_PATCH: \"{patch_level_serial}\"'\n        raise RuntimeError(msg)\n    version_hex_str = f\"{major:02x}{minor:02x}{patch:02x}{level[:1]}{serial:x}\"\n    return f\"0x{version_hex_str.upper()}\"\n\n\n# PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers\n# files, and the sys.prefix files (CMake and headers).\n\nglobal_sdist = os.environ.get(\"PYBIND11_GLOBAL_SDIST\", False)\n\nsetup_py = Path(\n    \"tools/setup_global.py.in\" if global_sdist else \"tools/setup_main.py.in\"\n)\nextra_cmd = 'cmdclass[\"sdist\"] = SDist\\n'\n\nto_src = (\n    (Path(\"pyproject.toml\"), Path(\"tools/pyproject.toml\")),\n    (Path(\"setup.py\"), setup_py),\n)\n\n\n# Read the listed version\nloc: Dict[str, str] = {}\ncode = compile(VERSION_FILE.read_text(encoding=\"utf-8\"), \"pybind11/_version.py\", \"exec\")\nexec(code, loc)\nversion = loc[\"__version__\"]\n\n# Verify that the version matches the one in C++\nmatches = dict(VERSION_REGEX.findall(COMMON_FILE.read_text(encoding=\"utf8\")))\ncpp_version = \"{MAJOR}.{MINOR}.{PATCH}\".format(**matches)\nif version != cpp_version:\n    msg = f\"Python version {version} does not match C++ version {cpp_version}!\"\n    raise RuntimeError(msg)\n\nversion_hex = matches.get(\"HEX\", \"MISSING\")\nexp_version_hex = build_expected_version_hex(matches)\nif version_hex != exp_version_hex:\n    msg = f\"PYBIND11_VERSION_HEX {version_hex} does not match expected value {exp_version_hex}!\"\n    raise RuntimeError(msg)\n\n\n# TODO: use literals & overload (typing extensions or Python 3.8)\ndef get_and_replace(\n    filename: Path, binary: bool = False, **opts: str\n) -> Union[bytes, str]:\n    if binary:\n        contents = filename.read_bytes()\n        return string.Template(contents.decode()).substitute(opts).encode()\n\n    return string.Template(filename.read_text()).substitute(opts)\n\n\n# Use our input files instead when making the SDist (and anything that depends\n# on it, like a wheel)\nclass SDist(setuptools.command.sdist.sdist):  # type: ignore[misc]\n    def make_release_tree(self, base_dir: str, files: List[str]) -> None:\n        super().make_release_tree(base_dir, files)\n\n        for to, src in to_src:\n            txt = get_and_replace(src, binary=True, version=version, extra_cmd=\"\")\n\n            dest = Path(base_dir) / to\n\n            # This is normally linked, so unlink before writing!\n            dest.unlink()\n            dest.write_bytes(txt)  # type: ignore[arg-type]\n\n\n# Remove the CMake install directory when done\n@contextlib.contextmanager\ndef remove_output(*sources: str) -> Iterator[None]:\n    try:\n        yield\n    finally:\n        for src in sources:\n            shutil.rmtree(src)\n\n\nwith remove_output(\"pybind11/include\", \"pybind11/share\"):\n    # Generate the files if they are not present.\n    with TemporaryDirectory() as tmpdir:\n        cmd = [\"cmake\", \"-S\", \".\", \"-B\", tmpdir] + [\n            \"-DCMAKE_INSTALL_PREFIX=pybind11\",\n            \"-DBUILD_TESTING=OFF\",\n            \"-DPYBIND11_NOPYTHON=ON\",\n            \"-Dprefix_for_pc_file=${pcfiledir}/../../\",\n        ]\n        if \"CMAKE_ARGS\" in os.environ:\n            fcommand = [\n                c\n                for c in os.environ[\"CMAKE_ARGS\"].split()\n                if \"DCMAKE_INSTALL_PREFIX\" not in c\n            ]\n            cmd += fcommand\n        subprocess.run(cmd, check=True, cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)\n        subprocess.run(\n            [\"cmake\", \"--install\", tmpdir],\n            check=True,\n            cwd=DIR,\n            stdout=sys.stdout,\n            stderr=sys.stderr,\n        )\n\n    txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)\n    code = compile(txt, setup_py, \"exec\")\n    exec(code, {\"SDist\": SDist})\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/CMakeLists.txt",
    "content": "# CMakeLists.txt -- Build system for the pybind11 test suite\n#\n# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\ncmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.21)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.21)\nendif()\n\n# Only needed for CMake < 3.5 support\ninclude(CMakeParseArguments)\n\n# Filter out items; print an optional message if any items filtered. This ignores extensions.\n#\n# Usage:\n#   pybind11_filter_tests(LISTNAME file1.cpp file2.cpp ... MESSAGE \"\")\n#\nmacro(pybind11_filter_tests LISTNAME)\n  cmake_parse_arguments(ARG \"\" \"MESSAGE\" \"\" ${ARGN})\n  set(PYBIND11_FILTER_TESTS_FOUND OFF)\n  # Make a list of the test without any extensions, for easier filtering.\n  set(_TMP_ACTUAL_LIST \"${${LISTNAME}};\") # enforce ';' at the end to allow matching last item.\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" LIST_WITHOUT_EXTENSIONS \"${_TMP_ACTUAL_LIST}\")\n  foreach(filename IN LISTS ARG_UNPARSED_ARGUMENTS)\n    string(REGEX REPLACE \"\\\\.[^.]*$\" \"\" filename_no_ext ${filename})\n    # Search in the list without extensions.\n    list(FIND LIST_WITHOUT_EXTENSIONS ${filename_no_ext} _FILE_FOUND)\n    if(_FILE_FOUND GREATER -1)\n      list(REMOVE_AT ${LISTNAME} ${_FILE_FOUND}) # And remove from the list with extensions.\n      list(REMOVE_AT LIST_WITHOUT_EXTENSIONS ${_FILE_FOUND}\n      )# And our search list, to ensure it is in sync.\n      set(PYBIND11_FILTER_TESTS_FOUND ON)\n    endif()\n  endforeach()\n  if(PYBIND11_FILTER_TESTS_FOUND AND ARG_MESSAGE)\n    message(STATUS \"${ARG_MESSAGE}\")\n  endif()\nendmacro()\n\nmacro(possibly_uninitialized)\n  foreach(VARNAME ${ARGN})\n    if(NOT DEFINED \"${VARNAME}\")\n      set(\"${VARNAME}\" \"\")\n    endif()\n  endforeach()\nendmacro()\n\n# Function to add additional targets if any of the provided tests are found.\n# Needles; Specifies the test names to look for.\n# Additions; Specifies the additional test targets to add when any of the needles are found.\nmacro(tests_extra_targets needles additions)\n  # Add the index for this relation to the index extra targets map.\n  list(LENGTH PYBIND11_TEST_EXTRA_TARGETS PYBIND11_TEST_EXTRA_TARGETS_LEN)\n  list(APPEND PYBIND11_TEST_EXTRA_TARGETS ${PYBIND11_TEST_EXTRA_TARGETS_LEN})\n  # Add the test names to look for, and the associated test target additions.\n  set(PYBIND11_TEST_EXTRA_TARGETS_NEEDLES_${PYBIND11_TEST_EXTRA_TARGETS_LEN} ${needles})\n  set(PYBIND11_TEST_EXTRA_TARGETS_ADDITION_${PYBIND11_TEST_EXTRA_TARGETS_LEN} ${additions})\nendmacro()\n\n# New Python support\nif(DEFINED Python_EXECUTABLE)\n  set(PYTHON_EXECUTABLE \"${Python_EXECUTABLE}\")\n  set(PYTHON_VERSION \"${Python_VERSION}\")\nendif()\n\n# There's no harm in including a project in a project\nproject(pybind11_tests CXX)\n\n# Access FindCatch and more\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}/../tools\")\n\noption(PYBIND11_WERROR \"Report all warnings as errors\" OFF)\noption(DOWNLOAD_EIGEN \"Download EIGEN (requires CMake 3.11+)\" OFF)\noption(PYBIND11_CUDA_TESTS \"Enable building CUDA tests (requires CMake 3.12+)\" OFF)\nset(PYBIND11_TEST_OVERRIDE\n    \"\"\n    CACHE STRING \"Tests from ;-separated list of *.cpp files will be built instead of all tests\")\nset(PYBIND11_TEST_FILTER\n    \"\"\n    CACHE STRING \"Tests from ;-separated list of *.cpp files will be removed from all tests\")\n\nif(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n  # We're being loaded directly, i.e. not via add_subdirectory, so make this\n  # work as its own project and load the pybind11Config to get the tools we need\n  find_package(pybind11 REQUIRED CONFIG)\nendif()\n\nif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)\n  message(STATUS \"Setting tests build type to MinSizeRel as none was specified\")\n  set(CMAKE_BUILD_TYPE\n      MinSizeRel\n      CACHE STRING \"Choose the type of build.\" FORCE)\n  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS \"Debug\" \"Release\" \"MinSizeRel\"\n                                               \"RelWithDebInfo\")\nendif()\n\nif(PYBIND11_CUDA_TESTS)\n  enable_language(CUDA)\n  if(DEFINED CMAKE_CXX_STANDARD)\n    set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD})\n  endif()\n  set(CMAKE_CUDA_STANDARD_REQUIRED ON)\nendif()\n\n# Full set of test files (you can override these; see below, overrides ignore extension)\n# Any test that has no extension is both .py and .cpp, so 'foo' will add 'foo.cpp' and 'foo.py'.\n# Any test that has an extension is exclusively that and handled as such.\nset(PYBIND11_TEST_FILES\n    test_async\n    test_buffers\n    test_builtin_casters\n    test_call_policies\n    test_callbacks\n    test_chrono\n    test_class\n    test_const_name\n    test_constants_and_functions\n    test_copy_move\n    test_custom_type_casters\n    test_custom_type_setup\n    test_docstring_options\n    test_eigen_matrix\n    test_eigen_tensor\n    test_eigen_tensor_avoid_stl_array.cpp\n    test_enum\n    test_eval\n    test_exceptions\n    test_factory_constructors\n    test_gil_scoped\n    test_iostream\n    test_kwargs_and_defaults\n    test_local_bindings\n    test_methods_and_attributes\n    test_modules\n    test_multiple_inheritance\n    test_numpy_array\n    test_numpy_dtypes\n    test_numpy_vectorize\n    test_opaque_types\n    test_operator_overloading\n    test_pickling\n    test_pytypes\n    test_sequences_and_iterators\n    test_smart_ptr\n    test_stl\n    test_stl_binders\n    test_tagbased_polymorphic\n    test_thread\n    test_union\n    test_virtual_functions)\n\n# Invoking cmake with something like:\n#     cmake -DPYBIND11_TEST_OVERRIDE=\"test_callbacks.cpp;test_pickling.cpp\" ..\n# lets you override the tests that get compiled and run.  You can restore to all tests with:\n#     cmake -DPYBIND11_TEST_OVERRIDE= ..\nif(PYBIND11_TEST_OVERRIDE)\n  # Instead of doing a direct override here, we iterate over the overrides without extension and\n  # match them against entries from the PYBIND11_TEST_FILES, anything that not matches goes into the filter list.\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" TEST_OVERRIDE_NO_EXT \"${PYBIND11_TEST_OVERRIDE};\")\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" TEST_FILES_NO_EXT \"${PYBIND11_TEST_FILES};\")\n  # This allows the override to be done with extensions, preserving backwards compatibility.\n  foreach(test_name ${TEST_FILES_NO_EXT})\n    if(NOT ${test_name} IN_LIST TEST_OVERRIDE_NO_EXT\n    )# If not in the whitelist, add to be filtered out.\n      list(APPEND PYBIND11_TEST_FILTER ${test_name})\n    endif()\n  endforeach()\nendif()\n\n# You can also filter tests:\nif(PYBIND11_TEST_FILTER)\n  pybind11_filter_tests(PYBIND11_TEST_FILES ${PYBIND11_TEST_FILTER})\nendif()\n\n# Skip tests for CUDA check:\n# /pybind11/tests/test_constants_and_functions.cpp(125):\n#   error: incompatible exception specifications\nif(PYBIND11_CUDA_TESTS)\n  pybind11_filter_tests(\n    PYBIND11_TEST_FILES test_constants_and_functions.cpp MESSAGE\n    \"Skipping test_constants_and_functions due to incompatible exception specifications\")\nendif()\n\n# Now that the test filtering is complete, we need to split the list into the test for PYTEST\n# and the list for the cpp targets.\nset(PYBIND11_CPPTEST_FILES \"\")\nset(PYBIND11_PYTEST_FILES \"\")\n\nforeach(test_name ${PYBIND11_TEST_FILES})\n  if(test_name MATCHES \"\\\\.py$\") # Ends in .py, purely python test.\n    list(APPEND PYBIND11_PYTEST_FILES ${test_name})\n  elseif(test_name MATCHES \"\\\\.cpp$\") # Ends in .cpp, purely cpp test.\n    list(APPEND PYBIND11_CPPTEST_FILES ${test_name})\n  elseif(NOT test_name MATCHES \"\\\\.\") # No extension specified, assume both, add extension.\n    list(APPEND PYBIND11_PYTEST_FILES ${test_name}.py)\n    list(APPEND PYBIND11_CPPTEST_FILES ${test_name}.cpp)\n  else()\n    message(WARNING \"Unhanded test extension in test: ${test_name}\")\n  endif()\nendforeach()\nset(PYBIND11_TEST_FILES ${PYBIND11_CPPTEST_FILES})\nlist(SORT PYBIND11_PYTEST_FILES)\n\n# Contains the set of test files that require pybind11_cross_module_tests to be\n# built; if none of these are built (i.e. because TEST_OVERRIDE is used and\n# doesn't include them) the second module doesn't get built.\ntests_extra_targets(\"test_exceptions.py;test_local_bindings.py;test_stl.py;test_stl_binders.py\"\n                    \"pybind11_cross_module_tests\")\n\n# And add additional targets for other tests.\ntests_extra_targets(\"test_exceptions.py\" \"cross_module_interleaved_error_already_set\")\ntests_extra_targets(\"test_gil_scoped.py\" \"cross_module_gil_utils\")\n\nset(PYBIND11_EIGEN_REPO\n    \"https://gitlab.com/libeigen/eigen.git\"\n    CACHE STRING \"Eigen repository to use for tests\")\n# Always use a hash for reconfigure speed and security reasons\n# Include the version number for pretty printing (keep in sync)\nset(PYBIND11_EIGEN_VERSION_AND_HASH\n    \"3.4.0;929bc0e191d0927b1735b9a1ddc0e8b77e3a25ec\"\n    CACHE STRING \"Eigen version to use for tests, format: VERSION;HASH\")\n\nlist(GET PYBIND11_EIGEN_VERSION_AND_HASH 0 PYBIND11_EIGEN_VERSION_STRING)\nlist(GET PYBIND11_EIGEN_VERSION_AND_HASH 1 PYBIND11_EIGEN_VERSION_HASH)\n\n# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but\n# keep it in PYBIND11_PYTEST_FILES, so that we get the \"eigen is not installed\"\n# skip message).\nlist(FIND PYBIND11_TEST_FILES test_eigen_matrix.cpp PYBIND11_TEST_FILES_EIGEN_I)\nif(PYBIND11_TEST_FILES_EIGEN_I EQUAL -1)\n  list(FIND PYBIND11_TEST_FILES test_eigen_tensor.cpp PYBIND11_TEST_FILES_EIGEN_I)\nendif()\nif(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n  # Try loading via newer Eigen's Eigen3Config first (bypassing tools/FindEigen3.cmake).\n  # Eigen 3.3.1+ exports a cmake 3.0+ target for handling dependency requirements, but also\n  # produces a fatal error if loaded from a pre-3.0 cmake.\n  if(DOWNLOAD_EIGEN)\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      message(FATAL_ERROR \"CMake 3.11+ required when using DOWNLOAD_EIGEN\")\n    endif()\n\n    include(FetchContent)\n    FetchContent_Declare(\n      eigen\n      GIT_REPOSITORY \"${PYBIND11_EIGEN_REPO}\"\n      GIT_TAG \"${PYBIND11_EIGEN_VERSION_HASH}\")\n\n    FetchContent_GetProperties(eigen)\n    if(NOT eigen_POPULATED)\n      message(\n        STATUS\n          \"Downloading Eigen ${PYBIND11_EIGEN_VERSION_STRING} (${PYBIND11_EIGEN_VERSION_HASH}) from ${PYBIND11_EIGEN_REPO}\"\n      )\n      FetchContent_Populate(eigen)\n    endif()\n\n    set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR})\n    set(EIGEN3_FOUND TRUE)\n    # When getting locally, the version is not visible from a superprojet,\n    # so just force it.\n    set(EIGEN3_VERSION \"${PYBIND11_EIGEN_VERSION_STRING}\")\n\n  else()\n    find_package(Eigen3 3.2.7 QUIET CONFIG)\n\n    if(NOT EIGEN3_FOUND)\n      # Couldn't load via target, so fall back to allowing module mode finding, which will pick up\n      # tools/FindEigen3.cmake\n      find_package(Eigen3 3.2.7 QUIET)\n    endif()\n  endif()\n\n  if(EIGEN3_FOUND)\n    if(NOT TARGET Eigen3::Eigen)\n      add_library(Eigen3::Eigen IMPORTED INTERFACE)\n      set_property(TARGET Eigen3::Eigen PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                 \"${EIGEN3_INCLUDE_DIR}\")\n    endif()\n\n    # Eigen 3.3.1+ cmake sets EIGEN3_VERSION_STRING (and hard codes the version when installed\n    # rather than looking it up in the cmake script); older versions, and the\n    # tools/FindEigen3.cmake, set EIGEN3_VERSION instead.\n    if(NOT EIGEN3_VERSION AND EIGEN3_VERSION_STRING)\n      set(EIGEN3_VERSION ${EIGEN3_VERSION_STRING})\n    endif()\n    message(STATUS \"Building tests with Eigen v${EIGEN3_VERSION}\")\n  else()\n    list(FIND PYBIND11_TEST_FILES test_eigen_matrix.cpp PYBIND11_TEST_FILES_EIGEN_I)\n    if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n      list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n    endif()\n\n    list(FIND PYBIND11_TEST_FILES test_eigen_tensor.cpp PYBIND11_TEST_FILES_EIGEN_I)\n    if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n      list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n    endif()\n    list(FIND PYBIND11_TEST_FILES test_eigen_tensor_avoid_stl_array.cpp\n         PYBIND11_TEST_FILES_EIGEN_I)\n    if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n      list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n    endif()\n    message(\n      STATUS \"Building tests WITHOUT Eigen, use -DDOWNLOAD_EIGEN=ON on CMake 3.11+ to download\")\n  endif()\nendif()\n\n# Some code doesn't support gcc 4\nif(CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)\n  list(FIND PYBIND11_TEST_FILES test_eigen_tensor.cpp PYBIND11_TEST_FILES_EIGEN_I)\n  if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n    list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n  endif()\n  list(FIND PYBIND11_TEST_FILES test_eigen_tensor_avoid_stl_array.cpp PYBIND11_TEST_FILES_EIGEN_I)\n  if(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n    list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n  endif()\nendif()\n\n# Optional dependency for some tests (boost::variant is only supported with version >= 1.56)\nfind_package(Boost 1.56)\n\nif(Boost_FOUND)\n  if(NOT TARGET Boost::headers)\n    add_library(Boost::headers IMPORTED INTERFACE)\n    if(TARGET Boost::boost)\n      # Classic FindBoost\n      set_property(TARGET Boost::boost PROPERTY INTERFACE_LINK_LIBRARIES Boost::boost)\n    else()\n      # Very old FindBoost, or newer Boost than CMake in older CMakes\n      set_property(TARGET Boost::headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                  ${Boost_INCLUDE_DIRS})\n    endif()\n  endif()\nendif()\n\n# Check if we need to add -lstdc++fs or -lc++fs or nothing\nif(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17)\n  set(STD_FS_NO_LIB_NEEDED TRUE)\nelseif(MSVC)\n  set(STD_FS_NO_LIB_NEEDED TRUE)\nelse()\n  file(\n    WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    \"#include <filesystem>\\nint main(int argc, char ** argv) {\\n  std::filesystem::path p(argv[0]);\\n  return p.string().length();\\n}\"\n  )\n  try_compile(\n    STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17)\n  try_compile(\n    STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17\n    LINK_LIBRARIES stdc++fs)\n  try_compile(\n    STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17\n    LINK_LIBRARIES c++fs)\nendif()\n\nif(${STD_FS_NEEDS_STDCXXFS})\n  set(STD_FS_LIB stdc++fs)\nelseif(${STD_FS_NEEDS_CXXFS})\n  set(STD_FS_LIB c++fs)\nelseif(${STD_FS_NO_LIB_NEEDED})\n  set(STD_FS_LIB \"\")\nelse()\n  message(WARNING \"Unknown C++17 compiler - not passing -lstdc++fs\")\n  set(STD_FS_LIB \"\")\nendif()\n\n# Compile with compiler warnings turned on\nfunction(pybind11_enable_warnings target_name)\n  if(MSVC)\n    target_compile_options(${target_name} PRIVATE /W4 /wd4189)\n  elseif(CMAKE_CXX_COMPILER_ID MATCHES \"(GNU|Intel|Clang)\" AND NOT PYBIND11_CUDA_TESTS)\n    target_compile_options(\n      ${target_name}\n      PRIVATE -Wall\n              -Wextra\n              -Wconversion\n              -Wcast-qual\n              -Wdeprecated\n              -Wundef\n              -Wnon-virtual-dtor)\n  endif()\n\n  if(PYBIND11_WERROR)\n    if(MSVC)\n      target_compile_options(${target_name} PRIVATE /WX)\n    elseif(PYBIND11_CUDA_TESTS)\n      target_compile_options(${target_name} PRIVATE \"SHELL:-Werror all-warnings\")\n    elseif(CMAKE_CXX_COMPILER_ID MATCHES \"(GNU|Clang|IntelLLVM)\")\n      target_compile_options(${target_name} PRIVATE -Werror)\n    elseif(CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\")\n      if(CMAKE_CXX_STANDARD EQUAL 17) # See PR #3570\n        target_compile_options(${target_name} PRIVATE -Wno-conversion)\n      endif()\n      target_compile_options(\n        ${target_name}\n        PRIVATE\n          -Werror-all\n          # \"Inlining inhibited by limit max-size\", \"Inlining inhibited by limit max-total-size\"\n          -diag-disable 11074,11076)\n    endif()\n  endif()\nendfunction()\n\nset(test_targets pybind11_tests)\n\n# Check if any tests need extra targets by iterating through the mappings registered.\nforeach(i ${PYBIND11_TEST_EXTRA_TARGETS})\n  foreach(needle ${PYBIND11_TEST_EXTRA_TARGETS_NEEDLES_${i}})\n    if(needle IN_LIST PYBIND11_PYTEST_FILES)\n      # Add all the additional targets to the test list. List join in newer cmake.\n      foreach(extra_target ${PYBIND11_TEST_EXTRA_TARGETS_ADDITION_${i}})\n        list(APPEND test_targets ${extra_target})\n      endforeach()\n      break() # Breaks out of the needle search, continues with the next mapping.\n    endif()\n  endforeach()\nendforeach()\n\n# Support CUDA testing by forcing the target file to compile with NVCC\nif(PYBIND11_CUDA_TESTS)\n  set_property(SOURCE ${PYBIND11_TEST_FILES} PROPERTY LANGUAGE CUDA)\nendif()\n\nforeach(target ${test_targets})\n  set(test_files ${PYBIND11_TEST_FILES})\n  if(NOT \"${target}\" STREQUAL \"pybind11_tests\")\n    set(test_files \"\")\n  endif()\n\n  # Support CUDA testing by forcing the target file to compile with NVCC\n  if(PYBIND11_CUDA_TESTS)\n    set_property(SOURCE ${target}.cpp PROPERTY LANGUAGE CUDA)\n  endif()\n\n  # Create the binding library\n  pybind11_add_module(${target} THIN_LTO ${target}.cpp ${test_files} ${PYBIND11_HEADERS})\n  pybind11_enable_warnings(${target})\n\n  if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n    get_property(\n      suffix\n      TARGET ${target}\n      PROPERTY SUFFIX)\n    set(source_output \"${CMAKE_CURRENT_SOURCE_DIR}/${target}${suffix}\")\n    if(suffix AND EXISTS \"${source_output}\")\n      message(WARNING \"Output file also in source directory; \"\n                      \"please remove to avoid confusion: ${source_output}\")\n    endif()\n  endif()\n\n  if(MSVC)\n    target_compile_options(${target} PRIVATE /utf-8)\n  endif()\n\n  if(EIGEN3_FOUND)\n    target_link_libraries(${target} PRIVATE Eigen3::Eigen)\n    target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_EIGEN)\n  endif()\n\n  if(Boost_FOUND)\n    target_link_libraries(${target} PRIVATE Boost::headers)\n    target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_BOOST)\n  endif()\n\n  target_link_libraries(${target} PRIVATE ${STD_FS_LIB})\n\n  # Always write the output file directly into the 'tests' directory (even on MSVC)\n  if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)\n    set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n                                               \"${CMAKE_CURRENT_BINARY_DIR}\")\n\n    if(DEFINED CMAKE_CONFIGURATION_TYPES)\n      foreach(config ${CMAKE_CONFIGURATION_TYPES})\n        string(TOUPPER ${config} config)\n        set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config}\n                                                   \"${CMAKE_CURRENT_BINARY_DIR}\")\n      endforeach()\n    endif()\n  endif()\nendforeach()\n\n# Provide nice organisation in IDEs\nif(NOT CMAKE_VERSION VERSION_LESS 3.8)\n  source_group(\n    TREE \"${CMAKE_CURRENT_SOURCE_DIR}/../include\"\n    PREFIX \"Header Files\"\n    FILES ${PYBIND11_HEADERS})\nendif()\n\n# Make sure pytest is found or produce a warning\npybind11_find_import(pytest VERSION 3.1)\n\nif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n  # This is not used later in the build, so it's okay to regenerate each time.\n  configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/pytest.ini\" \"${CMAKE_CURRENT_BINARY_DIR}/pytest.ini\"\n                 COPYONLY)\n  file(APPEND \"${CMAKE_CURRENT_BINARY_DIR}/pytest.ini\"\n       \"\\ntestpaths = \\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"\")\n\nendif()\n\n# cmake 3.12 added list(transform <list> prepend\n# but we can't use it yet\nstring(REPLACE \"test_\" \"${CMAKE_CURRENT_SOURCE_DIR}/test_\" PYBIND11_ABS_PYTEST_FILES\n               \"${PYBIND11_PYTEST_FILES}\")\n\nset(PYBIND11_TEST_PREFIX_COMMAND\n    \"\"\n    CACHE STRING \"Put this before pytest, use for checkers and such\")\n\n# A single command to compile and run the tests\nadd_custom_target(\n  pytest\n  COMMAND ${PYBIND11_TEST_PREFIX_COMMAND} ${PYTHON_EXECUTABLE} -m pytest\n          ${PYBIND11_ABS_PYTEST_FILES}\n  DEPENDS ${test_targets}\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\"\n  USES_TERMINAL)\n\nif(PYBIND11_TEST_OVERRIDE)\n  add_custom_command(\n    TARGET pytest\n    POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E echo\n            \"Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect\")\nendif()\n\n# cmake-format: off\nadd_custom_target(\n  memcheck\n  COMMAND\n    PYTHONMALLOC=malloc\n    valgrind\n    --leak-check=full\n    --show-leak-kinds=definite,indirect\n    --errors-for-leak-kinds=definite,indirect\n    --error-exitcode=1\n    --read-var-info=yes\n    --track-origins=yes\n    --suppressions=\"${CMAKE_CURRENT_SOURCE_DIR}/valgrind-python.supp\"\n    --suppressions=\"${CMAKE_CURRENT_SOURCE_DIR}/valgrind-numpy-scipy.supp\"\n    --gen-suppressions=all\n    ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_ABS_PYTEST_FILES}\n  DEPENDS ${test_targets}\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\"\n  USES_TERMINAL)\n# cmake-format: on\n\n# Add a check target to run all the tests, starting with pytest (we add dependencies to this below)\nadd_custom_target(check DEPENDS pytest)\n\n# The remaining tests only apply when being built as part of the pybind11 project, but not if the\n# tests are being built independently.\nif(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n  return()\nendif()\n\n# Add a post-build comment to show the primary test suite .so size and, if a previous size, compare it:\nadd_custom_command(\n  TARGET pybind11_tests\n  POST_BUILD\n  COMMAND\n    ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/libsize.py\n    $<TARGET_FILE:pybind11_tests>\n    ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt)\n\nif(NOT PYBIND11_CUDA_TESTS)\n  # Test embedding the interpreter. Provides the `cpptest` target.\n  add_subdirectory(test_embed)\n\n  # Test CMake build using functions and targets from subdirectory or installed location\n  add_subdirectory(test_cmake_build)\nendif()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/catch/catch.hpp",
    "content": "/*\n *  Catch v2.13.9\n *  Generated: 2022-04-12 22:37:23.260201\n *  ----------------------------------------------------------\n *  This file has been merged from multiple headers. Please don't edit it directly\n *  Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved.\n *\n *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\n#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n// start catch.hpp\n\n\n#define CATCH_VERSION_MAJOR 2\n#define CATCH_VERSION_MINOR 13\n#define CATCH_VERSION_PATCH 9\n\n#ifdef __clang__\n#    pragma clang system_header\n#elif defined __GNUC__\n#    pragma GCC system_header\n#endif\n\n// start catch_suppress_warnings.h\n\n#ifdef __clang__\n#   ifdef __ICC // icpc defines the __clang__ macro\n#       pragma warning(push)\n#       pragma warning(disable: 161 1682)\n#   else // __ICC\n#       pragma clang diagnostic push\n#       pragma clang diagnostic ignored \"-Wpadded\"\n#       pragma clang diagnostic ignored \"-Wswitch-enum\"\n#       pragma clang diagnostic ignored \"-Wcovered-switch-default\"\n#    endif\n#elif defined __GNUC__\n     // Because REQUIREs trigger GCC's -Wparentheses, and because still\n     // supported version of g++ have only buggy support for _Pragmas,\n     // Wparentheses have to be suppressed globally.\n#    pragma GCC diagnostic ignored \"-Wparentheses\" // See #674 for details\n\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wunused-variable\"\n#    pragma GCC diagnostic ignored \"-Wpadded\"\n#endif\n// end catch_suppress_warnings.h\n#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)\n#  define CATCH_IMPL\n#  define CATCH_CONFIG_ALL_PARTS\n#endif\n\n// In the impl file, we want to have access to all parts of the headers\n// Can also be used to sanely support PCHs\n#if defined(CATCH_CONFIG_ALL_PARTS)\n#  define CATCH_CONFIG_EXTERNAL_INTERFACES\n#  if defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#    undef CATCH_CONFIG_DISABLE_MATCHERS\n#  endif\n#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  endif\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n// start catch_platform.h\n\n// See e.g.:\n// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html\n#ifdef __APPLE__\n#  include <TargetConditionals.h>\n#  if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \\\n      (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)\n#    define CATCH_PLATFORM_MAC\n#  elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)\n#    define CATCH_PLATFORM_IPHONE\n#  endif\n\n#elif defined(linux) || defined(__linux) || defined(__linux__)\n#  define CATCH_PLATFORM_LINUX\n\n#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)\n#  define CATCH_PLATFORM_WINDOWS\n#endif\n\n// end catch_platform.h\n\n#ifdef CATCH_IMPL\n#  ifndef CLARA_CONFIG_MAIN\n#    define CLARA_CONFIG_MAIN_NOT_DEFINED\n#    define CLARA_CONFIG_MAIN\n#  endif\n#endif\n\n// start catch_user_interfaces.h\n\nnamespace Catch {\n    unsigned int rngSeed();\n}\n\n// end catch_user_interfaces.h\n// start catch_tag_alias_autoregistrar.h\n\n// start catch_common.h\n\n// start catch_compiler_capabilities.h\n\n// Detect a number of compiler features - by compiler\n// The following features are defined:\n//\n// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?\n// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?\n// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?\n// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?\n// ****************\n// Note to maintainers: if new toggles are added please document them\n// in configuration.md, too\n// ****************\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n#ifdef __cplusplus\n\n#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)\n#    define CATCH_CPP14_OR_GREATER\n#  endif\n\n#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)\n#    define CATCH_CPP17_OR_GREATER\n#  endif\n\n#endif\n\n// Only GCC compiler should be used in this block, so other compilers trying to\n// mask themselves as GCC should be ignored.\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"GCC diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"GCC diagnostic pop\" )\n\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)\n\n#endif\n\n#if defined(__clang__)\n\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"clang diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"clang diagnostic pop\" )\n\n// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug\n// which results in calls to destructors being emitted for each temporary,\n// without a matching initialization. In practice, this can result in something\n// like `std::string::~string` being called on an uninitialized value.\n//\n// For example, this code will likely segfault under IBM XL:\n// ```\n// REQUIRE(std::string(\"12\") + \"34\" == \"1234\")\n// ```\n//\n// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.\n#  if !defined(__ibmxl__) && !defined(__CUDACC__)\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */\n#  endif\n\n#    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wexit-time-destructors\\\"\" ) \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wglobal-constructors\\\"\")\n\n#    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wparentheses\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-variable\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wgnu-zero-variadic-macro-arguments\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-template\\\"\" )\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// Assume that non-Windows platforms support posix signals by default\n#if !defined(CATCH_PLATFORM_WINDOWS)\n    #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// We know some environments not to support full POSIX signals\n#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)\n    #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#endif\n\n#ifdef __OS400__\n#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#       define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Android somehow still does not support std::to_string\n#if defined(__ANDROID__)\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Not all Windows environments support SEH properly\n#if defined(__MINGW32__)\n#    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// PS4\n#if defined(__ORBIS__)\n#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Cygwin\n#ifdef __CYGWIN__\n\n// Required for some versions of Cygwin to declare gettimeofday\n// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin\n#   define _BSD_SOURCE\n// some versions of cygwin (most) do not support std::to_string. Use the libstd check.\n// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813\n# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \\\n           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))\n\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n\n# endif\n#endif // __CYGWIN__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#if defined(_MSC_VER)\n\n// Universal Windows platform does not support SEH\n// Or console colours (or console at all...)\n#  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)\n#    define CATCH_CONFIG_COLOUR_NONE\n#  else\n#    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH\n#  endif\n\n#  if !defined(__clang__) // Handle Clang masquerading for msvc\n\n// MSVC traditional preprocessor needs some workaround for __VA_ARGS__\n// _MSVC_TRADITIONAL == 0 means new conformant preprocessor\n// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor\n#    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)\n#      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#    endif // MSVC_TRADITIONAL\n\n// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )\n#  endif // __clang__\n\n#endif // _MSC_VER\n\n#if defined(_REENTRANT) || defined(_MSC_VER)\n// Enable async processing, as -pthread is specified or no additional linking is required\n# define CATCH_INTERNAL_CONFIG_USE_ASYNC\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n// Check if we are compiled with -fno-exceptions or equivalent\n#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)\n#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// DJGPP\n#ifdef __DJGPP__\n#  define CATCH_INTERNAL_CONFIG_NO_WCHAR\n#endif // __DJGPP__\n\n////////////////////////////////////////////////////////////////////////////////\n// Embarcadero C++Build\n#if defined(__BORLANDC__)\n    #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Use of __COUNTER__ is suppressed during code analysis in\n// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly\n// handled by it.\n// Otherwise all supported compilers support COUNTER macro,\n// but user still might want to turn it off\n#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )\n    #define CATCH_INTERNAL_CONFIG_COUNTER\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// RTX is a special version of Windows that is real time.\n// This means that it is detected as Windows, but does not provide\n// the same set of capabilities as real Windows does.\n#if defined(UNDER_RTSS) || defined(RTX64_BUILD)\n    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n    #define CATCH_INTERNAL_CONFIG_NO_ASYNC\n    #define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n#if !defined(_GLIBCXX_USE_C99_MATH_TR1)\n#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Various stdlib support checks that require __has_include\n#if defined(__has_include)\n  // Check if string_view is available and usable\n  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW\n  #endif\n\n  // Check if optional is available and usable\n  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL\n  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if byte is available and usable\n  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n  #    include <cstddef>\n  #    if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)\n  #      define CATCH_INTERNAL_CONFIG_CPP17_BYTE\n  #    endif\n  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if variant is available and usable\n  #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n  #    if defined(__clang__) && (__clang_major__ < 8)\n         // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852\n         // fix should be in clang 8, workaround in libstdc++ 8.2\n  #      include <ciso646>\n  #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #        define CATCH_CONFIG_NO_CPP17_VARIANT\n  #      else\n  #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #    else\n  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #    endif // defined(__clang__) && (__clang_major__ < 8)\n  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n#endif // defined(__has_include)\n\n#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)\n#   define CATCH_CONFIG_COUNTER\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)\n#   define CATCH_CONFIG_WINDOWS_SEH\n#endif\n// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.\n#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)\n#   define CATCH_CONFIG_POSIX_SIGNALS\n#endif\n// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.\n#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)\n#   define CATCH_CONFIG_WCHAR\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)\n#    define CATCH_CONFIG_CPP11_TO_STRING\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#  define CATCH_CONFIG_CPP17_OPTIONAL\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)\n#  define CATCH_CONFIG_CPP17_STRING_VIEW\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)\n#  define CATCH_CONFIG_CPP17_VARIANT\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)\n#  define CATCH_CONFIG_CPP17_BYTE\n#endif\n\n#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)\n#  define CATCH_CONFIG_NEW_CAPTURE\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#  define CATCH_CONFIG_DISABLE_EXCEPTIONS\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n#  define CATCH_CONFIG_POLYFILL_ISNAN\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)\n#  define CATCH_CONFIG_USE_ASYNC\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#  define CATCH_CONFIG_ANDROID_LOGWRITE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n#  define CATCH_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Even if we do not think the compiler has that warning, we still have\n// to provide a macro that can be used by the code.\n#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS\n#endif\n\n// The goal of this macro is to avoid evaluation of the arguments, but\n// still have the compiler warn on problems inside...\n#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)\n#   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)\n#endif\n\n#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#elif defined(__clang__) && (__clang_major__ < 5)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#define CATCH_TRY if ((true))\n#define CATCH_CATCH_ALL if ((false))\n#define CATCH_CATCH_ANON(type) if ((false))\n#else\n#define CATCH_TRY try\n#define CATCH_CATCH_ALL catch (...)\n#define CATCH_CATCH_ANON(type) catch (type)\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)\n#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#endif\n\n// end catch_compiler_capabilities.h\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )\n#ifdef CATCH_CONFIG_COUNTER\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )\n#else\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )\n#endif\n\n#include <iosfwd>\n#include <string>\n#include <cstdint>\n\n// We need a dummy global operator<< so we can bring it into Catch namespace later\nstruct Catch_global_namespace_dummy {};\nstd::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);\n\nnamespace Catch {\n\n    struct CaseSensitive { enum Choice {\n        Yes,\n        No\n    }; };\n\n    class NonCopyable {\n        NonCopyable( NonCopyable const& )              = delete;\n        NonCopyable( NonCopyable && )                  = delete;\n        NonCopyable& operator = ( NonCopyable const& ) = delete;\n        NonCopyable& operator = ( NonCopyable && )     = delete;\n\n    protected:\n        NonCopyable();\n        virtual ~NonCopyable();\n    };\n\n    struct SourceLineInfo {\n\n        SourceLineInfo() = delete;\n        SourceLineInfo( char const* _file, std::size_t _line ) noexcept\n        :   file( _file ),\n            line( _line )\n        {}\n\n        SourceLineInfo( SourceLineInfo const& other )            = default;\n        SourceLineInfo& operator = ( SourceLineInfo const& )     = default;\n        SourceLineInfo( SourceLineInfo&& )              noexcept = default;\n        SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;\n\n        bool empty() const noexcept { return file[0] == '\\0'; }\n        bool operator == ( SourceLineInfo const& other ) const noexcept;\n        bool operator < ( SourceLineInfo const& other ) const noexcept;\n\n        char const* file;\n        std::size_t line;\n    };\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );\n\n    // Bring in operator<< from global namespace into Catch namespace\n    // This is necessary because the overload of operator<< above makes\n    // lookup stop at namespace Catch\n    using ::operator<<;\n\n    // Use this in variadic streaming macros to allow\n    //    >> +StreamEndStop\n    // as well as\n    //    >> stuff +StreamEndStop\n    struct StreamEndStop {\n        std::string operator+() const;\n    };\n    template<typename T>\n    T const& operator + ( T const& value, StreamEndStop ) {\n        return value;\n    }\n}\n\n#define CATCH_INTERNAL_LINEINFO \\\n    ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )\n\n// end catch_common.h\nnamespace Catch {\n\n    struct RegistrarForTagAliases {\n        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n    };\n\n} // end namespace Catch\n\n#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_tag_alias_autoregistrar.h\n// start catch_test_registry.h\n\n// start catch_interfaces_testcase.h\n\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec;\n\n    struct ITestInvoker {\n        virtual void invoke () const = 0;\n        virtual ~ITestInvoker();\n    };\n\n    class TestCase;\n    struct IConfig;\n\n    struct ITestCaseRegistry {\n        virtual ~ITestCaseRegistry();\n        virtual std::vector<TestCase> const& getAllTests() const = 0;\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;\n    };\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n}\n\n// end catch_interfaces_testcase.h\n// start catch_stringref.h\n\n#include <cstddef>\n#include <string>\n#include <iosfwd>\n#include <cassert>\n\nnamespace Catch {\n\n    /// A non-owning string class (similar to the forthcoming std::string_view)\n    /// Note that, because a StringRef may be a substring of another string,\n    /// it may not be null terminated.\n    class StringRef {\n    public:\n        using size_type = std::size_t;\n        using const_iterator = const char*;\n\n    private:\n        static constexpr char const* const s_empty = \"\";\n\n        char const* m_start = s_empty;\n        size_type m_size = 0;\n\n    public: // construction\n        constexpr StringRef() noexcept = default;\n\n        StringRef( char const* rawChars ) noexcept;\n\n        constexpr StringRef( char const* rawChars, size_type size ) noexcept\n        :   m_start( rawChars ),\n            m_size( size )\n        {}\n\n        StringRef( std::string const& stdString ) noexcept\n        :   m_start( stdString.c_str() ),\n            m_size( stdString.size() )\n        {}\n\n        explicit operator std::string() const {\n            return std::string(m_start, m_size);\n        }\n\n    public: // operators\n        auto operator == ( StringRef const& other ) const noexcept -> bool;\n        auto operator != (StringRef const& other) const noexcept -> bool {\n            return !(*this == other);\n        }\n\n        auto operator[] ( size_type index ) const noexcept -> char {\n            assert(index < m_size);\n            return m_start[index];\n        }\n\n    public: // named queries\n        constexpr auto empty() const noexcept -> bool {\n            return m_size == 0;\n        }\n        constexpr auto size() const noexcept -> size_type {\n            return m_size;\n        }\n\n        // Returns the current start pointer. If the StringRef is not\n        // null-terminated, throws std::domain_exception\n        auto c_str() const -> char const*;\n\n    public: // substrings and searches\n        // Returns a substring of [start, start + length).\n        // If start + length > size(), then the substring is [start, size()).\n        // If start > size(), then the substring is empty.\n        auto substr( size_type start, size_type length ) const noexcept -> StringRef;\n\n        // Returns the current start pointer. May not be null-terminated.\n        auto data() const noexcept -> char const*;\n\n        constexpr auto isNullTerminated() const noexcept -> bool {\n            return m_start[m_size] == '\\0';\n        }\n\n    public: // iterators\n        constexpr const_iterator begin() const { return m_start; }\n        constexpr const_iterator end() const { return m_start + m_size; }\n    };\n\n    auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;\n    auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;\n\n    constexpr auto operator \"\" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {\n        return StringRef( rawChars, size );\n    }\n} // namespace Catch\n\nconstexpr auto operator \"\" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {\n    return Catch::StringRef( rawChars, size );\n}\n\n// end catch_stringref.h\n// start catch_preprocessor.hpp\n\n\n#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__\n#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))\n\n#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__\n// MSVC needs more evaluations\n#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))\n#else\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)\n#endif\n\n#define CATCH_REC_END(...)\n#define CATCH_REC_OUT\n\n#define CATCH_EMPTY()\n#define CATCH_DEFER(id) id CATCH_EMPTY()\n\n#define CATCH_REC_GET_END2() 0, CATCH_REC_END\n#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2\n#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1\n#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT\n#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)\n#define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)\n\n#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n\n#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n\n// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,\n// and passes userdata as the first parameter to each invocation,\n// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)\n#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)\n#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__\n#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__\n#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))\n#else\n// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)\n#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)\n#endif\n\n#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__\n#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)\n\n#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))\n#else\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))\n#endif\n\n#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\\\n    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)\n\n#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)\n#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)\n#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)\n#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)\n#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)\n#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)\n#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)\n#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)\n#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)\n#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)\n#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)\n\n#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N\n\n#define INTERNAL_CATCH_TYPE_GEN\\\n    template<typename...> struct TypeList {};\\\n    template<typename...Ts>\\\n    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\\\n    template<template<typename...> class...> struct TemplateTypeList{};\\\n    template<template<typename...> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\\\n    template<typename...>\\\n    struct append;\\\n    template<typename...>\\\n    struct rewrap;\\\n    template<template<typename...> class, typename...>\\\n    struct create;\\\n    template<template<typename...> class, typename>\\\n    struct convert;\\\n    \\\n    template<typename T> \\\n    struct append<T> { using type = T; };\\\n    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\\\n    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\\\n    template< template<typename...> class L1, typename...E1, typename...Rest>\\\n    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\\\n    \\\n    template< template<typename...> class Container, template<typename...> class List, typename...elems>\\\n    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\\\n    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\\\n    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\\\n    \\\n    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\\\n    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\\\n    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\\\n    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };\n\n#define INTERNAL_CATCH_NTTP_1(signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \\\n    \\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\\\n    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\\\n    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\\\n    template<typename TestType> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\\\n    template<typename TestType> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_NTTP_0\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)\n#else\n#define INTERNAL_CATCH_NTTP_0(signature)\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))\n#endif\n\n// end catch_preprocessor.hpp\n// start catch_meta.hpp\n\n\n#include <type_traits>\n\nnamespace Catch {\n    template<typename T>\n    struct always_false : std::false_type {};\n\n    template <typename> struct true_given : std::true_type {};\n    struct is_callable_tester {\n        template <typename Fun, typename... Args>\n        true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);\n        template <typename...>\n        std::false_type static test(...);\n    };\n\n    template <typename T>\n    struct is_callable;\n\n    template <typename Fun, typename... Args>\n    struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};\n\n#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703\n    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is\n    // replaced with std::invoke_result here.\n    template <typename Func, typename... U>\n    using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;\n#else\n    // Keep ::type here because we still support C++11\n    template <typename Func, typename... U>\n    using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;\n#endif\n\n} // namespace Catch\n\nnamespace mpl_{\n    struct na;\n}\n\n// end catch_meta.hpp\nnamespace Catch {\n\ntemplate<typename C>\nclass TestInvokerAsMethod : public ITestInvoker {\n    void (C::*m_testAsMethod)();\npublic:\n    TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}\n\n    void invoke() const override {\n        C obj;\n        (obj.*m_testAsMethod)();\n    }\n};\n\nauto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;\n\ntemplate<typename C>\nauto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {\n    return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );\n}\n\nstruct NameAndTags {\n    NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;\n    StringRef name;\n    StringRef tags;\n};\n\nstruct AutoReg : NonCopyable {\n    AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;\n    ~AutoReg();\n};\n\n} // end namespace Catch\n\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \\\n        namespace{                        \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test();              \\\n            };                            \\\n        }                                 \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \\\n        namespace{                                                                                  \\\n            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        }                                                                                           \\\n        }                                                                                           \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \\\n        static void TestName(); \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( ... ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, \"&\" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        } \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestName{\\\n                TestName(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n            return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \\\n        template<typename TestType> static void TestFuncName();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \\\n            INTERNAL_CATCH_TYPE_GEN                                                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \\\n            template<typename... Types>                               \\\n            struct TestName {                                         \\\n                void reg_tests() {                                          \\\n                    int index = 0;                                    \\\n                    using expander = int[];                           \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */\\\n                }                                                     \\\n            };                                                        \\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }                                                             \\\n        }                                                             \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFuncName()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> static void TestFunc();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n        INTERNAL_CATCH_TYPE_GEN\\\n        template<typename... Types>                               \\\n        struct TestName {                                         \\\n            void reg_tests() {                                          \\\n                int index = 0;                                    \\\n                using expander = int[];                           \\\n                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */\\\n            }                                                     \\\n        };\\\n        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename convert<TestName, TmplList>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFunc()\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )\n\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestNameClass{\\\n                TestNameClass(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n                return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n                void test();\\\n            };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\\\n            INTERNAL_CATCH_TYPE_GEN                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n            void test();\\\n        };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename convert<TestNameClass, TmplList>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )\n\n// end catch_test_registry.h\n// start catch_capture.hpp\n\n// start catch_assertionhandler.h\n\n// start catch_assertioninfo.h\n\n// start catch_result_type.h\n\nnamespace Catch {\n\n    // ResultWas::OfType enum\n    struct ResultWas { enum OfType {\n        Unknown = -1,\n        Ok = 0,\n        Info = 1,\n        Warning = 2,\n\n        FailureBit = 0x10,\n\n        ExpressionFailed = FailureBit | 1,\n        ExplicitFailure = FailureBit | 2,\n\n        Exception = 0x100 | FailureBit,\n\n        ThrewException = Exception | 1,\n        DidntThrowException = Exception | 2,\n\n        FatalErrorCondition = 0x200 | FailureBit\n\n    }; };\n\n    bool isOk( ResultWas::OfType resultType );\n    bool isJustInfo( int flags );\n\n    // ResultDisposition::Flags enum\n    struct ResultDisposition { enum Flags {\n        Normal = 0x01,\n\n        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues\n        FalseTest = 0x04,           // Prefix expression with !\n        SuppressFail = 0x08         // Failures are reported but do not fail the test\n    }; };\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );\n\n    bool shouldContinueOnFailure( int flags );\n    inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }\n    bool shouldSuppressFailure( int flags );\n\n} // end namespace Catch\n\n// end catch_result_type.h\nnamespace Catch {\n\n    struct AssertionInfo\n    {\n        StringRef macroName;\n        SourceLineInfo lineInfo;\n        StringRef capturedExpression;\n        ResultDisposition::Flags resultDisposition;\n\n        // We want to delete this constructor but a compiler bug in 4.8 means\n        // the struct is then treated as non-aggregate\n        //AssertionInfo() = delete;\n    };\n\n} // end namespace Catch\n\n// end catch_assertioninfo.h\n// start catch_decomposer.h\n\n// start catch_tostring.h\n\n#include <vector>\n#include <cstddef>\n#include <type_traits>\n#include <string>\n// start catch_stream.h\n\n#include <iosfwd>\n#include <cstddef>\n#include <ostream>\n\nnamespace Catch {\n\n    std::ostream& cout();\n    std::ostream& cerr();\n    std::ostream& clog();\n\n    class StringRef;\n\n    struct IStream {\n        virtual ~IStream();\n        virtual std::ostream& stream() const = 0;\n    };\n\n    auto makeStream( StringRef const &filename ) -> IStream const*;\n\n    class ReusableStringStream : NonCopyable {\n        std::size_t m_index;\n        std::ostream* m_oss;\n    public:\n        ReusableStringStream();\n        ~ReusableStringStream();\n\n        auto str() const -> std::string;\n\n        template<typename T>\n        auto operator << ( T const& value ) -> ReusableStringStream& {\n            *m_oss << value;\n            return *this;\n        }\n        auto get() -> std::ostream& { return *m_oss; }\n    };\n}\n\n// end catch_stream.h\n// start catch_interfaces_enum_values_registry.h\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace Detail {\n        struct EnumInfo {\n            StringRef m_name;\n            std::vector<std::pair<int, StringRef>> m_values;\n\n            ~EnumInfo();\n\n            StringRef lookup( int value ) const;\n        };\n    } // namespace Detail\n\n    struct IMutableEnumValuesRegistry {\n        virtual ~IMutableEnumValuesRegistry();\n\n        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;\n\n        template<typename E>\n        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {\n            static_assert(sizeof(int) >= sizeof(E), \"Cannot serialize enum to int\");\n            std::vector<int> intValues;\n            intValues.reserve( values.size() );\n            for( auto enumValue : values )\n                intValues.push_back( static_cast<int>( enumValue ) );\n            return registerEnum( enumName, allEnums, intValues );\n        }\n    };\n\n} // Catch\n\n// end catch_interfaces_enum_values_registry.h\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n#include <string_view>\n#endif\n\n#ifdef __OBJC__\n// start catch_objc_arc.hpp\n\n#import <Foundation/Foundation.h>\n\n#ifdef __has_feature\n#define CATCH_ARC_ENABLED __has_feature(objc_arc)\n#else\n#define CATCH_ARC_ENABLED 0\n#endif\n\nvoid arcSafeRelease( NSObject* obj );\nid performOptionalSelector( id obj, SEL sel );\n\n#if !CATCH_ARC_ENABLED\ninline void arcSafeRelease( NSObject* obj ) {\n    [obj release];\n}\ninline id performOptionalSelector( id obj, SEL sel ) {\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED\n#define CATCH_ARC_STRONG\n#else\ninline void arcSafeRelease( NSObject* ){}\ninline id performOptionalSelector( id obj, SEL sel ) {\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#endif\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained\n#define CATCH_ARC_STRONG __strong\n#endif\n\n// end catch_objc_arc.hpp\n#endif\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless\n#endif\n\nnamespace Catch {\n    namespace Detail {\n\n        extern const std::string unprintableString;\n\n        std::string rawMemoryToString( const void *object, std::size_t size );\n\n        template<typename T>\n        std::string rawMemoryToString( const T& object ) {\n          return rawMemoryToString( &object, sizeof(object) );\n        }\n\n        template<typename T>\n        class IsStreamInsertable {\n            template<typename Stream, typename U>\n            static auto test(int)\n                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());\n\n            template<typename, typename>\n            static auto test(...)->std::false_type;\n\n        public:\n            static const bool value = decltype(test<std::ostream, const T&>(0))::value;\n        };\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e );\n\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,\n        std::string>::type convertUnstreamable( T const& ) {\n            return Detail::unprintableString;\n        }\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,\n         std::string>::type convertUnstreamable(T const& ex) {\n            return ex.what();\n        }\n\n        template<typename T>\n        typename std::enable_if<\n            std::is_enum<T>::value\n        , std::string>::type convertUnstreamable( T const& value ) {\n            return convertUnknownEnumToString( value );\n        }\n\n#if defined(_MANAGED)\n        //! Convert a CLR string to a utf8 std::string\n        template<typename T>\n        std::string clrReferenceToString( T^ ref ) {\n            if (ref == nullptr)\n                return std::string(\"null\");\n            auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());\n            cli::pin_ptr<System::Byte> p = &bytes[0];\n            return std::string(reinterpret_cast<char const *>(p), bytes->Length);\n        }\n#endif\n\n    } // namespace Detail\n\n    // If we decide for C++14, change these to enable_if_ts\n    template <typename T, typename = void>\n    struct StringMaker {\n        template <typename Fake = T>\n        static\n        typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert(const Fake& value) {\n                ReusableStringStream rss;\n                // NB: call using the function-like syntax to avoid ambiguity with\n                // user-defined templated operator<< under clang.\n                rss.operator<<(value);\n                return rss.str();\n        }\n\n        template <typename Fake = T>\n        static\n        typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert( const Fake& value ) {\n#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)\n            return Detail::convertUnstreamable(value);\n#else\n            return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);\n#endif\n        }\n    };\n\n    namespace Detail {\n\n        // This function dispatches all stringification requests inside of Catch.\n        // Should be preferably called fully qualified, like ::Catch::Detail::stringify\n        template <typename T>\n        std::string stringify(const T& e) {\n            return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);\n        }\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e ) {\n            return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));\n        }\n\n#if defined(_MANAGED)\n        template <typename T>\n        std::string stringify( T^ e ) {\n            return ::Catch::StringMaker<T^>::convert(e);\n        }\n#endif\n\n    } // namespace Detail\n\n    // Some predefined specializations\n\n    template<>\n    struct StringMaker<std::string> {\n        static std::string convert(const std::string& str);\n    };\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::string_view> {\n        static std::string convert(std::string_view str);\n    };\n#endif\n\n    template<>\n    struct StringMaker<char const *> {\n        static std::string convert(char const * str);\n    };\n    template<>\n    struct StringMaker<char *> {\n        static std::string convert(char * str);\n    };\n\n#ifdef CATCH_CONFIG_WCHAR\n    template<>\n    struct StringMaker<std::wstring> {\n        static std::string convert(const std::wstring& wstr);\n    };\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::wstring_view> {\n        static std::string convert(std::wstring_view str);\n    };\n# endif\n\n    template<>\n    struct StringMaker<wchar_t const *> {\n        static std::string convert(wchar_t const * str);\n    };\n    template<>\n    struct StringMaker<wchar_t *> {\n        static std::string convert(wchar_t * str);\n    };\n#endif\n\n    // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,\n    //      while keeping string semantics?\n    template<int SZ>\n    struct StringMaker<char[SZ]> {\n        static std::string convert(char const* str) {\n            return ::Catch::Detail::stringify(std::string{ str });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<signed char[SZ]> {\n        static std::string convert(signed char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<unsigned char[SZ]> {\n        static std::string convert(unsigned char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<std::byte> {\n        static std::string convert(std::byte value);\n    };\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<int> {\n        static std::string convert(int value);\n    };\n    template<>\n    struct StringMaker<long> {\n        static std::string convert(long value);\n    };\n    template<>\n    struct StringMaker<long long> {\n        static std::string convert(long long value);\n    };\n    template<>\n    struct StringMaker<unsigned int> {\n        static std::string convert(unsigned int value);\n    };\n    template<>\n    struct StringMaker<unsigned long> {\n        static std::string convert(unsigned long value);\n    };\n    template<>\n    struct StringMaker<unsigned long long> {\n        static std::string convert(unsigned long long value);\n    };\n\n    template<>\n    struct StringMaker<bool> {\n        static std::string convert(bool b);\n    };\n\n    template<>\n    struct StringMaker<char> {\n        static std::string convert(char c);\n    };\n    template<>\n    struct StringMaker<signed char> {\n        static std::string convert(signed char c);\n    };\n    template<>\n    struct StringMaker<unsigned char> {\n        static std::string convert(unsigned char c);\n    };\n\n    template<>\n    struct StringMaker<std::nullptr_t> {\n        static std::string convert(std::nullptr_t);\n    };\n\n    template<>\n    struct StringMaker<float> {\n        static std::string convert(float value);\n        static int precision;\n    };\n\n    template<>\n    struct StringMaker<double> {\n        static std::string convert(double value);\n        static int precision;\n    };\n\n    template <typename T>\n    struct StringMaker<T*> {\n        template <typename U>\n        static std::string convert(U* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n    template <typename R, typename C>\n    struct StringMaker<R C::*> {\n        static std::string convert(R C::* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n#if defined(_MANAGED)\n    template <typename T>\n    struct StringMaker<T^> {\n        static std::string convert( T^ ref ) {\n            return ::Catch::Detail::clrReferenceToString(ref);\n        }\n    };\n#endif\n\n    namespace Detail {\n        template<typename InputIterator, typename Sentinel = InputIterator>\n        std::string rangeToString(InputIterator first, Sentinel last) {\n            ReusableStringStream rss;\n            rss << \"{ \";\n            if (first != last) {\n                rss << ::Catch::Detail::stringify(*first);\n                for (++first; first != last; ++first)\n                    rss << \", \" << ::Catch::Detail::stringify(*first);\n            }\n            rss << \" }\";\n            return rss.str();\n        }\n    }\n\n#ifdef __OBJC__\n    template<>\n    struct StringMaker<NSString*> {\n        static std::string convert(NSString * nsstring) {\n            if (!nsstring)\n                return \"nil\";\n            return std::string(\"@\") + [nsstring UTF8String];\n        }\n    };\n    template<>\n    struct StringMaker<NSObject*> {\n        static std::string convert(NSObject* nsObject) {\n            return ::Catch::Detail::stringify([nsObject description]);\n        }\n\n    };\n    namespace Detail {\n        inline std::string stringify( NSString* nsstring ) {\n            return StringMaker<NSString*>::convert( nsstring );\n        }\n\n    } // namespace Detail\n#endif // __OBJC__\n\n} // namespace Catch\n\n//////////////////////////////////////////////////////\n// Separate std-lib types stringification, so it can be selectively enabled\n// This means that we do not bring in\n\n#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)\n#  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n#endif\n\n// Separate std::pair specialization\n#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)\n#include <utility>\nnamespace Catch {\n    template<typename T1, typename T2>\n    struct StringMaker<std::pair<T1, T2> > {\n        static std::string convert(const std::pair<T1, T2>& pair) {\n            ReusableStringStream rss;\n            rss << \"{ \"\n                << ::Catch::Detail::stringify(pair.first)\n                << \", \"\n                << ::Catch::Detail::stringify(pair.second)\n                << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#include <optional>\nnamespace Catch {\n    template<typename T>\n    struct StringMaker<std::optional<T> > {\n        static std::string convert(const std::optional<T>& optional) {\n            ReusableStringStream rss;\n            if (optional.has_value()) {\n                rss << ::Catch::Detail::stringify(*optional);\n            } else {\n                rss << \"{ }\";\n            }\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n\n// Separate std::tuple specialization\n#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)\n#include <tuple>\nnamespace Catch {\n    namespace Detail {\n        template<\n            typename Tuple,\n            std::size_t N = 0,\n            bool = (N < std::tuple_size<Tuple>::value)\n            >\n            struct TupleElementPrinter {\n            static void print(const Tuple& tuple, std::ostream& os) {\n                os << (N ? \", \" : \" \")\n                    << ::Catch::Detail::stringify(std::get<N>(tuple));\n                TupleElementPrinter<Tuple, N + 1>::print(tuple, os);\n            }\n        };\n\n        template<\n            typename Tuple,\n            std::size_t N\n        >\n            struct TupleElementPrinter<Tuple, N, false> {\n            static void print(const Tuple&, std::ostream&) {}\n        };\n\n    }\n\n    template<typename ...Types>\n    struct StringMaker<std::tuple<Types...>> {\n        static std::string convert(const std::tuple<Types...>& tuple) {\n            ReusableStringStream rss;\n            rss << '{';\n            Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());\n            rss << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)\n#include <variant>\nnamespace Catch {\n    template<>\n    struct StringMaker<std::monostate> {\n        static std::string convert(const std::monostate&) {\n            return \"{ }\";\n        }\n    };\n\n    template<typename... Elements>\n    struct StringMaker<std::variant<Elements...>> {\n        static std::string convert(const std::variant<Elements...>& variant) {\n            if (variant.valueless_by_exception()) {\n                return \"{valueless variant}\";\n            } else {\n                return std::visit(\n                    [](const auto& value) {\n                        return ::Catch::Detail::stringify(value);\n                    },\n                    variant\n                );\n            }\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n\nnamespace Catch {\n    // Import begin/ end from std here\n    using std::begin;\n    using std::end;\n\n    namespace detail {\n        template <typename...>\n        struct void_type {\n            using type = void;\n        };\n\n        template <typename T, typename = void>\n        struct is_range_impl : std::false_type {\n        };\n\n        template <typename T>\n        struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {\n        };\n    } // namespace detail\n\n    template <typename T>\n    struct is_range : detail::is_range_impl<T> {\n    };\n\n#if defined(_MANAGED) // Managed types are never ranges\n    template <typename T>\n    struct is_range<T^> {\n        static const bool value = false;\n    };\n#endif\n\n    template<typename Range>\n    std::string rangeToString( Range const& range ) {\n        return ::Catch::Detail::rangeToString( begin( range ), end( range ) );\n    }\n\n    // Handle vector<bool> specially\n    template<typename Allocator>\n    std::string rangeToString( std::vector<bool, Allocator> const& v ) {\n        ReusableStringStream rss;\n        rss << \"{ \";\n        bool first = true;\n        for( bool b : v ) {\n            if( first )\n                first = false;\n            else\n                rss << \", \";\n            rss << ::Catch::Detail::stringify( b );\n        }\n        rss << \" }\";\n        return rss.str();\n    }\n\n    template<typename R>\n    struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {\n        static std::string convert( R const& range ) {\n            return rangeToString( range );\n        }\n    };\n\n    template <typename T, int SZ>\n    struct StringMaker<T[SZ]> {\n        static std::string convert(T const(&arr)[SZ]) {\n            return rangeToString(arr);\n        }\n    };\n\n} // namespace Catch\n\n// Separate std::chrono::duration specialization\n#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#include <ctime>\n#include <ratio>\n#include <chrono>\n\nnamespace Catch {\n\ntemplate <class Ratio>\nstruct ratio_string {\n    static std::string symbol();\n};\n\ntemplate <class Ratio>\nstd::string ratio_string<Ratio>::symbol() {\n    Catch::ReusableStringStream rss;\n    rss << '[' << Ratio::num << '/'\n        << Ratio::den << ']';\n    return rss.str();\n}\ntemplate <>\nstruct ratio_string<std::atto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::femto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::pico> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::nano> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::micro> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::milli> {\n    static std::string symbol();\n};\n\n    ////////////\n    // std::chrono::duration specializations\n    template<typename Value, typename Ratio>\n    struct StringMaker<std::chrono::duration<Value, Ratio>> {\n        static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" s\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" m\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" h\";\n            return rss.str();\n        }\n    };\n\n    ////////////\n    // std::chrono::time_point specialization\n    // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>\n    template<typename Clock, typename Duration>\n    struct StringMaker<std::chrono::time_point<Clock, Duration>> {\n        static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {\n            return ::Catch::Detail::stringify(time_point.time_since_epoch()) + \" since epoch\";\n        }\n    };\n    // std::chrono::time_point<system_clock> specialization\n    template<typename Duration>\n    struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {\n        static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {\n            auto converted = std::chrono::system_clock::to_time_t(time_point);\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &converted);\n#else\n            std::tm* timeInfo = std::gmtime(&converted);\n#endif\n\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp);\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n\n#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \\\nnamespace Catch { \\\n    template<> struct StringMaker<enumName> { \\\n        static std::string convert( enumName value ) { \\\n            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \\\n            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \\\n        } \\\n    }; \\\n}\n\n#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_tostring.h\n#include <iosfwd>\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4389) // '==' : signed/unsigned mismatch\n#pragma warning(disable:4018) // more \"signed/unsigned mismatch\"\n#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)\n#pragma warning(disable:4180) // qualifier applied to function type has no meaning\n#pragma warning(disable:4800) // Forcing result to true or false\n#endif\n\nnamespace Catch {\n\n    struct ITransientExpression {\n        auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }\n        auto getResult() const -> bool { return m_result; }\n        virtual void streamReconstructedExpression( std::ostream &os ) const = 0;\n\n        ITransientExpression( bool isBinaryExpression, bool result )\n        :   m_isBinaryExpression( isBinaryExpression ),\n            m_result( result )\n        {}\n\n        // We don't actually need a virtual destructor, but many static analysers\n        // complain if it's not here :-(\n        virtual ~ITransientExpression();\n\n        bool m_isBinaryExpression;\n        bool m_result;\n\n    };\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );\n\n    template<typename LhsT, typename RhsT>\n    class BinaryExpr  : public ITransientExpression {\n        LhsT m_lhs;\n        StringRef m_op;\n        RhsT m_rhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            formatReconstructedExpression\n                    ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );\n        }\n\n    public:\n        BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )\n        :   ITransientExpression{ true, comparisonResult },\n            m_lhs( lhs ),\n            m_op( op ),\n            m_rhs( rhs )\n        {}\n\n        template<typename T>\n        auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n    };\n\n    template<typename LhsT>\n    class UnaryExpr : public ITransientExpression {\n        LhsT m_lhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            os << Catch::Detail::stringify( m_lhs );\n        }\n\n    public:\n        explicit UnaryExpr( LhsT lhs )\n        :   ITransientExpression{ false, static_cast<bool>(lhs) },\n            m_lhs( lhs )\n        {}\n    };\n\n    // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)\n    template<typename LhsT, typename RhsT>\n    auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n    template<typename T>\n    auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n\n    template<typename LhsT, typename RhsT>\n    auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n    template<typename T>\n    auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n\n    template<typename LhsT>\n    class ExprLhs {\n        LhsT m_lhs;\n    public:\n        explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}\n\n        template<typename RhsT>\n        auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareEqual( m_lhs, rhs ), m_lhs, \"==\", rhs };\n        }\n        auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs == rhs, m_lhs, \"==\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareNotEqual( m_lhs, rhs ), m_lhs, \"!=\", rhs };\n        }\n        auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs != rhs, m_lhs, \"!=\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs > rhs), m_lhs, \">\", rhs };\n        }\n        template<typename RhsT>\n        auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs < rhs), m_lhs, \"<\", rhs };\n        }\n        template<typename RhsT>\n        auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs >= rhs), m_lhs, \">=\", rhs };\n        }\n        template<typename RhsT>\n        auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs <= rhs), m_lhs, \"<=\", rhs };\n        }\n        template <typename RhsT>\n        auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs | rhs), m_lhs, \"|\", rhs };\n        }\n        template <typename RhsT>\n        auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs & rhs), m_lhs, \"&\", rhs };\n        }\n        template <typename RhsT>\n        auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs ^ rhs), m_lhs, \"^\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator&& is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename RhsT>\n        auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator|| is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        auto makeUnaryExpr() const -> UnaryExpr<LhsT> {\n            return UnaryExpr<LhsT>{ m_lhs };\n        }\n    };\n\n    void handleExpression( ITransientExpression const& expr );\n\n    template<typename T>\n    void handleExpression( ExprLhs<T> const& expr ) {\n        handleExpression( expr.makeUnaryExpr() );\n    }\n\n    struct Decomposer {\n        template<typename T>\n        auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {\n            return ExprLhs<T const&>{ lhs };\n        }\n\n        auto operator <=( bool value ) -> ExprLhs<bool> {\n            return ExprLhs<bool>{ value };\n        }\n    };\n\n} // end namespace Catch\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_decomposer.h\n// start catch_interfaces_capture.h\n\n#include <string>\n#include <chrono>\n\nnamespace Catch {\n\n    class AssertionResult;\n    struct AssertionInfo;\n    struct SectionInfo;\n    struct SectionEndInfo;\n    struct MessageInfo;\n    struct MessageBuilder;\n    struct Counts;\n    struct AssertionReaction;\n    struct SourceLineInfo;\n\n    struct ITransientExpression;\n    struct IGeneratorTracker;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo;\n    template <typename Duration = std::chrono::duration<double, std::nano>>\n    struct BenchmarkStats;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IResultCapture {\n\n        virtual ~IResultCapture();\n\n        virtual bool sectionStarted(    SectionInfo const& sectionInfo,\n                                        Counts& assertions ) = 0;\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;\n\n        virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& name ) = 0;\n        virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;\n        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;\n        virtual void benchmarkFailed( std::string const& error ) = 0;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void pushScopedMessage( MessageInfo const& message ) = 0;\n        virtual void popScopedMessage( MessageInfo const& message ) = 0;\n\n        virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;\n\n        virtual void handleFatalErrorCondition( StringRef message ) = 0;\n\n        virtual void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleIncomplete\n                (   AssertionInfo const& info ) = 0;\n        virtual void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) = 0;\n\n        virtual bool lastAssertionPassed() = 0;\n        virtual void assertionPassed() = 0;\n\n        // Deprecated, do not use:\n        virtual std::string getCurrentTestName() const = 0;\n        virtual const AssertionResult* getLastResult() const = 0;\n        virtual void exceptionEarlyReported() = 0;\n    };\n\n    IResultCapture& getResultCapture();\n}\n\n// end catch_interfaces_capture.h\nnamespace Catch {\n\n    struct TestFailureException{};\n    struct AssertionResultData;\n    struct IResultCapture;\n    class RunContext;\n\n    class LazyExpression {\n        friend class AssertionHandler;\n        friend struct AssertionStats;\n        friend class RunContext;\n\n        ITransientExpression const* m_transientExpression = nullptr;\n        bool m_isNegated;\n    public:\n        LazyExpression( bool isNegated );\n        LazyExpression( LazyExpression const& other );\n        LazyExpression& operator = ( LazyExpression const& ) = delete;\n\n        explicit operator bool() const;\n\n        friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;\n    };\n\n    struct AssertionReaction {\n        bool shouldDebugBreak = false;\n        bool shouldThrow = false;\n    };\n\n    class AssertionHandler {\n        AssertionInfo m_assertionInfo;\n        AssertionReaction m_reaction;\n        bool m_completed = false;\n        IResultCapture& m_resultCapture;\n\n    public:\n        AssertionHandler\n            (   StringRef const& macroName,\n                SourceLineInfo const& lineInfo,\n                StringRef capturedExpression,\n                ResultDisposition::Flags resultDisposition );\n        ~AssertionHandler() {\n            if ( !m_completed ) {\n                m_resultCapture.handleIncomplete( m_assertionInfo );\n            }\n        }\n\n        template<typename T>\n        void handleExpr( ExprLhs<T> const& expr ) {\n            handleExpr( expr.makeUnaryExpr() );\n        }\n        void handleExpr( ITransientExpression const& expr );\n\n        void handleMessage(ResultWas::OfType resultType, StringRef const& message);\n\n        void handleExceptionThrownAsExpected();\n        void handleUnexpectedExceptionNotThrown();\n        void handleExceptionNotThrownAsExpected();\n        void handleThrowingCallSkipped();\n        void handleUnexpectedInflightException();\n\n        void complete();\n        void setCompleted();\n\n        // query\n        auto allowThrows() const -> bool;\n    };\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );\n\n} // namespace Catch\n\n// end catch_assertionhandler.h\n// start catch_message.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    struct MessageInfo {\n        MessageInfo(    StringRef const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        ResultWas::OfType _type );\n\n        StringRef macroName;\n        std::string message;\n        SourceLineInfo lineInfo;\n        ResultWas::OfType type;\n        unsigned int sequence;\n\n        bool operator == ( MessageInfo const& other ) const;\n        bool operator < ( MessageInfo const& other ) const;\n    private:\n        static unsigned int globalCount;\n    };\n\n    struct MessageStream {\n\n        template<typename T>\n        MessageStream& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        ReusableStringStream m_stream;\n    };\n\n    struct MessageBuilder : MessageStream {\n        MessageBuilder( StringRef const& macroName,\n                        SourceLineInfo const& lineInfo,\n                        ResultWas::OfType type );\n\n        template<typename T>\n        MessageBuilder& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        MessageInfo m_info;\n    };\n\n    class ScopedMessage {\n    public:\n        explicit ScopedMessage( MessageBuilder const& builder );\n        ScopedMessage( ScopedMessage& duplicate ) = delete;\n        ScopedMessage( ScopedMessage&& old );\n        ~ScopedMessage();\n\n        MessageInfo m_info;\n        bool m_moved;\n    };\n\n    class Capturer {\n        std::vector<MessageInfo> m_messages;\n        IResultCapture& m_resultCapture = getResultCapture();\n        size_t m_captured = 0;\n    public:\n        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );\n        ~Capturer();\n\n        void captureValue( size_t index, std::string const& value );\n\n        template<typename T>\n        void captureValues( size_t index, T const& value ) {\n            captureValue( index, Catch::Detail::stringify( value ) );\n        }\n\n        template<typename T, typename... Ts>\n        void captureValues( size_t index, T const& value, Ts const&... values ) {\n            captureValue( index, Catch::Detail::stringify(value) );\n            captureValues( index+1, values... );\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_message.h\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)\n  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__\n#else\n  #define CATCH_INTERNAL_STRINGIFY(...) \"Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION\"\n#endif\n\n#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n\n///////////////////////////////////////////////////////////////////////////////\n// Another way to speed-up compilation is to omit local try-catch for REQUIRE*\n// macros.\n#define INTERNAL_CATCH_TRY\n#define INTERNAL_CATCH_CATCH( capturer )\n\n#else // CATCH_CONFIG_FAST_COMPILE\n\n#define INTERNAL_CATCH_TRY try\n#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }\n\n#endif\n\n#define INTERNAL_CATCH_REACT( handler ) handler.complete();\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \\\n    do { \\\n        CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n            catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \\\n            CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( !Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        try { \\\n            static_cast<void>(__VA_ARGS__); \\\n            catchAssertionHandler.handleExceptionNotThrownAsExpected(); \\\n        } \\\n        catch( ... ) { \\\n            catchAssertionHandler.handleUnexpectedInflightException(); \\\n        } \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(expr); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \\\n        catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \\\n    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \\\n    varName.captureValues( 0, __VA_ARGS__ )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_INFO( macroName, log ) \\\n    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \\\n    Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )\n\n///////////////////////////////////////////////////////////////////////////////\n// Although this is matcher-based, it can be used with just a string\n#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_capture.hpp\n// start catch_section.h\n\n// start catch_section_info.h\n\n// start catch_totals.h\n\n#include <cstddef>\n\nnamespace Catch {\n\n    struct Counts {\n        Counts operator - ( Counts const& other ) const;\n        Counts& operator += ( Counts const& other );\n\n        std::size_t total() const;\n        bool allPassed() const;\n        bool allOk() const;\n\n        std::size_t passed = 0;\n        std::size_t failed = 0;\n        std::size_t failedButOk = 0;\n    };\n\n    struct Totals {\n\n        Totals operator - ( Totals const& other ) const;\n        Totals& operator += ( Totals const& other );\n\n        Totals delta( Totals const& prevTotals ) const;\n\n        int error = 0;\n        Counts assertions;\n        Counts testCases;\n    };\n}\n\n// end catch_totals.h\n#include <string>\n\nnamespace Catch {\n\n    struct SectionInfo {\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name );\n\n        // Deprecated\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name,\n                std::string const& ) : SectionInfo( _lineInfo, _name ) {}\n\n        std::string name;\n        std::string description; // !Deprecated: this will always be empty\n        SourceLineInfo lineInfo;\n    };\n\n    struct SectionEndInfo {\n        SectionInfo sectionInfo;\n        Counts prevAssertions;\n        double durationInSeconds;\n    };\n\n} // end namespace Catch\n\n// end catch_section_info.h\n// start catch_timer.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t;\n    auto getEstimatedClockResolution() -> uint64_t;\n\n    class Timer {\n        uint64_t m_nanoseconds = 0;\n    public:\n        void start();\n        auto getElapsedNanoseconds() const -> uint64_t;\n        auto getElapsedMicroseconds() const -> uint64_t;\n        auto getElapsedMilliseconds() const -> unsigned int;\n        auto getElapsedSeconds() const -> double;\n    };\n\n} // namespace Catch\n\n// end catch_timer.h\n#include <string>\n\nnamespace Catch {\n\n    class Section : NonCopyable {\n    public:\n        Section( SectionInfo const& info );\n        ~Section();\n\n        // This indicates whether the section should be executed or not\n        explicit operator bool() const;\n\n    private:\n        SectionInfo m_info;\n\n        std::string m_name;\n        Counts m_assertions;\n        bool m_sectionIncluded;\n        Timer m_timer;\n    };\n\n} // end namespace Catch\n\n#define INTERNAL_CATCH_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_section.h\n// start catch_interfaces_exception.h\n\n// start catch_interfaces_registry_hub.h\n\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class TestCase;\n    struct ITestCaseRegistry;\n    struct IExceptionTranslatorRegistry;\n    struct IExceptionTranslator;\n    struct IReporterRegistry;\n    struct IReporterFactory;\n    struct ITagAliasRegistry;\n    struct IMutableEnumValuesRegistry;\n\n    class StartupExceptionRegistry;\n\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IRegistryHub {\n        virtual ~IRegistryHub();\n\n        virtual IReporterRegistry const& getReporterRegistry() const = 0;\n        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;\n        virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;\n        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;\n\n        virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;\n    };\n\n    struct IMutableRegistryHub {\n        virtual ~IMutableRegistryHub();\n        virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerTest( TestCase const& testInfo ) = 0;\n        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;\n        virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;\n        virtual void registerStartupException() noexcept = 0;\n        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;\n    };\n\n    IRegistryHub const& getRegistryHub();\n    IMutableRegistryHub& getMutableRegistryHub();\n    void cleanUp();\n    std::string translateActiveException();\n\n}\n\n// end catch_interfaces_registry_hub.h\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \\\n        static std::string translatorName( signature )\n#endif\n\n#include <exception>\n#include <string>\n#include <vector>\n\nnamespace Catch {\n    using exceptionTranslateFunction = std::string(*)();\n\n    struct IExceptionTranslator;\n    using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;\n\n    struct IExceptionTranslator {\n        virtual ~IExceptionTranslator();\n        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;\n    };\n\n    struct IExceptionTranslatorRegistry {\n        virtual ~IExceptionTranslatorRegistry();\n\n        virtual std::string translateActiveException() const = 0;\n    };\n\n    class ExceptionTranslatorRegistrar {\n        template<typename T>\n        class ExceptionTranslator : public IExceptionTranslator {\n        public:\n\n            ExceptionTranslator( std::string(*translateFunction)( T& ) )\n            : m_translateFunction( translateFunction )\n            {}\n\n            std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                return \"\";\n#else\n                try {\n                    if( it == itEnd )\n                        std::rethrow_exception(std::current_exception());\n                    else\n                        return (*it)->translate( it+1, itEnd );\n                }\n                catch( T& ex ) {\n                    return m_translateFunction( ex );\n                }\n#endif\n            }\n\n        protected:\n            std::string(*m_translateFunction)( T& );\n        };\n\n    public:\n        template<typename T>\n        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {\n            getMutableRegistryHub().registerTranslator\n                ( new ExceptionTranslator<T>( translateFunction ) );\n        }\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \\\n    static std::string translatorName( signature ); \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n    static std::string translatorName( signature )\n\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// end catch_interfaces_exception.h\n// start catch_approx.h\n\n#include <type_traits>\n\nnamespace Catch {\nnamespace Detail {\n\n    class Approx {\n    private:\n        bool equalityComparisonImpl(double other) const;\n        // Validates the new margin (margin >= 0)\n        // out-of-line to avoid including stdexcept in the header\n        void setMargin(double margin);\n        // Validates the new epsilon (0 < epsilon < 1)\n        // out-of-line to avoid including stdexcept in the header\n        void setEpsilon(double epsilon);\n\n    public:\n        explicit Approx ( double value );\n\n        static Approx custom();\n\n        Approx operator-() const;\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx operator()( T const& value ) const {\n            Approx approx( static_cast<double>(value) );\n            approx.m_epsilon = m_epsilon;\n            approx.m_margin = m_margin;\n            approx.m_scale = m_scale;\n            return approx;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        explicit Approx( T const& value ): Approx(static_cast<double>(value))\n        {}\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( const T& lhs, Approx const& rhs ) {\n            auto lhs_v = static_cast<double>(lhs);\n            return rhs.equalityComparisonImpl(lhs_v);\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( Approx const& lhs, const T& rhs ) {\n            return operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( T const& lhs, Approx const& rhs ) {\n            return !operator==( lhs, rhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( Approx const& lhs, T const& rhs ) {\n            return !operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& epsilon( T const& newEpsilon ) {\n            double epsilonAsDouble = static_cast<double>(newEpsilon);\n            setEpsilon(epsilonAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& margin( T const& newMargin ) {\n            double marginAsDouble = static_cast<double>(newMargin);\n            setMargin(marginAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& scale( T const& newScale ) {\n            m_scale = static_cast<double>(newScale);\n            return *this;\n        }\n\n        std::string toString() const;\n\n    private:\n        double m_epsilon;\n        double m_margin;\n        double m_scale;\n        double m_value;\n    };\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val);\n    Detail::Approx operator \"\" _a(unsigned long long val);\n} // end namespace literals\n\ntemplate<>\nstruct StringMaker<Catch::Detail::Approx> {\n    static std::string convert(Catch::Detail::Approx const& value);\n};\n\n} // end namespace Catch\n\n// end catch_approx.h\n// start catch_string_manip.h\n\n#include <string>\n#include <iosfwd>\n#include <vector>\n\nnamespace Catch {\n\n    bool startsWith( std::string const& s, std::string const& prefix );\n    bool startsWith( std::string const& s, char prefix );\n    bool endsWith( std::string const& s, std::string const& suffix );\n    bool endsWith( std::string const& s, char suffix );\n    bool contains( std::string const& s, std::string const& infix );\n    void toLowerInPlace( std::string& s );\n    std::string toLower( std::string const& s );\n    //! Returns a new string without whitespace at the start/end\n    std::string trim( std::string const& str );\n    //! Returns a substring of the original ref without whitespace. Beware lifetimes!\n    StringRef trim(StringRef ref);\n\n    // !!! Be aware, returns refs into original string - make sure original string outlives them\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );\n\n    struct pluralise {\n        pluralise( std::size_t count, std::string const& label );\n\n        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );\n\n        std::size_t m_count;\n        std::string m_label;\n    };\n}\n\n// end catch_string_manip.h\n#ifndef CATCH_CONFIG_DISABLE_MATCHERS\n// start catch_capture_matchers.h\n\n// start catch_matchers.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        template<typename ArgT> struct MatchAllOf;\n        template<typename ArgT> struct MatchAnyOf;\n        template<typename ArgT> struct MatchNotOf;\n\n        class MatcherUntypedBase {\n        public:\n            MatcherUntypedBase() = default;\n            MatcherUntypedBase ( MatcherUntypedBase const& ) = default;\n            MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;\n            std::string toString() const;\n\n        protected:\n            virtual ~MatcherUntypedBase();\n            virtual std::string describe() const = 0;\n            mutable std::string m_cachedToString;\n        };\n\n#ifdef __clang__\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wnon-virtual-dtor\"\n#endif\n\n        template<typename ObjectT>\n        struct MatcherMethod {\n            virtual bool match( ObjectT const& arg ) const = 0;\n        };\n\n#if defined(__OBJC__)\n        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.\n        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation\n        template<>\n        struct MatcherMethod<NSString*> {\n            virtual bool match( NSString* arg ) const = 0;\n        };\n#endif\n\n#ifdef __clang__\n#    pragma clang diagnostic pop\n#endif\n\n        template<typename T>\n        struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {\n\n            MatchAllOf<T> operator && ( MatcherBase const& other ) const;\n            MatchAnyOf<T> operator || ( MatcherBase const& other ) const;\n            MatchNotOf<T> operator ! () const;\n        };\n\n        template<typename ArgT>\n        struct MatchAllOf : MatcherBase<ArgT> {\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (!matcher->match(arg))\n                        return false;\n                }\n                return true;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" and \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n        template<typename ArgT>\n        struct MatchAnyOf : MatcherBase<ArgT> {\n\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (matcher->match(arg))\n                        return true;\n                }\n                return false;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" or \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n\n        template<typename ArgT>\n        struct MatchNotOf : MatcherBase<ArgT> {\n\n            MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}\n\n            bool match( ArgT const& arg ) const override {\n                return !m_underlyingMatcher.match( arg );\n            }\n\n            std::string describe() const override {\n                return \"not \" + m_underlyingMatcher.toString();\n            }\n            MatcherBase<ArgT> const& m_underlyingMatcher;\n        };\n\n        template<typename T>\n        MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {\n            return MatchAllOf<T>() && *this && other;\n        }\n        template<typename T>\n        MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {\n            return MatchAnyOf<T>() || *this || other;\n        }\n        template<typename T>\n        MatchNotOf<T> MatcherBase<T>::operator ! () const {\n            return MatchNotOf<T>( *this );\n        }\n\n    } // namespace Impl\n\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n\n// end catch_matchers.h\n// start catch_matchers_exception.hpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nclass ExceptionMessageMatcher : public MatcherBase<std::exception> {\n    std::string m_message;\npublic:\n\n    ExceptionMessageMatcher(std::string const& message):\n        m_message(message)\n    {}\n\n    bool match(std::exception const& ex) const override;\n\n    std::string describe() const override;\n};\n\n} // namespace Exception\n\nException::ExceptionMessageMatcher Message(std::string const& message);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_exception.hpp\n// start catch_matchers_floating.h\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Floating {\n\n        enum class FloatingPointKind : uint8_t;\n\n        struct WithinAbsMatcher : MatcherBase<double> {\n            WithinAbsMatcher(double target, double margin);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_margin;\n        };\n\n        struct WithinUlpsMatcher : MatcherBase<double> {\n            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            uint64_t m_ulps;\n            FloatingPointKind m_type;\n        };\n\n        // Given IEEE-754 format for floats and doubles, we can assume\n        // that float -> double promotion is lossless. Given this, we can\n        // assume that if we do the standard relative comparison of\n        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get\n        // the same result if we do this for floats, as if we do this for\n        // doubles that were promoted from floats.\n        struct WithinRelMatcher : MatcherBase<double> {\n            WithinRelMatcher(double target, double epsilon);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_epsilon;\n        };\n\n    } // namespace Floating\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);\n    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);\n    Floating::WithinAbsMatcher WithinAbs(double target, double margin);\n    Floating::WithinRelMatcher WithinRel(double target, double eps);\n    // defaults epsilon to 100*numeric_limits<double>::epsilon()\n    Floating::WithinRelMatcher WithinRel(double target);\n    Floating::WithinRelMatcher WithinRel(float target, float eps);\n    // defaults epsilon to 100*numeric_limits<float>::epsilon()\n    Floating::WithinRelMatcher WithinRel(float target);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_floating.h\n// start catch_matchers_generic.hpp\n\n#include <functional>\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Generic {\n\nnamespace Detail {\n    std::string finalizeDescription(const std::string& desc);\n}\n\ntemplate <typename T>\nclass PredicateMatcher : public MatcherBase<T> {\n    std::function<bool(T const&)> m_predicate;\n    std::string m_description;\npublic:\n\n    PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)\n        :m_predicate(std::move(elem)),\n        m_description(Detail::finalizeDescription(descr))\n    {}\n\n    bool match( T const& item ) const override {\n        return m_predicate(item);\n    }\n\n    std::string describe() const override {\n        return m_description;\n    }\n};\n\n} // namespace Generic\n\n    // The following functions create the actual matcher objects.\n    // The user has to explicitly specify type to the function, because\n    // inferring std::function<bool(T const&)> is hard (but possible) and\n    // requires a lot of TMP.\n    template<typename T>\n    Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = \"\") {\n        return Generic::PredicateMatcher<T>(predicate, description);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_generic.hpp\n// start catch_matchers_string.h\n\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        struct CasedString\n        {\n            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );\n            std::string adjustString( std::string const& str ) const;\n            std::string caseSensitivitySuffix() const;\n\n            CaseSensitive::Choice m_caseSensitivity;\n            std::string m_str;\n        };\n\n        struct StringMatcherBase : MatcherBase<std::string> {\n            StringMatcherBase( std::string const& operation, CasedString const& comparator );\n            std::string describe() const override;\n\n            CasedString m_comparator;\n            std::string m_operation;\n        };\n\n        struct EqualsMatcher : StringMatcherBase {\n            EqualsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct ContainsMatcher : StringMatcherBase {\n            ContainsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct StartsWithMatcher : StringMatcherBase {\n            StartsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct EndsWithMatcher : StringMatcherBase {\n            EndsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n\n        struct RegexMatcher : MatcherBase<std::string> {\n            RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );\n            bool match( std::string const& matchee ) const override;\n            std::string describe() const override;\n\n        private:\n            std::string m_regex;\n            CaseSensitive::Choice m_caseSensitivity;\n        };\n\n    } // namespace StdString\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_string.h\n// start catch_matchers_vector.h\n\n#include <algorithm>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Vector {\n        template<typename T, typename Alloc>\n        struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {\n\n            ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}\n\n            bool match(std::vector<T, Alloc> const &v) const override {\n                for (auto const& el : v) {\n                    if (el == m_comparator) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            T const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: see note in EqualsMatcher\n                if (m_comparator.size() > v.size())\n                    return false;\n                for (auto const& comparator : m_comparator) {\n                    auto present = false;\n                    for (const auto& el : v) {\n                        if (el == comparator) {\n                            present = true;\n                            break;\n                        }\n                    }\n                    if (!present) {\n                        return false;\n                    }\n                }\n                return true;\n            }\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: This currently works if all elements can be compared using !=\n                // - a more general approach would be via a compare template that defaults\n                // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc\n                // - then just call that directly\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != v[i])\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"Equals: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != approx(v[i]))\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"is approx: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& epsilon( T const& newEpsilon ) {\n                approx.epsilon(newEpsilon);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& margin( T const& newMargin ) {\n                approx.margin(newMargin);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& scale( T const& newScale ) {\n                approx.scale(newScale);\n                return *this;\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n            UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}\n            bool match(std::vector<T, AllocMatch> const& vec) const override {\n                if (m_target.size() != vec.size()) {\n                    return false;\n                }\n                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());\n            }\n\n            std::string describe() const override {\n                return \"UnorderedEquals: \" + ::Catch::Detail::stringify(m_target);\n            }\n        private:\n            std::vector<T, AllocComp> const& m_target;\n        };\n\n    } // namespace Vector\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename Alloc = std::allocator<T>>\n    Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {\n        return Vector::ContainsElementMatcher<T, Alloc>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {\n        return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_vector.h\nnamespace Catch {\n\n    template<typename ArgT, typename MatcherT>\n    class MatchExpr : public ITransientExpression {\n        ArgT const& m_arg;\n        MatcherT m_matcher;\n        StringRef m_matcherString;\n    public:\n        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )\n        :   ITransientExpression{ true, matcher.match( arg ) },\n            m_arg( arg ),\n            m_matcher( matcher ),\n            m_matcherString( matcherString )\n        {}\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            auto matcherAsString = m_matcher.toString();\n            os << Catch::Detail::stringify( m_arg ) << ' ';\n            if( matcherAsString == Detail::unprintableString )\n                os << m_matcherString;\n            else\n                os << matcherAsString;\n        }\n    };\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );\n\n    template<typename ArgT, typename MatcherT>\n    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {\n        return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );\n    }\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__ ); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ex ) { \\\n                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n// end catch_capture_matchers.h\n#endif\n// start catch_generators.hpp\n\n// start catch_interfaces_generatortracker.h\n\n\n#include <memory>\n\nnamespace Catch {\n\n    namespace Generators {\n        class GeneratorUntypedBase {\n        public:\n            GeneratorUntypedBase() = default;\n            virtual ~GeneratorUntypedBase();\n            // Attempts to move the generator to the next element\n             //\n             // Returns true iff the move succeeded (and a valid element\n             // can be retrieved).\n            virtual bool next() = 0;\n        };\n        using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;\n\n    } // namespace Generators\n\n    struct IGeneratorTracker {\n        virtual ~IGeneratorTracker();\n        virtual auto hasGenerator() const -> bool = 0;\n        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;\n        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;\n    };\n\n} // namespace Catch\n\n// end catch_interfaces_generatortracker.h\n// start catch_enforce.h\n\n#include <exception>\n\nnamespace Catch {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    template <typename Ex>\n    [[noreturn]]\n    void throw_exception(Ex const& e) {\n        throw e;\n    }\n#else // ^^ Exceptions are enabled //  Exceptions are disabled vv\n    [[noreturn]]\n    void throw_exception(std::exception const& e);\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg);\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg);\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg);\n\n} // namespace Catch;\n\n#define CATCH_MAKE_MSG(...) \\\n    (Catch::ReusableStringStream() << __VA_ARGS__).str()\n\n#define CATCH_INTERNAL_ERROR(...) \\\n    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << \": Internal Catch2 error: \" << __VA_ARGS__))\n\n#define CATCH_ERROR(...) \\\n    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_RUNTIME_ERROR(...) \\\n    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_ENFORCE( condition, ... ) \\\n    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)\n\n// end catch_enforce.h\n#include <memory>\n#include <vector>\n#include <cassert>\n\n#include <utility>\n#include <exception>\n\nnamespace Catch {\n\nclass GeneratorException : public std::exception {\n    const char* const m_msg = \"\";\n\npublic:\n    GeneratorException(const char* msg):\n        m_msg(msg)\n    {}\n\n    const char* what() const noexcept override final;\n};\n\nnamespace Generators {\n\n    // !TBD move this into its own location?\n    namespace pf{\n        template<typename T, typename... Args>\n        std::unique_ptr<T> make_unique( Args&&... args ) {\n            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));\n        }\n    }\n\n    template<typename T>\n    struct IGenerator : GeneratorUntypedBase {\n        virtual ~IGenerator() = default;\n\n        // Returns the current element of the generator\n        //\n        // \\Precondition The generator is either freshly constructed,\n        // or the last call to `next()` returned true\n        virtual T const& get() const = 0;\n        using type = T;\n    };\n\n    template<typename T>\n    class SingleValueGenerator final : public IGenerator<T> {\n        T m_value;\n    public:\n        SingleValueGenerator(T&& value) : m_value(std::move(value)) {}\n\n        T const& get() const override {\n            return m_value;\n        }\n        bool next() override {\n            return false;\n        }\n    };\n\n    template<typename T>\n    class FixedValuesGenerator final : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"FixedValuesGenerator does not support bools because of std::vector<bool>\"\n            \"specialization, use SingleValue Generator instead.\");\n        std::vector<T> m_values;\n        size_t m_idx = 0;\n    public:\n        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}\n\n        T const& get() const override {\n            return m_values[m_idx];\n        }\n        bool next() override {\n            ++m_idx;\n            return m_idx < m_values.size();\n        }\n    };\n\n    template <typename T>\n    class GeneratorWrapper final {\n        std::unique_ptr<IGenerator<T>> m_generator;\n    public:\n        GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):\n            m_generator(std::move(generator))\n        {}\n        T const& get() const {\n            return m_generator->get();\n        }\n        bool next() {\n            return m_generator->next();\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> value(T&& value) {\n        return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));\n    }\n    template <typename T>\n    GeneratorWrapper<T> values(std::initializer_list<T> values) {\n        return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));\n    }\n\n    template<typename T>\n    class Generators : public IGenerator<T> {\n        std::vector<GeneratorWrapper<T>> m_generators;\n        size_t m_current = 0;\n\n        void populate(GeneratorWrapper<T>&& generator) {\n            m_generators.emplace_back(std::move(generator));\n        }\n        void populate(T&& val) {\n            m_generators.emplace_back(value(std::forward<T>(val)));\n        }\n        template<typename U>\n        void populate(U&& val) {\n            populate(T(std::forward<U>(val)));\n        }\n        template<typename U, typename... Gs>\n        void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {\n            populate(std::forward<U>(valueOrGenerator));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n    public:\n        template <typename... Gs>\n        Generators(Gs &&... moreGenerators) {\n            m_generators.reserve(sizeof...(Gs));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n        T const& get() const override {\n            return m_generators[m_current].get();\n        }\n\n        bool next() override {\n            if (m_current >= m_generators.size()) {\n                return false;\n            }\n            const bool current_status = m_generators[m_current].next();\n            if (!current_status) {\n                ++m_current;\n            }\n            return m_current < m_generators.size();\n        }\n    };\n\n    template<typename... Ts>\n    GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {\n        return values<std::tuple<Ts...>>( tuples );\n    }\n\n    // Tag type to signal that a generator sequence should convert arguments to a specific type\n    template <typename T>\n    struct as {};\n\n    template<typename T, typename... Gs>\n    auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {\n        return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);\n    }\n    template<typename T>\n    auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {\n        return Generators<T>(std::move(generator));\n    }\n    template<typename T, typename... Gs>\n    auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );\n    }\n    template<typename T, typename U, typename... Gs>\n    auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );\n    }\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;\n\n    template<typename L>\n    // Note: The type after -> is weird, because VS2015 cannot parse\n    //       the expression used in the typedef inside, when it is in\n    //       return type. Yeah.\n    auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {\n        using UnderlyingType = typename decltype(generatorExpression())::type;\n\n        IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );\n        if (!tracker.hasGenerator()) {\n            tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));\n        }\n\n        auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );\n        return generator.get();\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n#define GENERATE( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_COPY( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_REF( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n\n// end catch_generators.hpp\n// start catch_generators_generic.hpp\n\nnamespace Catch {\nnamespace Generators {\n\n    template <typename T>\n    class TakeGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        size_t m_returned = 0;\n        size_t m_target;\n    public:\n        TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target(target)\n        {\n            assert(target != 0 && \"Empty generators are not allowed\");\n        }\n        T const& get() const override {\n            return m_generator.get();\n        }\n        bool next() override {\n            ++m_returned;\n            if (m_returned >= m_target) {\n                return false;\n            }\n\n            const auto success = m_generator.next();\n            // If the underlying generator does not contain enough values\n            // then we cut short as well\n            if (!success) {\n                m_returned = m_target;\n            }\n            return success;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));\n    }\n\n    template <typename T, typename Predicate>\n    class FilterGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        Predicate m_predicate;\n    public:\n        template <typename P = Predicate>\n        FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_predicate(std::forward<P>(pred))\n        {\n            if (!m_predicate(m_generator.get())) {\n                // It might happen that there are no values that pass the\n                // filter. In that case we throw an exception.\n                auto has_initial_value = nextImpl();\n                if (!has_initial_value) {\n                    Catch::throw_exception(GeneratorException(\"No valid value found in filtered generator\"));\n                }\n            }\n        }\n\n        T const& get() const override {\n            return m_generator.get();\n        }\n\n        bool next() override {\n            return nextImpl();\n        }\n\n    private:\n        bool nextImpl() {\n            bool success = m_generator.next();\n            if (!success) {\n                return false;\n            }\n            while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);\n            return success;\n        }\n    };\n\n    template <typename T, typename Predicate>\n    GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));\n    }\n\n    template <typename T>\n    class RepeatGenerator : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"RepeatGenerator currently does not support bools\"\n            \"because of std::vector<bool> specialization\");\n        GeneratorWrapper<T> m_generator;\n        mutable std::vector<T> m_returned;\n        size_t m_target_repeats;\n        size_t m_current_repeat = 0;\n        size_t m_repeat_index = 0;\n    public:\n        RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target_repeats(repeats)\n        {\n            assert(m_target_repeats > 0 && \"Repeat generator must repeat at least once\");\n        }\n\n        T const& get() const override {\n            if (m_current_repeat == 0) {\n                m_returned.push_back(m_generator.get());\n                return m_returned.back();\n            }\n            return m_returned[m_repeat_index];\n        }\n\n        bool next() override {\n            // There are 2 basic cases:\n            // 1) We are still reading the generator\n            // 2) We are reading our own cache\n\n            // In the first case, we need to poke the underlying generator.\n            // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache\n            if (m_current_repeat == 0) {\n                const auto success = m_generator.next();\n                if (!success) {\n                    ++m_current_repeat;\n                }\n                return m_current_repeat < m_target_repeats;\n            }\n\n            // In the second case, we need to move indices forward and check that we haven't run up against the end\n            ++m_repeat_index;\n            if (m_repeat_index == m_returned.size()) {\n                m_repeat_index = 0;\n                ++m_current_repeat;\n            }\n            return m_current_repeat < m_target_repeats;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));\n    }\n\n    template <typename T, typename U, typename Func>\n    class MapGenerator : public IGenerator<T> {\n        // TBD: provide static assert for mapping function, for friendly error message\n        GeneratorWrapper<U> m_generator;\n        Func m_function;\n        // To avoid returning dangling reference, we have to save the values\n        T m_cache;\n    public:\n        template <typename F2 = Func>\n        MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :\n            m_generator(std::move(generator)),\n            m_function(std::forward<F2>(function)),\n            m_cache(m_function(m_generator.get()))\n        {}\n\n        T const& get() const override {\n            return m_cache;\n        }\n        bool next() override {\n            const auto success = m_generator.next();\n            if (success) {\n                m_cache = m_function(m_generator.get());\n            }\n            return success;\n        }\n    };\n\n    template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T, typename U, typename Func>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T>\n    class ChunkGenerator final : public IGenerator<std::vector<T>> {\n        std::vector<T> m_chunk;\n        size_t m_chunk_size;\n        GeneratorWrapper<T> m_generator;\n        bool m_used_up = false;\n    public:\n        ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :\n            m_chunk_size(size), m_generator(std::move(generator))\n        {\n            m_chunk.reserve(m_chunk_size);\n            if (m_chunk_size != 0) {\n                m_chunk.push_back(m_generator.get());\n                for (size_t i = 1; i < m_chunk_size; ++i) {\n                    if (!m_generator.next()) {\n                        Catch::throw_exception(GeneratorException(\"Not enough values to initialize the first chunk\"));\n                    }\n                    m_chunk.push_back(m_generator.get());\n                }\n            }\n        }\n        std::vector<T> const& get() const override {\n            return m_chunk;\n        }\n        bool next() override {\n            m_chunk.clear();\n            for (size_t idx = 0; idx < m_chunk_size; ++idx) {\n                if (!m_generator.next()) {\n                    return false;\n                }\n                m_chunk.push_back(m_generator.get());\n            }\n            return true;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<std::vector<T>>(\n            pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))\n        );\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_generic.hpp\n// start catch_generators_specific.hpp\n\n// start catch_context.h\n\n#include <memory>\n\nnamespace Catch {\n\n    struct IResultCapture;\n    struct IRunner;\n    struct IConfig;\n    struct IMutableContext;\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n\n    struct IContext\n    {\n        virtual ~IContext();\n\n        virtual IResultCapture* getResultCapture() = 0;\n        virtual IRunner* getRunner() = 0;\n        virtual IConfigPtr const& getConfig() const = 0;\n    };\n\n    struct IMutableContext : IContext\n    {\n        virtual ~IMutableContext();\n        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;\n        virtual void setRunner( IRunner* runner ) = 0;\n        virtual void setConfig( IConfigPtr const& config ) = 0;\n\n    private:\n        static IMutableContext *currentContext;\n        friend IMutableContext& getCurrentMutableContext();\n        friend void cleanUpContext();\n        static void createContext();\n    };\n\n    inline IMutableContext& getCurrentMutableContext()\n    {\n        if( !IMutableContext::currentContext )\n            IMutableContext::createContext();\n        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)\n        return *IMutableContext::currentContext;\n    }\n\n    inline IContext& getCurrentContext()\n    {\n        return getCurrentMutableContext();\n    }\n\n    void cleanUpContext();\n\n    class SimplePcg32;\n    SimplePcg32& rng();\n}\n\n// end catch_context.h\n// start catch_interfaces_config.h\n\n// start catch_option.hpp\n\nnamespace Catch {\n\n    // An optional type\n    template<typename T>\n    class Option {\n    public:\n        Option() : nullableValue( nullptr ) {}\n        Option( T const& _value )\n        : nullableValue( new( storage ) T( _value ) )\n        {}\n        Option( Option const& _other )\n        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )\n        {}\n\n        ~Option() {\n            reset();\n        }\n\n        Option& operator= ( Option const& _other ) {\n            if( &_other != this ) {\n                reset();\n                if( _other )\n                    nullableValue = new( storage ) T( *_other );\n            }\n            return *this;\n        }\n        Option& operator = ( T const& _value ) {\n            reset();\n            nullableValue = new( storage ) T( _value );\n            return *this;\n        }\n\n        void reset() {\n            if( nullableValue )\n                nullableValue->~T();\n            nullableValue = nullptr;\n        }\n\n        T& operator*() { return *nullableValue; }\n        T const& operator*() const { return *nullableValue; }\n        T* operator->() { return nullableValue; }\n        const T* operator->() const { return nullableValue; }\n\n        T valueOr( T const& defaultValue ) const {\n            return nullableValue ? *nullableValue : defaultValue;\n        }\n\n        bool some() const { return nullableValue != nullptr; }\n        bool none() const { return nullableValue == nullptr; }\n\n        bool operator !() const { return nullableValue == nullptr; }\n        explicit operator bool() const {\n            return some();\n        }\n\n    private:\n        T *nullableValue;\n        alignas(alignof(T)) char storage[sizeof(T)];\n    };\n\n} // end namespace Catch\n\n// end catch_option.hpp\n#include <chrono>\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    enum class Verbosity {\n        Quiet = 0,\n        Normal,\n        High\n    };\n\n    struct WarnAbout { enum What {\n        Nothing = 0x00,\n        NoAssertions = 0x01,\n        NoTests = 0x02\n    }; };\n\n    struct ShowDurations { enum OrNot {\n        DefaultForReporter,\n        Always,\n        Never\n    }; };\n    struct RunTests { enum InWhatOrder {\n        InDeclarationOrder,\n        InLexicographicalOrder,\n        InRandomOrder\n    }; };\n    struct UseColour { enum YesOrNo {\n        Auto,\n        Yes,\n        No\n    }; };\n    struct WaitForKeypress { enum When {\n        Never,\n        BeforeStart = 1,\n        BeforeExit = 2,\n        BeforeStartAndExit = BeforeStart | BeforeExit\n    }; };\n\n    class TestSpec;\n\n    struct IConfig : NonCopyable {\n\n        virtual ~IConfig();\n\n        virtual bool allowThrows() const = 0;\n        virtual std::ostream& stream() const = 0;\n        virtual std::string name() const = 0;\n        virtual bool includeSuccessfulResults() const = 0;\n        virtual bool shouldDebugBreak() const = 0;\n        virtual bool warnAboutMissingAssertions() const = 0;\n        virtual bool warnAboutNoTests() const = 0;\n        virtual int abortAfter() const = 0;\n        virtual bool showInvisibles() const = 0;\n        virtual ShowDurations::OrNot showDurations() const = 0;\n        virtual double minDuration() const = 0;\n        virtual TestSpec const& testSpec() const = 0;\n        virtual bool hasTestFilters() const = 0;\n        virtual std::vector<std::string> const& getTestsOrTags() const = 0;\n        virtual RunTests::InWhatOrder runOrder() const = 0;\n        virtual unsigned int rngSeed() const = 0;\n        virtual UseColour::YesOrNo useColour() const = 0;\n        virtual std::vector<std::string> const& getSectionsToRun() const = 0;\n        virtual Verbosity verbosity() const = 0;\n\n        virtual bool benchmarkNoAnalysis() const = 0;\n        virtual int benchmarkSamples() const = 0;\n        virtual double benchmarkConfidenceInterval() const = 0;\n        virtual unsigned int benchmarkResamples() const = 0;\n        virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;\n    };\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n}\n\n// end catch_interfaces_config.h\n// start catch_random_number_generator.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    // This is a simple implementation of C++11 Uniform Random Number\n    // Generator. It does not provide all operators, because Catch2\n    // does not use it, but it should behave as expected inside stdlib's\n    // distributions.\n    // The implementation is based on the PCG family (http://pcg-random.org)\n    class SimplePcg32 {\n        using state_type = std::uint64_t;\n    public:\n        using result_type = std::uint32_t;\n        static constexpr result_type (min)() {\n            return 0;\n        }\n        static constexpr result_type (max)() {\n            return static_cast<result_type>(-1);\n        }\n\n        // Provide some default initial state for the default constructor\n        SimplePcg32():SimplePcg32(0xed743cc4U) {}\n\n        explicit SimplePcg32(result_type seed_);\n\n        void seed(result_type seed_);\n        void discard(uint64_t skip);\n\n        result_type operator()();\n\n    private:\n        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n\n        // In theory we also need operator<< and operator>>\n        // In practice we do not use them, so we will skip them for now\n\n        std::uint64_t m_state;\n        // This part of the state determines which \"stream\" of the numbers\n        // is chosen -- we take it as a constant for Catch2, so we only\n        // need to deal with seeding the main state.\n        // Picked by reading 8 bytes from `/dev/random` :-)\n        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;\n    };\n\n} // end namespace Catch\n\n// end catch_random_number_generator.h\n#include <random>\n\nnamespace Catch {\nnamespace Generators {\n\ntemplate <typename Float>\nclass RandomFloatingGenerator final : public IGenerator<Float> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_real_distribution<Float> m_dist;\n    Float m_current_number;\npublic:\n\n    RandomFloatingGenerator(Float a, Float b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Float const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\ntemplate <typename Integer>\nclass RandomIntegerGenerator final : public IGenerator<Integer> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_int_distribution<Integer> m_dist;\n    Integer m_current_number;\npublic:\n\n    RandomIntegerGenerator(Integer a, Integer b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Integer const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\n// TODO: Ideally this would be also constrained against the various char types,\n//       but I don't expect users to run into that in practice.\ntemplate <typename T>\ntypename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomIntegerGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\ntypename std::enable_if<std::is_floating_point<T>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomFloatingGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\nclass RangeGenerator final : public IGenerator<T> {\n    T m_current;\n    T m_end;\n    T m_step;\n    bool m_positive;\n\npublic:\n    RangeGenerator(T const& start, T const& end, T const& step):\n        m_current(start),\n        m_end(end),\n        m_step(step),\n        m_positive(m_step > T(0))\n    {\n        assert(m_current != m_end && \"Range start and end cannot be equal\");\n        assert(m_step != T(0) && \"Step size cannot be zero\");\n        assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && \"Step moves away from end\");\n    }\n\n    RangeGenerator(T const& start, T const& end):\n        RangeGenerator(start, end, (start < end) ? T(1) : T(-1))\n    {}\n\n    T const& get() const override {\n        return m_current;\n    }\n\n    bool next() override {\n        m_current += m_step;\n        return (m_positive) ? (m_current < m_end) : (m_current > m_end);\n    }\n};\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end, T const& step) {\n    static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, \"Type must be numeric\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));\n}\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end) {\n    static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, \"Type must be an integer\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));\n}\n\ntemplate <typename T>\nclass IteratorGenerator final : public IGenerator<T> {\n    static_assert(!std::is_same<T, bool>::value,\n        \"IteratorGenerator currently does not support bools\"\n        \"because of std::vector<bool> specialization\");\n\n    std::vector<T> m_elems;\n    size_t m_current = 0;\npublic:\n    template <typename InputIterator, typename InputSentinel>\n    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {\n        if (m_elems.empty()) {\n            Catch::throw_exception(GeneratorException(\"IteratorGenerator received no valid values\"));\n        }\n    }\n\n    T const& get() const override {\n        return m_elems[m_current];\n    }\n\n    bool next() override {\n        ++m_current;\n        return m_current != m_elems.size();\n    }\n};\n\ntemplate <typename InputIterator,\n          typename InputSentinel,\n          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>\nGeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));\n}\n\ntemplate <typename Container,\n          typename ResultType = typename Container::value_type>\nGeneratorWrapper<ResultType> from_range(Container const& cnt) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));\n}\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_specific.hpp\n\n// These files are included here so the single_include script doesn't put them\n// in the conditionally compiled sections\n// start catch_test_case_info.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    struct ITestInvoker;\n\n    struct TestCaseInfo {\n        enum SpecialProperties{\n            None = 0,\n            IsHidden = 1 << 1,\n            ShouldFail = 1 << 2,\n            MayFail = 1 << 3,\n            Throws = 1 << 4,\n            NonPortable = 1 << 5,\n            Benchmark = 1 << 6\n        };\n\n        TestCaseInfo(   std::string const& _name,\n                        std::string const& _className,\n                        std::string const& _description,\n                        std::vector<std::string> const& _tags,\n                        SourceLineInfo const& _lineInfo );\n\n        friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );\n\n        bool isHidden() const;\n        bool throws() const;\n        bool okToFail() const;\n        bool expectedToFail() const;\n\n        std::string tagsAsString() const;\n\n        std::string name;\n        std::string className;\n        std::string description;\n        std::vector<std::string> tags;\n        std::vector<std::string> lcaseTags;\n        SourceLineInfo lineInfo;\n        SpecialProperties properties;\n    };\n\n    class TestCase : public TestCaseInfo {\n    public:\n\n        TestCase( ITestInvoker* testCase, TestCaseInfo&& info );\n\n        TestCase withName( std::string const& _newName ) const;\n\n        void invoke() const;\n\n        TestCaseInfo const& getTestCaseInfo() const;\n\n        bool operator == ( TestCase const& other ) const;\n        bool operator < ( TestCase const& other ) const;\n\n    private:\n        std::shared_ptr<ITestInvoker> test;\n    };\n\n    TestCase makeTestCase(  ITestInvoker* testCase,\n                            std::string const& className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& lineInfo );\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_case_info.h\n// start catch_interfaces_runner.h\n\nnamespace Catch {\n\n    struct IRunner {\n        virtual ~IRunner();\n        virtual bool aborting() const = 0;\n    };\n}\n\n// end catch_interfaces_runner.h\n\n#ifdef __OBJC__\n// start catch_objc.hpp\n\n#import <objc/runtime.h>\n\n#include <string>\n\n// NB. Any general catch headers included here must be included\n// in catch.hpp first to make sure they are included by the single\n// header for non obj-usage\n\n///////////////////////////////////////////////////////////////////////////////\n// This protocol is really only here for (self) documenting purposes, since\n// all its methods are optional.\n@protocol OcFixture\n\n@optional\n\n-(void) setUp;\n-(void) tearDown;\n\n@end\n\nnamespace Catch {\n\n    class OcMethod : public ITestInvoker {\n\n    public:\n        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}\n\n        virtual void invoke() const {\n            id obj = [[m_cls alloc] init];\n\n            performOptionalSelector( obj, @selector(setUp)  );\n            performOptionalSelector( obj, m_sel );\n            performOptionalSelector( obj, @selector(tearDown)  );\n\n            arcSafeRelease( obj );\n        }\n    private:\n        virtual ~OcMethod() {}\n\n        Class m_cls;\n        SEL m_sel;\n    };\n\n    namespace Detail{\n\n        inline std::string getAnnotation(   Class cls,\n                                            std::string const& annotationName,\n                                            std::string const& testCaseName ) {\n            NSString* selStr = [[NSString alloc] initWithFormat:@\"Catch_%s_%s\", annotationName.c_str(), testCaseName.c_str()];\n            SEL sel = NSSelectorFromString( selStr );\n            arcSafeRelease( selStr );\n            id value = performOptionalSelector( cls, sel );\n            if( value )\n                return [(NSString*)value UTF8String];\n            return \"\";\n        }\n    }\n\n    inline std::size_t registerTestMethods() {\n        std::size_t noTestMethods = 0;\n        int noClasses = objc_getClassList( nullptr, 0 );\n\n        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);\n        objc_getClassList( classes, noClasses );\n\n        for( int c = 0; c < noClasses; c++ ) {\n            Class cls = classes[c];\n            {\n                u_int count;\n                Method* methods = class_copyMethodList( cls, &count );\n                for( u_int m = 0; m < count ; m++ ) {\n                    SEL selector = method_getName(methods[m]);\n                    std::string methodName = sel_getName(selector);\n                    if( startsWith( methodName, \"Catch_TestCase_\" ) ) {\n                        std::string testCaseName = methodName.substr( 15 );\n                        std::string name = Detail::getAnnotation( cls, \"Name\", testCaseName );\n                        std::string desc = Detail::getAnnotation( cls, \"Description\", testCaseName );\n                        const char* className = class_getName( cls );\n\n                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo(\"\",0) ) );\n                        noTestMethods++;\n                    }\n                }\n                free(methods);\n            }\n        }\n        return noTestMethods;\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n\n    namespace Matchers {\n        namespace Impl {\n        namespace NSStringMatchers {\n\n            struct StringHolder : MatcherBase<NSString*>{\n                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}\n                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}\n                StringHolder() {\n                    arcSafeRelease( m_substr );\n                }\n\n                bool match( NSString* str ) const override {\n                    return false;\n                }\n\n                NSString* CATCH_ARC_STRONG m_substr;\n            };\n\n            struct Equals : StringHolder {\n                Equals( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str isEqualToString:m_substr];\n                }\n\n                std::string describe() const override {\n                    return \"equals string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct Contains : StringHolder {\n                Contains( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location != NSNotFound;\n                }\n\n                std::string describe() const override {\n                    return \"contains string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct StartsWith : StringHolder {\n                StartsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == 0;\n                }\n\n                std::string describe() const override {\n                    return \"starts with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n            struct EndsWith : StringHolder {\n                EndsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];\n                }\n\n                std::string describe() const override {\n                    return \"ends with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n        } // namespace NSStringMatchers\n        } // namespace Impl\n\n        inline Impl::NSStringMatchers::Equals\n            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }\n\n        inline Impl::NSStringMatchers::Contains\n            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }\n\n        inline Impl::NSStringMatchers::StartsWith\n            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }\n\n        inline Impl::NSStringMatchers::EndsWith\n            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }\n\n    } // namespace Matchers\n\n    using namespace Matchers;\n\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix\n#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \\\n{ \\\nreturn @ name; \\\n} \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \\\n{ \\\nreturn @ desc; \\\n} \\\n-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )\n\n#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )\n\n// end catch_objc.hpp\n#endif\n\n// Benchmarking needs the externally-facing parts of reporters to work\n#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_external_interfaces.h\n\n// start catch_reporter_bases.hpp\n\n// start catch_interfaces_reporter.h\n\n// start catch_config.hpp\n\n// start catch_test_spec_parser.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_test_spec.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_wildcard_pattern.h\n\nnamespace Catch\n{\n    class WildcardPattern {\n        enum WildcardPosition {\n            NoWildcard = 0,\n            WildcardAtStart = 1,\n            WildcardAtEnd = 2,\n            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd\n        };\n\n    public:\n\n        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );\n        virtual ~WildcardPattern() = default;\n        virtual bool matches( std::string const& str ) const;\n\n    private:\n        std::string normaliseString( std::string const& str ) const;\n        CaseSensitive::Choice m_caseSensitivity;\n        WildcardPosition m_wildcard = NoWildcard;\n        std::string m_pattern;\n    };\n}\n\n// end catch_wildcard_pattern.h\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    struct IConfig;\n\n    class TestSpec {\n        class Pattern {\n        public:\n            explicit Pattern( std::string const& name );\n            virtual ~Pattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const = 0;\n            std::string const& name() const;\n        private:\n            std::string const m_name;\n        };\n        using PatternPtr = std::shared_ptr<Pattern>;\n\n        class NamePattern : public Pattern {\n        public:\n            explicit NamePattern( std::string const& name, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            WildcardPattern m_wildcardPattern;\n        };\n\n        class TagPattern : public Pattern {\n        public:\n            explicit TagPattern( std::string const& tag, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            std::string m_tag;\n        };\n\n        class ExcludedPattern : public Pattern {\n        public:\n            explicit ExcludedPattern( PatternPtr const& underlyingPattern );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            PatternPtr m_underlyingPattern;\n        };\n\n        struct Filter {\n            std::vector<PatternPtr> m_patterns;\n\n            bool matches( TestCaseInfo const& testCase ) const;\n            std::string name() const;\n        };\n\n    public:\n        struct FilterMatch {\n            std::string name;\n            std::vector<TestCase const*> tests;\n        };\n        using Matches = std::vector<FilterMatch>;\n        using vectorStrings = std::vector<std::string>;\n\n        bool hasFilters() const;\n        bool matches( TestCaseInfo const& testCase ) const;\n        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;\n        const vectorStrings & getInvalidArgs() const;\n\n    private:\n        std::vector<Filter> m_filters;\n        std::vector<std::string> m_invalidArgs;\n        friend class TestSpecParser;\n    };\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec.h\n// start catch_interfaces_tag_alias_registry.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias;\n\n    struct ITagAliasRegistry {\n        virtual ~ITagAliasRegistry();\n        // Nullptr if not present\n        virtual TagAlias const* find( std::string const& alias ) const = 0;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;\n\n        static ITagAliasRegistry const& get();\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_tag_alias_registry.h\nnamespace Catch {\n\n    class TestSpecParser {\n        enum Mode{ None, Name, QuotedName, Tag, EscapedName };\n        Mode m_mode = None;\n        Mode lastMode = None;\n        bool m_exclusion = false;\n        std::size_t m_pos = 0;\n        std::size_t m_realPatternPos = 0;\n        std::string m_arg;\n        std::string m_substring;\n        std::string m_patternName;\n        std::vector<std::size_t> m_escapeChars;\n        TestSpec::Filter m_currentFilter;\n        TestSpec m_testSpec;\n        ITagAliasRegistry const* m_tagAliases = nullptr;\n\n    public:\n        TestSpecParser( ITagAliasRegistry const& tagAliases );\n\n        TestSpecParser& parse( std::string const& arg );\n        TestSpec testSpec();\n\n    private:\n        bool visitChar( char c );\n        void startNewMode( Mode mode );\n        bool processNoneChar( char c );\n        void processNameChar( char c );\n        bool processOtherChar( char c );\n        void endMode();\n        void escape();\n        bool isControlChar( char c ) const;\n        void saveLastMode();\n        void revertBackToLastMode();\n        void addFilter();\n        bool separate();\n\n        // Handles common preprocessing of the pattern for name/tag patterns\n        std::string preprocessPattern();\n        // Adds the current pattern as a test name\n        void addNamePattern();\n        // Adds the current pattern as a tag\n        void addTagPattern();\n\n        inline void addCharToPattern(char c) {\n            m_substring += c;\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n\n    };\n    TestSpec parseTestSpec( std::string const& arg );\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec_parser.h\n// Libstdc++ doesn't like incomplete classes for unique_ptr\n\n#include <memory>\n#include <vector>\n#include <string>\n\n#ifndef CATCH_CONFIG_CONSOLE_WIDTH\n#define CATCH_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\n\n    struct IStream;\n\n    struct ConfigData {\n        bool listTests = false;\n        bool listTags = false;\n        bool listReporters = false;\n        bool listTestNamesOnly = false;\n\n        bool showSuccessfulTests = false;\n        bool shouldDebugBreak = false;\n        bool noThrow = false;\n        bool showHelp = false;\n        bool showInvisibles = false;\n        bool filenamesAsTags = false;\n        bool libIdentify = false;\n\n        int abortAfter = -1;\n        unsigned int rngSeed = 0;\n\n        bool benchmarkNoAnalysis = false;\n        unsigned int benchmarkSamples = 100;\n        double benchmarkConfidenceInterval = 0.95;\n        unsigned int benchmarkResamples = 100000;\n        std::chrono::milliseconds::rep benchmarkWarmupTime = 100;\n\n        Verbosity verbosity = Verbosity::Normal;\n        WarnAbout::What warnings = WarnAbout::Nothing;\n        ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;\n        double minDuration = -1;\n        RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;\n        UseColour::YesOrNo useColour = UseColour::Auto;\n        WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;\n\n        std::string outputFilename;\n        std::string name;\n        std::string processName;\n#ifndef CATCH_CONFIG_DEFAULT_REPORTER\n#define CATCH_CONFIG_DEFAULT_REPORTER \"console\"\n#endif\n        std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;\n#undef CATCH_CONFIG_DEFAULT_REPORTER\n\n        std::vector<std::string> testsOrTags;\n        std::vector<std::string> sectionsToRun;\n    };\n\n    class Config : public IConfig {\n    public:\n\n        Config() = default;\n        Config( ConfigData const& data );\n        virtual ~Config() = default;\n\n        std::string const& getFilename() const;\n\n        bool listTests() const;\n        bool listTestNamesOnly() const;\n        bool listTags() const;\n        bool listReporters() const;\n\n        std::string getProcessName() const;\n        std::string const& getReporterName() const;\n\n        std::vector<std::string> const& getTestsOrTags() const override;\n        std::vector<std::string> const& getSectionsToRun() const override;\n\n        TestSpec const& testSpec() const override;\n        bool hasTestFilters() const override;\n\n        bool showHelp() const;\n\n        // IConfig interface\n        bool allowThrows() const override;\n        std::ostream& stream() const override;\n        std::string name() const override;\n        bool includeSuccessfulResults() const override;\n        bool warnAboutMissingAssertions() const override;\n        bool warnAboutNoTests() const override;\n        ShowDurations::OrNot showDurations() const override;\n        double minDuration() const override;\n        RunTests::InWhatOrder runOrder() const override;\n        unsigned int rngSeed() const override;\n        UseColour::YesOrNo useColour() const override;\n        bool shouldDebugBreak() const override;\n        int abortAfter() const override;\n        bool showInvisibles() const override;\n        Verbosity verbosity() const override;\n        bool benchmarkNoAnalysis() const override;\n        int benchmarkSamples() const override;\n        double benchmarkConfidenceInterval() const override;\n        unsigned int benchmarkResamples() const override;\n        std::chrono::milliseconds benchmarkWarmupTime() const override;\n\n    private:\n\n        IStream const* openStream();\n        ConfigData m_data;\n\n        std::unique_ptr<IStream const> m_stream;\n        TestSpec m_testSpec;\n        bool m_hasTestFilters = false;\n    };\n\n} // end namespace Catch\n\n// end catch_config.hpp\n// start catch_assertionresult.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct AssertionResultData\n    {\n        AssertionResultData() = delete;\n\n        AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );\n\n        std::string message;\n        mutable std::string reconstructedExpression;\n        LazyExpression lazyExpression;\n        ResultWas::OfType resultType;\n\n        std::string reconstructExpression() const;\n    };\n\n    class AssertionResult {\n    public:\n        AssertionResult() = delete;\n        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );\n\n        bool isOk() const;\n        bool succeeded() const;\n        ResultWas::OfType getResultType() const;\n        bool hasExpression() const;\n        bool hasMessage() const;\n        std::string getExpression() const;\n        std::string getExpressionInMacro() const;\n        bool hasExpandedExpression() const;\n        std::string getExpandedExpression() const;\n        std::string getMessage() const;\n        SourceLineInfo getSourceInfo() const;\n        StringRef getTestMacroName() const;\n\n    //protected:\n        AssertionInfo m_info;\n        AssertionResultData m_resultData;\n    };\n\n} // end namespace Catch\n\n// end catch_assertionresult.h\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_estimate.hpp\n\n // Statistics estimates\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct Estimate {\n            Duration point;\n            Duration lower_bound;\n            Duration upper_bound;\n            double confidence_interval;\n\n            template <typename Duration2>\n            operator Estimate<Duration2>() const {\n                return { point, lower_bound, upper_bound, confidence_interval };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate.hpp\n// start catch_outlier_classification.hpp\n\n// Outlier information\n\nnamespace Catch {\n    namespace Benchmark {\n        struct OutlierClassification {\n            int samples_seen = 0;\n            int low_severe = 0;     // more than 3 times IQR below Q1\n            int low_mild = 0;       // 1.5 to 3 times IQR below Q1\n            int high_mild = 0;      // 1.5 to 3 times IQR above Q3\n            int high_severe = 0;    // more than 3 times IQR above Q3\n\n            int total() const {\n                return low_severe + low_mild + high_mild + high_severe;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_outlier_classification.hpp\n\n#include <iterator>\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n#include <string>\n#include <iosfwd>\n#include <map>\n#include <set>\n#include <memory>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct ReporterConfig {\n        explicit ReporterConfig( IConfigPtr const& _fullConfig );\n\n        ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );\n\n        std::ostream& stream() const;\n        IConfigPtr fullConfig() const;\n\n    private:\n        std::ostream* m_stream;\n        IConfigPtr m_fullConfig;\n    };\n\n    struct ReporterPreferences {\n        bool shouldRedirectStdOut = false;\n        bool shouldReportAllAssertions = false;\n    };\n\n    template<typename T>\n    struct LazyStat : Option<T> {\n        LazyStat& operator=( T const& _value ) {\n            Option<T>::operator=( _value );\n            used = false;\n            return *this;\n        }\n        void reset() {\n            Option<T>::reset();\n            used = false;\n        }\n        bool used = false;\n    };\n\n    struct TestRunInfo {\n        TestRunInfo( std::string const& _name );\n        std::string name;\n    };\n    struct GroupInfo {\n        GroupInfo(  std::string const& _name,\n                    std::size_t _groupIndex,\n                    std::size_t _groupsCount );\n\n        std::string name;\n        std::size_t groupIndex;\n        std::size_t groupsCounts;\n    };\n\n    struct AssertionStats {\n        AssertionStats( AssertionResult const& _assertionResult,\n                        std::vector<MessageInfo> const& _infoMessages,\n                        Totals const& _totals );\n\n        AssertionStats( AssertionStats const& )              = default;\n        AssertionStats( AssertionStats && )                  = default;\n        AssertionStats& operator = ( AssertionStats const& ) = delete;\n        AssertionStats& operator = ( AssertionStats && )     = delete;\n        virtual ~AssertionStats();\n\n        AssertionResult assertionResult;\n        std::vector<MessageInfo> infoMessages;\n        Totals totals;\n    };\n\n    struct SectionStats {\n        SectionStats(   SectionInfo const& _sectionInfo,\n                        Counts const& _assertions,\n                        double _durationInSeconds,\n                        bool _missingAssertions );\n        SectionStats( SectionStats const& )              = default;\n        SectionStats( SectionStats && )                  = default;\n        SectionStats& operator = ( SectionStats const& ) = default;\n        SectionStats& operator = ( SectionStats && )     = default;\n        virtual ~SectionStats();\n\n        SectionInfo sectionInfo;\n        Counts assertions;\n        double durationInSeconds;\n        bool missingAssertions;\n    };\n\n    struct TestCaseStats {\n        TestCaseStats(  TestCaseInfo const& _testInfo,\n                        Totals const& _totals,\n                        std::string const& _stdOut,\n                        std::string const& _stdErr,\n                        bool _aborting );\n\n        TestCaseStats( TestCaseStats const& )              = default;\n        TestCaseStats( TestCaseStats && )                  = default;\n        TestCaseStats& operator = ( TestCaseStats const& ) = default;\n        TestCaseStats& operator = ( TestCaseStats && )     = default;\n        virtual ~TestCaseStats();\n\n        TestCaseInfo testInfo;\n        Totals totals;\n        std::string stdOut;\n        std::string stdErr;\n        bool aborting;\n    };\n\n    struct TestGroupStats {\n        TestGroupStats( GroupInfo const& _groupInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n        TestGroupStats( GroupInfo const& _groupInfo );\n\n        TestGroupStats( TestGroupStats const& )              = default;\n        TestGroupStats( TestGroupStats && )                  = default;\n        TestGroupStats& operator = ( TestGroupStats const& ) = default;\n        TestGroupStats& operator = ( TestGroupStats && )     = default;\n        virtual ~TestGroupStats();\n\n        GroupInfo groupInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    struct TestRunStats {\n        TestRunStats(   TestRunInfo const& _runInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n\n        TestRunStats( TestRunStats const& )              = default;\n        TestRunStats( TestRunStats && )                  = default;\n        TestRunStats& operator = ( TestRunStats const& ) = default;\n        TestRunStats& operator = ( TestRunStats && )     = default;\n        virtual ~TestRunStats();\n\n        TestRunInfo runInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo {\n        std::string name;\n        double estimatedDuration;\n        int iterations;\n        int samples;\n        unsigned int resamples;\n        double clockResolution;\n        double clockCost;\n    };\n\n    template <class Duration>\n    struct BenchmarkStats {\n        BenchmarkInfo info;\n\n        std::vector<Duration> samples;\n        Benchmark::Estimate<Duration> mean;\n        Benchmark::Estimate<Duration> standardDeviation;\n        Benchmark::OutlierClassification outliers;\n        double outlierVariance;\n\n        template <typename Duration2>\n        operator BenchmarkStats<Duration2>() const {\n            std::vector<Duration2> samples2;\n            samples2.reserve(samples.size());\n            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n            return {\n                info,\n                std::move(samples2),\n                mean,\n                standardDeviation,\n                outliers,\n                outlierVariance,\n            };\n        }\n    };\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IStreamingReporter {\n        virtual ~IStreamingReporter() = default;\n\n        // Implementing class must also provide the following static methods:\n        // static std::string getDescription();\n        // static std::set<Verbosity> getSupportedVerbosities()\n\n        virtual ReporterPreferences getPreferences() const = 0;\n\n        virtual void noMatchingTestCases( std::string const& spec ) = 0;\n\n        virtual void reportInvalidArguments(std::string const&) {}\n\n        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& ) {}\n        virtual void benchmarkStarting( BenchmarkInfo const& ) {}\n        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}\n        virtual void benchmarkFailed( std::string const& ) {}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;\n\n        // The return value indicates if the messages buffer should be cleared:\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;\n        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;\n\n        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;\n\n        // Default empty implementation provided\n        virtual void fatalErrorEncountered( StringRef name );\n\n        virtual bool isMulti() const;\n    };\n    using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;\n\n    struct IReporterFactory {\n        virtual ~IReporterFactory();\n        virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;\n        virtual std::string getDescription() const = 0;\n    };\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IReporterRegistry {\n        using FactoryMap = std::map<std::string, IReporterFactoryPtr>;\n        using Listeners = std::vector<IReporterFactoryPtr>;\n\n        virtual ~IReporterRegistry();\n        virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;\n        virtual FactoryMap const& getFactories() const = 0;\n        virtual Listeners const& getListeners() const = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_reporter.h\n#include <algorithm>\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n#include <ostream>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result);\n\n    // Returns double formatted as %.3f (format expected on output)\n    std::string getFormattedDuration( double duration );\n\n    //! Should the reporter show\n    bool shouldShowDuration( IConfig const& config, double duration );\n\n    std::string serializeFilters( std::vector<std::string> const& container );\n\n    template<typename DerivedT>\n    struct StreamingReporterBase : IStreamingReporter {\n\n        StreamingReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        ~StreamingReporterBase() override = default;\n\n        void noMatchingTestCases(std::string const&) override {}\n\n        void reportInvalidArguments(std::string const&) override {}\n\n        void testRunStarting(TestRunInfo const& _testRunInfo) override {\n            currentTestRunInfo = _testRunInfo;\n        }\n\n        void testGroupStarting(GroupInfo const& _groupInfo) override {\n            currentGroupInfo = _groupInfo;\n        }\n\n        void testCaseStarting(TestCaseInfo const& _testInfo) override  {\n            currentTestCaseInfo = _testInfo;\n        }\n        void sectionStarting(SectionInfo const& _sectionInfo) override {\n            m_sectionStack.push_back(_sectionInfo);\n        }\n\n        void sectionEnded(SectionStats const& /* _sectionStats */) override {\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {\n            currentTestCaseInfo.reset();\n        }\n        void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {\n            currentGroupInfo.reset();\n        }\n        void testRunEnded(TestRunStats const& /* _testRunStats */) override {\n            currentTestCaseInfo.reset();\n            currentGroupInfo.reset();\n            currentTestRunInfo.reset();\n        }\n\n        void skipTest(TestCaseInfo const&) override {\n            // Don't do anything with this by default.\n            // It can optionally be overridden in the derived class.\n        }\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n\n        LazyStat<TestRunInfo> currentTestRunInfo;\n        LazyStat<GroupInfo> currentGroupInfo;\n        LazyStat<TestCaseInfo> currentTestCaseInfo;\n\n        std::vector<SectionInfo> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<typename DerivedT>\n    struct CumulativeReporterBase : IStreamingReporter {\n        template<typename T, typename ChildNodeT>\n        struct Node {\n            explicit Node( T const& _value ) : value( _value ) {}\n            virtual ~Node() {}\n\n            using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;\n            T value;\n            ChildNodes children;\n        };\n        struct SectionNode {\n            explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}\n            virtual ~SectionNode() = default;\n\n            bool operator == (SectionNode const& other) const {\n                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;\n            }\n            bool operator == (std::shared_ptr<SectionNode> const& other) const {\n                return operator==(*other);\n            }\n\n            SectionStats stats;\n            using ChildSections = std::vector<std::shared_ptr<SectionNode>>;\n            using Assertions = std::vector<AssertionStats>;\n            ChildSections childSections;\n            Assertions assertions;\n            std::string stdOut;\n            std::string stdErr;\n        };\n\n        struct BySectionInfo {\n            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}\n            BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}\n            bool operator() (std::shared_ptr<SectionNode> const& node) const {\n                return ((node->stats.sectionInfo.name == m_other.name) &&\n                        (node->stats.sectionInfo.lineInfo == m_other.lineInfo));\n            }\n            void operator=(BySectionInfo const&) = delete;\n\n        private:\n            SectionInfo const& m_other;\n        };\n\n        using TestCaseNode = Node<TestCaseStats, SectionNode>;\n        using TestGroupNode = Node<TestGroupStats, TestCaseNode>;\n        using TestRunNode = Node<TestRunStats, TestGroupNode>;\n\n        CumulativeReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n        ~CumulativeReporterBase() override = default;\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        void testRunStarting( TestRunInfo const& ) override {}\n        void testGroupStarting( GroupInfo const& ) override {}\n\n        void testCaseStarting( TestCaseInfo const& ) override {}\n\n        void sectionStarting( SectionInfo const& sectionInfo ) override {\n            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );\n            std::shared_ptr<SectionNode> node;\n            if( m_sectionStack.empty() ) {\n                if( !m_rootSection )\n                    m_rootSection = std::make_shared<SectionNode>( incompleteStats );\n                node = m_rootSection;\n            }\n            else {\n                SectionNode& parentNode = *m_sectionStack.back();\n                auto it =\n                    std::find_if(   parentNode.childSections.begin(),\n                                    parentNode.childSections.end(),\n                                    BySectionInfo( sectionInfo ) );\n                if( it == parentNode.childSections.end() ) {\n                    node = std::make_shared<SectionNode>( incompleteStats );\n                    parentNode.childSections.push_back( node );\n                }\n                else\n                    node = *it;\n            }\n            m_sectionStack.push_back( node );\n            m_deepestSection = std::move(node);\n        }\n\n        void assertionStarting(AssertionInfo const&) override {}\n\n        bool assertionEnded(AssertionStats const& assertionStats) override {\n            assert(!m_sectionStack.empty());\n            // AssertionResult holds a pointer to a temporary DecomposedExpression,\n            // which getExpandedExpression() calls to build the expression string.\n            // Our section stack copy of the assertionResult will likely outlive the\n            // temporary, so it must be expanded or discarded now to avoid calling\n            // a destroyed object later.\n            prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );\n            SectionNode& sectionNode = *m_sectionStack.back();\n            sectionNode.assertions.push_back(assertionStats);\n            return true;\n        }\n        void sectionEnded(SectionStats const& sectionStats) override {\n            assert(!m_sectionStack.empty());\n            SectionNode& node = *m_sectionStack.back();\n            node.stats = sectionStats;\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& testCaseStats) override {\n            auto node = std::make_shared<TestCaseNode>(testCaseStats);\n            assert(m_sectionStack.size() == 0);\n            node->children.push_back(m_rootSection);\n            m_testCases.push_back(node);\n            m_rootSection.reset();\n\n            assert(m_deepestSection);\n            m_deepestSection->stdOut = testCaseStats.stdOut;\n            m_deepestSection->stdErr = testCaseStats.stdErr;\n        }\n        void testGroupEnded(TestGroupStats const& testGroupStats) override {\n            auto node = std::make_shared<TestGroupNode>(testGroupStats);\n            node->children.swap(m_testCases);\n            m_testGroups.push_back(node);\n        }\n        void testRunEnded(TestRunStats const& testRunStats) override {\n            auto node = std::make_shared<TestRunNode>(testRunStats);\n            node->children.swap(m_testGroups);\n            m_testRuns.push_back(node);\n            testRunEndedCumulative();\n        }\n        virtual void testRunEndedCumulative() = 0;\n\n        void skipTest(TestCaseInfo const&) override {}\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n        std::vector<AssertionStats> m_assertions;\n        std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;\n        std::vector<std::shared_ptr<TestCaseNode>> m_testCases;\n        std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;\n\n        std::vector<std::shared_ptr<TestRunNode>> m_testRuns;\n\n        std::shared_ptr<SectionNode> m_rootSection;\n        std::shared_ptr<SectionNode> m_deepestSection;\n        std::vector<std::shared_ptr<SectionNode>> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<char C>\n    char const* getLineOfChars() {\n        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};\n        if( !*line ) {\n            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );\n            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;\n        }\n        return line;\n    }\n\n    struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {\n        TestEventListenerBase( ReporterConfig const& _config );\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n        void assertionStarting(AssertionInfo const&) override;\n        bool assertionEnded(AssertionStats const&) override;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_bases.hpp\n// start catch_console_colour.h\n\nnamespace Catch {\n\n    struct Colour {\n        enum Code {\n            None = 0,\n\n            White,\n            Red,\n            Green,\n            Blue,\n            Cyan,\n            Yellow,\n            Grey,\n\n            Bright = 0x10,\n\n            BrightRed = Bright | Red,\n            BrightGreen = Bright | Green,\n            LightGrey = Bright | Grey,\n            BrightWhite = Bright | White,\n            BrightYellow = Bright | Yellow,\n\n            // By intention\n            FileName = LightGrey,\n            Warning = BrightYellow,\n            ResultError = BrightRed,\n            ResultSuccess = BrightGreen,\n            ResultExpectedFailure = Warning,\n\n            Error = BrightRed,\n            Success = Green,\n\n            OriginalExpression = Cyan,\n            ReconstructedExpression = BrightYellow,\n\n            SecondaryText = LightGrey,\n            Headers = White\n        };\n\n        // Use constructed object for RAII guard\n        Colour( Code _colourCode );\n        Colour( Colour&& other ) noexcept;\n        Colour& operator=( Colour&& other ) noexcept;\n        ~Colour();\n\n        // Use static method for one-shot changes\n        static void use( Code _colourCode );\n\n    private:\n        bool m_moved = false;\n    };\n\n    std::ostream& operator << ( std::ostream& os, Colour const& );\n\n} // end namespace Catch\n\n// end catch_console_colour.h\n// start catch_reporter_registrars.hpp\n\n\nnamespace Catch {\n\n    template<typename T>\n    class ReporterRegistrar {\n\n        class ReporterFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n\n            std::string getDescription() const override {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        explicit ReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );\n        }\n    };\n\n    template<typename T>\n    class ListenerRegistrar {\n\n        class ListenerFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n            std::string getDescription() const override {\n                return std::string();\n            }\n        };\n\n    public:\n\n        ListenerRegistrar() {\n            getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );\n        }\n    };\n}\n\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#define CATCH_REGISTER_REPORTER( name, reporterType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \\\n    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define CATCH_REGISTER_LISTENER( listenerType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \\\n    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#else // CATCH_CONFIG_DISABLE\n\n#define CATCH_REGISTER_REPORTER(name, reporterType)\n#define CATCH_REGISTER_LISTENER(listenerType)\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_reporter_registrars.hpp\n// Allow users to base their work off existing reporters\n// start catch_reporter_compact.h\n\nnamespace Catch {\n\n    struct CompactReporter : StreamingReporterBase<CompactReporter> {\n\n        using StreamingReporterBase::StreamingReporterBase;\n\n        ~CompactReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_compact.h\n// start catch_reporter_console.h\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    // Fwd decls\n    struct SummaryColumn;\n    class TablePrinter;\n\n    struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {\n        std::unique_ptr<TablePrinter> m_tablePrinter;\n\n        ConsoleReporter(ReporterConfig const& config);\n        ~ConsoleReporter() override;\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionStarting(SectionInfo const& _sectionInfo) override;\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const& info) override;\n        void benchmarkEnded(BenchmarkStats<> const& stats) override;\n        void benchmarkFailed(std::string const& error) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testCaseEnded(TestCaseStats const& _testCaseStats) override;\n        void testGroupEnded(TestGroupStats const& _testGroupStats) override;\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n        void testRunStarting(TestRunInfo const& _testRunInfo) override;\n    private:\n\n        void lazyPrint();\n\n        void lazyPrintWithoutClosingBenchmarkTable();\n        void lazyPrintRunInfo();\n        void lazyPrintGroupInfo();\n        void printTestCaseAndSectionHeader();\n\n        void printClosedHeader(std::string const& _name);\n        void printOpenHeader(std::string const& _name);\n\n        // if string has a : in first line will set indent to follow it on\n        // subsequent lines\n        void printHeaderString(std::string const& _string, std::size_t indent = 0);\n\n        void printTotals(Totals const& totals);\n        void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);\n\n        void printTotalsDivider(Totals const& totals);\n        void printSummaryDivider();\n        void printTestFilters();\n\n    private:\n        bool m_headerPrinted = false;\n    };\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n// end catch_reporter_console.h\n// start catch_reporter_junit.h\n\n// start catch_xmlwriter.h\n\n#include <vector>\n\nnamespace Catch {\n    enum class XmlFormatting {\n        None = 0x00,\n        Indent = 0x01,\n        Newline = 0x02,\n    };\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );\n\n        void encodeTo( std::ostream& os ) const;\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer, XmlFormatting fmt );\n\n            ScopedElement( ScopedElement&& other ) noexcept;\n            ScopedElement& operator=( ScopedElement&& other ) noexcept;\n\n            ~ScopedElement();\n\n            ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer = nullptr;\n            XmlFormatting m_fmt;\n        };\n\n        XmlWriter( std::ostream& os = Catch::cout() );\n        ~XmlWriter();\n\n        XmlWriter( XmlWriter const& ) = delete;\n        XmlWriter& operator=( XmlWriter const& ) = delete;\n\n        XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute );\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n            ReusableStringStream rss;\n            rss << attribute;\n            return writeAttribute( name, rss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        void writeStylesheetRef( std::string const& url );\n\n        XmlWriter& writeBlankLine();\n\n        void ensureTagClosed();\n\n    private:\n\n        void applyFormatting(XmlFormatting fmt);\n\n        void writeDeclaration();\n\n        void newlineIfNecessary();\n\n        bool m_tagIsOpen = false;\n        bool m_needsNewline = false;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream& m_os;\n    };\n\n}\n\n// end catch_xmlwriter.h\nnamespace Catch {\n\n    class JunitReporter : public CumulativeReporterBase<JunitReporter> {\n    public:\n        JunitReporter(ReporterConfig const& _config);\n\n        ~JunitReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& /*spec*/) override;\n\n        void testRunStarting(TestRunInfo const& runInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testCaseInfo) override;\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEndedCumulative() override;\n\n        void writeGroup(TestGroupNode const& groupNode, double suiteTime);\n\n        void writeTestCase(TestCaseNode const& testCaseNode);\n\n        void writeSection( std::string const& className,\n                           std::string const& rootName,\n                           SectionNode const& sectionNode,\n                           bool testOkToFail );\n\n        void writeAssertions(SectionNode const& sectionNode);\n        void writeAssertion(AssertionStats const& stats);\n\n        XmlWriter xml;\n        Timer suiteTimer;\n        std::string stdOutForSuite;\n        std::string stdErrForSuite;\n        unsigned int unexpectedExceptions = 0;\n        bool m_okToFail = false;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_junit.h\n// start catch_reporter_xml.h\n\nnamespace Catch {\n    class XmlReporter : public StreamingReporterBase<XmlReporter> {\n    public:\n        XmlReporter(ReporterConfig const& _config);\n\n        ~XmlReporter() override;\n\n        static std::string getDescription();\n\n        virtual std::string getStylesheetRef() const;\n\n        void writeSourceInfo(SourceLineInfo const& sourceInfo);\n\n    public: // StreamingReporterBase\n\n        void noMatchingTestCases(std::string const& s) override;\n\n        void testRunStarting(TestRunInfo const& testInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testInfo) override;\n\n        void sectionStarting(SectionInfo const& sectionInfo) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void sectionEnded(SectionStats const& sectionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEnded(TestRunStats const& testRunStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const&) override;\n        void benchmarkEnded(BenchmarkStats<> const&) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    private:\n        Timer m_testCaseTimer;\n        XmlWriter m_xml;\n        int m_sectionDepth = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_xml.h\n\n// end catch_external_interfaces.h\n#endif\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_benchmarking_all.hpp\n\n// A proxy header that includes all of the benchmarking headers to allow\n// concise include of the benchmarking features. You should prefer the\n// individual includes in standard use.\n\n// start catch_benchmark.hpp\n\n // Benchmark\n\n// start catch_chronometer.hpp\n\n// User-facing chronometer\n\n\n// start catch_clock.hpp\n\n// Clocks\n\n\n#include <chrono>\n#include <ratio>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Clock>\n        using ClockDuration = typename Clock::duration;\n        template <typename Clock>\n        using FloatDuration = std::chrono::duration<double, typename Clock::period>;\n\n        template <typename Clock>\n        using TimePoint = typename Clock::time_point;\n\n        using default_clock = std::chrono::steady_clock;\n\n        template <typename Clock>\n        struct now {\n            TimePoint<Clock> operator()() const {\n                return Clock::now();\n            }\n        };\n\n        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_clock.hpp\n// start catch_optimizer.hpp\n\n // Hinting the optimizer\n\n\n#if defined(_MSC_VER)\n#   include <atomic> // atomic_thread_fence\n#endif\n\nnamespace Catch {\n    namespace Benchmark {\n#if defined(__GNUC__) || defined(__clang__)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            asm volatile(\"\" : : \"g\"(p) : \"memory\");\n        }\n        inline void keep_memory() {\n            asm volatile(\"\" : : : \"memory\");\n        }\n\n        namespace Detail {\n            inline void optimizer_barrier() { keep_memory(); }\n        } // namespace Detail\n#elif defined(_MSC_VER)\n\n#pragma optimize(\"\", off)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            // thanks @milleniumbug\n            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);\n        }\n        // TODO equivalent keep_memory()\n#pragma optimize(\"\", on)\n\n        namespace Detail {\n            inline void optimizer_barrier() {\n                std::atomic_thread_fence(std::memory_order_seq_cst);\n            }\n        } // namespace Detail\n\n#endif\n\n        template <typename T>\n        inline void deoptimize_value(T&& x) {\n            keep_memory(&x);\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {\n            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {\n            std::forward<Fn>(fn) (std::forward<Args...>(args...));\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_optimizer.hpp\n// start catch_complete_invoke.hpp\n\n// Invoke with a special case for void\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            struct CompleteType { using type = T; };\n            template <>\n            struct CompleteType<void> { struct type {}; };\n\n            template <typename T>\n            using CompleteType_t = typename CompleteType<T>::type;\n\n            template <typename Result>\n            struct CompleteInvoker {\n                template <typename Fun, typename... Args>\n                static Result invoke(Fun&& fun, Args&&... args) {\n                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                }\n            };\n            template <>\n            struct CompleteInvoker<void> {\n                template <typename Fun, typename... Args>\n                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {\n                    std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                    return {};\n                }\n            };\n\n            // invoke and not return void :(\n            template <typename Fun, typename... Args>\n            CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {\n                return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);\n            }\n\n            const std::string benchmarkErrorMsg = \"a benchmark failed to run successfully\";\n        } // namespace Detail\n\n        template <typename Fun>\n        Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {\n            CATCH_TRY{\n                return Detail::complete_invoke(std::forward<Fun>(fun));\n            } CATCH_CATCH_ALL{\n                getResultCapture().benchmarkFailed(translateActiveException());\n                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);\n            }\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_complete_invoke.hpp\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            struct ChronometerConcept {\n                virtual void start() = 0;\n                virtual void finish() = 0;\n                virtual ~ChronometerConcept() = default;\n            };\n            template <typename Clock>\n            struct ChronometerModel final : public ChronometerConcept {\n                void start() override { started = Clock::now(); }\n                void finish() override { finished = Clock::now(); }\n\n                ClockDuration<Clock> elapsed() const { return finished - started; }\n\n                TimePoint<Clock> started;\n                TimePoint<Clock> finished;\n            };\n        } // namespace Detail\n\n        struct Chronometer {\n        public:\n            template <typename Fun>\n            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }\n\n            int runs() const { return k; }\n\n            Chronometer(Detail::ChronometerConcept& meter, int k)\n                : impl(&meter)\n                , k(k) {}\n\n        private:\n            template <typename Fun>\n            void measure(Fun&& fun, std::false_type) {\n                measure([&fun](int) { return fun(); }, std::true_type());\n            }\n\n            template <typename Fun>\n            void measure(Fun&& fun, std::true_type) {\n                Detail::optimizer_barrier();\n                impl->start();\n                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);\n                impl->finish();\n                Detail::optimizer_barrier();\n            }\n\n            Detail::ChronometerConcept* impl;\n            int k;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_chronometer.hpp\n// start catch_environment.hpp\n\n// Environment information\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct EnvironmentEstimate {\n            Duration mean;\n            OutlierClassification outliers;\n\n            template <typename Duration2>\n            operator EnvironmentEstimate<Duration2>() const {\n                return { mean, outliers };\n            }\n        };\n        template <typename Clock>\n        struct Environment {\n            using clock_type = Clock;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_environment.hpp\n// start catch_execution_plan.hpp\n\n // Execution plan\n\n\n// start catch_benchmark_function.hpp\n\n // Dumb std::function implementation for consistent call overhead\n\n\n#include <cassert>\n#include <type_traits>\n#include <utility>\n#include <memory>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            using Decay = typename std::decay<T>::type;\n            template <typename T, typename U>\n            struct is_related\n                : std::is_same<Decay<T>, Decay<U>> {};\n\n            /// We need to reinvent std::function because every piece of code that might add overhead\n            /// in a measurement context needs to have consistent performance characteristics so that we\n            /// can account for it in the measurement.\n            /// Implementations of std::function with optimizations that aren't always applicable, like\n            /// small buffer optimizations, are not uncommon.\n            /// This is effectively an implementation of std::function without any such optimizations;\n            /// it may be slow, but it is consistently slow.\n            struct BenchmarkFunction {\n            private:\n                struct callable {\n                    virtual void call(Chronometer meter) const = 0;\n                    virtual callable* clone() const = 0;\n                    virtual ~callable() = default;\n                };\n                template <typename Fun>\n                struct model : public callable {\n                    model(Fun&& fun) : fun(std::move(fun)) {}\n                    model(Fun const& fun) : fun(fun) {}\n\n                    model<Fun>* clone() const override { return new model<Fun>(*this); }\n\n                    void call(Chronometer meter) const override {\n                        call(meter, is_callable<Fun(Chronometer)>());\n                    }\n                    void call(Chronometer meter, std::true_type) const {\n                        fun(meter);\n                    }\n                    void call(Chronometer meter, std::false_type) const {\n                        meter.measure(fun);\n                    }\n\n                    Fun fun;\n                };\n\n                struct do_nothing { void operator()() const {} };\n\n                template <typename T>\n                BenchmarkFunction(model<T>* c) : f(c) {}\n\n            public:\n                BenchmarkFunction()\n                    : f(new model<do_nothing>{ {} }) {}\n\n                template <typename Fun,\n                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>\n                    BenchmarkFunction(Fun&& fun)\n                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}\n\n                BenchmarkFunction(BenchmarkFunction&& that)\n                    : f(std::move(that.f)) {}\n\n                BenchmarkFunction(BenchmarkFunction const& that)\n                    : f(that.f->clone()) {}\n\n                BenchmarkFunction& operator=(BenchmarkFunction&& that) {\n                    f = std::move(that.f);\n                    return *this;\n                }\n\n                BenchmarkFunction& operator=(BenchmarkFunction const& that) {\n                    f.reset(that.f->clone());\n                    return *this;\n                }\n\n                void operator()(Chronometer meter) const { f->call(meter); }\n\n            private:\n                std::unique_ptr<callable> f;\n            };\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_benchmark_function.hpp\n// start catch_repeat.hpp\n\n// repeat algorithm\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Fun>\n            struct repeater {\n                void operator()(int k) const {\n                    for (int i = 0; i < k; ++i) {\n                        fun();\n                    }\n                }\n                Fun fun;\n            };\n            template <typename Fun>\n            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {\n                return { std::forward<Fun>(fun) };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_repeat.hpp\n// start catch_run_for_at_least.hpp\n\n// Run a function for a minimum amount of time\n\n\n// start catch_measure.hpp\n\n// Measure\n\n\n// start catch_timing.hpp\n\n// Timing\n\n\n#include <tuple>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration, typename Result>\n        struct Timing {\n            Duration elapsed;\n            Result result;\n            int iterations;\n        };\n        template <typename Clock, typename Func, typename... Args>\n        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_timing.hpp\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun, typename... Args>\n            TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {\n                auto start = Clock::now();\n                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);\n                auto end = Clock::now();\n                auto delta = end - start;\n                return { delta, std::forward<decltype(r)>(r), 1 };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_measure.hpp\n#include <utility>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {\n                return Detail::measure<Clock>(fun, iters);\n            }\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {\n                Detail::ChronometerModel<Clock> meter;\n                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));\n\n                return { meter.elapsed(), std::move(result), iters };\n            }\n\n            template <typename Clock, typename Fun>\n            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;\n\n            struct optimized_away_error : std::exception {\n                const char* what() const noexcept override {\n                    return \"could not measure benchmark, maybe it was optimized away\";\n                }\n            };\n\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {\n                auto iters = seed;\n                while (iters < (1 << 30)) {\n                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());\n\n                    if (Timing.elapsed >= how_long) {\n                        return { Timing.elapsed, std::move(Timing.result), iters };\n                    }\n                    iters *= 2;\n                }\n                Catch::throw_exception(optimized_away_error{});\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_run_for_at_least.hpp\n#include <algorithm>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct ExecutionPlan {\n            int iterations_per_sample;\n            Duration estimated_duration;\n            Detail::BenchmarkFunction benchmark;\n            Duration warmup_time;\n            int warmup_iterations;\n\n            template <typename Duration2>\n            operator ExecutionPlan<Duration2>() const {\n                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };\n            }\n\n            template <typename Clock>\n            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                // warmup a bit\n                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));\n\n                std::vector<FloatDuration<Clock>> times;\n                times.reserve(cfg.benchmarkSamples());\n                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {\n                    Detail::ChronometerModel<Clock> model;\n                    this->benchmark(Chronometer(model, iterations_per_sample));\n                    auto sample_time = model.elapsed() - env.clock_cost.mean;\n                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();\n                    return sample_time / iterations_per_sample;\n                });\n                return times;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_execution_plan.hpp\n// start catch_estimate_clock.hpp\n\n // Environment measurement\n\n\n// start catch_stats.hpp\n\n// Statistical analysis tools\n\n\n#include <algorithm>\n#include <functional>\n#include <vector>\n#include <iterator>\n#include <numeric>\n#include <tuple>\n#include <cmath>\n#include <utility>\n#include <cstddef>\n#include <random>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            using sample = std::vector<double>;\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);\n\n            template <typename Iterator>\n            OutlierClassification classify_outliers(Iterator first, Iterator last) {\n                std::vector<double> copy(first, last);\n\n                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());\n                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());\n                auto iqr = q3 - q1;\n                auto los = q1 - (iqr * 3.);\n                auto lom = q1 - (iqr * 1.5);\n                auto him = q3 + (iqr * 1.5);\n                auto his = q3 + (iqr * 3.);\n\n                OutlierClassification o;\n                for (; first != last; ++first) {\n                    auto&& t = *first;\n                    if (t < los) ++o.low_severe;\n                    else if (t < lom) ++o.low_mild;\n                    else if (t > his) ++o.high_severe;\n                    else if (t > him) ++o.high_mild;\n                    ++o.samples_seen;\n                }\n                return o;\n            }\n\n            template <typename Iterator>\n            double mean(Iterator first, Iterator last) {\n                auto count = last - first;\n                double sum = std::accumulate(first, last, 0.);\n                return sum / count;\n            }\n\n            template <typename URng, typename Iterator, typename Estimator>\n            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {\n                auto n = last - first;\n                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);\n\n                sample out;\n                out.reserve(resamples);\n                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {\n                    std::vector<double> resampled;\n                    resampled.reserve(n);\n                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });\n                    return estimator(resampled.begin(), resampled.end());\n                });\n                std::sort(out.begin(), out.end());\n                return out;\n            }\n\n            template <typename Estimator, typename Iterator>\n            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {\n                auto n = last - first;\n                auto second = std::next(first);\n                sample results;\n                results.reserve(n);\n\n                for (auto it = first; it != last; ++it) {\n                    std::iter_swap(it, first);\n                    results.push_back(estimator(second, last));\n                }\n\n                return results;\n            }\n\n            inline double normal_cdf(double x) {\n                return std::erfc(-x / std::sqrt(2.0)) / 2.0;\n            }\n\n            double erfc_inv(double x);\n\n            double normal_quantile(double p);\n\n            template <typename Iterator, typename Estimator>\n            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {\n                auto n_samples = last - first;\n\n                double point = estimator(first, last);\n                // Degenerate case with a single sample\n                if (n_samples == 1) return { point, point, point, confidence_level };\n\n                sample jack = jackknife(estimator, first, last);\n                double jack_mean = mean(jack.begin(), jack.end());\n                double sum_squares, sum_cubes;\n                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {\n                    auto d = jack_mean - x;\n                    auto d2 = d * d;\n                    auto d3 = d2 * d;\n                    return { sqcb.first + d2, sqcb.second + d3 };\n                });\n\n                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));\n                int n = static_cast<int>(resample.size());\n                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;\n                // degenerate case with uniform samples\n                if (prob_n == 0) return { point, point, point, confidence_level };\n\n                double bias = normal_quantile(prob_n);\n                double z1 = normal_quantile((1. - confidence_level) / 2.);\n\n                auto cumn = [n](double x) -> int {\n                    return std::lround(normal_cdf(x) * n); };\n                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };\n                double b1 = bias + z1;\n                double b2 = bias - z1;\n                double a1 = a(b1);\n                double a2 = a(b2);\n                auto lo = (std::max)(cumn(a1), 0);\n                auto hi = (std::min)(cumn(a2), n - 1);\n\n                return { point, resample[lo], resample[hi], confidence_level };\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);\n\n            struct bootstrap_analysis {\n                Estimate<double> mean;\n                Estimate<double> standard_deviation;\n                double outlier_variance;\n            };\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_stats.hpp\n#include <algorithm>\n#include <iterator>\n#include <tuple>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock>\n            std::vector<double> resolution(int k) {\n                std::vector<TimePoint<Clock>> times;\n                times.reserve(k + 1);\n                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});\n\n                std::vector<double> deltas;\n                deltas.reserve(k);\n                std::transform(std::next(times.begin()), times.end(), times.begin(),\n                    std::back_inserter(deltas),\n                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });\n\n                return deltas;\n            }\n\n            const auto warmup_iterations = 10000;\n            const auto warmup_time = std::chrono::milliseconds(100);\n            const auto minimum_ticks = 1000;\n            const auto warmup_seed = 10000;\n            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);\n            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);\n            const auto clock_cost_estimation_tick_limit = 100000;\n            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);\n            const auto clock_cost_estimation_iterations = 10000;\n\n            template <typename Clock>\n            int warmup() {\n                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)\n                    .iterations;\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {\n                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)\n                    .result;\n                return {\n                    FloatDuration<Clock>(mean(r.begin(), r.end())),\n                    classify_outliers(r.begin(), r.end()),\n                };\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {\n                auto time_limit = (std::min)(\n                    resolution * clock_cost_estimation_tick_limit,\n                    FloatDuration<Clock>(clock_cost_estimation_time_limit));\n                auto time_clock = [](int k) {\n                    return Detail::measure<Clock>([k] {\n                        for (int i = 0; i < k; ++i) {\n                            volatile auto ignored = Clock::now();\n                            (void)ignored;\n                        }\n                    }).elapsed;\n                };\n                time_clock(1);\n                int iters = clock_cost_estimation_iterations;\n                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);\n                std::vector<double> times;\n                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));\n                times.reserve(nsamples);\n                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {\n                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());\n                });\n                return {\n                    FloatDuration<Clock>(mean(times.begin(), times.end())),\n                    classify_outliers(times.begin(), times.end()),\n                };\n            }\n\n            template <typename Clock>\n            Environment<FloatDuration<Clock>> measure_environment() {\n                static Environment<FloatDuration<Clock>>* env = nullptr;\n                if (env) {\n                    return *env;\n                }\n\n                auto iters = Detail::warmup<Clock>();\n                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);\n                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);\n\n                env = new Environment<FloatDuration<Clock>>{ resolution, cost };\n                return *env;\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate_clock.hpp\n// start catch_analyse.hpp\n\n // Run and analyse one benchmark\n\n\n// start catch_sample_analysis.hpp\n\n// Benchmark results\n\n\n#include <algorithm>\n#include <vector>\n#include <string>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct SampleAnalysis {\n            std::vector<Duration> samples;\n            Estimate<Duration> mean;\n            Estimate<Duration> standard_deviation;\n            OutlierClassification outliers;\n            double outlier_variance;\n\n            template <typename Duration2>\n            operator SampleAnalysis<Duration2>() const {\n                std::vector<Duration2> samples2;\n                samples2.reserve(samples.size());\n                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n                return {\n                    std::move(samples2),\n                    mean,\n                    standard_deviation,\n                    outliers,\n                    outlier_variance,\n                };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_sample_analysis.hpp\n#include <algorithm>\n#include <iterator>\n#include <vector>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Duration, typename Iterator>\n            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {\n                if (!cfg.benchmarkNoAnalysis()) {\n                    std::vector<double> samples;\n                    samples.reserve(last - first);\n                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });\n\n                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());\n                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());\n\n                    auto wrap_estimate = [](Estimate<double> e) {\n                        return Estimate<Duration> {\n                            Duration(e.point),\n                                Duration(e.lower_bound),\n                                Duration(e.upper_bound),\n                                e.confidence_interval,\n                        };\n                    };\n                    std::vector<Duration> samples2;\n                    samples2.reserve(samples.size());\n                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });\n                    return {\n                        std::move(samples2),\n                        wrap_estimate(analysis.mean),\n                        wrap_estimate(analysis.standard_deviation),\n                        outliers,\n                        analysis.outlier_variance,\n                    };\n                } else {\n                    std::vector<Duration> samples;\n                    samples.reserve(last - first);\n\n                    Duration mean = Duration(0);\n                    int i = 0;\n                    for (auto it = first; it < last; ++it, ++i) {\n                        samples.push_back(Duration(*it));\n                        mean += Duration(*it);\n                    }\n                    mean /= i;\n\n                    return {\n                        std::move(samples),\n                        Estimate<Duration>{mean, mean, mean, 0.0},\n                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},\n                        OutlierClassification{},\n                        0.0\n                    };\n                }\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_analyse.hpp\n#include <algorithm>\n#include <functional>\n#include <string>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        struct Benchmark {\n            Benchmark(std::string &&name)\n                : name(std::move(name)) {}\n\n            template <class FUN>\n            Benchmark(std::string &&name, FUN &&func)\n                : fun(std::move(func)), name(std::move(name)) {}\n\n            template <typename Clock>\n            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;\n                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));\n                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);\n                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));\n                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };\n            }\n\n            template <typename Clock = default_clock>\n            void run() {\n                IConfigPtr cfg = getCurrentContext().getConfig();\n\n                auto env = Detail::measure_environment<Clock>();\n\n                getResultCapture().benchmarkPreparing(name);\n                CATCH_TRY{\n                    auto plan = user_code([&] {\n                        return prepare<Clock>(*cfg, env);\n                    });\n\n                    BenchmarkInfo info {\n                        name,\n                        plan.estimated_duration.count(),\n                        plan.iterations_per_sample,\n                        cfg->benchmarkSamples(),\n                        cfg->benchmarkResamples(),\n                        env.clock_resolution.mean.count(),\n                        env.clock_cost.mean.count()\n                    };\n\n                    getResultCapture().benchmarkStarting(info);\n\n                    auto samples = user_code([&] {\n                        return plan.template run<Clock>(*cfg, env);\n                    });\n\n                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());\n                    BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };\n                    getResultCapture().benchmarkEnded(stats);\n\n                } CATCH_CATCH_ALL{\n                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.\n                        std::rethrow_exception(std::current_exception());\n                }\n            }\n\n            // sets lambda to be used in fun *and* executes benchmark!\n            template <typename Fun,\n                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>\n                Benchmark & operator=(Fun func) {\n                fun = Detail::BenchmarkFunction(func);\n                run();\n                return *this;\n            }\n\n            explicit operator bool() {\n                return true;\n            }\n\n        private:\n            Detail::BenchmarkFunction fun;\n            std::string name;\n        };\n    }\n} // namespace Catch\n\n#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1\n#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2\n\n#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&](int benchmarkIndex)\n\n#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&]\n\n// end catch_benchmark.hpp\n// start catch_constructor.hpp\n\n// Constructor and destructor helpers\n\n\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T, bool Destruct>\n            struct ObjectStorage\n            {\n                using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;\n\n                ObjectStorage() : data() {}\n\n                ObjectStorage(const ObjectStorage& other)\n                {\n                    new(&data) T(other.stored_object());\n                }\n\n                ObjectStorage(ObjectStorage&& other)\n                {\n                    new(&data) T(std::move(other.stored_object()));\n                }\n\n                ~ObjectStorage() { destruct_on_exit<T>(); }\n\n                template <typename... Args>\n                void construct(Args&&... args)\n                {\n                    new (&data) T(std::forward<Args>(args)...);\n                }\n\n                template <bool AllowManualDestruction = !Destruct>\n                typename std::enable_if<AllowManualDestruction>::type destruct()\n                {\n                    stored_object().~T();\n                }\n\n            private:\n                // If this is a constructor benchmark, destruct the underlying object\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }\n                // Otherwise, don't\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }\n\n                T& stored_object() {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                T const& stored_object() const {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                TStorage data;\n            };\n        }\n\n        template <typename T>\n        using storage_for = Detail::ObjectStorage<T, true>;\n\n        template <typename T>\n        using destructable_object = Detail::ObjectStorage<T, false>;\n    }\n}\n\n// end catch_constructor.hpp\n// end catch_benchmarking_all.hpp\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n#ifdef CATCH_IMPL\n// start catch_impl.hpp\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#endif\n\n// Keep these here for external reporters\n// start catch_test_case_tracker.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    struct NameAndLocation {\n        std::string name;\n        SourceLineInfo location;\n\n        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );\n        friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {\n            return lhs.name == rhs.name\n                && lhs.location == rhs.location;\n        }\n    };\n\n    class ITracker;\n\n    using ITrackerPtr = std::shared_ptr<ITracker>;\n\n    class  ITracker {\n        NameAndLocation m_nameAndLocation;\n\n    public:\n        ITracker(NameAndLocation const& nameAndLoc) :\n            m_nameAndLocation(nameAndLoc)\n        {}\n\n        // static queries\n        NameAndLocation const& nameAndLocation() const {\n            return m_nameAndLocation;\n        }\n\n        virtual ~ITracker();\n\n        // dynamic queries\n        virtual bool isComplete() const = 0; // Successfully completed or failed\n        virtual bool isSuccessfullyCompleted() const = 0;\n        virtual bool isOpen() const = 0; // Started but not complete\n        virtual bool hasChildren() const = 0;\n        virtual bool hasStarted() const = 0;\n\n        virtual ITracker& parent() = 0;\n\n        // actions\n        virtual void close() = 0; // Successfully complete\n        virtual void fail() = 0;\n        virtual void markAsNeedingAnotherRun() = 0;\n\n        virtual void addChild( ITrackerPtr const& child ) = 0;\n        virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;\n        virtual void openChild() = 0;\n\n        // Debug/ checking\n        virtual bool isSectionTracker() const = 0;\n        virtual bool isGeneratorTracker() const = 0;\n    };\n\n    class TrackerContext {\n\n        enum RunState {\n            NotStarted,\n            Executing,\n            CompletedCycle\n        };\n\n        ITrackerPtr m_rootTracker;\n        ITracker* m_currentTracker = nullptr;\n        RunState m_runState = NotStarted;\n\n    public:\n\n        ITracker& startRun();\n        void endRun();\n\n        void startCycle();\n        void completeCycle();\n\n        bool completedCycle() const;\n        ITracker& currentTracker();\n        void setCurrentTracker( ITracker* tracker );\n    };\n\n    class TrackerBase : public ITracker {\n    protected:\n        enum CycleState {\n            NotStarted,\n            Executing,\n            ExecutingChildren,\n            NeedsAnotherRun,\n            CompletedSuccessfully,\n            Failed\n        };\n\n        using Children = std::vector<ITrackerPtr>;\n        TrackerContext& m_ctx;\n        ITracker* m_parent;\n        Children m_children;\n        CycleState m_runState = NotStarted;\n\n    public:\n        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isComplete() const override;\n        bool isSuccessfullyCompleted() const override;\n        bool isOpen() const override;\n        bool hasChildren() const override;\n        bool hasStarted() const override {\n            return m_runState != NotStarted;\n        }\n\n        void addChild( ITrackerPtr const& child ) override;\n\n        ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;\n        ITracker& parent() override;\n\n        void openChild() override;\n\n        bool isSectionTracker() const override;\n        bool isGeneratorTracker() const override;\n\n        void open();\n\n        void close() override;\n        void fail() override;\n        void markAsNeedingAnotherRun() override;\n\n    private:\n        void moveToParent();\n        void moveToThis();\n    };\n\n    class SectionTracker : public TrackerBase {\n        std::vector<std::string> m_filters;\n        std::string m_trimmed_name;\n    public:\n        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isSectionTracker() const override;\n\n        bool isComplete() const override;\n\n        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );\n\n        void tryOpen();\n\n        void addInitialFilters( std::vector<std::string> const& filters );\n        void addNextFilters( std::vector<std::string> const& filters );\n        //! Returns filters active in this tracker\n        std::vector<std::string> const& getFilters() const;\n        //! Returns whitespace-trimmed name of the tracked section\n        std::string const& trimmedName() const;\n    };\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n// end catch_test_case_tracker.h\n\n// start catch_leak_detector.h\n\nnamespace Catch {\n\n    struct LeakDetector {\n        LeakDetector();\n        ~LeakDetector();\n    };\n\n}\n// end catch_leak_detector.h\n// Cpp files will be included in the single-header file here\n// start catch_stats.cpp\n\n// Statistical analysis tools\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n\n#include <cassert>\n#include <random>\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n#include <future>\n#endif\n\nnamespace {\n    double erf_inv(double x) {\n        // Code accompanying the article \"Approximating the erfinv function\" in GPU Computing Gems, Volume 2\n        double w, p;\n\n        w = -log((1.0 - x) * (1.0 + x));\n\n        if (w < 6.250000) {\n            w = w - 3.125000;\n            p = -3.6444120640178196996e-21;\n            p = -1.685059138182016589e-19 + p * w;\n            p = 1.2858480715256400167e-18 + p * w;\n            p = 1.115787767802518096e-17 + p * w;\n            p = -1.333171662854620906e-16 + p * w;\n            p = 2.0972767875968561637e-17 + p * w;\n            p = 6.6376381343583238325e-15 + p * w;\n            p = -4.0545662729752068639e-14 + p * w;\n            p = -8.1519341976054721522e-14 + p * w;\n            p = 2.6335093153082322977e-12 + p * w;\n            p = -1.2975133253453532498e-11 + p * w;\n            p = -5.4154120542946279317e-11 + p * w;\n            p = 1.051212273321532285e-09 + p * w;\n            p = -4.1126339803469836976e-09 + p * w;\n            p = -2.9070369957882005086e-08 + p * w;\n            p = 4.2347877827932403518e-07 + p * w;\n            p = -1.3654692000834678645e-06 + p * w;\n            p = -1.3882523362786468719e-05 + p * w;\n            p = 0.0001867342080340571352 + p * w;\n            p = -0.00074070253416626697512 + p * w;\n            p = -0.0060336708714301490533 + p * w;\n            p = 0.24015818242558961693 + p * w;\n            p = 1.6536545626831027356 + p * w;\n        } else if (w < 16.000000) {\n            w = sqrt(w) - 3.250000;\n            p = 2.2137376921775787049e-09;\n            p = 9.0756561938885390979e-08 + p * w;\n            p = -2.7517406297064545428e-07 + p * w;\n            p = 1.8239629214389227755e-08 + p * w;\n            p = 1.5027403968909827627e-06 + p * w;\n            p = -4.013867526981545969e-06 + p * w;\n            p = 2.9234449089955446044e-06 + p * w;\n            p = 1.2475304481671778723e-05 + p * w;\n            p = -4.7318229009055733981e-05 + p * w;\n            p = 6.8284851459573175448e-05 + p * w;\n            p = 2.4031110387097893999e-05 + p * w;\n            p = -0.0003550375203628474796 + p * w;\n            p = 0.00095328937973738049703 + p * w;\n            p = -0.0016882755560235047313 + p * w;\n            p = 0.0024914420961078508066 + p * w;\n            p = -0.0037512085075692412107 + p * w;\n            p = 0.005370914553590063617 + p * w;\n            p = 1.0052589676941592334 + p * w;\n            p = 3.0838856104922207635 + p * w;\n        } else {\n            w = sqrt(w) - 5.000000;\n            p = -2.7109920616438573243e-11;\n            p = -2.5556418169965252055e-10 + p * w;\n            p = 1.5076572693500548083e-09 + p * w;\n            p = -3.7894654401267369937e-09 + p * w;\n            p = 7.6157012080783393804e-09 + p * w;\n            p = -1.4960026627149240478e-08 + p * w;\n            p = 2.9147953450901080826e-08 + p * w;\n            p = -6.7711997758452339498e-08 + p * w;\n            p = 2.2900482228026654717e-07 + p * w;\n            p = -9.9298272942317002539e-07 + p * w;\n            p = 4.5260625972231537039e-06 + p * w;\n            p = -1.9681778105531670567e-05 + p * w;\n            p = 7.5995277030017761139e-05 + p * w;\n            p = -0.00021503011930044477347 + p * w;\n            p = -0.00013871931833623122026 + p * w;\n            p = 1.0103004648645343977 + p * w;\n            p = 4.8499064014085844221 + p * w;\n        }\n        return p * x;\n    }\n\n    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {\n        auto m = Catch::Benchmark::Detail::mean(first, last);\n        double variance = std::accumulate(first, last, 0., [m](double a, double b) {\n            double diff = b - m;\n            return a + diff * diff;\n            }) / (last - first);\n            return std::sqrt(variance);\n    }\n\n}\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                auto count = last - first;\n                double idx = (count - 1) * k / static_cast<double>(q);\n                int j = static_cast<int>(idx);\n                double g = idx - j;\n                std::nth_element(first, first + j, last);\n                auto xj = first[j];\n                if (g == 0) return xj;\n\n                auto xj1 = *std::min_element(first + (j + 1), last);\n                return xj + g * (xj1 - xj);\n            }\n\n            double erfc_inv(double x) {\n                return erf_inv(1.0 - x);\n            }\n\n            double normal_quantile(double p) {\n                static const double ROOT_TWO = std::sqrt(2.0);\n\n                double result = 0.0;\n                assert(p >= 0 && p <= 1);\n                if (p < 0 || p > 1) {\n                    return result;\n                }\n\n                result = -erfc_inv(2.0 * p);\n                // result *= normal distribution standard deviation (1.0) * sqrt(2)\n                result *= /*sd * */ ROOT_TWO;\n                // result += normal disttribution mean (0)\n                return result;\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {\n                double sb = stddev.point;\n                double mn = mean.point / n;\n                double mg_min = mn / 2.;\n                double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));\n                double sg2 = sg * sg;\n                double sb2 = sb * sb;\n\n                auto c_max = [n, mn, sb2, sg2](double x) -> double {\n                    double k = mn - x;\n                    double d = k * k;\n                    double nd = n * d;\n                    double k0 = -n * nd;\n                    double k1 = sb2 - n * sg2 + nd;\n                    double det = k1 * k1 - 4 * sg2 * k0;\n                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));\n                };\n\n                auto var_out = [n, sb2, sg2](double c) {\n                    double nc = n - c;\n                    return (nc / n) * (sb2 - nc * sg2);\n                };\n\n                return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;\n            }\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n                static std::random_device entropy;\n                CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++\n\n                auto mean = &Detail::mean<std::vector<double>::iterator>;\n                auto stddev = &standard_deviation;\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    return std::async(std::launch::async, [=] {\n                        std::mt19937 rng(seed);\n                        auto resampled = resample(rng, n_resamples, first, last, f);\n                        return bootstrap(confidence_level, first, last, resampled, f);\n                    });\n                };\n\n                auto mean_future = Estimate(mean);\n                auto stddev_future = Estimate(stddev);\n\n                auto mean_estimate = mean_future.get();\n                auto stddev_estimate = stddev_future.get();\n#else\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    std::mt19937 rng(seed);\n                    auto resampled = resample(rng, n_resamples, first, last, f);\n                    return bootstrap(confidence_level, first, last, resampled, f);\n                };\n\n                auto mean_estimate = Estimate(mean);\n                auto stddev_estimate = Estimate(stddev);\n#endif // CATCH_USE_ASYNC\n\n                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);\n\n                return { mean_estimate, stddev_estimate, outlier_variance };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n// end catch_stats.cpp\n// start catch_approx.cpp\n\n#include <cmath>\n#include <limits>\n\nnamespace {\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\n}\n\nnamespace Catch {\nnamespace Detail {\n\n    Approx::Approx ( double value )\n    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),\n        m_margin( 0.0 ),\n        m_scale( 0.0 ),\n        m_value( value )\n    {}\n\n    Approx Approx::custom() {\n        return Approx( 0 );\n    }\n\n    Approx Approx::operator-() const {\n        auto temp(*this);\n        temp.m_value = -temp.m_value;\n        return temp;\n    }\n\n    std::string Approx::toString() const {\n        ReusableStringStream rss;\n        rss << \"Approx( \" << ::Catch::Detail::stringify( m_value ) << \" )\";\n        return rss.str();\n    }\n\n    bool Approx::equalityComparisonImpl(const double other) const {\n        // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value\n        // Thanks to Richard Harris for his help refining the scaled margin value\n        return marginComparison(m_value, other, m_margin)\n            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));\n    }\n\n    void Approx::setMargin(double newMargin) {\n        CATCH_ENFORCE(newMargin >= 0,\n            \"Invalid Approx::margin: \" << newMargin << '.'\n            << \" Approx::Margin has to be non-negative.\");\n        m_margin = newMargin;\n    }\n\n    void Approx::setEpsilon(double newEpsilon) {\n        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,\n            \"Invalid Approx::epsilon: \" << newEpsilon << '.'\n            << \" Approx::epsilon has to be in [0, 1]\");\n        m_epsilon = newEpsilon;\n    }\n\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val) {\n        return Detail::Approx(val);\n    }\n    Detail::Approx operator \"\" _a(unsigned long long val) {\n        return Detail::Approx(val);\n    }\n} // end namespace literals\n\nstd::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {\n    return value.toString();\n}\n\n} // end namespace Catch\n// end catch_approx.cpp\n// start catch_assertionhandler.cpp\n\n// start catch_debugger.h\n\nnamespace Catch {\n    bool isDebuggerActive();\n}\n\n#ifdef CATCH_PLATFORM_MAC\n\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP() __asm__(\"int $3\\n\" : : ) /* NOLINT */\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd4200000\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_IPHONE)\n\n    // use inline assembler\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP()  __asm__(\"int $3\")\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd4200000\")\n    #elif defined(__arm__) && !defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xe7f001f0\")\n    #elif defined(__arm__) &&  defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xde01\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    // If we can use inline assembler, do it because this allows us to break\n    // directly at the location of the failing check instead of breaking inside\n    // raise() called from it, i.e. one stack frame below.\n    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n        #define CATCH_TRAP() asm volatile (\"int $3\") /* NOLINT */\n    #else // Fall back to the generic way.\n        #include <signal.h>\n\n        #define CATCH_TRAP() raise(SIGTRAP)\n    #endif\n#elif defined(_MSC_VER)\n    #define CATCH_TRAP() __debugbreak()\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\n    #define CATCH_TRAP() DebugBreak()\n#endif\n\n#ifndef CATCH_BREAK_INTO_DEBUGGER\n    #ifdef CATCH_TRAP\n        #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()\n    #else\n        #define CATCH_BREAK_INTO_DEBUGGER() []{}()\n    #endif\n#endif\n\n// end catch_debugger.h\n// start catch_run_context.h\n\n// start catch_fatal_condition.h\n\n#include <cassert>\n\nnamespace Catch {\n\n    // Wrapper for platform-specific fatal error (signals/SEH) handlers\n    //\n    // Tries to be cooperative with other handlers, and not step over\n    // other handlers. This means that unknown structured exceptions\n    // are passed on, previous signal handlers are called, and so on.\n    //\n    // Can only be instantiated once, and assumes that once a signal\n    // is caught, the binary will end up terminating. Thus, there\n    class FatalConditionHandler {\n        bool m_started = false;\n\n        // Install/disengage implementation for specific platform.\n        // Should be if-defed to work on current platform, can assume\n        // engage-disengage 1:1 pairing.\n        void engage_platform();\n        void disengage_platform();\n    public:\n        // Should also have platform-specific implementations as needed\n        FatalConditionHandler();\n        ~FatalConditionHandler();\n\n        void engage() {\n            assert(!m_started && \"Handler cannot be installed twice.\");\n            m_started = true;\n            engage_platform();\n        }\n\n        void disengage() {\n            assert(m_started && \"Handler cannot be uninstalled without being installed first\");\n            m_started = false;\n            disengage_platform();\n        }\n    };\n\n    //! Simple RAII guard for (dis)engaging the FatalConditionHandler\n    class FatalConditionHandlerGuard {\n        FatalConditionHandler* m_handler;\n    public:\n        FatalConditionHandlerGuard(FatalConditionHandler* handler):\n            m_handler(handler) {\n            m_handler->engage();\n        }\n        ~FatalConditionHandlerGuard() {\n            m_handler->disengage();\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_fatal_condition.h\n#include <string>\n\nnamespace Catch {\n\n    struct IMutableContext;\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class RunContext : public IResultCapture, public IRunner {\n\n    public:\n        RunContext( RunContext const& ) = delete;\n        RunContext& operator =( RunContext const& ) = delete;\n\n        explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );\n\n        ~RunContext() override;\n\n        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );\n        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );\n\n        Totals runTest(TestCase const& testCase);\n\n        IConfigPtr config() const;\n        IStreamingReporter& reporter() const;\n\n    public: // IResultCapture\n\n        // Assertion handlers\n        void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) override;\n        void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) override;\n        void handleIncomplete\n                (   AssertionInfo const& info ) override;\n        void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) override;\n\n        bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;\n\n        void sectionEnded( SectionEndInfo const& endInfo ) override;\n        void sectionEndedEarly( SectionEndInfo const& endInfo ) override;\n\n        auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing( std::string const& name ) override;\n        void benchmarkStarting( BenchmarkInfo const& info ) override;\n        void benchmarkEnded( BenchmarkStats<> const& stats ) override;\n        void benchmarkFailed( std::string const& error ) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void pushScopedMessage( MessageInfo const& message ) override;\n        void popScopedMessage( MessageInfo const& message ) override;\n\n        void emplaceUnscopedMessage( MessageBuilder const& builder ) override;\n\n        std::string getCurrentTestName() const override;\n\n        const AssertionResult* getLastResult() const override;\n\n        void exceptionEarlyReported() override;\n\n        void handleFatalErrorCondition( StringRef message ) override;\n\n        bool lastAssertionPassed() override;\n\n        void assertionPassed() override;\n\n    public:\n        // !TBD We need to do this another way!\n        bool aborting() const final;\n\n    private:\n\n        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );\n        void invokeActiveTestCase();\n\n        void resetAssertionInfo();\n        bool testForMissingAssertions( Counts& assertions );\n\n        void assertionEnded( AssertionResult const& result );\n        void reportExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    ITransientExpression const *expr,\n                    bool negated );\n\n        void populateReaction( AssertionReaction& reaction );\n\n    private:\n\n        void handleUnfinishedSections();\n\n        TestRunInfo m_runInfo;\n        IMutableContext& m_context;\n        TestCase const* m_activeTestCase = nullptr;\n        ITracker* m_testCaseTracker = nullptr;\n        Option<AssertionResult> m_lastResult;\n\n        IConfigPtr m_config;\n        Totals m_totals;\n        IStreamingReporterPtr m_reporter;\n        std::vector<MessageInfo> m_messages;\n        std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */\n        AssertionInfo m_lastAssertionInfo;\n        std::vector<SectionEndInfo> m_unfinishedSections;\n        std::vector<ITracker*> m_activeSections;\n        TrackerContext m_trackerContext;\n        FatalConditionHandler m_fatalConditionhandler;\n        bool m_lastAssertionPassed = false;\n        bool m_shouldReportUnexpected = true;\n        bool m_includeSuccessfulResults;\n    };\n\n    void seedRng(IConfig const& config);\n    unsigned int rngSeed();\n} // end namespace Catch\n\n// end catch_run_context.h\nnamespace Catch {\n\n    namespace {\n        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {\n            expr.streamReconstructedExpression( os );\n            return os;\n        }\n    }\n\n    LazyExpression::LazyExpression( bool isNegated )\n    :   m_isNegated( isNegated )\n    {}\n\n    LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}\n\n    LazyExpression::operator bool() const {\n        return m_transientExpression != nullptr;\n    }\n\n    auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {\n        if( lazyExpr.m_isNegated )\n            os << \"!\";\n\n        if( lazyExpr ) {\n            if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )\n                os << \"(\" << *lazyExpr.m_transientExpression << \")\";\n            else\n                os << *lazyExpr.m_transientExpression;\n        }\n        else {\n            os << \"{** error - unchecked empty expression requested **}\";\n        }\n        return os;\n    }\n\n    AssertionHandler::AssertionHandler\n        (   StringRef const& macroName,\n            SourceLineInfo const& lineInfo,\n            StringRef capturedExpression,\n            ResultDisposition::Flags resultDisposition )\n    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },\n        m_resultCapture( getResultCapture() )\n    {}\n\n    void AssertionHandler::handleExpr( ITransientExpression const& expr ) {\n        m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );\n    }\n    void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {\n        m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );\n    }\n\n    auto AssertionHandler::allowThrows() const -> bool {\n        return getCurrentContext().getConfig()->allowThrows();\n    }\n\n    void AssertionHandler::complete() {\n        setCompleted();\n        if( m_reaction.shouldDebugBreak ) {\n\n            // If you find your debugger stopping you here then go one level up on the\n            // call-stack for the code that caused it (typically a failed assertion)\n\n            // (To go back to the test and change execution, jump over the throw, next)\n            CATCH_BREAK_INTO_DEBUGGER();\n        }\n        if (m_reaction.shouldThrow) {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n            throw Catch::TestFailureException();\n#else\n            CATCH_ERROR( \"Test failure requires aborting test!\" );\n#endif\n        }\n    }\n    void AssertionHandler::setCompleted() {\n        m_completed = true;\n    }\n\n    void AssertionHandler::handleUnexpectedInflightException() {\n        m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );\n    }\n\n    void AssertionHandler::handleExceptionThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n    void AssertionHandler::handleExceptionNotThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    void AssertionHandler::handleUnexpectedExceptionNotThrown() {\n        m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );\n    }\n\n    void AssertionHandler::handleThrowingCallSkipped() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    // This is the overload that takes a string and infers the Equals matcher from it\n    // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {\n        handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );\n    }\n\n} // namespace Catch\n// end catch_assertionhandler.cpp\n// start catch_assertionresult.cpp\n\nnamespace Catch {\n    AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):\n        lazyExpression(_lazyExpression),\n        resultType(_resultType) {}\n\n    std::string AssertionResultData::reconstructExpression() const {\n\n        if( reconstructedExpression.empty() ) {\n            if( lazyExpression ) {\n                ReusableStringStream rss;\n                rss << lazyExpression;\n                reconstructedExpression = rss.str();\n            }\n        }\n        return reconstructedExpression;\n    }\n\n    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )\n    :   m_info( info ),\n        m_resultData( data )\n    {}\n\n    // Result was a success\n    bool AssertionResult::succeeded() const {\n        return Catch::isOk( m_resultData.resultType );\n    }\n\n    // Result was a success, or failure is suppressed\n    bool AssertionResult::isOk() const {\n        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );\n    }\n\n    ResultWas::OfType AssertionResult::getResultType() const {\n        return m_resultData.resultType;\n    }\n\n    bool AssertionResult::hasExpression() const {\n        return !m_info.capturedExpression.empty();\n    }\n\n    bool AssertionResult::hasMessage() const {\n        return !m_resultData.message.empty();\n    }\n\n    std::string AssertionResult::getExpression() const {\n        // Possibly overallocating by 3 characters should be basically free\n        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += \"!(\";\n        }\n        expr += m_info.capturedExpression;\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += ')';\n        }\n        return expr;\n    }\n\n    std::string AssertionResult::getExpressionInMacro() const {\n        std::string expr;\n        if( m_info.macroName.empty() )\n            expr = static_cast<std::string>(m_info.capturedExpression);\n        else {\n            expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );\n            expr += m_info.macroName;\n            expr += \"( \";\n            expr += m_info.capturedExpression;\n            expr += \" )\";\n        }\n        return expr;\n    }\n\n    bool AssertionResult::hasExpandedExpression() const {\n        return hasExpression() && getExpandedExpression() != getExpression();\n    }\n\n    std::string AssertionResult::getExpandedExpression() const {\n        std::string expr = m_resultData.reconstructExpression();\n        return expr.empty()\n                ? getExpression()\n                : expr;\n    }\n\n    std::string AssertionResult::getMessage() const {\n        return m_resultData.message;\n    }\n    SourceLineInfo AssertionResult::getSourceInfo() const {\n        return m_info.lineInfo;\n    }\n\n    StringRef AssertionResult::getTestMacroName() const {\n        return m_info.macroName;\n    }\n\n} // end namespace Catch\n// end catch_assertionresult.cpp\n// start catch_capture_matchers.cpp\n\nnamespace Catch {\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    // This is the general overload that takes a any string matcher\n    // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers\n    // the Equals matcher (so the header does not mention matchers)\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {\n        std::string exceptionMessage = Catch::translateActiveException();\n        MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );\n        handler.handleExpr( expr );\n    }\n\n} // namespace Catch\n// end catch_capture_matchers.cpp\n// start catch_commandline.cpp\n\n// start catch_commandline.h\n\n// start catch_clara.h\n\n// Use Catch's value for console width (store Clara's off to the side, if present)\n#ifdef CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#endif\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#pragma clang diagnostic ignored \"-Wshadow\"\n#endif\n\n// start clara.hpp\n// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// See https://github.com/philsquared/Clara for more details\n\n// Clara v1.1.5\n\n\n#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80\n#endif\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n#ifndef CLARA_CONFIG_OPTIONAL_TYPE\n#ifdef __has_include\n#if __has_include(<optional>) && __cplusplus >= 201703L\n#include <optional>\n#define CLARA_CONFIG_OPTIONAL_TYPE std::optional\n#endif\n#endif\n#endif\n\n// ----------- #included from clara_textflow.hpp -----------\n\n// TextFlowCpp\n//\n// A single-header library for wrapping and laying out basic text, by Phil Nash\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// This project is hosted at https://github.com/philsquared/textflowcpp\n\n\n#include <cassert>\n#include <ostream>\n#include <sstream>\n#include <vector>\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\nnamespace clara {\nnamespace TextFlow {\n\ninline auto isWhitespace(char c) -> bool {\n\tstatic std::string chars = \" \\t\\n\\r\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableBefore(char c) -> bool {\n\tstatic std::string chars = \"[({<|\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableAfter(char c) -> bool {\n\tstatic std::string chars = \"])}>.,:;*+-=&/\\\\\";\n\treturn chars.find(c) != std::string::npos;\n}\n\nclass Columns;\n\nclass Column {\n\tstd::vector<std::string> m_strings;\n\tsize_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;\n\tsize_t m_indent = 0;\n\tsize_t m_initialIndent = std::string::npos;\n\npublic:\n\tclass iterator {\n\t\tfriend Column;\n\n\t\tColumn const& m_column;\n\t\tsize_t m_stringIndex = 0;\n\t\tsize_t m_pos = 0;\n\n\t\tsize_t m_len = 0;\n\t\tsize_t m_end = 0;\n\t\tbool m_suffix = false;\n\n\t\titerator(Column const& column, size_t stringIndex)\n\t\t\t: m_column(column),\n\t\t\tm_stringIndex(stringIndex) {}\n\n\t\tauto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }\n\n\t\tauto isBoundary(size_t at) const -> bool {\n\t\t\tassert(at > 0);\n\t\t\tassert(at <= line().size());\n\n\t\t\treturn at == line().size() ||\n\t\t\t\t(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||\n\t\t\t\tisBreakableBefore(line()[at]) ||\n\t\t\t\tisBreakableAfter(line()[at - 1]);\n\t\t}\n\n\t\tvoid calcLength() {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\n\t\t\tm_suffix = false;\n\t\t\tauto width = m_column.m_width - indent();\n\t\t\tm_end = m_pos;\n\t\t\tif (line()[m_pos] == '\\n') {\n\t\t\t\t++m_end;\n\t\t\t}\n\t\t\twhile (m_end < line().size() && line()[m_end] != '\\n')\n\t\t\t\t++m_end;\n\n\t\t\tif (m_end < m_pos + width) {\n\t\t\t\tm_len = m_end - m_pos;\n\t\t\t} else {\n\t\t\t\tsize_t len = width;\n\t\t\t\twhile (len > 0 && !isBoundary(m_pos + len))\n\t\t\t\t\t--len;\n\t\t\t\twhile (len > 0 && isWhitespace(line()[m_pos + len - 1]))\n\t\t\t\t\t--len;\n\n\t\t\t\tif (len > 0) {\n\t\t\t\t\tm_len = len;\n\t\t\t\t} else {\n\t\t\t\t\tm_suffix = true;\n\t\t\t\t\tm_len = width - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tauto indent() const -> size_t {\n\t\t\tauto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;\n\t\t\treturn initial == std::string::npos ? m_column.m_indent : initial;\n\t\t}\n\n\t\tauto addIndentAndSuffix(std::string const &plain) const -> std::string {\n\t\t\treturn std::string(indent(), ' ') + (m_suffix ? plain + \"-\" : plain);\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Column const& column) : m_column(column) {\n\t\t\tassert(m_column.m_width > m_column.m_indent);\n\t\t\tassert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);\n\t\t\tcalcLength();\n\t\t\tif (m_len == 0)\n\t\t\t\tm_stringIndex++; // Empty string\n\t\t}\n\n\t\tauto operator *() const -> std::string {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\t\t\tassert(m_pos <= m_end);\n\t\t\treturn addIndentAndSuffix(line().substr(m_pos, m_len));\n\t\t}\n\n\t\tauto operator ++() -> iterator& {\n\t\t\tm_pos += m_len;\n\t\t\tif (m_pos < line().size() && line()[m_pos] == '\\n')\n\t\t\t\tm_pos += 1;\n\t\t\telse\n\t\t\t\twhile (m_pos < line().size() && isWhitespace(line()[m_pos]))\n\t\t\t\t\t++m_pos;\n\n\t\t\tif (m_pos == line().size()) {\n\t\t\t\tm_pos = 0;\n\t\t\t\t++m_stringIndex;\n\t\t\t}\n\t\t\tif (m_stringIndex < m_column.m_strings.size())\n\t\t\t\tcalcLength();\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn\n\t\t\t\tm_pos == other.m_pos &&\n\t\t\t\tm_stringIndex == other.m_stringIndex &&\n\t\t\t\t&m_column == &other.m_column;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn !operator==(other);\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\texplicit Column(std::string const& text) { m_strings.push_back(text); }\n\n\tauto width(size_t newWidth) -> Column& {\n\t\tassert(newWidth > 0);\n\t\tm_width = newWidth;\n\t\treturn *this;\n\t}\n\tauto indent(size_t newIndent) -> Column& {\n\t\tm_indent = newIndent;\n\t\treturn *this;\n\t}\n\tauto initialIndent(size_t newIndent) -> Column& {\n\t\tm_initialIndent = newIndent;\n\t\treturn *this;\n\t}\n\n\tauto width() const -> size_t { return m_width; }\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, m_strings.size() }; }\n\n\tinline friend std::ostream& operator << (std::ostream& os, Column const& col) {\n\t\tbool first = true;\n\t\tfor (auto line : col) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto operator + (Column const& other)->Columns;\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\nclass Spacer : public Column {\n\npublic:\n\texplicit Spacer(size_t spaceWidth) : Column(\"\") {\n\t\twidth(spaceWidth);\n\t}\n};\n\nclass Columns {\n\tstd::vector<Column> m_columns;\n\npublic:\n\n\tclass iterator {\n\t\tfriend Columns;\n\t\tstruct EndTag {};\n\n\t\tstd::vector<Column> const& m_columns;\n\t\tstd::vector<Column::iterator> m_iterators;\n\t\tsize_t m_activeIterators;\n\n\t\titerator(Columns const& columns, EndTag)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(0) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.end());\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Columns const& columns)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(m_columns.size()) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.begin());\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn m_iterators == other.m_iterators;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn m_iterators != other.m_iterators;\n\t\t}\n\t\tauto operator *() const -> std::string {\n\t\t\tstd::string row, padding;\n\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tauto width = m_columns[i].width();\n\t\t\t\tif (m_iterators[i] != m_columns[i].end()) {\n\t\t\t\t\tstd::string col = *m_iterators[i];\n\t\t\t\t\trow += padding + col;\n\t\t\t\t\tif (col.size() < width)\n\t\t\t\t\t\tpadding = std::string(width - col.size(), ' ');\n\t\t\t\t\telse\n\t\t\t\t\t\tpadding = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpadding += std::string(width, ' ');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn row;\n\t\t}\n\t\tauto operator ++() -> iterator& {\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tif (m_iterators[i] != m_columns[i].end())\n\t\t\t\t\t++m_iterators[i];\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, iterator::EndTag() }; }\n\n\tauto operator += (Column const& col) -> Columns& {\n\t\tm_columns.push_back(col);\n\t\treturn *this;\n\t}\n\tauto operator + (Column const& col) -> Columns {\n\t\tColumns combined = *this;\n\t\tcombined += col;\n\t\treturn combined;\n\t}\n\n\tinline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {\n\n\t\tbool first = true;\n\t\tfor (auto line : cols) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\ninline auto Column::operator + (Column const& other) -> Columns {\n\tColumns cols;\n\tcols += *this;\n\tcols += other;\n\treturn cols;\n}\n}\n\n}\n}\n\n// ----------- end of #include from clara_textflow.hpp -----------\n// ........... back in clara.hpp\n\n#include <cctype>\n#include <string>\n#include <memory>\n#include <set>\n#include <algorithm>\n\n#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )\n#define CATCH_PLATFORM_WINDOWS\n#endif\n\nnamespace Catch { namespace clara {\nnamespace detail {\n\n    // Traits for extracting arg and return type of lambdas (for single argument lambdas)\n    template<typename L>\n    struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};\n\n    template<typename ClassT, typename ReturnT, typename... Args>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {\n        static const bool isValid = false;\n    };\n\n    template<typename ClassT, typename ReturnT, typename ArgT>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {\n        static const bool isValid = true;\n        using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;\n        using ReturnType = ReturnT;\n    };\n\n    class TokenStream;\n\n    // Transport for raw args (copied from main args, or supplied via init list for testing)\n    class Args {\n        friend TokenStream;\n        std::string m_exeName;\n        std::vector<std::string> m_args;\n\n    public:\n        Args( int argc, char const* const* argv )\n            : m_exeName(argv[0]),\n              m_args(argv + 1, argv + argc) {}\n\n        Args( std::initializer_list<std::string> args )\n        :   m_exeName( *args.begin() ),\n            m_args( args.begin()+1, args.end() )\n        {}\n\n        auto exeName() const -> std::string {\n            return m_exeName;\n        }\n    };\n\n    // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string\n    // may encode an option + its argument if the : or = form is used\n    enum class TokenType {\n        Option, Argument\n    };\n    struct Token {\n        TokenType type;\n        std::string token;\n    };\n\n    inline auto isOptPrefix( char c ) -> bool {\n        return c == '-'\n#ifdef CATCH_PLATFORM_WINDOWS\n            || c == '/'\n#endif\n        ;\n    }\n\n    // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled\n    class TokenStream {\n        using Iterator = std::vector<std::string>::const_iterator;\n        Iterator it;\n        Iterator itEnd;\n        std::vector<Token> m_tokenBuffer;\n\n        void loadBuffer() {\n            m_tokenBuffer.resize( 0 );\n\n            // Skip any empty strings\n            while( it != itEnd && it->empty() )\n                ++it;\n\n            if( it != itEnd ) {\n                auto const &next = *it;\n                if( isOptPrefix( next[0] ) ) {\n                    auto delimiterPos = next.find_first_of( \" :=\" );\n                    if( delimiterPos != std::string::npos ) {\n                        m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );\n                        m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );\n                    } else {\n                        if( next[1] != '-' && next.size() > 2 ) {\n                            std::string opt = \"- \";\n                            for( size_t i = 1; i < next.size(); ++i ) {\n                                opt[1] = next[i];\n                                m_tokenBuffer.push_back( { TokenType::Option, opt } );\n                            }\n                        } else {\n                            m_tokenBuffer.push_back( { TokenType::Option, next } );\n                        }\n                    }\n                } else {\n                    m_tokenBuffer.push_back( { TokenType::Argument, next } );\n                }\n            }\n        }\n\n    public:\n        explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}\n\n        TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {\n            loadBuffer();\n        }\n\n        explicit operator bool() const {\n            return !m_tokenBuffer.empty() || it != itEnd;\n        }\n\n        auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }\n\n        auto operator*() const -> Token {\n            assert( !m_tokenBuffer.empty() );\n            return m_tokenBuffer.front();\n        }\n\n        auto operator->() const -> Token const * {\n            assert( !m_tokenBuffer.empty() );\n            return &m_tokenBuffer.front();\n        }\n\n        auto operator++() -> TokenStream & {\n            if( m_tokenBuffer.size() >= 2 ) {\n                m_tokenBuffer.erase( m_tokenBuffer.begin() );\n            } else {\n                if( it != itEnd )\n                    ++it;\n                loadBuffer();\n            }\n            return *this;\n        }\n    };\n\n    class ResultBase {\n    public:\n        enum Type {\n            Ok, LogicError, RuntimeError\n        };\n\n    protected:\n        ResultBase( Type type ) : m_type( type ) {}\n        virtual ~ResultBase() = default;\n\n        virtual void enforceOk() const = 0;\n\n        Type m_type;\n    };\n\n    template<typename T>\n    class ResultValueBase : public ResultBase {\n    public:\n        auto value() const -> T const & {\n            enforceOk();\n            return m_value;\n        }\n\n    protected:\n        ResultValueBase( Type type ) : ResultBase( type ) {}\n\n        ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n        }\n\n        ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {\n            new( &m_value ) T( value );\n        }\n\n        auto operator=( ResultValueBase const &other ) -> ResultValueBase & {\n            if( m_type == ResultBase::Ok )\n                m_value.~T();\n            ResultBase::operator=(other);\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n            return *this;\n        }\n\n        ~ResultValueBase() override {\n            if( m_type == Ok )\n                m_value.~T();\n        }\n\n        union {\n            T m_value;\n        };\n    };\n\n    template<>\n    class ResultValueBase<void> : public ResultBase {\n    protected:\n        using ResultBase::ResultBase;\n    };\n\n    template<typename T = void>\n    class BasicResult : public ResultValueBase<T> {\n    public:\n        template<typename U>\n        explicit BasicResult( BasicResult<U> const &other )\n        :   ResultValueBase<T>( other.type() ),\n            m_errorMessage( other.errorMessage() )\n        {\n            assert( type() != ResultBase::Ok );\n        }\n\n        template<typename U>\n        static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }\n        static auto ok() -> BasicResult { return { ResultBase::Ok }; }\n        static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }\n        static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }\n\n        explicit operator bool() const { return m_type == ResultBase::Ok; }\n        auto type() const -> ResultBase::Type { return m_type; }\n        auto errorMessage() const -> std::string { return m_errorMessage; }\n\n    protected:\n        void enforceOk() const override {\n\n            // Errors shouldn't reach this point, but if they do\n            // the actual error message will be in m_errorMessage\n            assert( m_type != ResultBase::LogicError );\n            assert( m_type != ResultBase::RuntimeError );\n            if( m_type != ResultBase::Ok )\n                std::abort();\n        }\n\n        std::string m_errorMessage; // Only populated if resultType is an error\n\n        BasicResult( ResultBase::Type type, std::string const &message )\n        :   ResultValueBase<T>(type),\n            m_errorMessage(message)\n        {\n            assert( m_type != ResultBase::Ok );\n        }\n\n        using ResultValueBase<T>::ResultValueBase;\n        using ResultBase::m_type;\n    };\n\n    enum class ParseResultType {\n        Matched, NoMatch, ShortCircuitAll, ShortCircuitSame\n    };\n\n    class ParseState {\n    public:\n\n        ParseState( ParseResultType type, TokenStream const &remainingTokens )\n        : m_type(type),\n          m_remainingTokens( remainingTokens )\n        {}\n\n        auto type() const -> ParseResultType { return m_type; }\n        auto remainingTokens() const -> TokenStream { return m_remainingTokens; }\n\n    private:\n        ParseResultType m_type;\n        TokenStream m_remainingTokens;\n    };\n\n    using Result = BasicResult<void>;\n    using ParserResult = BasicResult<ParseResultType>;\n    using InternalParseResult = BasicResult<ParseState>;\n\n    struct HelpColumns {\n        std::string left;\n        std::string right;\n    };\n\n    template<typename T>\n    inline auto convertInto( std::string const &source, T& target ) -> ParserResult {\n        std::stringstream ss;\n        ss << source;\n        ss >> target;\n        if( ss.fail() )\n            return ParserResult::runtimeError( \"Unable to convert '\" + source + \"' to destination type\" );\n        else\n            return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {\n        target = source;\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {\n        std::string srcLC = source;\n        std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );\n        if (srcLC == \"y\" || srcLC == \"1\" || srcLC == \"true\" || srcLC == \"yes\" || srcLC == \"on\")\n            target = true;\n        else if (srcLC == \"n\" || srcLC == \"0\" || srcLC == \"false\" || srcLC == \"no\" || srcLC == \"off\")\n            target = false;\n        else\n            return ParserResult::runtimeError( \"Expected a boolean value but did not recognise: '\" + source + \"'\" );\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n#ifdef CLARA_CONFIG_OPTIONAL_TYPE\n    template<typename T>\n    inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {\n        T temp;\n        auto result = convertInto( source, temp );\n        if( result )\n            target = std::move(temp);\n        return result;\n    }\n#endif // CLARA_CONFIG_OPTIONAL_TYPE\n\n    struct NonCopyable {\n        NonCopyable() = default;\n        NonCopyable( NonCopyable const & ) = delete;\n        NonCopyable( NonCopyable && ) = delete;\n        NonCopyable &operator=( NonCopyable const & ) = delete;\n        NonCopyable &operator=( NonCopyable && ) = delete;\n    };\n\n    struct BoundRef : NonCopyable {\n        virtual ~BoundRef() = default;\n        virtual auto isContainer() const -> bool { return false; }\n        virtual auto isFlag() const -> bool { return false; }\n    };\n    struct BoundValueRefBase : BoundRef {\n        virtual auto setValue( std::string const &arg ) -> ParserResult = 0;\n    };\n    struct BoundFlagRefBase : BoundRef {\n        virtual auto setFlag( bool flag ) -> ParserResult = 0;\n        virtual auto isFlag() const -> bool { return true; }\n    };\n\n    template<typename T>\n    struct BoundValueRef : BoundValueRefBase {\n        T &m_ref;\n\n        explicit BoundValueRef( T &ref ) : m_ref( ref ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return convertInto( arg, m_ref );\n        }\n    };\n\n    template<typename T>\n    struct BoundValueRef<std::vector<T>> : BoundValueRefBase {\n        std::vector<T> &m_ref;\n\n        explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}\n\n        auto isContainer() const -> bool override { return true; }\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            T temp;\n            auto result = convertInto( arg, temp );\n            if( result )\n                m_ref.push_back( temp );\n            return result;\n        }\n    };\n\n    struct BoundFlagRef : BoundFlagRefBase {\n        bool &m_ref;\n\n        explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            m_ref = flag;\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ReturnType>\n    struct LambdaInvoker {\n        static_assert( std::is_same<ReturnType, ParserResult>::value, \"Lambda must return void or clara::ParserResult\" );\n\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            return lambda( arg );\n        }\n    };\n\n    template<>\n    struct LambdaInvoker<void> {\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            lambda( arg );\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ArgType, typename L>\n    inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {\n        ArgType temp{};\n        auto result = convertInto( arg, temp );\n        return !result\n           ? result\n           : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );\n    }\n\n    template<typename L>\n    struct BoundLambda : BoundValueRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );\n        }\n    };\n\n    template<typename L>\n    struct BoundFlagLambda : BoundFlagRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, \"flags must be boolean\" );\n\n        explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );\n        }\n    };\n\n    enum class Optionality { Optional, Required };\n\n    struct Parser;\n\n    class ParserBase {\n    public:\n        virtual ~ParserBase() = default;\n        virtual auto validate() const -> Result { return Result::ok(); }\n        virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;\n        virtual auto cardinality() const -> size_t { return 1; }\n\n        auto parse( Args const &args ) const -> InternalParseResult {\n            return parse( args.exeName(), TokenStream( args ) );\n        }\n    };\n\n    template<typename DerivedT>\n    class ComposableParserImpl : public ParserBase {\n    public:\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser;\n\n\t\ttemplate<typename T>\n        auto operator+( T const &other ) const -> Parser;\n    };\n\n    // Common code and state for Args and Opts\n    template<typename DerivedT>\n    class ParserRefImpl : public ComposableParserImpl<DerivedT> {\n    protected:\n        Optionality m_optionality = Optionality::Optional;\n        std::shared_ptr<BoundRef> m_ref;\n        std::string m_hint;\n        std::string m_description;\n\n        explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}\n\n    public:\n        template<typename T>\n        ParserRefImpl( T &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),\n            m_hint( hint )\n        {}\n\n        template<typename LambdaT>\n        ParserRefImpl( LambdaT const &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),\n            m_hint(hint)\n        {}\n\n        auto operator()( std::string const &description ) -> DerivedT & {\n            m_description = description;\n            return static_cast<DerivedT &>( *this );\n        }\n\n        auto optional() -> DerivedT & {\n            m_optionality = Optionality::Optional;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto required() -> DerivedT & {\n            m_optionality = Optionality::Required;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto isOptional() const -> bool {\n            return m_optionality == Optionality::Optional;\n        }\n\n        auto cardinality() const -> size_t override {\n            if( m_ref->isContainer() )\n                return 0;\n            else\n                return 1;\n        }\n\n        auto hint() const -> std::string { return m_hint; }\n    };\n\n    class ExeName : public ComposableParserImpl<ExeName> {\n        std::shared_ptr<std::string> m_name;\n        std::shared_ptr<BoundValueRefBase> m_ref;\n\n        template<typename LambdaT>\n        static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {\n            return std::make_shared<BoundLambda<LambdaT>>( lambda) ;\n        }\n\n    public:\n        ExeName() : m_name( std::make_shared<std::string>( \"<executable>\" ) ) {}\n\n        explicit ExeName( std::string &ref ) : ExeName() {\n            m_ref = std::make_shared<BoundValueRef<std::string>>( ref );\n        }\n\n        template<typename LambdaT>\n        explicit ExeName( LambdaT const& lambda ) : ExeName() {\n            m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );\n        }\n\n        // The exe name is not parsed out of the normal tokens, but is handled specially\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n        }\n\n        auto name() const -> std::string { return *m_name; }\n        auto set( std::string const& newName ) -> ParserResult {\n\n            auto lastSlash = newName.find_last_of( \"\\\\/\" );\n            auto filename = ( lastSlash == std::string::npos )\n                    ? newName\n                    : newName.substr( lastSlash+1 );\n\n            *m_name = filename;\n            if( m_ref )\n                return m_ref->setValue( filename );\n            else\n                return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    class Arg : public ParserRefImpl<Arg> {\n    public:\n        using ParserRefImpl::ParserRefImpl;\n\n        auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            auto const &token = *remainingTokens;\n            if( token.type != TokenType::Argument )\n                return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n\n            assert( !m_ref->isFlag() );\n            auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n\n            auto result = valueRef->setValue( remainingTokens->token );\n            if( !result )\n                return InternalParseResult( result );\n            else\n                return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n        }\n    };\n\n    inline auto normaliseOpt( std::string const &optName ) -> std::string {\n#ifdef CATCH_PLATFORM_WINDOWS\n        if( optName[0] == '/' )\n            return \"-\" + optName.substr( 1 );\n        else\n#endif\n            return optName;\n    }\n\n    class Opt : public ParserRefImpl<Opt> {\n    protected:\n        std::vector<std::string> m_optNames;\n\n    public:\n        template<typename LambdaT>\n        explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}\n\n        explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}\n\n        template<typename LambdaT>\n        Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        template<typename T>\n        Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        auto operator[]( std::string const &optName ) -> Opt & {\n            m_optNames.push_back( optName );\n            return *this;\n        }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::ostringstream oss;\n            bool first = true;\n            for( auto const &opt : m_optNames ) {\n                if (first)\n                    first = false;\n                else\n                    oss << \", \";\n                oss << opt;\n            }\n            if( !m_hint.empty() )\n                oss << \" <\" << m_hint << \">\";\n            return { { oss.str(), m_description } };\n        }\n\n        auto isMatch( std::string const &optToken ) const -> bool {\n            auto normalisedToken = normaliseOpt( optToken );\n            for( auto const &name : m_optNames ) {\n                if( normaliseOpt( name ) == normalisedToken )\n                    return true;\n            }\n            return false;\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            if( remainingTokens && remainingTokens->type == TokenType::Option ) {\n                auto const &token = *remainingTokens;\n                if( isMatch(token.token ) ) {\n                    if( m_ref->isFlag() ) {\n                        auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );\n                        auto result = flagRef->setFlag( true );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    } else {\n                        auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n                        ++remainingTokens;\n                        if( !remainingTokens )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto const &argToken = *remainingTokens;\n                        if( argToken.type != TokenType::Argument )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto result = valueRef->setValue( argToken.token );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    }\n                    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n                }\n            }\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n        }\n\n        auto validate() const -> Result override {\n            if( m_optNames.empty() )\n                return Result::logicError( \"No options supplied to Opt\" );\n            for( auto const &name : m_optNames ) {\n                if( name.empty() )\n                    return Result::logicError( \"Option name cannot be empty\" );\n#ifdef CATCH_PLATFORM_WINDOWS\n                if( name[0] != '-' && name[0] != '/' )\n                    return Result::logicError( \"Option name must begin with '-' or '/'\" );\n#else\n                if( name[0] != '-' )\n                    return Result::logicError( \"Option name must begin with '-'\" );\n#endif\n            }\n            return ParserRefImpl::validate();\n        }\n    };\n\n    struct Help : Opt {\n        Help( bool &showHelpFlag )\n        :   Opt([&]( bool flag ) {\n                showHelpFlag = flag;\n                return ParserResult::ok( ParseResultType::ShortCircuitAll );\n            })\n        {\n            static_cast<Opt &>( *this )\n                    (\"display usage information\")\n                    [\"-?\"][\"-h\"][\"--help\"]\n                    .optional();\n        }\n    };\n\n    struct Parser : ParserBase {\n\n        mutable ExeName m_exeName;\n        std::vector<Opt> m_options;\n        std::vector<Arg> m_args;\n\n        auto operator|=( ExeName const &exeName ) -> Parser & {\n            m_exeName = exeName;\n            return *this;\n        }\n\n        auto operator|=( Arg const &arg ) -> Parser & {\n            m_args.push_back(arg);\n            return *this;\n        }\n\n        auto operator|=( Opt const &opt ) -> Parser & {\n            m_options.push_back(opt);\n            return *this;\n        }\n\n        auto operator|=( Parser const &other ) -> Parser & {\n            m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());\n            m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());\n            return *this;\n        }\n\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser {\n            return Parser( *this ) |= other;\n        }\n\n        // Forward deprecated interface with '+' instead of '|'\n        template<typename T>\n        auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }\n        template<typename T>\n        auto operator+( T const &other ) const -> Parser { return operator|( other ); }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::vector<HelpColumns> cols;\n            for (auto const &o : m_options) {\n                auto childCols = o.getHelpColumns();\n                cols.insert( cols.end(), childCols.begin(), childCols.end() );\n            }\n            return cols;\n        }\n\n        void writeToStream( std::ostream &os ) const {\n            if (!m_exeName.name().empty()) {\n                os << \"usage:\\n\" << \"  \" << m_exeName.name() << \" \";\n                bool required = true, first = true;\n                for( auto const &arg : m_args ) {\n                    if (first)\n                        first = false;\n                    else\n                        os << \" \";\n                    if( arg.isOptional() && required ) {\n                        os << \"[\";\n                        required = false;\n                    }\n                    os << \"<\" << arg.hint() << \">\";\n                    if( arg.cardinality() == 0 )\n                        os << \" ... \";\n                }\n                if( !required )\n                    os << \"]\";\n                if( !m_options.empty() )\n                    os << \" options\";\n                os << \"\\n\\nwhere options are:\" << std::endl;\n            }\n\n            auto rows = getHelpColumns();\n            size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;\n            size_t optWidth = 0;\n            for( auto const &cols : rows )\n                optWidth = (std::max)(optWidth, cols.left.size() + 2);\n\n            optWidth = (std::min)(optWidth, consoleWidth/2);\n\n            for( auto const &cols : rows ) {\n                auto row =\n                        TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +\n                        TextFlow::Spacer(4) +\n                        TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );\n                os << row << std::endl;\n            }\n        }\n\n        friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {\n            parser.writeToStream( os );\n            return os;\n        }\n\n        auto validate() const -> Result override {\n            for( auto const &opt : m_options ) {\n                auto result = opt.validate();\n                if( !result )\n                    return result;\n            }\n            for( auto const &arg : m_args ) {\n                auto result = arg.validate();\n                if( !result )\n                    return result;\n            }\n            return Result::ok();\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {\n\n            struct ParserInfo {\n                ParserBase const* parser = nullptr;\n                size_t count = 0;\n            };\n            const size_t totalParsers = m_options.size() + m_args.size();\n            assert( totalParsers < 512 );\n            // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do\n            ParserInfo parseInfos[512];\n\n            {\n                size_t i = 0;\n                for (auto const &opt : m_options) parseInfos[i++].parser = &opt;\n                for (auto const &arg : m_args) parseInfos[i++].parser = &arg;\n            }\n\n            m_exeName.set( exeName );\n\n            auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n            while( result.value().remainingTokens() ) {\n                bool tokenParsed = false;\n\n                for( size_t i = 0; i < totalParsers; ++i ) {\n                    auto&  parseInfo = parseInfos[i];\n                    if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {\n                        result = parseInfo.parser->parse(exeName, result.value().remainingTokens());\n                        if (!result)\n                            return result;\n                        if (result.value().type() != ParseResultType::NoMatch) {\n                            tokenParsed = true;\n                            ++parseInfo.count;\n                            break;\n                        }\n                    }\n                }\n\n                if( result.value().type() == ParseResultType::ShortCircuitAll )\n                    return result;\n                if( !tokenParsed )\n                    return InternalParseResult::runtimeError( \"Unrecognised token: \" + result.value().remainingTokens()->token );\n            }\n            // !TBD Check missing required options\n            return result;\n        }\n    };\n\n    template<typename DerivedT>\n    template<typename T>\n    auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {\n        return Parser() | static_cast<DerivedT const &>( *this ) | other;\n    }\n} // namespace detail\n\n// A Combined parser\nusing detail::Parser;\n\n// A parser for options\nusing detail::Opt;\n\n// A parser for arguments\nusing detail::Arg;\n\n// Wrapper for argc, argv from main()\nusing detail::Args;\n\n// Specifies the name of the executable\nusing detail::ExeName;\n\n// Convenience wrapper for option parser that specifies the help option\nusing detail::Help;\n\n// enum of result types from a parse\nusing detail::ParseResultType;\n\n// Result type for parser operation\nusing detail::ParserResult;\n\n}} // namespace Catch::clara\n\n// end clara.hpp\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// Restore Clara's value for console width, if present\n#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n// end catch_clara.h\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config );\n\n} // end namespace Catch\n\n// end catch_commandline.h\n#include <fstream>\n#include <ctime>\n\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config ) {\n\n        using namespace clara;\n\n        auto const setWarning = [&]( std::string const& warning ) {\n                auto warningSet = [&]() {\n                    if( warning == \"NoAssertions\" )\n                        return WarnAbout::NoAssertions;\n\n                    if ( warning == \"NoTests\" )\n                        return WarnAbout::NoTests;\n\n                    return WarnAbout::Nothing;\n                }();\n\n                if (warningSet == WarnAbout::Nothing)\n                    return ParserResult::runtimeError( \"Unrecognised warning: '\" + warning + \"'\" );\n                config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const loadTestNamesFromFile = [&]( std::string const& filename ) {\n                std::ifstream f( filename.c_str() );\n                if( !f.is_open() )\n                    return ParserResult::runtimeError( \"Unable to load input file: '\" + filename + \"'\" );\n\n                std::string line;\n                while( std::getline( f, line ) ) {\n                    line = trim(line);\n                    if( !line.empty() && !startsWith( line, '#' ) ) {\n                        if( !startsWith( line, '\"' ) )\n                            line = '\"' + line + '\"';\n                        config.testsOrTags.push_back( line );\n                        config.testsOrTags.emplace_back( \",\" );\n                    }\n                }\n                //Remove comma in the end\n                if(!config.testsOrTags.empty())\n                    config.testsOrTags.erase( config.testsOrTags.end()-1 );\n\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setTestOrder = [&]( std::string const& order ) {\n                if( startsWith( \"declared\", order ) )\n                    config.runOrder = RunTests::InDeclarationOrder;\n                else if( startsWith( \"lexical\", order ) )\n                    config.runOrder = RunTests::InLexicographicalOrder;\n                else if( startsWith( \"random\", order ) )\n                    config.runOrder = RunTests::InRandomOrder;\n                else\n                    return clara::ParserResult::runtimeError( \"Unrecognised ordering: '\" + order + \"'\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setRngSeed = [&]( std::string const& seed ) {\n                if( seed != \"time\" )\n                    return clara::detail::convertInto( seed, config.rngSeed );\n                config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setColourUsage = [&]( std::string const& useColour ) {\n                    auto mode = toLower( useColour );\n\n                    if( mode == \"yes\" )\n                        config.useColour = UseColour::Yes;\n                    else if( mode == \"no\" )\n                        config.useColour = UseColour::No;\n                    else if( mode == \"auto\" )\n                        config.useColour = UseColour::Auto;\n                    else\n                        return ParserResult::runtimeError( \"colour mode must be one of: auto, yes or no. '\" + useColour + \"' not recognised\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setWaitForKeypress = [&]( std::string const& keypress ) {\n                auto keypressLc = toLower( keypress );\n                if (keypressLc == \"never\")\n                    config.waitForKeypress = WaitForKeypress::Never;\n                else if( keypressLc == \"start\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStart;\n                else if( keypressLc == \"exit\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeExit;\n                else if( keypressLc == \"both\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;\n                else\n                    return ParserResult::runtimeError( \"keypress argument must be one of: never, start, exit or both. '\" + keypress + \"' not recognised\" );\n            return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setVerbosity = [&]( std::string const& verbosity ) {\n            auto lcVerbosity = toLower( verbosity );\n            if( lcVerbosity == \"quiet\" )\n                config.verbosity = Verbosity::Quiet;\n            else if( lcVerbosity == \"normal\" )\n                config.verbosity = Verbosity::Normal;\n            else if( lcVerbosity == \"high\" )\n                config.verbosity = Verbosity::High;\n            else\n                return ParserResult::runtimeError( \"Unrecognised verbosity, '\" + verbosity + \"'\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n        auto const setReporter = [&]( std::string const& reporter ) {\n            IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n\n            auto lcReporter = toLower( reporter );\n            auto result = factories.find( lcReporter );\n\n            if( factories.end() != result )\n                config.reporterName = lcReporter;\n            else\n                return ParserResult::runtimeError( \"Unrecognized reporter, '\" + reporter + \"'. Check available with --list-reporters\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n\n        auto cli\n            = ExeName( config.processName )\n            | Help( config.showHelp )\n            | Opt( config.listTests )\n                [\"-l\"][\"--list-tests\"]\n                ( \"list all/matching test cases\" )\n            | Opt( config.listTags )\n                [\"-t\"][\"--list-tags\"]\n                ( \"list all/matching tags\" )\n            | Opt( config.showSuccessfulTests )\n                [\"-s\"][\"--success\"]\n                ( \"include successful tests in output\" )\n            | Opt( config.shouldDebugBreak )\n                [\"-b\"][\"--break\"]\n                ( \"break into debugger on failure\" )\n            | Opt( config.noThrow )\n                [\"-e\"][\"--nothrow\"]\n                ( \"skip exception tests\" )\n            | Opt( config.showInvisibles )\n                [\"-i\"][\"--invisibles\"]\n                ( \"show invisibles (tabs, newlines)\" )\n            | Opt( config.outputFilename, \"filename\" )\n                [\"-o\"][\"--out\"]\n                ( \"output filename\" )\n            | Opt( setReporter, \"name\" )\n                [\"-r\"][\"--reporter\"]\n                ( \"reporter to use (defaults to console)\" )\n            | Opt( config.name, \"name\" )\n                [\"-n\"][\"--name\"]\n                ( \"suite name\" )\n            | Opt( [&]( bool ){ config.abortAfter = 1; } )\n                [\"-a\"][\"--abort\"]\n                ( \"abort at first failure\" )\n            | Opt( [&]( int x ){ config.abortAfter = x; }, \"no. failures\" )\n                [\"-x\"][\"--abortx\"]\n                ( \"abort after x failures\" )\n            | Opt( setWarning, \"warning name\" )\n                [\"-w\"][\"--warn\"]\n                ( \"enable warnings\" )\n            | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, \"yes|no\" )\n                [\"-d\"][\"--durations\"]\n                ( \"show test durations\" )\n            | Opt( config.minDuration, \"seconds\" )\n                [\"-D\"][\"--min-duration\"]\n                ( \"show test durations for tests taking at least the given number of seconds\" )\n            | Opt( loadTestNamesFromFile, \"filename\" )\n                [\"-f\"][\"--input-file\"]\n                ( \"load test names to run from a file\" )\n            | Opt( config.filenamesAsTags )\n                [\"-#\"][\"--filenames-as-tags\"]\n                ( \"adds a tag for the filename\" )\n            | Opt( config.sectionsToRun, \"section name\" )\n                [\"-c\"][\"--section\"]\n                ( \"specify section to run\" )\n            | Opt( setVerbosity, \"quiet|normal|high\" )\n                [\"-v\"][\"--verbosity\"]\n                ( \"set output verbosity\" )\n            | Opt( config.listTestNamesOnly )\n                [\"--list-test-names-only\"]\n                ( \"list all/matching test cases names only\" )\n            | Opt( config.listReporters )\n                [\"--list-reporters\"]\n                ( \"list all reporters\" )\n            | Opt( setTestOrder, \"decl|lex|rand\" )\n                [\"--order\"]\n                ( \"test case order (defaults to decl)\" )\n            | Opt( setRngSeed, \"'time'|number\" )\n                [\"--rng-seed\"]\n                ( \"set a specific seed for random numbers\" )\n            | Opt( setColourUsage, \"yes|no\" )\n                [\"--use-colour\"]\n                ( \"should output be colourised\" )\n            | Opt( config.libIdentify )\n                [\"--libidentify\"]\n                ( \"report name and version according to libidentify standard\" )\n            | Opt( setWaitForKeypress, \"never|start|exit|both\" )\n                [\"--wait-for-keypress\"]\n                ( \"waits for a keypress before exiting\" )\n            | Opt( config.benchmarkSamples, \"samples\" )\n                [\"--benchmark-samples\"]\n                ( \"number of samples to collect (default: 100)\" )\n            | Opt( config.benchmarkResamples, \"resamples\" )\n                [\"--benchmark-resamples\"]\n                ( \"number of resamples for the bootstrap (default: 100000)\" )\n            | Opt( config.benchmarkConfidenceInterval, \"confidence interval\" )\n                [\"--benchmark-confidence-interval\"]\n                ( \"confidence interval for the bootstrap (between 0 and 1, default: 0.95)\" )\n            | Opt( config.benchmarkNoAnalysis )\n                [\"--benchmark-no-analysis\"]\n                ( \"perform only measurements; do not perform any analysis\" )\n            | Opt( config.benchmarkWarmupTime, \"benchmarkWarmupTime\" )\n                [\"--benchmark-warmup-time\"]\n                ( \"amount of time in milliseconds spent on warming up each test (default: 100)\" )\n            | Arg( config.testsOrTags, \"test name|pattern|tags\" )\n                ( \"which test or tests to use\" );\n\n        return cli;\n    }\n\n} // end namespace Catch\n// end catch_commandline.cpp\n// start catch_common.cpp\n\n#include <cstring>\n#include <ostream>\n\nnamespace Catch {\n\n    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {\n        return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);\n    }\n    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {\n        // We can assume that the same file will usually have the same pointer.\n        // Thus, if the pointers are the same, there is no point in calling the strcmp\n        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));\n    }\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {\n#ifndef __GNUG__\n        os << info.file << '(' << info.line << ')';\n#else\n        os << info.file << ':' << info.line;\n#endif\n        return os;\n    }\n\n    std::string StreamEndStop::operator+() const {\n        return std::string();\n    }\n\n    NonCopyable::NonCopyable() = default;\n    NonCopyable::~NonCopyable() = default;\n\n}\n// end catch_common.cpp\n// start catch_config.cpp\n\nnamespace Catch {\n\n    Config::Config( ConfigData const& data )\n    :   m_data( data ),\n        m_stream( openStream() )\n    {\n        // We need to trim filter specs to avoid trouble with superfluous\n        // whitespace (esp. important for bdd macros, as those are manually\n        // aligned with whitespace).\n\n        for (auto& elem : m_data.testsOrTags) {\n            elem = trim(elem);\n        }\n        for (auto& elem : m_data.sectionsToRun) {\n            elem = trim(elem);\n        }\n\n        TestSpecParser parser(ITagAliasRegistry::get());\n        if (!m_data.testsOrTags.empty()) {\n            m_hasTestFilters = true;\n            for (auto const& testOrTags : m_data.testsOrTags) {\n                parser.parse(testOrTags);\n            }\n        }\n        m_testSpec = parser.testSpec();\n    }\n\n    std::string const& Config::getFilename() const {\n        return m_data.outputFilename ;\n    }\n\n    bool Config::listTests() const          { return m_data.listTests; }\n    bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }\n    bool Config::listTags() const           { return m_data.listTags; }\n    bool Config::listReporters() const      { return m_data.listReporters; }\n\n    std::string Config::getProcessName() const { return m_data.processName; }\n    std::string const& Config::getReporterName() const { return m_data.reporterName; }\n\n    std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }\n    std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }\n\n    TestSpec const& Config::testSpec() const { return m_testSpec; }\n    bool Config::hasTestFilters() const { return m_hasTestFilters; }\n\n    bool Config::showHelp() const { return m_data.showHelp; }\n\n    // IConfig interface\n    bool Config::allowThrows() const                   { return !m_data.noThrow; }\n    std::ostream& Config::stream() const               { return m_stream->stream(); }\n    std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }\n    bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }\n    bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }\n    bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }\n    ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }\n    double Config::minDuration() const                 { return m_data.minDuration; }\n    RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }\n    unsigned int Config::rngSeed() const               { return m_data.rngSeed; }\n    UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }\n    bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }\n    int Config::abortAfter() const                     { return m_data.abortAfter; }\n    bool Config::showInvisibles() const                { return m_data.showInvisibles; }\n    Verbosity Config::verbosity() const                { return m_data.verbosity; }\n\n    bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }\n    int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }\n    double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }\n    unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }\n    std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }\n\n    IStream const* Config::openStream() {\n        return Catch::makeStream(m_data.outputFilename);\n    }\n\n} // end namespace Catch\n// end catch_config.cpp\n// start catch_console_colour.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\n// start catch_errno_guard.h\n\nnamespace Catch {\n\n    class ErrnoGuard {\n    public:\n        ErrnoGuard();\n        ~ErrnoGuard();\n    private:\n        int m_oldErrno;\n    };\n\n}\n\n// end catch_errno_guard.h\n// start catch_windows_h_proxy.h\n\n\n#if defined(CATCH_PLATFORM_WINDOWS)\n\n#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)\n#  define CATCH_DEFINED_NOMINMAX\n#  define NOMINMAX\n#endif\n#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)\n#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef CATCH_DEFINED_NOMINMAX\n#  undef NOMINMAX\n#endif\n#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  undef WIN32_LEAN_AND_MEAN\n#endif\n\n#endif // defined(CATCH_PLATFORM_WINDOWS)\n\n// end catch_windows_h_proxy.h\n#include <sstream>\n\nnamespace Catch {\n    namespace {\n\n        struct IColourImpl {\n            virtual ~IColourImpl() = default;\n            virtual void use( Colour::Code _colourCode ) = 0;\n        };\n\n        struct NoColourImpl : IColourImpl {\n            void use( Colour::Code ) override {}\n\n            static IColourImpl* instance() {\n                static NoColourImpl s_instance;\n                return &s_instance;\n            }\n        };\n\n    } // anon namespace\n} // namespace Catch\n\n#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )\n#   ifdef CATCH_PLATFORM_WINDOWS\n#       define CATCH_CONFIG_COLOUR_WINDOWS\n#   else\n#       define CATCH_CONFIG_COLOUR_ANSI\n#   endif\n#endif\n\n#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////\n\nnamespace Catch {\nnamespace {\n\n    class Win32ColourImpl : public IColourImpl {\n    public:\n        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )\n        {\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );\n            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );\n            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );\n        }\n\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:      return setTextAttribute( originalForegroundAttributes );\n                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );\n                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );\n                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );\n                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );\n                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );\n                case Colour::Grey:      return setTextAttribute( 0 );\n\n                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );\n                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );\n                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );\n                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n\n                default:\n                    CATCH_ERROR( \"Unknown colour requested\" );\n            }\n        }\n\n    private:\n        void setTextAttribute( WORD _textAttribute ) {\n            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );\n        }\n        HANDLE stdoutHandle;\n        WORD originalForegroundAttributes;\n        WORD originalBackgroundAttributes;\n    };\n\n    IColourImpl* platformColourInstance() {\n        static Win32ColourImpl s_instance;\n\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = UseColour::Yes;\n        return colourMode == UseColour::Yes\n            ? &s_instance\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////\n\n#include <unistd.h>\n\nnamespace Catch {\nnamespace {\n\n    // use POSIX/ ANSI console terminal codes\n    // Thanks to Adam Strzelecki for original contribution\n    // (http://github.com/nanoant)\n    // https://github.com/philsquared/Catch/pull/131\n    class PosixColourImpl : public IColourImpl {\n    public:\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:\n                case Colour::White:     return setColour( \"[0m\" );\n                case Colour::Red:       return setColour( \"[0;31m\" );\n                case Colour::Green:     return setColour( \"[0;32m\" );\n                case Colour::Blue:      return setColour( \"[0;34m\" );\n                case Colour::Cyan:      return setColour( \"[0;36m\" );\n                case Colour::Yellow:    return setColour( \"[0;33m\" );\n                case Colour::Grey:      return setColour( \"[1;30m\" );\n\n                case Colour::LightGrey:     return setColour( \"[0;37m\" );\n                case Colour::BrightRed:     return setColour( \"[1;31m\" );\n                case Colour::BrightGreen:   return setColour( \"[1;32m\" );\n                case Colour::BrightWhite:   return setColour( \"[1;37m\" );\n                case Colour::BrightYellow:  return setColour( \"[1;33m\" );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n                default: CATCH_INTERNAL_ERROR( \"Unknown colour requested\" );\n            }\n        }\n        static IColourImpl* instance() {\n            static PosixColourImpl s_instance;\n            return &s_instance;\n        }\n\n    private:\n        void setColour( const char* _escapeCode ) {\n            getCurrentContext().getConfig()->stream()\n                << '\\033' << _escapeCode;\n        }\n    };\n\n    bool useColourOnPlatform() {\n        return\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n            !isDebuggerActive() &&\n#endif\n#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))\n            isatty(STDOUT_FILENO)\n#else\n            false\n#endif\n            ;\n    }\n    IColourImpl* platformColourInstance() {\n        ErrnoGuard guard;\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = useColourOnPlatform()\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? PosixColourImpl::instance()\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#else  // not Windows or ANSI ///////////////////////////////////////////////\n\nnamespace Catch {\n\n    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }\n\n} // end namespace Catch\n\n#endif // Windows/ ANSI/ None\n\nnamespace Catch {\n\n    Colour::Colour( Code _colourCode ) { use( _colourCode ); }\n    Colour::Colour( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved = true;\n    }\n    Colour& Colour::operator=( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved  = true;\n        return *this;\n    }\n\n    Colour::~Colour(){ if( !m_moved ) use( None ); }\n\n    void Colour::use( Code _colourCode ) {\n        static IColourImpl* impl = platformColourInstance();\n        // Strictly speaking, this cannot possibly happen.\n        // However, under some conditions it does happen (see #1626),\n        // and this change is small enough that we can let practicality\n        // triumph over purity in this case.\n        if (impl != nullptr) {\n            impl->use( _colourCode );\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, Colour const& ) {\n        return os;\n    }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_console_colour.cpp\n// start catch_context.cpp\n\nnamespace Catch {\n\n    class Context : public IMutableContext, NonCopyable {\n\n    public: // IContext\n        IResultCapture* getResultCapture() override {\n            return m_resultCapture;\n        }\n        IRunner* getRunner() override {\n            return m_runner;\n        }\n\n        IConfigPtr const& getConfig() const override {\n            return m_config;\n        }\n\n        ~Context() override;\n\n    public: // IMutableContext\n        void setResultCapture( IResultCapture* resultCapture ) override {\n            m_resultCapture = resultCapture;\n        }\n        void setRunner( IRunner* runner ) override {\n            m_runner = runner;\n        }\n        void setConfig( IConfigPtr const& config ) override {\n            m_config = config;\n        }\n\n        friend IMutableContext& getCurrentMutableContext();\n\n    private:\n        IConfigPtr m_config;\n        IRunner* m_runner = nullptr;\n        IResultCapture* m_resultCapture = nullptr;\n    };\n\n    IMutableContext *IMutableContext::currentContext = nullptr;\n\n    void IMutableContext::createContext()\n    {\n        currentContext = new Context();\n    }\n\n    void cleanUpContext() {\n        delete IMutableContext::currentContext;\n        IMutableContext::currentContext = nullptr;\n    }\n    IContext::~IContext() = default;\n    IMutableContext::~IMutableContext() = default;\n    Context::~Context() = default;\n\n    SimplePcg32& rng() {\n        static SimplePcg32 s_rng;\n        return s_rng;\n    }\n\n}\n// end catch_context.cpp\n// start catch_debug_console.cpp\n\n// start catch_debug_console.h\n\n#include <string>\n\nnamespace Catch {\n    void writeToDebugConsole( std::string const& text );\n}\n\n// end catch_debug_console.h\n#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#include <android/log.h>\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            __android_log_write( ANDROID_LOG_DEBUG, \"Catch\", text.c_str() );\n        }\n    }\n\n#elif defined(CATCH_PLATFORM_WINDOWS)\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            ::OutputDebugStringA( text.c_str() );\n        }\n    }\n\n#else\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            // !TBD: Need a version for Mac/ XCode and other IDEs\n            Catch::cout() << text;\n        }\n    }\n\n#endif // Platform\n// end catch_debug_console.cpp\n// start catch_debugger.cpp\n\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n\n#  include <cassert>\n#  include <sys/types.h>\n#  include <unistd.h>\n#  include <cstddef>\n#  include <ostream>\n\n#ifdef __apple_build_version__\n    // These headers will only compile with AppleClang (XCode)\n    // For other compilers (Clang, GCC, ... ) we need to exclude them\n#  include <sys/sysctl.h>\n#endif\n\n    namespace Catch {\n        #ifdef __apple_build_version__\n        // The following function is taken directly from the following technical note:\n        // https://developer.apple.com/library/archive/qa/qa1361/_index.html\n\n        // Returns true if the current process is being debugged (either\n        // running under the debugger or has a debugger attached post facto).\n        bool isDebuggerActive(){\n            int                 mib[4];\n            struct kinfo_proc   info;\n            std::size_t         size;\n\n            // Initialize the flags so that, if sysctl fails for some bizarre\n            // reason, we get a predictable result.\n\n            info.kp_proc.p_flag = 0;\n\n            // Initialize mib, which tells sysctl the info we want, in this case\n            // we're looking for information about a specific process ID.\n\n            mib[0] = CTL_KERN;\n            mib[1] = KERN_PROC;\n            mib[2] = KERN_PROC_PID;\n            mib[3] = getpid();\n\n            // Call sysctl.\n\n            size = sizeof(info);\n            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {\n                Catch::cerr() << \"\\n** Call to sysctl failed - unable to determine if debugger is active **\\n\" << std::endl;\n                return false;\n            }\n\n            // We're being debugged if the P_TRACED flag is set.\n\n            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n        }\n        #else\n        bool isDebuggerActive() {\n            // We need to find another way to determine this for non-appleclang compilers on macOS\n            return false;\n        }\n        #endif\n    } // namespace Catch\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    #include <fstream>\n    #include <string>\n\n    namespace Catch{\n        // The standard POSIX way of detecting a debugger is to attempt to\n        // ptrace() the process, but this needs to be done from a child and not\n        // this process itself to still allow attaching to this process later\n        // if wanted, so is rather heavy. Under Linux we have the PID of the\n        // \"debugger\" (which doesn't need to be gdb, of course, it could also\n        // be strace, for example) in /proc/$PID/status, so just get it from\n        // there instead.\n        bool isDebuggerActive(){\n            // Libstdc++ has a bug, where std::ifstream sets errno to 0\n            // This way our users can properly assert over errno values\n            ErrnoGuard guard;\n            std::ifstream in(\"/proc/self/status\");\n            for( std::string line; std::getline(in, line); ) {\n                static const int PREFIX_LEN = 11;\n                if( line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0 ) {\n                    // We're traced if the PID is not 0 and no other PID starts\n                    // with 0 digit, so it's enough to check for just a single\n                    // character.\n                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n                }\n            }\n\n            return false;\n        }\n    } // namespace Catch\n#elif defined(_MSC_VER)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#else\n    namespace Catch {\n       bool isDebuggerActive() { return false; }\n    }\n#endif // Platform\n// end catch_debugger.cpp\n// start catch_decomposer.cpp\n\nnamespace Catch {\n\n    ITransientExpression::~ITransientExpression() = default;\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {\n        if( lhs.size() + rhs.size() < 40 &&\n                lhs.find('\\n') == std::string::npos &&\n                rhs.find('\\n') == std::string::npos )\n            os << lhs << \" \" << op << \" \" << rhs;\n        else\n            os << lhs << \"\\n\" << op << \"\\n\" << rhs;\n    }\n}\n// end catch_decomposer.cpp\n// start catch_enforce.cpp\n\n#include <stdexcept>\n\nnamespace Catch {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)\n    [[noreturn]]\n    void throw_exception(std::exception const& e) {\n        Catch::cerr() << \"Catch will terminate because it needed to throw an exception.\\n\"\n                      << \"The message was: \" << e.what() << '\\n';\n        std::terminate();\n    }\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg) {\n        throw_exception(std::logic_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg) {\n        throw_exception(std::domain_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg) {\n        throw_exception(std::runtime_error(msg));\n    }\n\n} // namespace Catch;\n// end catch_enforce.cpp\n// start catch_enum_values_registry.cpp\n// start catch_enum_values_registry.h\n\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    namespace Detail {\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );\n\n        class EnumValuesRegistry : public IMutableEnumValuesRegistry {\n\n            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;\n\n            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;\n        };\n\n        std::vector<StringRef> parseEnums( StringRef enums );\n\n    } // Detail\n\n} // Catch\n\n// end catch_enum_values_registry.h\n\n#include <map>\n#include <cassert>\n\nnamespace Catch {\n\n    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}\n\n    namespace Detail {\n\n        namespace {\n            // Extracts the actual name part of an enum instance\n            // In other words, it returns the Blue part of Bikeshed::Colour::Blue\n            StringRef extractInstanceName(StringRef enumInstance) {\n                // Find last occurrence of \":\"\n                size_t name_start = enumInstance.size();\n                while (name_start > 0 && enumInstance[name_start - 1] != ':') {\n                    --name_start;\n                }\n                return enumInstance.substr(name_start, enumInstance.size() - name_start);\n            }\n        }\n\n        std::vector<StringRef> parseEnums( StringRef enums ) {\n            auto enumValues = splitStringRef( enums, ',' );\n            std::vector<StringRef> parsed;\n            parsed.reserve( enumValues.size() );\n            for( auto const& enumValue : enumValues ) {\n                parsed.push_back(trim(extractInstanceName(enumValue)));\n            }\n            return parsed;\n        }\n\n        EnumInfo::~EnumInfo() {}\n\n        StringRef EnumInfo::lookup( int value ) const {\n            for( auto const& valueToName : m_values ) {\n                if( valueToName.first == value )\n                    return valueToName.second;\n            }\n            return \"{** unexpected enum value **}\"_sr;\n        }\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );\n            enumInfo->m_name = enumName;\n            enumInfo->m_values.reserve( values.size() );\n\n            const auto valueNames = Catch::Detail::parseEnums( allValueNames );\n            assert( valueNames.size() == values.size() );\n            std::size_t i = 0;\n            for( auto value : values )\n                enumInfo->m_values.emplace_back(value, valueNames[i++]);\n\n            return enumInfo;\n        }\n\n        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));\n            return *m_enumInfos.back();\n        }\n\n    } // Detail\n} // Catch\n\n// end catch_enum_values_registry.cpp\n// start catch_errno_guard.cpp\n\n#include <cerrno>\n\nnamespace Catch {\n        ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}\n        ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }\n}\n// end catch_errno_guard.cpp\n// start catch_exception_translator_registry.cpp\n\n// start catch_exception_translator_registry.h\n\n#include <vector>\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {\n    public:\n        ~ExceptionTranslatorRegistry();\n        virtual void registerTranslator( const IExceptionTranslator* translator );\n        std::string translateActiveException() const override;\n        std::string tryTranslators() const;\n\n    private:\n        std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;\n    };\n}\n\n// end catch_exception_translator_registry.h\n#ifdef __OBJC__\n#import \"Foundation/Foundation.h\"\n#endif\n\nnamespace Catch {\n\n    ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {\n    }\n\n    void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {\n        m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        try {\n#ifdef __OBJC__\n            // In Objective-C try objective-c exceptions first\n            @try {\n                return tryTranslators();\n            }\n            @catch (NSException *exception) {\n                return Catch::Detail::stringify( [exception description] );\n            }\n#else\n            // Compiling a mixed mode project with MSVC means that CLR\n            // exceptions will be caught in (...) as well. However, these\n            // do not fill-in std::current_exception and thus lead to crash\n            // when attempting rethrow.\n            // /EHa switch also causes structured exceptions to be caught\n            // here, but they fill-in current_exception properly, so\n            // at worst the output should be a little weird, instead of\n            // causing a crash.\n            if (std::current_exception() == nullptr) {\n                return \"Non C++ exception. Possibly a CLR exception.\";\n            }\n            return tryTranslators();\n#endif\n        }\n        catch( TestFailureException& ) {\n            std::rethrow_exception(std::current_exception());\n        }\n        catch( std::exception& ex ) {\n            return ex.what();\n        }\n        catch( std::string& msg ) {\n            return msg;\n        }\n        catch( const char* msg ) {\n            return msg;\n        }\n        catch(...) {\n            return \"Unknown exception\";\n        }\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        if (m_translators.empty()) {\n            std::rethrow_exception(std::current_exception());\n        } else {\n            return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());\n        }\n    }\n\n#else // ^^ Exceptions are enabled // Exceptions are disabled vv\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n#endif\n\n}\n// end catch_exception_translator_registry.cpp\n// start catch_fatal_condition.cpp\n\n#include <algorithm>\n\n#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace Catch {\n\n    // If neither SEH nor signal handling is required, the handler impls\n    // do not have to do anything, and can be empty.\n    void FatalConditionHandler::engage_platform() {}\n    void FatalConditionHandler::disengage_platform() {}\n    FatalConditionHandler::FatalConditionHandler() = default;\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n} // end namespace Catch\n\n#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )\n#error \"Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time\"\n#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace {\n    //! Signals fatal error message to the run context\n    void reportFatal( char const * const message ) {\n        Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );\n    }\n\n    //! Minimal size Catch2 needs for its own fatal error handling.\n    //! Picked anecdotally, so it might not be sufficient on all\n    //! platforms, and for all configurations.\n    constexpr std::size_t minStackSizeForErrors = 32 * 1024;\n} // end unnamed namespace\n\n#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH )\n\nnamespace Catch {\n\n    struct SignalDefs { DWORD id; const char* name; };\n\n    // There is no 1-1 mapping between signals and windows exceptions.\n    // Windows can easily distinguish between SO and SigSegV,\n    // but SigInt, SigTerm, etc are handled differently.\n    static SignalDefs signalDefs[] = {\n        { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  \"SIGILL - Illegal instruction signal\" },\n        { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), \"SIGSEGV - Stack overflow\" },\n        { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), \"SIGSEGV - Segmentation violation signal\" },\n        { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), \"Divide by zero error\" },\n    };\n\n    static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {\n        for (auto const& def : signalDefs) {\n            if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {\n                reportFatal(def.name);\n            }\n        }\n        // If its not an exception we care about, pass it along.\n        // This stops us from eating debugger breaks etc.\n        return EXCEPTION_CONTINUE_SEARCH;\n    }\n\n    // Since we do not support multiple instantiations, we put these\n    // into global variables and rely on cleaning them up in outlined\n    // constructors/destructors\n    static PVOID exceptionHandlerHandle = nullptr;\n\n    // For MSVC, we reserve part of the stack memory for handling\n    // memory overflow structured exception.\n    FatalConditionHandler::FatalConditionHandler() {\n        ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);\n        if (!SetThreadStackGuarantee(&guaranteeSize)) {\n            // We do not want to fully error out, because needing\n            // the stack reserve should be rare enough anyway.\n            Catch::cerr()\n                << \"Failed to reserve piece of stack.\"\n                << \" Stack overflows will not be reported successfully.\";\n        }\n    }\n\n    // We do not attempt to unset the stack guarantee, because\n    // Windows does not support lowering the stack size guarantee.\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n    void FatalConditionHandler::engage_platform() {\n        // Register as first handler in current chain\n        exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);\n        if (!exceptionHandlerHandle) {\n            CATCH_RUNTIME_ERROR(\"Could not register vectored exception handler\");\n        }\n    }\n\n    void FatalConditionHandler::disengage_platform() {\n        if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {\n            CATCH_RUNTIME_ERROR(\"Could not unregister vectored exception handler\");\n        }\n        exceptionHandlerHandle = nullptr;\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_WINDOWS_SEH\n\n#if defined( CATCH_CONFIG_POSIX_SIGNALS )\n\n#include <signal.h>\n\nnamespace Catch {\n\n    struct SignalDefs {\n        int id;\n        const char* name;\n    };\n\n    static SignalDefs signalDefs[] = {\n        { SIGINT,  \"SIGINT - Terminal interrupt signal\" },\n        { SIGILL,  \"SIGILL - Illegal instruction signal\" },\n        { SIGFPE,  \"SIGFPE - Floating point error signal\" },\n        { SIGSEGV, \"SIGSEGV - Segmentation violation signal\" },\n        { SIGTERM, \"SIGTERM - Termination request signal\" },\n        { SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\" }\n    };\n\n// Older GCCs trigger -Wmissing-field-initializers for T foo = {}\n// which is zero initialization, but not explicit. We want to avoid\n// that.\n#if defined(__GNUC__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n    static char* altStackMem = nullptr;\n    static std::size_t altStackSize = 0;\n    static stack_t oldSigStack{};\n    static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};\n\n    static void restorePreviousSignalHandlers() {\n        // We set signal handlers back to the previous ones. Hopefully\n        // nobody overwrote them in the meantime, and doesn't expect\n        // their signal handlers to live past ours given that they\n        // installed them after ours..\n        for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);\n        }\n        // Return the old stack\n        sigaltstack(&oldSigStack, nullptr);\n    }\n\n    static void handleSignal( int sig ) {\n        char const * name = \"<unknown signal>\";\n        for (auto const& def : signalDefs) {\n            if (sig == def.id) {\n                name = def.name;\n                break;\n            }\n        }\n        // We need to restore previous signal handlers and let them do\n        // their thing, so that the users can have the debugger break\n        // when a signal is raised, and so on.\n        restorePreviousSignalHandlers();\n        reportFatal( name );\n        raise( sig );\n    }\n\n    FatalConditionHandler::FatalConditionHandler() {\n        assert(!altStackMem && \"Cannot initialize POSIX signal handler when one already exists\");\n        if (altStackSize == 0) {\n            altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);\n        }\n        altStackMem = new char[altStackSize]();\n    }\n\n    FatalConditionHandler::~FatalConditionHandler() {\n        delete[] altStackMem;\n        // We signal that another instance can be constructed by zeroing\n        // out the pointer.\n        altStackMem = nullptr;\n    }\n\n    void FatalConditionHandler::engage_platform() {\n        stack_t sigStack;\n        sigStack.ss_sp = altStackMem;\n        sigStack.ss_size = altStackSize;\n        sigStack.ss_flags = 0;\n        sigaltstack(&sigStack, &oldSigStack);\n        struct sigaction sa = { };\n\n        sa.sa_handler = handleSignal;\n        sa.sa_flags = SA_ONSTACK;\n        for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);\n        }\n    }\n\n#if defined(__GNUC__)\n#    pragma GCC diagnostic pop\n#endif\n\n    void FatalConditionHandler::disengage_platform() {\n        restorePreviousSignalHandlers();\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_POSIX_SIGNALS\n// end catch_fatal_condition.cpp\n// start catch_generators.cpp\n\n#include <limits>\n#include <set>\n\nnamespace Catch {\n\nIGeneratorTracker::~IGeneratorTracker() {}\n\nconst char* GeneratorException::what() const noexcept {\n    return m_msg;\n}\n\nnamespace Generators {\n\n    GeneratorUntypedBase::~GeneratorUntypedBase() {}\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );\n    }\n\n} // namespace Generators\n} // namespace Catch\n// end catch_generators.cpp\n// start catch_interfaces_capture.cpp\n\nnamespace Catch {\n    IResultCapture::~IResultCapture() = default;\n}\n// end catch_interfaces_capture.cpp\n// start catch_interfaces_config.cpp\n\nnamespace Catch {\n    IConfig::~IConfig() = default;\n}\n// end catch_interfaces_config.cpp\n// start catch_interfaces_exception.cpp\n\nnamespace Catch {\n    IExceptionTranslator::~IExceptionTranslator() = default;\n    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;\n}\n// end catch_interfaces_exception.cpp\n// start catch_interfaces_registry_hub.cpp\n\nnamespace Catch {\n    IRegistryHub::~IRegistryHub() = default;\n    IMutableRegistryHub::~IMutableRegistryHub() = default;\n}\n// end catch_interfaces_registry_hub.cpp\n// start catch_interfaces_reporter.cpp\n\n// start catch_reporter_listening.h\n\nnamespace Catch {\n\n    class ListeningReporter : public IStreamingReporter {\n        using Reporters = std::vector<IStreamingReporterPtr>;\n        Reporters m_listeners;\n        IStreamingReporterPtr m_reporter = nullptr;\n        ReporterPreferences m_preferences;\n\n    public:\n        ListeningReporter();\n\n        void addListener( IStreamingReporterPtr&& listener );\n        void addReporter( IStreamingReporterPtr&& reporter );\n\n    public: // IStreamingReporter\n\n        ReporterPreferences getPreferences() const override;\n\n        void noMatchingTestCases( std::string const& spec ) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;\n        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testRunStarting( TestRunInfo const& testRunInfo ) override;\n        void testGroupStarting( GroupInfo const& groupInfo ) override;\n        void testCaseStarting( TestCaseInfo const& testInfo ) override;\n        void sectionStarting( SectionInfo const& sectionInfo ) override;\n        void assertionStarting( AssertionInfo const& assertionInfo ) override;\n\n        // The return value indicates if the messages buffer should be cleared:\n        bool assertionEnded( AssertionStats const& assertionStats ) override;\n        void sectionEnded( SectionStats const& sectionStats ) override;\n        void testCaseEnded( TestCaseStats const& testCaseStats ) override;\n        void testGroupEnded( TestGroupStats const& testGroupStats ) override;\n        void testRunEnded( TestRunStats const& testRunStats ) override;\n\n        void skipTest( TestCaseInfo const& testInfo ) override;\n        bool isMulti() const override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_listening.h\nnamespace Catch {\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )\n    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )\n    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}\n\n    std::ostream& ReporterConfig::stream() const { return *m_stream; }\n    IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }\n\n    TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}\n\n    GroupInfo::GroupInfo(  std::string const& _name,\n                           std::size_t _groupIndex,\n                           std::size_t _groupsCount )\n    :   name( _name ),\n        groupIndex( _groupIndex ),\n        groupsCounts( _groupsCount )\n    {}\n\n     AssertionStats::AssertionStats( AssertionResult const& _assertionResult,\n                                     std::vector<MessageInfo> const& _infoMessages,\n                                     Totals const& _totals )\n    :   assertionResult( _assertionResult ),\n        infoMessages( _infoMessages ),\n        totals( _totals )\n    {\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;\n\n        if( assertionResult.hasMessage() ) {\n            // Copy message into messages list.\n            // !TBD This should have been done earlier, somewhere\n            MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );\n            builder << assertionResult.getMessage();\n            builder.m_info.message = builder.m_stream.str();\n\n            infoMessages.push_back( builder.m_info );\n        }\n    }\n\n     AssertionStats::~AssertionStats() = default;\n\n    SectionStats::SectionStats(  SectionInfo const& _sectionInfo,\n                                 Counts const& _assertions,\n                                 double _durationInSeconds,\n                                 bool _missingAssertions )\n    :   sectionInfo( _sectionInfo ),\n        assertions( _assertions ),\n        durationInSeconds( _durationInSeconds ),\n        missingAssertions( _missingAssertions )\n    {}\n\n    SectionStats::~SectionStats() = default;\n\n    TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,\n                                   Totals const& _totals,\n                                   std::string const& _stdOut,\n                                   std::string const& _stdErr,\n                                   bool _aborting )\n    : testInfo( _testInfo ),\n        totals( _totals ),\n        stdOut( _stdOut ),\n        stdErr( _stdErr ),\n        aborting( _aborting )\n    {}\n\n    TestCaseStats::~TestCaseStats() = default;\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,\n                                    Totals const& _totals,\n                                    bool _aborting )\n    :   groupInfo( _groupInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )\n    :   groupInfo( _groupInfo ),\n        aborting( false )\n    {}\n\n    TestGroupStats::~TestGroupStats() = default;\n\n    TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,\n                    Totals const& _totals,\n                    bool _aborting )\n    :   runInfo( _runInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestRunStats::~TestRunStats() = default;\n\n    void IStreamingReporter::fatalErrorEncountered( StringRef ) {}\n    bool IStreamingReporter::isMulti() const { return false; }\n\n    IReporterFactory::~IReporterFactory() = default;\n    IReporterRegistry::~IReporterRegistry() = default;\n\n} // end namespace Catch\n// end catch_interfaces_reporter.cpp\n// start catch_interfaces_runner.cpp\n\nnamespace Catch {\n    IRunner::~IRunner() = default;\n}\n// end catch_interfaces_runner.cpp\n// start catch_interfaces_testcase.cpp\n\nnamespace Catch {\n    ITestInvoker::~ITestInvoker() = default;\n    ITestCaseRegistry::~ITestCaseRegistry() = default;\n}\n// end catch_interfaces_testcase.cpp\n// start catch_leak_detector.cpp\n\n#ifdef CATCH_CONFIG_WINDOWS_CRTDBG\n#include <crtdbg.h>\n\nnamespace Catch {\n\n    LeakDetector::LeakDetector() {\n        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);\n        flag |= _CRTDBG_LEAK_CHECK_DF;\n        flag |= _CRTDBG_ALLOC_MEM_DF;\n        _CrtSetDbgFlag(flag);\n        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);\n        // Change this to leaking allocation's number to break there\n        _CrtSetBreakAlloc(-1);\n    }\n}\n\n#else\n\n    Catch::LeakDetector::LeakDetector() {}\n\n#endif\n\nCatch::LeakDetector::~LeakDetector() {\n    Catch::cleanUp();\n}\n// end catch_leak_detector.cpp\n// start catch_list.cpp\n\n// start catch_list.h\n\n#include <set>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config );\n\n    std::size_t listTestsNamesOnly( Config const& config );\n\n    struct TagInfo {\n        void add( std::string const& spelling );\n        std::string all() const;\n\n        std::set<std::string> spellings;\n        std::size_t count = 0;\n    };\n\n    std::size_t listTags( Config const& config );\n\n    std::size_t listReporters();\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config );\n\n} // end namespace Catch\n\n// end catch_list.h\n// start catch_text.h\n\nnamespace Catch {\n    using namespace clara::TextFlow;\n}\n\n// end catch_text.h\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available test cases:\\n\";\n        }\n\n        auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            Colour::Code colour = testCaseInfo.isHidden()\n                ? Colour::SecondaryText\n                : Colour::None;\n            Colour colourGuard( colour );\n\n            Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << \"\\n\";\n            if( config.verbosity() >= Verbosity::High ) {\n                Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;\n                std::string description = testCaseInfo.description;\n                if( description.empty() )\n                    description = \"(NO DESCRIPTION)\";\n                Catch::cout() << Column( description ).indent(4) << std::endl;\n            }\n            if( !testCaseInfo.tags.empty() )\n                Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << \"\\n\";\n        }\n\n        if( !config.hasTestFilters() )\n            Catch::cout() << pluralise( matchedTestCases.size(), \"test case\" ) << '\\n' << std::endl;\n        else\n            Catch::cout() << pluralise( matchedTestCases.size(), \"matching test case\" ) << '\\n' << std::endl;\n        return matchedTestCases.size();\n    }\n\n    std::size_t listTestsNamesOnly( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        std::size_t matchedTests = 0;\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            matchedTests++;\n            if( startsWith( testCaseInfo.name, '#' ) )\n               Catch::cout() << '\"' << testCaseInfo.name << '\"';\n            else\n               Catch::cout() << testCaseInfo.name;\n            if ( config.verbosity() >= Verbosity::High )\n                Catch::cout() << \"\\t@\" << testCaseInfo.lineInfo;\n            Catch::cout() << std::endl;\n        }\n        return matchedTests;\n    }\n\n    void TagInfo::add( std::string const& spelling ) {\n        ++count;\n        spellings.insert( spelling );\n    }\n\n    std::string TagInfo::all() const {\n        size_t size = 0;\n        for (auto const& spelling : spellings) {\n            // Add 2 for the brackes\n            size += spelling.size() + 2;\n        }\n\n        std::string out; out.reserve(size);\n        for (auto const& spelling : spellings) {\n            out += '[';\n            out += spelling;\n            out += ']';\n        }\n        return out;\n    }\n\n    std::size_t listTags( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Tags for matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available tags:\\n\";\n        }\n\n        std::map<std::string, TagInfo> tagCounts;\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCase : matchedTestCases ) {\n            for( auto const& tagName : testCase.getTestCaseInfo().tags ) {\n                std::string lcaseTagName = toLower( tagName );\n                auto countIt = tagCounts.find( lcaseTagName );\n                if( countIt == tagCounts.end() )\n                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;\n                countIt->second.add( tagName );\n            }\n        }\n\n        for( auto const& tagCount : tagCounts ) {\n            ReusableStringStream rss;\n            rss << \"  \" << std::setw(2) << tagCount.second.count << \"  \";\n            auto str = rss.str();\n            auto wrapper = Column( tagCount.second.all() )\n                                                    .initialIndent( 0 )\n                                                    .indent( str.size() )\n                                                    .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );\n            Catch::cout() << str << wrapper << '\\n';\n        }\n        Catch::cout() << pluralise( tagCounts.size(), \"tag\" ) << '\\n' << std::endl;\n        return tagCounts.size();\n    }\n\n    std::size_t listReporters() {\n        Catch::cout() << \"Available reporters:\\n\";\n        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n        std::size_t maxNameLen = 0;\n        for( auto const& factoryKvp : factories )\n            maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );\n\n        for( auto const& factoryKvp : factories ) {\n            Catch::cout()\n                    << Column( factoryKvp.first + \":\" )\n                            .indent(2)\n                            .width( 5+maxNameLen )\n                    +  Column( factoryKvp.second->getDescription() )\n                            .initialIndent(0)\n                            .indent(2)\n                            .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )\n                    << \"\\n\";\n        }\n        Catch::cout() << std::endl;\n        return factories.size();\n    }\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config ) {\n        Option<std::size_t> listedCount;\n        getCurrentMutableContext().setConfig( config );\n        if( config->listTests() )\n            listedCount = listedCount.valueOr(0) + listTests( *config );\n        if( config->listTestNamesOnly() )\n            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );\n        if( config->listTags() )\n            listedCount = listedCount.valueOr(0) + listTags( *config );\n        if( config->listReporters() )\n            listedCount = listedCount.valueOr(0) + listReporters();\n        return listedCount;\n    }\n\n} // end namespace Catch\n// end catch_list.cpp\n// start catch_matchers.cpp\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        std::string MatcherUntypedBase::toString() const {\n            if( m_cachedToString.empty() )\n                m_cachedToString = describe();\n            return m_cachedToString;\n        }\n\n        MatcherUntypedBase::~MatcherUntypedBase() = default;\n\n    } // namespace Impl\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n// end catch_matchers.cpp\n// start catch_matchers_exception.cpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nbool ExceptionMessageMatcher::match(std::exception const& ex) const {\n    return ex.what() == m_message;\n}\n\nstd::string ExceptionMessageMatcher::describe() const {\n    return \"exception message matches \\\"\" + m_message + \"\\\"\";\n}\n\n}\nException::ExceptionMessageMatcher Message(std::string const& message) {\n    return Exception::ExceptionMessageMatcher(message);\n}\n\n// namespace Exception\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_exception.cpp\n// start catch_matchers_floating.cpp\n\n// start catch_polyfills.hpp\n\nnamespace Catch {\n    bool isnan(float f);\n    bool isnan(double d);\n}\n\n// end catch_polyfills.hpp\n// start catch_to_string.hpp\n\n#include <string>\n\nnamespace Catch {\n    template <typename T>\n    std::string to_string(T const& t) {\n#if defined(CATCH_CONFIG_CPP11_TO_STRING)\n        return std::to_string(t);\n#else\n        ReusableStringStream rss;\n        rss << t;\n        return rss.str();\n#endif\n    }\n} // end namespace Catch\n\n// end catch_to_string.hpp\n#include <algorithm>\n#include <cmath>\n#include <cstdlib>\n#include <cstdint>\n#include <cstring>\n#include <sstream>\n#include <type_traits>\n#include <iomanip>\n#include <limits>\n\nnamespace Catch {\nnamespace {\n\n    int32_t convert(float f) {\n        static_assert(sizeof(float) == sizeof(int32_t), \"Important ULP matcher assumption violated\");\n        int32_t i;\n        std::memcpy(&i, &f, sizeof(f));\n        return i;\n    }\n\n    int64_t convert(double d) {\n        static_assert(sizeof(double) == sizeof(int64_t), \"Important ULP matcher assumption violated\");\n        int64_t i;\n        std::memcpy(&i, &d, sizeof(d));\n        return i;\n    }\n\n    template <typename FP>\n    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {\n        // Comparison with NaN should always be false.\n        // This way we can rule it out before getting into the ugly details\n        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {\n            return false;\n        }\n\n        auto lc = convert(lhs);\n        auto rc = convert(rhs);\n\n        if ((lc < 0) != (rc < 0)) {\n            // Potentially we can have +0 and -0\n            return lhs == rhs;\n        }\n\n        // static cast as a workaround for IBM XLC\n        auto ulpDiff = std::abs(static_cast<FP>(lc - rc));\n        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;\n    }\n\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n\n    float nextafter(float x, float y) {\n        return ::nextafterf(x, y);\n    }\n\n    double nextafter(double x, double y) {\n        return ::nextafter(x, y);\n    }\n\n#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^\n\ntemplate <typename FP>\nFP step(FP start, FP direction, uint64_t steps) {\n    for (uint64_t i = 0; i < steps; ++i) {\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n        start = Catch::nextafter(start, direction);\n#else\n        start = std::nextafter(start, direction);\n#endif\n    }\n    return start;\n}\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\ntemplate <typename FloatingPoint>\nvoid write(std::ostream& out, FloatingPoint num) {\n    out << std::scientific\n        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)\n        << num;\n}\n\n} // end anonymous namespace\n\nnamespace Matchers {\nnamespace Floating {\n\n    enum class FloatingPointKind : uint8_t {\n        Float,\n        Double\n    };\n\n    WithinAbsMatcher::WithinAbsMatcher(double target, double margin)\n        :m_target{ target }, m_margin{ margin } {\n        CATCH_ENFORCE(margin >= 0, \"Invalid margin: \" << margin << '.'\n            << \" Margin has to be non-negative.\");\n    }\n\n    // Performs equivalent check of std::fabs(lhs - rhs) <= margin\n    // But without the subtraction to allow for INFINITY in comparison\n    bool WithinAbsMatcher::match(double const& matchee) const {\n        return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);\n    }\n\n    std::string WithinAbsMatcher::describe() const {\n        return \"is within \" + ::Catch::Detail::stringify(m_margin) + \" of \" + ::Catch::Detail::stringify(m_target);\n    }\n\n    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)\n        :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {\n        CATCH_ENFORCE(m_type == FloatingPointKind::Double\n                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),\n            \"Provided ULP is impossibly large for a float comparison.\");\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n// Clang <3.5 reports on the default branch in the switch below\n#pragma clang diagnostic ignored \"-Wunreachable-code\"\n#endif\n\n    bool WithinUlpsMatcher::match(double const& matchee) const {\n        switch (m_type) {\n        case FloatingPointKind::Float:\n            return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);\n        case FloatingPointKind::Double:\n            return almostEqualUlps<double>(matchee, m_target, m_ulps);\n        default:\n            CATCH_INTERNAL_ERROR( \"Unknown FloatingPointKind value\" );\n        }\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\n    std::string WithinUlpsMatcher::describe() const {\n        std::stringstream ret;\n\n        ret << \"is within \" << m_ulps << \" ULPs of \";\n\n        if (m_type == FloatingPointKind::Float) {\n            write(ret, static_cast<float>(m_target));\n            ret << 'f';\n        } else {\n            write(ret, m_target);\n        }\n\n        ret << \" ([\";\n        if (m_type == FloatingPointKind::Double) {\n            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));\n        } else {\n            // We have to cast INFINITY to float because of MinGW, see #1782\n            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));\n        }\n        ret << \"])\";\n\n        return ret.str();\n    }\n\n    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):\n        m_target(target),\n        m_epsilon(epsilon){\n        CATCH_ENFORCE(m_epsilon >= 0., \"Relative comparison with epsilon <  0 does not make sense.\");\n        CATCH_ENFORCE(m_epsilon  < 1., \"Relative comparison with epsilon >= 1 does not make sense.\");\n    }\n\n    bool WithinRelMatcher::match(double const& matchee) const {\n        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));\n        return marginComparison(matchee, m_target,\n                                std::isinf(relMargin)? 0 : relMargin);\n    }\n\n    std::string WithinRelMatcher::describe() const {\n        Catch::ReusableStringStream sstr;\n        sstr << \"and \" << m_target << \" are within \" << m_epsilon * 100. << \"% of each other\";\n        return sstr.str();\n    }\n\n}// namespace Floating\n\nFloating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);\n}\n\nFloating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);\n}\n\nFloating::WithinAbsMatcher WithinAbs(double target, double margin) {\n    return Floating::WithinAbsMatcher(target, margin);\n}\n\nFloating::WithinRelMatcher WithinRel(double target, double eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(double target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);\n}\n\nFloating::WithinRelMatcher WithinRel(float target, float eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(float target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);\n}\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_floating.cpp\n// start catch_matchers_generic.cpp\n\nstd::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {\n    if (desc.empty()) {\n        return \"matches undescribed predicate\";\n    } else {\n        return \"matches predicate: \\\"\" + desc + '\"';\n    }\n}\n// end catch_matchers_generic.cpp\n// start catch_matchers_string.cpp\n\n#include <regex>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )\n        :   m_caseSensitivity( caseSensitivity ),\n            m_str( adjustString( str ) )\n        {}\n        std::string CasedString::adjustString( std::string const& str ) const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? toLower( str )\n                   : str;\n        }\n        std::string CasedString::caseSensitivitySuffix() const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? \" (case insensitive)\"\n                   : std::string();\n        }\n\n        StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )\n        : m_comparator( comparator ),\n          m_operation( operation ) {\n        }\n\n        std::string StringMatcherBase::describe() const {\n            std::string description;\n            description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +\n                                        m_comparator.caseSensitivitySuffix().size());\n            description += m_operation;\n            description += \": \\\"\";\n            description += m_comparator.m_str;\n            description += \"\\\"\";\n            description += m_comparator.caseSensitivitySuffix();\n            return description;\n        }\n\n        EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( \"equals\", comparator ) {}\n\n        bool EqualsMatcher::match( std::string const& source ) const {\n            return m_comparator.adjustString( source ) == m_comparator.m_str;\n        }\n\n        ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( \"contains\", comparator ) {}\n\n        bool ContainsMatcher::match( std::string const& source ) const {\n            return contains( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"starts with\", comparator ) {}\n\n        bool StartsWithMatcher::match( std::string const& source ) const {\n            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"ends with\", comparator ) {}\n\n        bool EndsWithMatcher::match( std::string const& source ) const {\n            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}\n\n        bool RegexMatcher::match(std::string const& matchee) const {\n            auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway\n            if (m_caseSensitivity == CaseSensitive::Choice::No) {\n                flags |= std::regex::icase;\n            }\n            auto reg = std::regex(m_regex, flags);\n            return std::regex_match(matchee, reg);\n        }\n\n        std::string RegexMatcher::describe() const {\n            return \"matches \" + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? \" case sensitively\" : \" case insensitively\");\n        }\n\n    } // namespace StdString\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n\n    StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {\n        return StdString::RegexMatcher(regex, caseSensitivity);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_string.cpp\n// start catch_message.cpp\n\n// start catch_uncaught_exceptions.h\n\nnamespace Catch {\n    bool uncaught_exceptions();\n} // end namespace Catch\n\n// end catch_uncaught_exceptions.h\n#include <cassert>\n#include <stack>\n\nnamespace Catch {\n\n    MessageInfo::MessageInfo(   StringRef const& _macroName,\n                                SourceLineInfo const& _lineInfo,\n                                ResultWas::OfType _type )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        type( _type ),\n        sequence( ++globalCount )\n    {}\n\n    bool MessageInfo::operator==( MessageInfo const& other ) const {\n        return sequence == other.sequence;\n    }\n\n    bool MessageInfo::operator<( MessageInfo const& other ) const {\n        return sequence < other.sequence;\n    }\n\n    // This may need protecting if threading support is added\n    unsigned int MessageInfo::globalCount = 0;\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,\n                                           SourceLineInfo const& lineInfo,\n                                           ResultWas::OfType type )\n        :m_info(macroName, lineInfo, type) {}\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    ScopedMessage::ScopedMessage( MessageBuilder const& builder )\n    : m_info( builder.m_info ), m_moved()\n    {\n        m_info.message = builder.m_stream.str();\n        getResultCapture().pushScopedMessage( m_info );\n    }\n\n    ScopedMessage::ScopedMessage( ScopedMessage&& old )\n    : m_info( old.m_info ), m_moved()\n    {\n        old.m_moved = true;\n    }\n\n    ScopedMessage::~ScopedMessage() {\n        if ( !uncaught_exceptions() && !m_moved ){\n            getResultCapture().popScopedMessage(m_info);\n        }\n    }\n\n    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {\n        auto trimmed = [&] (size_t start, size_t end) {\n            while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {\n                ++start;\n            }\n            while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {\n                --end;\n            }\n            return names.substr(start, end - start + 1);\n        };\n        auto skipq = [&] (size_t start, char quote) {\n            for (auto i = start + 1; i < names.size() ; ++i) {\n                if (names[i] == quote)\n                    return i;\n                if (names[i] == '\\\\')\n                    ++i;\n            }\n            CATCH_INTERNAL_ERROR(\"CAPTURE parsing encountered unmatched quote\");\n        };\n\n        size_t start = 0;\n        std::stack<char> openings;\n        for (size_t pos = 0; pos < names.size(); ++pos) {\n            char c = names[pos];\n            switch (c) {\n            case '[':\n            case '{':\n            case '(':\n            // It is basically impossible to disambiguate between\n            // comparison and start of template args in this context\n//            case '<':\n                openings.push(c);\n                break;\n            case ']':\n            case '}':\n            case ')':\n//           case '>':\n                openings.pop();\n                break;\n            case '\"':\n            case '\\'':\n                pos = skipq(pos, c);\n                break;\n            case ',':\n                if (start != pos && openings.empty()) {\n                    m_messages.emplace_back(macroName, lineInfo, resultType);\n                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));\n                    m_messages.back().message += \" := \";\n                    start = pos;\n                }\n            }\n        }\n        assert(openings.empty() && \"Mismatched openings\");\n        m_messages.emplace_back(macroName, lineInfo, resultType);\n        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));\n        m_messages.back().message += \" := \";\n    }\n    Capturer::~Capturer() {\n        if ( !uncaught_exceptions() ){\n            assert( m_captured == m_messages.size() );\n            for( size_t i = 0; i < m_captured; ++i  )\n                m_resultCapture.popScopedMessage( m_messages[i] );\n        }\n    }\n\n    void Capturer::captureValue( size_t index, std::string const& value ) {\n        assert( index < m_messages.size() );\n        m_messages[index].message += value;\n        m_resultCapture.pushScopedMessage( m_messages[index] );\n        m_captured++;\n    }\n\n} // end namespace Catch\n// end catch_message.cpp\n// start catch_output_redirect.cpp\n\n// start catch_output_redirect.h\n#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n\n#include <cstdio>\n#include <iosfwd>\n#include <string>\n\nnamespace Catch {\n\n    class RedirectedStream {\n        std::ostream& m_originalStream;\n        std::ostream& m_redirectionStream;\n        std::streambuf* m_prevBuf;\n\n    public:\n        RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );\n        ~RedirectedStream();\n    };\n\n    class RedirectedStdOut {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cout;\n    public:\n        RedirectedStdOut();\n        auto str() const -> std::string;\n    };\n\n    // StdErr has two constituent streams in C++, std::cerr and std::clog\n    // This means that we need to redirect 2 streams into 1 to keep proper\n    // order of writes\n    class RedirectedStdErr {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cerr;\n        RedirectedStream m_clog;\n    public:\n        RedirectedStdErr();\n        auto str() const -> std::string;\n    };\n\n    class RedirectedStreams {\n    public:\n        RedirectedStreams(RedirectedStreams const&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams const&) = delete;\n        RedirectedStreams(RedirectedStreams&&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams&&) = delete;\n\n        RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);\n        ~RedirectedStreams();\n    private:\n        std::string& m_redirectedCout;\n        std::string& m_redirectedCerr;\n        RedirectedStdOut m_redirectedStdOut;\n        RedirectedStdErr m_redirectedStdErr;\n    };\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n    // Windows's implementation of std::tmpfile is terrible (it tries\n    // to create a file inside system folder, thus requiring elevated\n    // privileges for the binary), so we have to use tmpnam(_s) and\n    // create the file ourselves there.\n    class TempFile {\n    public:\n        TempFile(TempFile const&) = delete;\n        TempFile& operator=(TempFile const&) = delete;\n        TempFile(TempFile&&) = delete;\n        TempFile& operator=(TempFile&&) = delete;\n\n        TempFile();\n        ~TempFile();\n\n        std::FILE* getFile();\n        std::string getContents();\n\n    private:\n        std::FILE* m_file = nullptr;\n    #if defined(_MSC_VER)\n        char m_buffer[L_tmpnam] = { 0 };\n    #endif\n    };\n\n    class OutputRedirect {\n    public:\n        OutputRedirect(OutputRedirect const&) = delete;\n        OutputRedirect& operator=(OutputRedirect const&) = delete;\n        OutputRedirect(OutputRedirect&&) = delete;\n        OutputRedirect& operator=(OutputRedirect&&) = delete;\n\n        OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);\n        ~OutputRedirect();\n\n    private:\n        int m_originalStdout = -1;\n        int m_originalStderr = -1;\n        TempFile m_stdoutFile;\n        TempFile m_stderrFile;\n        std::string& m_stdoutDest;\n        std::string& m_stderrDest;\n    };\n\n#endif\n\n} // end namespace Catch\n\n#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n// end catch_output_redirect.h\n#include <cstdio>\n#include <cstring>\n#include <fstream>\n#include <sstream>\n#include <stdexcept>\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #include <io.h>      //_dup and _dup2\n    #define dup _dup\n    #define dup2 _dup2\n    #define fileno _fileno\n    #else\n    #include <unistd.h>  // dup and dup2\n    #endif\n#endif\n\nnamespace Catch {\n\n    RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )\n    :   m_originalStream( originalStream ),\n        m_redirectionStream( redirectionStream ),\n        m_prevBuf( m_originalStream.rdbuf() )\n    {\n        m_originalStream.rdbuf( m_redirectionStream.rdbuf() );\n    }\n\n    RedirectedStream::~RedirectedStream() {\n        m_originalStream.rdbuf( m_prevBuf );\n    }\n\n    RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}\n    auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStdErr::RedirectedStdErr()\n    :   m_cerr( Catch::cerr(), m_rss.get() ),\n        m_clog( Catch::clog(), m_rss.get() )\n    {}\n    auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)\n    :   m_redirectedCout(redirectedCout),\n        m_redirectedCerr(redirectedCerr)\n    {}\n\n    RedirectedStreams::~RedirectedStreams() {\n        m_redirectedCout += m_redirectedStdOut.str();\n        m_redirectedCerr += m_redirectedStdErr.str();\n    }\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n#if defined(_MSC_VER)\n    TempFile::TempFile() {\n        if (tmpnam_s(m_buffer)) {\n            CATCH_RUNTIME_ERROR(\"Could not get a temp filename\");\n        }\n        if (fopen_s(&m_file, m_buffer, \"w+\")) {\n            char buffer[100];\n            if (strerror_s(buffer, errno)) {\n                CATCH_RUNTIME_ERROR(\"Could not translate errno to a string\");\n            }\n            CATCH_RUNTIME_ERROR(\"Could not open the temp file: '\" << m_buffer << \"' because: \" << buffer);\n        }\n    }\n#else\n    TempFile::TempFile() {\n        m_file = std::tmpfile();\n        if (!m_file) {\n            CATCH_RUNTIME_ERROR(\"Could not create a temp file.\");\n        }\n    }\n\n#endif\n\n    TempFile::~TempFile() {\n         // TBD: What to do about errors here?\n         std::fclose(m_file);\n         // We manually create the file on Windows only, on Linux\n         // it will be autodeleted\n#if defined(_MSC_VER)\n         std::remove(m_buffer);\n#endif\n    }\n\n    FILE* TempFile::getFile() {\n        return m_file;\n    }\n\n    std::string TempFile::getContents() {\n        std::stringstream sstr;\n        char buffer[100] = {};\n        std::rewind(m_file);\n        while (std::fgets(buffer, sizeof(buffer), m_file)) {\n            sstr << buffer;\n        }\n        return sstr.str();\n    }\n\n    OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :\n        m_originalStdout(dup(1)),\n        m_originalStderr(dup(2)),\n        m_stdoutDest(stdout_dest),\n        m_stderrDest(stderr_dest) {\n        dup2(fileno(m_stdoutFile.getFile()), 1);\n        dup2(fileno(m_stderrFile.getFile()), 2);\n    }\n\n    OutputRedirect::~OutputRedirect() {\n        Catch::cout() << std::flush;\n        fflush(stdout);\n        // Since we support overriding these streams, we flush cerr\n        // even though std::cerr is unbuffered\n        Catch::cerr() << std::flush;\n        Catch::clog() << std::flush;\n        fflush(stderr);\n\n        dup2(m_originalStdout, 1);\n        dup2(m_originalStderr, 2);\n\n        m_stdoutDest += m_stdoutFile.getContents();\n        m_stderrDest += m_stderrFile.getContents();\n    }\n\n#endif // CATCH_CONFIG_NEW_CAPTURE\n\n} // namespace Catch\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #undef dup\n    #undef dup2\n    #undef fileno\n    #endif\n#endif\n// end catch_output_redirect.cpp\n// start catch_polyfills.cpp\n\n#include <cmath>\n\nnamespace Catch {\n\n#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n    bool isnan(float f) {\n        return std::isnan(f);\n    }\n    bool isnan(double d) {\n        return std::isnan(d);\n    }\n#else\n    // For now we only use this for embarcadero\n    bool isnan(float f) {\n        return std::_isnan(f);\n    }\n    bool isnan(double d) {\n        return std::_isnan(d);\n    }\n#endif\n\n} // end namespace Catch\n// end catch_polyfills.cpp\n// start catch_random_number_generator.cpp\n\nnamespace Catch {\n\nnamespace {\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4146) // we negate uint32 during the rotate\n#endif\n        // Safe rotr implementation thanks to John Regehr\n        uint32_t rotate_right(uint32_t val, uint32_t count) {\n            const uint32_t mask = 31;\n            count &= mask;\n            return (val >> count) | (val << (-count & mask));\n        }\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n}\n\n    SimplePcg32::SimplePcg32(result_type seed_) {\n        seed(seed_);\n    }\n\n    void SimplePcg32::seed(result_type seed_) {\n        m_state = 0;\n        (*this)();\n        m_state += seed_;\n        (*this)();\n    }\n\n    void SimplePcg32::discard(uint64_t skip) {\n        // We could implement this to run in O(log n) steps, but this\n        // should suffice for our use case.\n        for (uint64_t s = 0; s < skip; ++s) {\n            static_cast<void>((*this)());\n        }\n    }\n\n    SimplePcg32::result_type SimplePcg32::operator()() {\n        // prepare the output value\n        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);\n        const auto output = rotate_right(xorshifted, m_state >> 59u);\n\n        // advance state\n        m_state = m_state * 6364136223846793005ULL + s_inc;\n\n        return output;\n    }\n\n    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state == rhs.m_state;\n    }\n\n    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state != rhs.m_state;\n    }\n}\n// end catch_random_number_generator.cpp\n// start catch_registry_hub.cpp\n\n// start catch_test_case_registry_impl.h\n\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <ios>\n\nnamespace Catch {\n\n    class TestCase;\n    struct IConfig;\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n    class TestRegistry : public ITestCaseRegistry {\n    public:\n        virtual ~TestRegistry() = default;\n\n        virtual void registerTest( TestCase const& testCase );\n\n        std::vector<TestCase> const& getAllTests() const override;\n        std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;\n\n    private:\n        std::vector<TestCase> m_functions;\n        mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;\n        mutable std::vector<TestCase> m_sortedFunctions;\n        std::size_t m_unnamedCount = 0;\n        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class TestInvokerAsFunction : public ITestInvoker {\n        void(*m_testAsFunction)();\n    public:\n        TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;\n\n        void invoke() const override;\n    };\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName );\n\n    ///////////////////////////////////////////////////////////////////////////\n\n} // end namespace Catch\n\n// end catch_test_case_registry_impl.h\n// start catch_reporter_registry.h\n\n#include <map>\n\nnamespace Catch {\n\n    class ReporterRegistry : public IReporterRegistry {\n\n    public:\n\n        ~ReporterRegistry() override;\n\n        IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;\n\n        void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );\n        void registerListener( IReporterFactoryPtr const& factory );\n\n        FactoryMap const& getFactories() const override;\n        Listeners const& getListeners() const override;\n\n    private:\n        FactoryMap m_factories;\n        Listeners m_listeners;\n    };\n}\n\n// end catch_reporter_registry.h\n// start catch_tag_alias_registry.h\n\n// start catch_tag_alias.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias {\n        TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);\n\n        std::string tag;\n        SourceLineInfo lineInfo;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias.h\n#include <map>\n\nnamespace Catch {\n\n    class TagAliasRegistry : public ITagAliasRegistry {\n    public:\n        ~TagAliasRegistry() override;\n        TagAlias const* find( std::string const& alias ) const override;\n        std::string expandAliases( std::string const& unexpandedTestSpec ) const override;\n        void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );\n\n    private:\n        std::map<std::string, TagAlias> m_registry;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias_registry.h\n// start catch_startup_exception_registry.h\n\n#include <vector>\n#include <exception>\n\nnamespace Catch {\n\n    class StartupExceptionRegistry {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    public:\n        void add(std::exception_ptr const& exception) noexcept;\n        std::vector<std::exception_ptr> const& getExceptions() const noexcept;\n    private:\n        std::vector<std::exception_ptr> m_exceptions;\n#endif\n    };\n\n} // end namespace Catch\n\n// end catch_startup_exception_registry.h\n// start catch_singletons.hpp\n\nnamespace Catch {\n\n    struct ISingleton {\n        virtual ~ISingleton();\n    };\n\n    void addSingleton( ISingleton* singleton );\n    void cleanupSingletons();\n\n    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>\n    class Singleton : SingletonImplT, public ISingleton {\n\n        static auto getInternal() -> Singleton* {\n            static Singleton* s_instance = nullptr;\n            if( !s_instance ) {\n                s_instance = new Singleton;\n                addSingleton( s_instance );\n            }\n            return s_instance;\n        }\n\n    public:\n        static auto get() -> InterfaceT const& {\n            return *getInternal();\n        }\n        static auto getMutable() -> MutableInterfaceT& {\n            return *getInternal();\n        }\n    };\n\n} // namespace Catch\n\n// end catch_singletons.hpp\nnamespace Catch {\n\n    namespace {\n\n        class RegistryHub : public IRegistryHub, public IMutableRegistryHub,\n                            private NonCopyable {\n\n        public: // IRegistryHub\n            RegistryHub() = default;\n            IReporterRegistry const& getReporterRegistry() const override {\n                return m_reporterRegistry;\n            }\n            ITestCaseRegistry const& getTestCaseRegistry() const override {\n                return m_testCaseRegistry;\n            }\n            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {\n                return m_exceptionTranslatorRegistry;\n            }\n            ITagAliasRegistry const& getTagAliasRegistry() const override {\n                return m_tagAliasRegistry;\n            }\n            StartupExceptionRegistry const& getStartupExceptionRegistry() const override {\n                return m_exceptionRegistry;\n            }\n\n        public: // IMutableRegistryHub\n            void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerReporter( name, factory );\n            }\n            void registerListener( IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerListener( factory );\n            }\n            void registerTest( TestCase const& testInfo ) override {\n                m_testCaseRegistry.registerTest( testInfo );\n            }\n            void registerTranslator( const IExceptionTranslator* translator ) override {\n                m_exceptionTranslatorRegistry.registerTranslator( translator );\n            }\n            void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {\n                m_tagAliasRegistry.add( alias, tag, lineInfo );\n            }\n            void registerStartupException() noexcept override {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                m_exceptionRegistry.add(std::current_exception());\n#else\n                CATCH_INTERNAL_ERROR(\"Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n#endif\n            }\n            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {\n                return m_enumValuesRegistry;\n            }\n\n        private:\n            TestRegistry m_testCaseRegistry;\n            ReporterRegistry m_reporterRegistry;\n            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;\n            TagAliasRegistry m_tagAliasRegistry;\n            StartupExceptionRegistry m_exceptionRegistry;\n            Detail::EnumValuesRegistry m_enumValuesRegistry;\n        };\n    }\n\n    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;\n\n    IRegistryHub const& getRegistryHub() {\n        return RegistryHubSingleton::get();\n    }\n    IMutableRegistryHub& getMutableRegistryHub() {\n        return RegistryHubSingleton::getMutable();\n    }\n    void cleanUp() {\n        cleanupSingletons();\n        cleanUpContext();\n    }\n    std::string translateActiveException() {\n        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();\n    }\n\n} // end namespace Catch\n// end catch_registry_hub.cpp\n// start catch_reporter_registry.cpp\n\nnamespace Catch {\n\n    ReporterRegistry::~ReporterRegistry() = default;\n\n    IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {\n        auto it =  m_factories.find( name );\n        if( it == m_factories.end() )\n            return nullptr;\n        return it->second->create( ReporterConfig( config ) );\n    }\n\n    void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {\n        m_factories.emplace(name, factory);\n    }\n    void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {\n        m_listeners.push_back( factory );\n    }\n\n    IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {\n        return m_factories;\n    }\n    IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {\n        return m_listeners;\n    }\n\n}\n// end catch_reporter_registry.cpp\n// start catch_result_type.cpp\n\nnamespace Catch {\n\n    bool isOk( ResultWas::OfType resultType ) {\n        return ( resultType & ResultWas::FailureBit ) == 0;\n    }\n    bool isJustInfo( int flags ) {\n        return flags == ResultWas::Info;\n    }\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {\n        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );\n    }\n\n    bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }\n    bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }\n\n} // end namespace Catch\n// end catch_result_type.cpp\n// start catch_run_context.cpp\n\n#include <cassert>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace Generators {\n        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {\n            GeneratorBasePtr m_generator;\n\n            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n            :   TrackerBase( nameAndLocation, ctx, parent )\n            {}\n            ~GeneratorTracker();\n\n            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {\n                std::shared_ptr<GeneratorTracker> tracker;\n\n                ITracker& currentTracker = ctx.currentTracker();\n                // Under specific circumstances, the generator we want\n                // to acquire is also the current tracker. If this is\n                // the case, we have to avoid looking through current\n                // tracker's children, and instead return the current\n                // tracker.\n                // A case where this check is important is e.g.\n                //     for (int i = 0; i < 5; ++i) {\n                //         int n = GENERATE(1, 2);\n                //     }\n                //\n                // without it, the code above creates 5 nested generators.\n                if (currentTracker.nameAndLocation() == nameAndLocation) {\n                    auto thisTracker = currentTracker.parent().findChild(nameAndLocation);\n                    assert(thisTracker);\n                    assert(thisTracker->isGeneratorTracker());\n                    tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);\n                } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n                    assert( childTracker );\n                    assert( childTracker->isGeneratorTracker() );\n                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );\n                } else {\n                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );\n                    currentTracker.addChild( tracker );\n                }\n\n                if( !tracker->isComplete() ) {\n                    tracker->open();\n                }\n\n                return *tracker;\n            }\n\n            // TrackerBase interface\n            bool isGeneratorTracker() const override { return true; }\n            auto hasGenerator() const -> bool override {\n                return !!m_generator;\n            }\n            void close() override {\n                TrackerBase::close();\n                // If a generator has a child (it is followed by a section)\n                // and none of its children have started, then we must wait\n                // until later to start consuming its values.\n                // This catches cases where `GENERATE` is placed between two\n                // `SECTION`s.\n                // **The check for m_children.empty cannot be removed**.\n                // doing so would break `GENERATE` _not_ followed by `SECTION`s.\n                const bool should_wait_for_child = [&]() {\n                    // No children -> nobody to wait for\n                    if ( m_children.empty() ) {\n                        return false;\n                    }\n                    // If at least one child started executing, don't wait\n                    if ( std::find_if(\n                             m_children.begin(),\n                             m_children.end(),\n                             []( TestCaseTracking::ITrackerPtr tracker ) {\n                                 return tracker->hasStarted();\n                             } ) != m_children.end() ) {\n                        return false;\n                    }\n\n                    // No children have started. We need to check if they _can_\n                    // start, and thus we should wait for them, or they cannot\n                    // start (due to filters), and we shouldn't wait for them\n                    auto* parent = m_parent;\n                    // This is safe: there is always at least one section\n                    // tracker in a test case tracking tree\n                    while ( !parent->isSectionTracker() ) {\n                        parent = &( parent->parent() );\n                    }\n                    assert( parent &&\n                            \"Missing root (test case) level section\" );\n\n                    auto const& parentSection =\n                        static_cast<SectionTracker&>( *parent );\n                    auto const& filters = parentSection.getFilters();\n                    // No filters -> no restrictions on running sections\n                    if ( filters.empty() ) {\n                        return true;\n                    }\n\n                    for ( auto const& child : m_children ) {\n                        if ( child->isSectionTracker() &&\n                             std::find( filters.begin(),\n                                        filters.end(),\n                                        static_cast<SectionTracker&>( *child )\n                                            .trimmedName() ) !=\n                                 filters.end() ) {\n                            return true;\n                        }\n                    }\n                    return false;\n                }();\n\n                // This check is a bit tricky, because m_generator->next()\n                // has a side-effect, where it consumes generator's current\n                // value, but we do not want to invoke the side-effect if\n                // this generator is still waiting for any child to start.\n                if ( should_wait_for_child ||\n                     ( m_runState == CompletedSuccessfully &&\n                       m_generator->next() ) ) {\n                    m_children.clear();\n                    m_runState = Executing;\n                }\n            }\n\n            // IGeneratorTracker interface\n            auto getGenerator() const -> GeneratorBasePtr const& override {\n                return m_generator;\n            }\n            void setGenerator( GeneratorBasePtr&& generator ) override {\n                m_generator = std::move( generator );\n            }\n        };\n        GeneratorTracker::~GeneratorTracker() {}\n    }\n\n    RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)\n    :   m_runInfo(_config->name()),\n        m_context(getCurrentMutableContext()),\n        m_config(_config),\n        m_reporter(std::move(reporter)),\n        m_lastAssertionInfo{ StringRef(), SourceLineInfo(\"\",0), StringRef(), ResultDisposition::Normal },\n        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )\n    {\n        m_context.setRunner(this);\n        m_context.setConfig(m_config);\n        m_context.setResultCapture(this);\n        m_reporter->testRunStarting(m_runInfo);\n    }\n\n    RunContext::~RunContext() {\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));\n    }\n\n    void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));\n    }\n\n    void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));\n    }\n\n    Totals RunContext::runTest(TestCase const& testCase) {\n        Totals prevTotals = m_totals;\n\n        std::string redirectedCout;\n        std::string redirectedCerr;\n\n        auto const& testInfo = testCase.getTestCaseInfo();\n\n        m_reporter->testCaseStarting(testInfo);\n\n        m_activeTestCase = &testCase;\n\n        ITracker& rootTracker = m_trackerContext.startRun();\n        assert(rootTracker.isSectionTracker());\n        static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());\n        do {\n            m_trackerContext.startCycle();\n            m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));\n            runCurrentTest(redirectedCout, redirectedCerr);\n        } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());\n\n        Totals deltaTotals = m_totals.delta(prevTotals);\n        if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {\n            deltaTotals.assertions.failed++;\n            deltaTotals.testCases.passed--;\n            deltaTotals.testCases.failed++;\n        }\n        m_totals.testCases += deltaTotals.testCases;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  redirectedCout,\n                                  redirectedCerr,\n                                  aborting()));\n\n        m_activeTestCase = nullptr;\n        m_testCaseTracker = nullptr;\n\n        return deltaTotals;\n    }\n\n    IConfigPtr RunContext::config() const {\n        return m_config;\n    }\n\n    IStreamingReporter& RunContext::reporter() const {\n        return *m_reporter;\n    }\n\n    void RunContext::assertionEnded(AssertionResult const & result) {\n        if (result.getResultType() == ResultWas::Ok) {\n            m_totals.assertions.passed++;\n            m_lastAssertionPassed = true;\n        } else if (!result.isOk()) {\n            m_lastAssertionPassed = false;\n            if( m_activeTestCase->getTestCaseInfo().okToFail() )\n                m_totals.assertions.failedButOk++;\n            else\n                m_totals.assertions.failed++;\n        }\n        else {\n            m_lastAssertionPassed = true;\n        }\n\n        // We have no use for the return value (whether messages should be cleared), because messages were made scoped\n        // and should be let to clear themselves out.\n        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));\n\n        if (result.getResultType() != ResultWas::Warning)\n            m_messageScopes.clear();\n\n        // Reset working state\n        resetAssertionInfo();\n        m_lastResult = result;\n    }\n    void RunContext::resetAssertionInfo() {\n        m_lastAssertionInfo.macroName = StringRef();\n        m_lastAssertionInfo.capturedExpression = \"{Unknown expression after the reported line}\"_sr;\n    }\n\n    bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {\n        ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));\n        if (!sectionTracker.isOpen())\n            return false;\n        m_activeSections.push_back(&sectionTracker);\n\n        m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;\n\n        m_reporter->sectionStarting(sectionInfo);\n\n        assertions = m_totals.assertions;\n\n        return true;\n    }\n    auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        using namespace Generators;\n        GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,\n                                                              TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );\n        m_lastAssertionInfo.lineInfo = lineInfo;\n        return tracker;\n    }\n\n    bool RunContext::testForMissingAssertions(Counts& assertions) {\n        if (assertions.total() != 0)\n            return false;\n        if (!m_config->warnAboutMissingAssertions())\n            return false;\n        if (m_trackerContext.currentTracker().hasChildren())\n            return false;\n        m_totals.assertions.failed++;\n        assertions.failed++;\n        return true;\n    }\n\n    void RunContext::sectionEnded(SectionEndInfo const & endInfo) {\n        Counts assertions = m_totals.assertions - endInfo.prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        if (!m_activeSections.empty()) {\n            m_activeSections.back()->close();\n            m_activeSections.pop_back();\n        }\n\n        m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));\n        m_messages.clear();\n        m_messageScopes.clear();\n    }\n\n    void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {\n        if (m_unfinishedSections.empty())\n            m_activeSections.back()->fail();\n        else\n            m_activeSections.back()->close();\n        m_activeSections.pop_back();\n\n        m_unfinishedSections.push_back(endInfo);\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void RunContext::benchmarkPreparing(std::string const& name) {\n        m_reporter->benchmarkPreparing(name);\n    }\n    void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {\n        m_reporter->benchmarkStarting( info );\n    }\n    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {\n        m_reporter->benchmarkEnded( stats );\n    }\n    void RunContext::benchmarkFailed(std::string const & error) {\n        m_reporter->benchmarkFailed(error);\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void RunContext::pushScopedMessage(MessageInfo const & message) {\n        m_messages.push_back(message);\n    }\n\n    void RunContext::popScopedMessage(MessageInfo const & message) {\n        m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());\n    }\n\n    void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {\n        m_messageScopes.emplace_back( builder );\n    }\n\n    std::string RunContext::getCurrentTestName() const {\n        return m_activeTestCase\n            ? m_activeTestCase->getTestCaseInfo().name\n            : std::string();\n    }\n\n    const AssertionResult * RunContext::getLastResult() const {\n        return &(*m_lastResult);\n    }\n\n    void RunContext::exceptionEarlyReported() {\n        m_shouldReportUnexpected = false;\n    }\n\n    void RunContext::handleFatalErrorCondition( StringRef message ) {\n        // First notify reporter that bad things happened\n        m_reporter->fatalErrorEncountered(message);\n\n        // Don't rebuild the result -- the stringification itself can cause more fatal errors\n        // Instead, fake a result data.\n        AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );\n        tempResult.message = static_cast<std::string>(message);\n        AssertionResult result(m_lastAssertionInfo, tempResult);\n\n        assertionEnded(result);\n\n        handleUnfinishedSections();\n\n        // Recreate section for test case (as we will lose the one that was in scope)\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n\n        Counts assertions;\n        assertions.failed = 1;\n        SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);\n        m_reporter->sectionEnded(testCaseSectionStats);\n\n        auto const& testInfo = m_activeTestCase->getTestCaseInfo();\n\n        Totals deltaTotals;\n        deltaTotals.testCases.failed = 1;\n        deltaTotals.assertions.failed = 1;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  std::string(),\n                                  std::string(),\n                                  false));\n        m_totals.testCases.failed++;\n        testGroupEnded(std::string(), m_totals, 1, 1);\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));\n    }\n\n    bool RunContext::lastAssertionPassed() {\n         return m_lastAssertionPassed;\n    }\n\n    void RunContext::assertionPassed() {\n        m_lastAssertionPassed = true;\n        ++m_totals.assertions.passed;\n        resetAssertionInfo();\n        m_messageScopes.clear();\n    }\n\n    bool RunContext::aborting() const {\n        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());\n    }\n\n    void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n        m_reporter->sectionStarting(testCaseSection);\n        Counts prevAssertions = m_totals.assertions;\n        double duration = 0;\n        m_shouldReportUnexpected = true;\n        m_lastAssertionInfo = { \"TEST_CASE\"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };\n\n        seedRng(*m_config);\n\n        Timer timer;\n        CATCH_TRY {\n            if (m_reporter->getPreferences().shouldRedirectStdOut) {\n#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n                RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);\n\n                timer.start();\n                invokeActiveTestCase();\n#else\n                OutputRedirect r(redirectedCout, redirectedCerr);\n                timer.start();\n                invokeActiveTestCase();\n#endif\n            } else {\n                timer.start();\n                invokeActiveTestCase();\n            }\n            duration = timer.getElapsedSeconds();\n        } CATCH_CATCH_ANON (TestFailureException&) {\n            // This just means the test was aborted due to failure\n        } CATCH_CATCH_ALL {\n            // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions\n            // are reported without translation at the point of origin.\n            if( m_shouldReportUnexpected ) {\n                AssertionReaction dummyReaction;\n                handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );\n            }\n        }\n        Counts assertions = m_totals.assertions - prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        m_testCaseTracker->close();\n        handleUnfinishedSections();\n        m_messages.clear();\n        m_messageScopes.clear();\n\n        SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);\n        m_reporter->sectionEnded(testCaseSectionStats);\n    }\n\n    void RunContext::invokeActiveTestCase() {\n        FatalConditionHandlerGuard _(&m_fatalConditionhandler);\n        m_activeTestCase->invoke();\n    }\n\n    void RunContext::handleUnfinishedSections() {\n        // If sections ended prematurely due to an exception we stored their\n        // infos here so we can tear them down outside the unwind process.\n        for (auto it = m_unfinishedSections.rbegin(),\n             itEnd = m_unfinishedSections.rend();\n             it != itEnd;\n             ++it)\n            sectionEnded(*it);\n        m_unfinishedSections.clear();\n    }\n\n    void RunContext::handleExpr(\n        AssertionInfo const& info,\n        ITransientExpression const& expr,\n        AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        bool negated = isFalseTest( info.resultDisposition );\n        bool result = expr.getResult() != negated;\n\n        if( result ) {\n            if (!m_includeSuccessfulResults) {\n                assertionPassed();\n            }\n            else {\n                reportExpr(info, ResultWas::Ok, &expr, negated);\n            }\n        }\n        else {\n            reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );\n            populateReaction( reaction );\n        }\n    }\n    void RunContext::reportExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            ITransientExpression const *expr,\n            bool negated ) {\n\n        m_lastAssertionInfo = info;\n        AssertionResultData data( resultType, LazyExpression( negated ) );\n\n        AssertionResult assertionResult{ info, data };\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;\n\n        assertionEnded( assertionResult );\n    }\n\n    void RunContext::handleMessage(\n            AssertionInfo const& info,\n            ResultWas::OfType resultType,\n            StringRef const& message,\n            AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        data.message = static_cast<std::string>(message);\n        AssertionResult assertionResult{ m_lastAssertionInfo, data };\n        assertionEnded( assertionResult );\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n    void RunContext::handleUnexpectedExceptionNotThrown(\n            AssertionInfo const& info,\n            AssertionReaction& reaction\n    ) {\n        handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);\n    }\n\n    void RunContext::handleUnexpectedInflightException(\n            AssertionInfo const& info,\n            std::string const& message,\n            AssertionReaction& reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = message;\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n        populateReaction( reaction );\n    }\n\n    void RunContext::populateReaction( AssertionReaction& reaction ) {\n        reaction.shouldDebugBreak = m_config->shouldDebugBreak();\n        reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);\n    }\n\n    void RunContext::handleIncomplete(\n            AssertionInfo const& info\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = \"Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE\";\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n    }\n    void RunContext::handleNonExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            AssertionReaction &reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n\n    IResultCapture& getResultCapture() {\n        if (auto* capture = getCurrentContext().getResultCapture())\n            return *capture;\n        else\n            CATCH_INTERNAL_ERROR(\"No result capture instance\");\n    }\n\n    void seedRng(IConfig const& config) {\n        if (config.rngSeed() != 0) {\n            std::srand(config.rngSeed());\n            rng().seed(config.rngSeed());\n        }\n    }\n\n    unsigned int rngSeed() {\n        return getCurrentContext().getConfig()->rngSeed();\n    }\n\n}\n// end catch_run_context.cpp\n// start catch_section.cpp\n\nnamespace Catch {\n\n    Section::Section( SectionInfo const& info )\n    :   m_info( info ),\n        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )\n    {\n        m_timer.start();\n    }\n\n    Section::~Section() {\n        if( m_sectionIncluded ) {\n            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };\n            if( uncaught_exceptions() )\n                getResultCapture().sectionEndedEarly( endInfo );\n            else\n                getResultCapture().sectionEnded( endInfo );\n        }\n    }\n\n    // This indicates whether the section should be executed or not\n    Section::operator bool() const {\n        return m_sectionIncluded;\n    }\n\n} // end namespace Catch\n// end catch_section.cpp\n// start catch_section_info.cpp\n\nnamespace Catch {\n\n    SectionInfo::SectionInfo\n        (   SourceLineInfo const& _lineInfo,\n            std::string const& _name )\n    :   name( _name ),\n        lineInfo( _lineInfo )\n    {}\n\n} // end namespace Catch\n// end catch_section_info.cpp\n// start catch_session.cpp\n\n// start catch_session.h\n\n#include <memory>\n\nnamespace Catch {\n\n    class Session : NonCopyable {\n    public:\n\n        Session();\n        ~Session() override;\n\n        void showHelp() const;\n        void libIdentify();\n\n        int applyCommandLine( int argc, char const * const * argv );\n    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n        int applyCommandLine( int argc, wchar_t const * const * argv );\n    #endif\n\n        void useConfigData( ConfigData const& configData );\n\n        template<typename CharT>\n        int run(int argc, CharT const * const argv[]) {\n            if (m_startupExceptions)\n                return 1;\n            int returnCode = applyCommandLine(argc, argv);\n            if (returnCode == 0)\n                returnCode = run();\n            return returnCode;\n        }\n\n        int run();\n\n        clara::Parser const& cli() const;\n        void cli( clara::Parser const& newParser );\n        ConfigData& configData();\n        Config& config();\n    private:\n        int runInternal();\n\n        clara::Parser m_cli;\n        ConfigData m_configData;\n        std::shared_ptr<Config> m_config;\n        bool m_startupExceptions = false;\n    };\n\n} // end namespace Catch\n\n// end catch_session.h\n// start catch_version.h\n\n#include <iosfwd>\n\nnamespace Catch {\n\n    // Versioning information\n    struct Version {\n        Version( Version const& ) = delete;\n        Version& operator=( Version const& ) = delete;\n        Version(    unsigned int _majorVersion,\n                    unsigned int _minorVersion,\n                    unsigned int _patchNumber,\n                    char const * const _branchName,\n                    unsigned int _buildNumber );\n\n        unsigned int const majorVersion;\n        unsigned int const minorVersion;\n        unsigned int const patchNumber;\n\n        // buildNumber is only used if branchName is not null\n        char const * const branchName;\n        unsigned int const buildNumber;\n\n        friend std::ostream& operator << ( std::ostream& os, Version const& version );\n    };\n\n    Version const& libraryVersion();\n}\n\n// end catch_version.h\n#include <cstdlib>\n#include <iomanip>\n#include <set>\n#include <iterator>\n\nnamespace Catch {\n\n    namespace {\n        const int MaxExitCode = 255;\n\n        IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {\n            auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);\n            CATCH_ENFORCE(reporter, \"No reporter registered with name: '\" << reporterName << \"'\");\n\n            return reporter;\n        }\n\n        IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {\n            if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {\n                return createReporter(config->getReporterName(), config);\n            }\n\n            // On older platforms, returning std::unique_ptr<ListeningReporter>\n            // when the return type is std::unique_ptr<IStreamingReporter>\n            // doesn't compile without a std::move call. However, this causes\n            // a warning on newer platforms. Thus, we have to work around\n            // it a bit and downcast the pointer manually.\n            auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);\n            auto& multi = static_cast<ListeningReporter&>(*ret);\n            auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();\n            for (auto const& listener : listeners) {\n                multi.addListener(listener->create(Catch::ReporterConfig(config)));\n            }\n            multi.addReporter(createReporter(config->getReporterName(), config));\n            return ret;\n        }\n\n        class TestGroup {\n        public:\n            explicit TestGroup(std::shared_ptr<Config> const& config)\n            : m_config{config}\n            , m_context{config, makeReporter(config)}\n            {\n                auto const& allTestCases = getAllTestCasesSorted(*m_config);\n                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n\n                if (m_matches.empty() && invalidArgs.empty()) {\n                    for (auto const& test : allTestCases)\n                        if (!test.isHidden())\n                            m_tests.emplace(&test);\n                } else {\n                    for (auto const& match : m_matches)\n                        m_tests.insert(match.tests.begin(), match.tests.end());\n                }\n            }\n\n            Totals execute() {\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n                Totals totals;\n                m_context.testGroupStarting(m_config->name(), 1, 1);\n                for (auto const& testCase : m_tests) {\n                    if (!m_context.aborting())\n                        totals += m_context.runTest(*testCase);\n                    else\n                        m_context.reporter().skipTest(*testCase);\n                }\n\n                for (auto const& match : m_matches) {\n                    if (match.tests.empty()) {\n                        m_context.reporter().noMatchingTestCases(match.name);\n                        totals.error = -1;\n                    }\n                }\n\n                if (!invalidArgs.empty()) {\n                    for (auto const& invalidArg: invalidArgs)\n                         m_context.reporter().reportInvalidArguments(invalidArg);\n                }\n\n                m_context.testGroupEnded(m_config->name(), totals, 1, 1);\n                return totals;\n            }\n\n        private:\n            using Tests = std::set<TestCase const*>;\n\n            std::shared_ptr<Config> m_config;\n            RunContext m_context;\n            Tests m_tests;\n            TestSpec::Matches m_matches;\n        };\n\n        void applyFilenamesAsTags(Catch::IConfig const& config) {\n            auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));\n            for (auto& testCase : tests) {\n                auto tags = testCase.tags;\n\n                std::string filename = testCase.lineInfo.file;\n                auto lastSlash = filename.find_last_of(\"\\\\/\");\n                if (lastSlash != std::string::npos) {\n                    filename.erase(0, lastSlash);\n                    filename[0] = '#';\n                }\n                else\n                {\n                    filename.insert(0, \"#\");\n                }\n\n                auto lastDot = filename.find_last_of('.');\n                if (lastDot != std::string::npos) {\n                    filename.erase(lastDot);\n                }\n\n                tags.push_back(std::move(filename));\n                setTags(testCase, tags);\n            }\n        }\n\n    } // anon namespace\n\n    Session::Session() {\n        static bool alreadyInstantiated = false;\n        if( alreadyInstantiated ) {\n            CATCH_TRY { CATCH_INTERNAL_ERROR( \"Only one instance of Catch::Session can ever be used\" ); }\n            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }\n        }\n\n        // There cannot be exceptions at startup in no-exception mode.\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();\n        if ( !exceptions.empty() ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n\n            m_startupExceptions = true;\n            Colour colourGuard( Colour::Red );\n            Catch::cerr() << \"Errors occurred during startup!\" << '\\n';\n            // iterate over all exceptions and notify user\n            for ( const auto& ex_ptr : exceptions ) {\n                try {\n                    std::rethrow_exception(ex_ptr);\n                } catch ( std::exception const& ex ) {\n                    Catch::cerr() << Column( ex.what() ).indent(2) << '\\n';\n                }\n            }\n        }\n#endif\n\n        alreadyInstantiated = true;\n        m_cli = makeCommandLineParser( m_configData );\n    }\n    Session::~Session() {\n        Catch::cleanUp();\n    }\n\n    void Session::showHelp() const {\n        Catch::cout()\n                << \"\\nCatch v\" << libraryVersion() << \"\\n\"\n                << m_cli << std::endl\n                << \"For more detailed usage please see the project docs\\n\" << std::endl;\n    }\n    void Session::libIdentify() {\n        Catch::cout()\n                << std::left << std::setw(16) << \"description: \" << \"A Catch2 test executable\\n\"\n                << std::left << std::setw(16) << \"category: \" << \"testframework\\n\"\n                << std::left << std::setw(16) << \"framework: \" << \"Catch Test\\n\"\n                << std::left << std::setw(16) << \"version: \" << libraryVersion() << std::endl;\n    }\n\n    int Session::applyCommandLine( int argc, char const * const * argv ) {\n        if( m_startupExceptions )\n            return 1;\n\n        auto result = m_cli.parse( clara::Args( argc, argv ) );\n        if( !result ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n            Catch::cerr()\n                << Colour( Colour::Red )\n                << \"\\nError(s) in input:\\n\"\n                << Column( result.errorMessage() ).indent( 2 )\n                << \"\\n\\n\";\n            Catch::cerr() << \"Run with -? for usage\\n\" << std::endl;\n            return MaxExitCode;\n        }\n\n        if( m_configData.showHelp )\n            showHelp();\n        if( m_configData.libIdentify )\n            libIdentify();\n        m_config.reset();\n        return 0;\n    }\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n    int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {\n\n        char **utf8Argv = new char *[ argc ];\n\n        for ( int i = 0; i < argc; ++i ) {\n            int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );\n\n            utf8Argv[ i ] = new char[ bufSize ];\n\n            WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );\n        }\n\n        int returnCode = applyCommandLine( argc, utf8Argv );\n\n        for ( int i = 0; i < argc; ++i )\n            delete [] utf8Argv[ i ];\n\n        delete [] utf8Argv;\n\n        return returnCode;\n    }\n#endif\n\n    void Session::useConfigData( ConfigData const& configData ) {\n        m_configData = configData;\n        m_config.reset();\n    }\n\n    int Session::run() {\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before starting\" << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        int exitCode = runInternal();\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before exiting, with code: \" << exitCode << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        return exitCode;\n    }\n\n    clara::Parser const& Session::cli() const {\n        return m_cli;\n    }\n    void Session::cli( clara::Parser const& newParser ) {\n        m_cli = newParser;\n    }\n    ConfigData& Session::configData() {\n        return m_configData;\n    }\n    Config& Session::config() {\n        if( !m_config )\n            m_config = std::make_shared<Config>( m_configData );\n        return *m_config;\n    }\n\n    int Session::runInternal() {\n        if( m_startupExceptions )\n            return 1;\n\n        if (m_configData.showHelp || m_configData.libIdentify) {\n            return 0;\n        }\n\n        CATCH_TRY {\n            config(); // Force config to be constructed\n\n            seedRng( *m_config );\n\n            if( m_configData.filenamesAsTags )\n                applyFilenamesAsTags( *m_config );\n\n            // Handle list request\n            if( Option<std::size_t> listed = list( m_config ) )\n                return static_cast<int>( *listed );\n\n            TestGroup tests { m_config };\n            auto const totals = tests.execute();\n\n            if( m_config->warnAboutNoTests() && totals.error == -1 )\n                return 2;\n\n            // Note that on unices only the lower 8 bits are usually used, clamping\n            // the return value to 255 prevents false negative when some multiple\n            // of 256 tests has failed\n            return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));\n        }\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        catch( std::exception& ex ) {\n            Catch::cerr() << ex.what() << std::endl;\n            return MaxExitCode;\n        }\n#endif\n    }\n\n} // end namespace Catch\n// end catch_session.cpp\n// start catch_singletons.cpp\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        static auto getSingletons() -> std::vector<ISingleton*>*& {\n            static std::vector<ISingleton*>* g_singletons = nullptr;\n            if( !g_singletons )\n                g_singletons = new std::vector<ISingleton*>();\n            return g_singletons;\n        }\n    }\n\n    ISingleton::~ISingleton() {}\n\n    void addSingleton(ISingleton* singleton ) {\n        getSingletons()->push_back( singleton );\n    }\n    void cleanupSingletons() {\n        auto& singletons = getSingletons();\n        for( auto singleton : *singletons )\n            delete singleton;\n        delete singletons;\n        singletons = nullptr;\n    }\n\n} // namespace Catch\n// end catch_singletons.cpp\n// start catch_startup_exception_registry.cpp\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\nnamespace Catch {\nvoid StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {\n        CATCH_TRY {\n            m_exceptions.push_back(exception);\n        } CATCH_CATCH_ALL {\n            // If we run out of memory during start-up there's really not a lot more we can do about it\n            std::terminate();\n        }\n    }\n\n    std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {\n        return m_exceptions;\n    }\n\n} // end namespace Catch\n#endif\n// end catch_startup_exception_registry.cpp\n// start catch_stream.cpp\n\n#include <cstdio>\n#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    Catch::IStream::~IStream() = default;\n\n    namespace Detail { namespace {\n        template<typename WriterF, std::size_t bufferSize=256>\n        class StreamBufImpl : public std::streambuf {\n            char data[bufferSize];\n            WriterF m_writer;\n\n        public:\n            StreamBufImpl() {\n                setp( data, data + sizeof(data) );\n            }\n\n            ~StreamBufImpl() noexcept {\n                StreamBufImpl::sync();\n            }\n\n        private:\n            int overflow( int c ) override {\n                sync();\n\n                if( c != EOF ) {\n                    if( pbase() == epptr() )\n                        m_writer( std::string( 1, static_cast<char>( c ) ) );\n                    else\n                        sputc( static_cast<char>( c ) );\n                }\n                return 0;\n            }\n\n            int sync() override {\n                if( pbase() != pptr() ) {\n                    m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );\n                    setp( pbase(), epptr() );\n                }\n                return 0;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        struct OutputDebugWriter {\n\n            void operator()( std::string const&str ) {\n                writeToDebugConsole( str );\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class FileStream : public IStream {\n            mutable std::ofstream m_ofs;\n        public:\n            FileStream( StringRef filename ) {\n                m_ofs.open( filename.c_str() );\n                CATCH_ENFORCE( !m_ofs.fail(), \"Unable to open file: '\" << filename << \"'\" );\n            }\n            ~FileStream() override = default;\n        public: // IStream\n            std::ostream& stream() const override {\n                return m_ofs;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class CoutStream : public IStream {\n            mutable std::ostream m_os;\n        public:\n            // Store the streambuf from cout up-front because\n            // cout may get redirected when running tests\n            CoutStream() : m_os( Catch::cout().rdbuf() ) {}\n            ~CoutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class DebugOutStream : public IStream {\n            std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;\n            mutable std::ostream m_os;\n        public:\n            DebugOutStream()\n            :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),\n                m_os( m_streamBuf.get() )\n            {}\n\n            ~DebugOutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n    }} // namespace anon::detail\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    auto makeStream( StringRef const &filename ) -> IStream const* {\n        if( filename.empty() )\n            return new Detail::CoutStream();\n        else if( filename[0] == '%' ) {\n            if( filename == \"%debug\" )\n                return new Detail::DebugOutStream();\n            else\n                CATCH_ERROR( \"Unrecognised stream: '\" << filename << \"'\" );\n        }\n        else\n            return new Detail::FileStream( filename );\n    }\n\n    // This class encapsulates the idea of a pool of ostringstreams that can be reused.\n    struct StringStreams {\n        std::vector<std::unique_ptr<std::ostringstream>> m_streams;\n        std::vector<std::size_t> m_unused;\n        std::ostringstream m_referenceStream; // Used for copy state/ flags from\n\n        auto add() -> std::size_t {\n            if( m_unused.empty() ) {\n                m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );\n                return m_streams.size()-1;\n            }\n            else {\n                auto index = m_unused.back();\n                m_unused.pop_back();\n                return index;\n            }\n        }\n\n        void release( std::size_t index ) {\n            m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state\n            m_unused.push_back(index);\n        }\n    };\n\n    ReusableStringStream::ReusableStringStream()\n    :   m_index( Singleton<StringStreams>::getMutable().add() ),\n        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )\n    {}\n\n    ReusableStringStream::~ReusableStringStream() {\n        static_cast<std::ostringstream*>( m_oss )->str(\"\");\n        m_oss->clear();\n        Singleton<StringStreams>::getMutable().release( m_index );\n    }\n\n    auto ReusableStringStream::str() const -> std::string {\n        return static_cast<std::ostringstream*>( m_oss )->str();\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n\n#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions\n    std::ostream& cout() { return std::cout; }\n    std::ostream& cerr() { return std::cerr; }\n    std::ostream& clog() { return std::clog; }\n#endif\n}\n// end catch_stream.cpp\n// start catch_string_manip.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cctype>\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        char toLowerCh(char c) {\n            return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );\n        }\n    }\n\n    bool startsWith( std::string const& s, std::string const& prefix ) {\n        return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());\n    }\n    bool startsWith( std::string const& s, char prefix ) {\n        return !s.empty() && s[0] == prefix;\n    }\n    bool endsWith( std::string const& s, std::string const& suffix ) {\n        return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());\n    }\n    bool endsWith( std::string const& s, char suffix ) {\n        return !s.empty() && s[s.size()-1] == suffix;\n    }\n    bool contains( std::string const& s, std::string const& infix ) {\n        return s.find( infix ) != std::string::npos;\n    }\n    void toLowerInPlace( std::string& s ) {\n        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );\n    }\n    std::string toLower( std::string const& s ) {\n        std::string lc = s;\n        toLowerInPlace( lc );\n        return lc;\n    }\n    std::string trim( std::string const& str ) {\n        static char const* whitespaceChars = \"\\n\\r\\t \";\n        std::string::size_type start = str.find_first_not_of( whitespaceChars );\n        std::string::size_type end = str.find_last_not_of( whitespaceChars );\n\n        return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();\n    }\n\n    StringRef trim(StringRef ref) {\n        const auto is_ws = [](char c) {\n            return c == ' ' || c == '\\t' || c == '\\n' || c == '\\r';\n        };\n        size_t real_begin = 0;\n        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }\n        size_t real_end = ref.size();\n        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }\n\n        return ref.substr(real_begin, real_end - real_begin);\n    }\n\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {\n        bool replaced = false;\n        std::size_t i = str.find( replaceThis );\n        while( i != std::string::npos ) {\n            replaced = true;\n            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );\n            if( i < str.size()-withThis.size() )\n                i = str.find( replaceThis, i+withThis.size() );\n            else\n                i = std::string::npos;\n        }\n        return replaced;\n    }\n\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {\n        std::vector<StringRef> subStrings;\n        std::size_t start = 0;\n        for(std::size_t pos = 0; pos < str.size(); ++pos ) {\n            if( str[pos] == delimiter ) {\n                if( pos - start > 1 )\n                    subStrings.push_back( str.substr( start, pos-start ) );\n                start = pos+1;\n            }\n        }\n        if( start < str.size() )\n            subStrings.push_back( str.substr( start, str.size()-start ) );\n        return subStrings;\n    }\n\n    pluralise::pluralise( std::size_t count, std::string const& label )\n    :   m_count( count ),\n        m_label( label )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {\n        os << pluraliser.m_count << ' ' << pluraliser.m_label;\n        if( pluraliser.m_count != 1 )\n            os << 's';\n        return os;\n    }\n\n}\n// end catch_string_manip.cpp\n// start catch_stringref.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cstdint>\n\nnamespace Catch {\n    StringRef::StringRef( char const* rawChars ) noexcept\n    : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )\n    {}\n\n    auto StringRef::c_str() const -> char const* {\n        CATCH_ENFORCE(isNullTerminated(), \"Called StringRef::c_str() on a non-null-terminated instance\");\n        return m_start;\n    }\n    auto StringRef::data() const noexcept -> char const* {\n        return m_start;\n    }\n\n    auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {\n        if (start < m_size) {\n            return StringRef(m_start + start, (std::min)(m_size - start, size));\n        } else {\n            return StringRef();\n        }\n    }\n    auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {\n        return m_size == other.m_size\n            && (std::memcmp( m_start, other.m_start, m_size ) == 0);\n    }\n\n    auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {\n        return os.write(str.data(), str.size());\n    }\n\n    auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {\n        lhs.append(rhs.data(), rhs.size());\n        return lhs;\n    }\n\n} // namespace Catch\n// end catch_stringref.cpp\n// start catch_tag_alias.cpp\n\nnamespace Catch {\n    TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}\n}\n// end catch_tag_alias.cpp\n// start catch_tag_alias_autoregistrar.cpp\n\nnamespace Catch {\n\n    RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {\n        CATCH_TRY {\n            getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n}\n// end catch_tag_alias_autoregistrar.cpp\n// start catch_tag_alias_registry.cpp\n\n#include <sstream>\n\nnamespace Catch {\n\n    TagAliasRegistry::~TagAliasRegistry() {}\n\n    TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {\n        auto it = m_registry.find( alias );\n        if( it != m_registry.end() )\n            return &(it->second);\n        else\n            return nullptr;\n    }\n\n    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {\n        std::string expandedTestSpec = unexpandedTestSpec;\n        for( auto const& registryKvp : m_registry ) {\n            std::size_t pos = expandedTestSpec.find( registryKvp.first );\n            if( pos != std::string::npos ) {\n                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +\n                                    registryKvp.second.tag +\n                                    expandedTestSpec.substr( pos + registryKvp.first.size() );\n            }\n        }\n        return expandedTestSpec;\n    }\n\n    void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {\n        CATCH_ENFORCE( startsWith(alias, \"[@\") && endsWith(alias, ']'),\n                      \"error: tag alias, '\" << alias << \"' is not of the form [@alias name].\\n\" << lineInfo );\n\n        CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,\n                      \"error: tag alias, '\" << alias << \"' already registered.\\n\"\n                      << \"\\tFirst seen at: \" << find(alias)->lineInfo << \"\\n\"\n                      << \"\\tRedefined at: \" << lineInfo );\n    }\n\n    ITagAliasRegistry::~ITagAliasRegistry() {}\n\n    ITagAliasRegistry const& ITagAliasRegistry::get() {\n        return getRegistryHub().getTagAliasRegistry();\n    }\n\n} // end namespace Catch\n// end catch_tag_alias_registry.cpp\n// start catch_test_case_info.cpp\n\n#include <cctype>\n#include <exception>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {\n            if( startsWith( tag, '.' ) ||\n                tag == \"!hide\" )\n                return TestCaseInfo::IsHidden;\n            else if( tag == \"!throws\" )\n                return TestCaseInfo::Throws;\n            else if( tag == \"!shouldfail\" )\n                return TestCaseInfo::ShouldFail;\n            else if( tag == \"!mayfail\" )\n                return TestCaseInfo::MayFail;\n            else if( tag == \"!nonportable\" )\n                return TestCaseInfo::NonPortable;\n            else if( tag == \"!benchmark\" )\n                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );\n            else\n                return TestCaseInfo::None;\n        }\n        bool isReservedTag( std::string const& tag ) {\n            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );\n        }\n        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {\n            CATCH_ENFORCE( !isReservedTag(tag),\n                          \"Tag name: [\" << tag << \"] is not allowed.\\n\"\n                          << \"Tag names starting with non alphanumeric characters are reserved\\n\"\n                          << _lineInfo );\n        }\n    }\n\n    TestCase makeTestCase(  ITestInvoker* _testCase,\n                            std::string const& _className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& _lineInfo )\n    {\n        bool isHidden = false;\n\n        // Parse out tags\n        std::vector<std::string> tags;\n        std::string desc, tag;\n        bool inTag = false;\n        for (char c : nameAndTags.tags) {\n            if( !inTag ) {\n                if( c == '[' )\n                    inTag = true;\n                else\n                    desc += c;\n            }\n            else {\n                if( c == ']' ) {\n                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );\n                    if( ( prop & TestCaseInfo::IsHidden ) != 0 )\n                        isHidden = true;\n                    else if( prop == TestCaseInfo::None )\n                        enforceNotReservedTag( tag, _lineInfo );\n\n                    // Merged hide tags like `[.approvals]` should be added as\n                    // `[.][approvals]`. The `[.]` is added at later point, so\n                    // we only strip the prefix\n                    if (startsWith(tag, '.') && tag.size() > 1) {\n                        tag.erase(0, 1);\n                    }\n                    tags.push_back( tag );\n                    tag.clear();\n                    inTag = false;\n                }\n                else\n                    tag += c;\n            }\n        }\n        if( isHidden ) {\n            // Add all \"hidden\" tags to make them behave identically\n            tags.insert( tags.end(), { \".\", \"!hide\" } );\n        }\n\n        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );\n        return TestCase( _testCase, std::move(info) );\n    }\n\n    void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {\n        std::sort(begin(tags), end(tags));\n        tags.erase(std::unique(begin(tags), end(tags)), end(tags));\n        testCaseInfo.lcaseTags.clear();\n\n        for( auto const& tag : tags ) {\n            std::string lcaseTag = toLower( tag );\n            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );\n            testCaseInfo.lcaseTags.push_back( lcaseTag );\n        }\n        testCaseInfo.tags = std::move(tags);\n    }\n\n    TestCaseInfo::TestCaseInfo( std::string const& _name,\n                                std::string const& _className,\n                                std::string const& _description,\n                                std::vector<std::string> const& _tags,\n                                SourceLineInfo const& _lineInfo )\n    :   name( _name ),\n        className( _className ),\n        description( _description ),\n        lineInfo( _lineInfo ),\n        properties( None )\n    {\n        setTags( *this, _tags );\n    }\n\n    bool TestCaseInfo::isHidden() const {\n        return ( properties & IsHidden ) != 0;\n    }\n    bool TestCaseInfo::throws() const {\n        return ( properties & Throws ) != 0;\n    }\n    bool TestCaseInfo::okToFail() const {\n        return ( properties & (ShouldFail | MayFail ) ) != 0;\n    }\n    bool TestCaseInfo::expectedToFail() const {\n        return ( properties & (ShouldFail ) ) != 0;\n    }\n\n    std::string TestCaseInfo::tagsAsString() const {\n        std::string ret;\n        // '[' and ']' per tag\n        std::size_t full_size = 2 * tags.size();\n        for (const auto& tag : tags) {\n            full_size += tag.size();\n        }\n        ret.reserve(full_size);\n        for (const auto& tag : tags) {\n            ret.push_back('[');\n            ret.append(tag);\n            ret.push_back(']');\n        }\n\n        return ret;\n    }\n\n    TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}\n\n    TestCase TestCase::withName( std::string const& _newName ) const {\n        TestCase other( *this );\n        other.name = _newName;\n        return other;\n    }\n\n    void TestCase::invoke() const {\n        test->invoke();\n    }\n\n    bool TestCase::operator == ( TestCase const& other ) const {\n        return  test.get() == other.test.get() &&\n                name == other.name &&\n                className == other.className;\n    }\n\n    bool TestCase::operator < ( TestCase const& other ) const {\n        return name < other.name;\n    }\n\n    TestCaseInfo const& TestCase::getTestCaseInfo() const\n    {\n        return *this;\n    }\n\n} // end namespace Catch\n// end catch_test_case_info.cpp\n// start catch_test_case_registry_impl.cpp\n\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        struct TestHasher {\n            using hash_t = uint64_t;\n\n            explicit TestHasher( hash_t hashSuffix ):\n                m_hashSuffix{ hashSuffix } {}\n\n            uint32_t operator()( TestCase const& t ) const {\n                // FNV-1a hash with multiplication fold.\n                const hash_t prime = 1099511628211u;\n                hash_t hash = 14695981039346656037u;\n                for ( const char c : t.name ) {\n                    hash ^= c;\n                    hash *= prime;\n                }\n                hash ^= m_hashSuffix;\n                hash *= prime;\n                const uint32_t low{ static_cast<uint32_t>( hash ) };\n                const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };\n                return low * high;\n            }\n\n        private:\n            hash_t m_hashSuffix;\n        };\n    } // end unnamed namespace\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {\n        switch( config.runOrder() ) {\n            case RunTests::InDeclarationOrder:\n                // already in declaration order\n                break;\n\n            case RunTests::InLexicographicalOrder: {\n                std::vector<TestCase> sorted = unsortedTestCases;\n                std::sort( sorted.begin(), sorted.end() );\n                return sorted;\n            }\n\n            case RunTests::InRandomOrder: {\n                seedRng( config );\n                TestHasher h{ config.rngSeed() };\n\n                using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;\n                std::vector<hashedTest> indexed_tests;\n                indexed_tests.reserve( unsortedTestCases.size() );\n\n                for (auto const& testCase : unsortedTestCases) {\n                    indexed_tests.emplace_back(h(testCase), &testCase);\n                }\n\n                std::sort(indexed_tests.begin(), indexed_tests.end(),\n                          [](hashedTest const& lhs, hashedTest const& rhs) {\n                          if (lhs.first == rhs.first) {\n                              return lhs.second->name < rhs.second->name;\n                          }\n                          return lhs.first < rhs.first;\n                });\n\n                std::vector<TestCase> sorted;\n                sorted.reserve( indexed_tests.size() );\n\n                for (auto const& hashed : indexed_tests) {\n                    sorted.emplace_back(*hashed.second);\n                }\n\n                return sorted;\n            }\n        }\n        return unsortedTestCases;\n    }\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {\n        return !testCase.throws() || config.allowThrows();\n    }\n\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {\n        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );\n    }\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {\n        std::set<TestCase> seenFunctions;\n        for( auto const& function : functions ) {\n            auto prev = seenFunctions.insert( function );\n            CATCH_ENFORCE( prev.second,\n                    \"error: TEST_CASE( \\\"\" << function.name << \"\\\" ) already defined.\\n\"\n                    << \"\\tFirst seen at \" << prev.first->getTestCaseInfo().lineInfo << \"\\n\"\n                    << \"\\tRedefined at \" << function.getTestCaseInfo().lineInfo );\n        }\n    }\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {\n        std::vector<TestCase> filtered;\n        filtered.reserve( testCases.size() );\n        for (auto const& testCase : testCases) {\n            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||\n                (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {\n                filtered.push_back(testCase);\n            }\n        }\n        return filtered;\n    }\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {\n        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );\n    }\n\n    void TestRegistry::registerTest( TestCase const& testCase ) {\n        std::string name = testCase.getTestCaseInfo().name;\n        if( name.empty() ) {\n            ReusableStringStream rss;\n            rss << \"Anonymous test case \" << ++m_unnamedCount;\n            return registerTest( testCase.withName( rss.str() ) );\n        }\n        m_functions.push_back( testCase );\n    }\n\n    std::vector<TestCase> const& TestRegistry::getAllTests() const {\n        return m_functions;\n    }\n    std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {\n        if( m_sortedFunctions.empty() )\n            enforceNoDuplicateTestCases( m_functions );\n\n        if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {\n            m_sortedFunctions = sortTests( config, m_functions );\n            m_currentSortOrder = config.runOrder();\n        }\n        return m_sortedFunctions;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}\n\n    void TestInvokerAsFunction::invoke() const {\n        m_testAsFunction();\n    }\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {\n        std::string className(classOrQualifiedMethodName);\n        if( startsWith( className, '&' ) )\n        {\n            std::size_t lastColons = className.rfind( \"::\" );\n            std::size_t penultimateColons = className.rfind( \"::\", lastColons-1 );\n            if( penultimateColons == std::string::npos )\n                penultimateColons = 1;\n            className = className.substr( penultimateColons, lastColons-penultimateColons );\n        }\n        return className;\n    }\n\n} // end namespace Catch\n// end catch_test_case_registry_impl.cpp\n// start catch_test_case_tracker.cpp\n\n#include <algorithm>\n#include <cassert>\n#include <stdexcept>\n#include <memory>\n#include <sstream>\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )\n    :   name( _name ),\n        location( _location )\n    {}\n\n    ITracker::~ITracker() = default;\n\n    ITracker& TrackerContext::startRun() {\n        m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( \"{root}\", CATCH_INTERNAL_LINEINFO ), *this, nullptr );\n        m_currentTracker = nullptr;\n        m_runState = Executing;\n        return *m_rootTracker;\n    }\n\n    void TrackerContext::endRun() {\n        m_rootTracker.reset();\n        m_currentTracker = nullptr;\n        m_runState = NotStarted;\n    }\n\n    void TrackerContext::startCycle() {\n        m_currentTracker = m_rootTracker.get();\n        m_runState = Executing;\n    }\n    void TrackerContext::completeCycle() {\n        m_runState = CompletedCycle;\n    }\n\n    bool TrackerContext::completedCycle() const {\n        return m_runState == CompletedCycle;\n    }\n    ITracker& TrackerContext::currentTracker() {\n        return *m_currentTracker;\n    }\n    void TrackerContext::setCurrentTracker( ITracker* tracker ) {\n        m_currentTracker = tracker;\n    }\n\n    TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):\n        ITracker(nameAndLocation),\n        m_ctx( ctx ),\n        m_parent( parent )\n    {}\n\n    bool TrackerBase::isComplete() const {\n        return m_runState == CompletedSuccessfully || m_runState == Failed;\n    }\n    bool TrackerBase::isSuccessfullyCompleted() const {\n        return m_runState == CompletedSuccessfully;\n    }\n    bool TrackerBase::isOpen() const {\n        return m_runState != NotStarted && !isComplete();\n    }\n    bool TrackerBase::hasChildren() const {\n        return !m_children.empty();\n    }\n\n    void TrackerBase::addChild( ITrackerPtr const& child ) {\n        m_children.push_back( child );\n    }\n\n    ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {\n        auto it = std::find_if( m_children.begin(), m_children.end(),\n            [&nameAndLocation]( ITrackerPtr const& tracker ){\n                return\n                    tracker->nameAndLocation().location == nameAndLocation.location &&\n                    tracker->nameAndLocation().name == nameAndLocation.name;\n            } );\n        return( it != m_children.end() )\n            ? *it\n            : nullptr;\n    }\n    ITracker& TrackerBase::parent() {\n        assert( m_parent ); // Should always be non-null except for root\n        return *m_parent;\n    }\n\n    void TrackerBase::openChild() {\n        if( m_runState != ExecutingChildren ) {\n            m_runState = ExecutingChildren;\n            if( m_parent )\n                m_parent->openChild();\n        }\n    }\n\n    bool TrackerBase::isSectionTracker() const { return false; }\n    bool TrackerBase::isGeneratorTracker() const { return false; }\n\n    void TrackerBase::open() {\n        m_runState = Executing;\n        moveToThis();\n        if( m_parent )\n            m_parent->openChild();\n    }\n\n    void TrackerBase::close() {\n\n        // Close any still open children (e.g. generators)\n        while( &m_ctx.currentTracker() != this )\n            m_ctx.currentTracker().close();\n\n        switch( m_runState ) {\n            case NeedsAnotherRun:\n                break;\n\n            case Executing:\n                m_runState = CompletedSuccessfully;\n                break;\n            case ExecutingChildren:\n                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )\n                    m_runState = CompletedSuccessfully;\n                break;\n\n            case NotStarted:\n            case CompletedSuccessfully:\n            case Failed:\n                CATCH_INTERNAL_ERROR( \"Illogical state: \" << m_runState );\n\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown state: \" << m_runState );\n        }\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::fail() {\n        m_runState = Failed;\n        if( m_parent )\n            m_parent->markAsNeedingAnotherRun();\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::markAsNeedingAnotherRun() {\n        m_runState = NeedsAnotherRun;\n    }\n\n    void TrackerBase::moveToParent() {\n        assert( m_parent );\n        m_ctx.setCurrentTracker( m_parent );\n    }\n    void TrackerBase::moveToThis() {\n        m_ctx.setCurrentTracker( this );\n    }\n\n    SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n    :   TrackerBase( nameAndLocation, ctx, parent ),\n        m_trimmed_name(trim(nameAndLocation.name))\n    {\n        if( parent ) {\n            while( !parent->isSectionTracker() )\n                parent = &parent->parent();\n\n            SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );\n            addNextFilters( parentSection.m_filters );\n        }\n    }\n\n    bool SectionTracker::isComplete() const {\n        bool complete = true;\n\n        if (m_filters.empty()\n            || m_filters[0] == \"\"\n            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {\n            complete = TrackerBase::isComplete();\n        }\n        return complete;\n    }\n\n    bool SectionTracker::isSectionTracker() const { return true; }\n\n    SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {\n        std::shared_ptr<SectionTracker> section;\n\n        ITracker& currentTracker = ctx.currentTracker();\n        if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n            assert( childTracker );\n            assert( childTracker->isSectionTracker() );\n            section = std::static_pointer_cast<SectionTracker>( childTracker );\n        }\n        else {\n            section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );\n            currentTracker.addChild( section );\n        }\n        if( !ctx.completedCycle() )\n            section->tryOpen();\n        return *section;\n    }\n\n    void SectionTracker::tryOpen() {\n        if( !isComplete() )\n            open();\n    }\n\n    void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {\n        if( !filters.empty() ) {\n            m_filters.reserve( m_filters.size() + filters.size() + 2 );\n            m_filters.emplace_back(\"\"); // Root - should never be consulted\n            m_filters.emplace_back(\"\"); // Test Case - not a section filter\n            m_filters.insert( m_filters.end(), filters.begin(), filters.end() );\n        }\n    }\n    void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {\n        if( filters.size() > 1 )\n            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );\n    }\n\n    std::vector<std::string> const& SectionTracker::getFilters() const {\n        return m_filters;\n    }\n\n    std::string const& SectionTracker::trimmedName() const {\n        return m_trimmed_name;\n    }\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n// end catch_test_case_tracker.cpp\n// start catch_test_registry.cpp\n\nnamespace Catch {\n\n    auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {\n        return new(std::nothrow) TestInvokerAsFunction( testAsFunction );\n    }\n\n    NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}\n\n    AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {\n        CATCH_TRY {\n            getMutableRegistryHub()\n                    .registerTest(\n                        makeTestCase(\n                            invoker,\n                            extractClassName( classOrMethod ),\n                            nameAndTags,\n                            lineInfo));\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n    AutoReg::~AutoReg() = default;\n}\n// end catch_test_registry.cpp\n// start catch_test_spec.cpp\n\n#include <algorithm>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    TestSpec::Pattern::Pattern( std::string const& name )\n    : m_name( name )\n    {}\n\n    TestSpec::Pattern::~Pattern() = default;\n\n    std::string const& TestSpec::Pattern::name() const {\n        return m_name;\n    }\n\n    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )\n    : Pattern( filterString )\n    , m_wildcardPattern( toLower( name ), CaseSensitive::No )\n    {}\n\n    bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {\n        return m_wildcardPattern.matches( testCase.name );\n    }\n\n    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )\n    : Pattern( filterString )\n    , m_tag( toLower( tag ) )\n    {}\n\n    bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {\n        return std::find(begin(testCase.lcaseTags),\n                         end(testCase.lcaseTags),\n                         m_tag) != end(testCase.lcaseTags);\n    }\n\n    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )\n    : Pattern( underlyingPattern->name() )\n    , m_underlyingPattern( underlyingPattern )\n    {}\n\n    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {\n        return !m_underlyingPattern->matches( testCase );\n    }\n\n    bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {\n        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );\n    }\n\n    std::string TestSpec::Filter::name() const {\n        std::string name;\n        for( auto const& p : m_patterns )\n            name += p->name();\n        return name;\n    }\n\n    bool TestSpec::hasFilters() const {\n        return !m_filters.empty();\n    }\n\n    bool TestSpec::matches( TestCaseInfo const& testCase ) const {\n        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );\n    }\n\n    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const\n    {\n        Matches matches( m_filters.size() );\n        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){\n            std::vector<TestCase const*> currentMatches;\n            for( auto const& test : testCases )\n                if( isThrowSafe( test, config ) && filter.matches( test ) )\n                    currentMatches.emplace_back( &test );\n            return FilterMatch{ filter.name(), currentMatches };\n        } );\n        return matches;\n    }\n\n    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{\n        return  (m_invalidArgs);\n    }\n\n}\n// end catch_test_spec.cpp\n// start catch_test_spec_parser.cpp\n\nnamespace Catch {\n\n    TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}\n\n    TestSpecParser& TestSpecParser::parse( std::string const& arg ) {\n        m_mode = None;\n        m_exclusion = false;\n        m_arg = m_tagAliases->expandAliases( arg );\n        m_escapeChars.clear();\n        m_substring.reserve(m_arg.size());\n        m_patternName.reserve(m_arg.size());\n        m_realPatternPos = 0;\n\n        for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )\n          //if visitChar fails\n           if( !visitChar( m_arg[m_pos] ) ){\n               m_testSpec.m_invalidArgs.push_back(arg);\n               break;\n           }\n        endMode();\n        return *this;\n    }\n    TestSpec TestSpecParser::testSpec() {\n        addFilter();\n        return m_testSpec;\n    }\n    bool TestSpecParser::visitChar( char c ) {\n        if( (m_mode != EscapedName) && (c == '\\\\') ) {\n            escape();\n            addCharToPattern(c);\n            return true;\n        }else if((m_mode != EscapedName) && (c == ',') )  {\n            return separate();\n        }\n\n        switch( m_mode ) {\n        case None:\n            if( processNoneChar( c ) )\n                return true;\n            break;\n        case Name:\n            processNameChar( c );\n            break;\n        case EscapedName:\n            endMode();\n            addCharToPattern(c);\n            return true;\n        default:\n        case Tag:\n        case QuotedName:\n            if( processOtherChar( c ) )\n                return true;\n            break;\n        }\n\n        m_substring += c;\n        if( !isControlChar( c ) ) {\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n        return true;\n    }\n    // Two of the processing methods return true to signal the caller to return\n    // without adding the given character to the current pattern strings\n    bool TestSpecParser::processNoneChar( char c ) {\n        switch( c ) {\n        case ' ':\n            return true;\n        case '~':\n            m_exclusion = true;\n            return false;\n        case '[':\n            startNewMode( Tag );\n            return false;\n        case '\"':\n            startNewMode( QuotedName );\n            return false;\n        default:\n            startNewMode( Name );\n            return false;\n        }\n    }\n    void TestSpecParser::processNameChar( char c ) {\n        if( c == '[' ) {\n            if( m_substring == \"exclude:\" )\n                m_exclusion = true;\n            else\n                endMode();\n            startNewMode( Tag );\n        }\n    }\n    bool TestSpecParser::processOtherChar( char c ) {\n        if( !isControlChar( c ) )\n            return false;\n        m_substring += c;\n        endMode();\n        return true;\n    }\n    void TestSpecParser::startNewMode( Mode mode ) {\n        m_mode = mode;\n    }\n    void TestSpecParser::endMode() {\n        switch( m_mode ) {\n        case Name:\n        case QuotedName:\n            return addNamePattern();\n        case Tag:\n            return addTagPattern();\n        case EscapedName:\n            revertBackToLastMode();\n            return;\n        case None:\n        default:\n            return startNewMode( None );\n        }\n    }\n    void TestSpecParser::escape() {\n        saveLastMode();\n        m_mode = EscapedName;\n        m_escapeChars.push_back(m_realPatternPos);\n    }\n    bool TestSpecParser::isControlChar( char c ) const {\n        switch( m_mode ) {\n            default:\n                return false;\n            case None:\n                return c == '~';\n            case Name:\n                return c == '[';\n            case EscapedName:\n                return true;\n            case QuotedName:\n                return c == '\"';\n            case Tag:\n                return c == '[' || c == ']';\n        }\n    }\n\n    void TestSpecParser::addFilter() {\n        if( !m_currentFilter.m_patterns.empty() ) {\n            m_testSpec.m_filters.push_back( m_currentFilter );\n            m_currentFilter = TestSpec::Filter();\n        }\n    }\n\n    void TestSpecParser::saveLastMode() {\n      lastMode = m_mode;\n    }\n\n    void TestSpecParser::revertBackToLastMode() {\n      m_mode = lastMode;\n    }\n\n    bool TestSpecParser::separate() {\n      if( (m_mode==QuotedName) || (m_mode==Tag) ){\n         //invalid argument, signal failure to previous scope.\n         m_mode = None;\n         m_pos = m_arg.size();\n         m_substring.clear();\n         m_patternName.clear();\n         m_realPatternPos = 0;\n         return false;\n      }\n      endMode();\n      addFilter();\n      return true; //success\n    }\n\n    std::string TestSpecParser::preprocessPattern() {\n        std::string token = m_patternName;\n        for (std::size_t i = 0; i < m_escapeChars.size(); ++i)\n            token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);\n        m_escapeChars.clear();\n        if (startsWith(token, \"exclude:\")) {\n            m_exclusion = true;\n            token = token.substr(8);\n        }\n\n        m_patternName.clear();\n        m_realPatternPos = 0;\n\n        return token;\n    }\n\n    void TestSpecParser::addNamePattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);\n            if (m_exclusion)\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    void TestSpecParser::addTagPattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            // If the tag pattern is the \"hide and tag\" shorthand (e.g. [.foo])\n            // we have to create a separate hide tag and shorten the real one\n            if (token.size() > 1 && token[0] == '.') {\n                token.erase(token.begin());\n                TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(\".\", m_substring);\n                if (m_exclusion) {\n                    pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n                }\n                m_currentFilter.m_patterns.push_back(pattern);\n            }\n\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);\n\n            if (m_exclusion) {\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            }\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    TestSpec parseTestSpec( std::string const& arg ) {\n        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();\n    }\n\n} // namespace Catch\n// end catch_test_spec_parser.cpp\n// start catch_timer.cpp\n\n#include <chrono>\n\nstatic const uint64_t nanosecondsInSecond = 1000000000;\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t {\n        return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();\n    }\n\n    namespace {\n        auto estimateClockResolution() -> uint64_t {\n            uint64_t sum = 0;\n            static const uint64_t iterations = 1000000;\n\n            auto startTime = getCurrentNanosecondsSinceEpoch();\n\n            for( std::size_t i = 0; i < iterations; ++i ) {\n\n                uint64_t ticks;\n                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();\n                do {\n                    ticks = getCurrentNanosecondsSinceEpoch();\n                } while( ticks == baseTicks );\n\n                auto delta = ticks - baseTicks;\n                sum += delta;\n\n                // If we have been calibrating for over 3 seconds -- the clock\n                // is terrible and we should move on.\n                // TBD: How to signal that the measured resolution is probably wrong?\n                if (ticks > startTime + 3 * nanosecondsInSecond) {\n                    return sum / ( i + 1u );\n                }\n            }\n\n            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers\n            // - and potentially do more iterations if there's a high variance.\n            return sum/iterations;\n        }\n    }\n    auto getEstimatedClockResolution() -> uint64_t {\n        static auto s_resolution = estimateClockResolution();\n        return s_resolution;\n    }\n\n    void Timer::start() {\n       m_nanoseconds = getCurrentNanosecondsSinceEpoch();\n    }\n    auto Timer::getElapsedNanoseconds() const -> uint64_t {\n        return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;\n    }\n    auto Timer::getElapsedMicroseconds() const -> uint64_t {\n        return getElapsedNanoseconds()/1000;\n    }\n    auto Timer::getElapsedMilliseconds() const -> unsigned int {\n        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);\n    }\n    auto Timer::getElapsedSeconds() const -> double {\n        return getElapsedMicroseconds()/1000000.0;\n    }\n\n} // namespace Catch\n// end catch_timer.cpp\n// start catch_tostring.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#    pragma clang diagnostic ignored \"-Wglobal-constructors\"\n#endif\n\n// Enable specific decls locally\n#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#endif\n\n#include <cmath>\n#include <iomanip>\n\nnamespace Catch {\n\nnamespace Detail {\n\n    const std::string unprintableString = \"{?}\";\n\n    namespace {\n        const int hexThreshold = 255;\n\n        struct Endianness {\n            enum Arch { Big, Little };\n\n            static Arch which() {\n                int one = 1;\n                // If the lowest byte we read is non-zero, we can assume\n                // that little endian format is used.\n                auto value = *reinterpret_cast<char*>(&one);\n                return value ? Little : Big;\n            }\n        };\n    }\n\n    std::string rawMemoryToString( const void *object, std::size_t size ) {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>( size ), inc = 1;\n        if( Endianness::which() == Endianness::Little ) {\n            i = end-1;\n            end = inc = -1;\n        }\n\n        unsigned char const *bytes = static_cast<unsigned char const *>(object);\n        ReusableStringStream rss;\n        rss << \"0x\" << std::setfill('0') << std::hex;\n        for( ; i != end; i += inc )\n             rss << std::setw(2) << static_cast<unsigned>(bytes[i]);\n       return rss.str();\n    }\n}\n\ntemplate<typename T>\nstd::string fpToString( T value, int precision ) {\n    if (Catch::isnan(value)) {\n        return \"nan\";\n    }\n\n    ReusableStringStream rss;\n    rss << std::setprecision( precision )\n        << std::fixed\n        << value;\n    std::string d = rss.str();\n    std::size_t i = d.find_last_not_of( '0' );\n    if( i != std::string::npos && i != d.size()-1 ) {\n        if( d[i] == '.' )\n            i++;\n        d = d.substr( 0, i+1 );\n    }\n    return d;\n}\n\n//// ======================================================= ////\n//\n//   Out-of-line defs for full specialization of StringMaker\n//\n//// ======================================================= ////\n\nstd::string StringMaker<std::string>::convert(const std::string& str) {\n    if (!getCurrentContext().getConfig()->showInvisibles()) {\n        return '\"' + str + '\"';\n    }\n\n    std::string s(\"\\\"\");\n    for (char c : str) {\n        switch (c) {\n        case '\\n':\n            s.append(\"\\\\n\");\n            break;\n        case '\\t':\n            s.append(\"\\\\t\");\n            break;\n        default:\n            s.push_back(c);\n            break;\n        }\n    }\n    s.append(\"\\\"\");\n    return s;\n}\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::string_view>::convert(std::string_view str) {\n    return ::Catch::Detail::stringify(std::string{ str });\n}\n#endif\n\nstd::string StringMaker<char const*>::convert(char const* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<char*>::convert(char* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n\n#ifdef CATCH_CONFIG_WCHAR\nstd::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {\n    std::string s;\n    s.reserve(wstr.size());\n    for (auto c : wstr) {\n        s += (c <= 0xff) ? static_cast<char>(c) : '?';\n    }\n    return ::Catch::Detail::stringify(s);\n}\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {\n    return StringMaker<std::wstring>::convert(std::wstring(str));\n}\n# endif\n\nstd::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<wchar_t *>::convert(wchar_t * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n#endif\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n#include <cstddef>\nstd::string StringMaker<std::byte>::convert(std::byte value) {\n    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));\n}\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n\nstd::string StringMaker<int>::convert(int value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long>::convert(long value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long long>::convert(long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<unsigned int>::convert(unsigned int value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long>::convert(unsigned long value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long long>::convert(unsigned long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<bool>::convert(bool b) {\n    return b ? \"true\" : \"false\";\n}\n\nstd::string StringMaker<signed char>::convert(signed char value) {\n    if (value == '\\r') {\n        return \"'\\\\r'\";\n    } else if (value == '\\f') {\n        return \"'\\\\f'\";\n    } else if (value == '\\n') {\n        return \"'\\\\n'\";\n    } else if (value == '\\t') {\n        return \"'\\\\t'\";\n    } else if ('\\0' <= value && value < ' ') {\n        return ::Catch::Detail::stringify(static_cast<unsigned int>(value));\n    } else {\n        char chstr[] = \"' '\";\n        chstr[1] = value;\n        return chstr;\n    }\n}\nstd::string StringMaker<char>::convert(char c) {\n    return ::Catch::Detail::stringify(static_cast<signed char>(c));\n}\nstd::string StringMaker<unsigned char>::convert(unsigned char c) {\n    return ::Catch::Detail::stringify(static_cast<char>(c));\n}\n\nstd::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {\n    return \"nullptr\";\n}\n\nint StringMaker<float>::precision = 5;\n\nstd::string StringMaker<float>::convert(float value) {\n    return fpToString(value, precision) + 'f';\n}\n\nint StringMaker<double>::precision = 10;\n\nstd::string StringMaker<double>::convert(double value) {\n    return fpToString(value, precision);\n}\n\nstd::string ratio_string<std::atto>::symbol() { return \"a\"; }\nstd::string ratio_string<std::femto>::symbol() { return \"f\"; }\nstd::string ratio_string<std::pico>::symbol() { return \"p\"; }\nstd::string ratio_string<std::nano>::symbol() { return \"n\"; }\nstd::string ratio_string<std::micro>::symbol() { return \"u\"; }\nstd::string ratio_string<std::milli>::symbol() { return \"m\"; }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_tostring.cpp\n// start catch_totals.cpp\n\nnamespace Catch {\n\n    Counts Counts::operator - ( Counts const& other ) const {\n        Counts diff;\n        diff.passed = passed - other.passed;\n        diff.failed = failed - other.failed;\n        diff.failedButOk = failedButOk - other.failedButOk;\n        return diff;\n    }\n\n    Counts& Counts::operator += ( Counts const& other ) {\n        passed += other.passed;\n        failed += other.failed;\n        failedButOk += other.failedButOk;\n        return *this;\n    }\n\n    std::size_t Counts::total() const {\n        return passed + failed + failedButOk;\n    }\n    bool Counts::allPassed() const {\n        return failed == 0 && failedButOk == 0;\n    }\n    bool Counts::allOk() const {\n        return failed == 0;\n    }\n\n    Totals Totals::operator - ( Totals const& other ) const {\n        Totals diff;\n        diff.assertions = assertions - other.assertions;\n        diff.testCases = testCases - other.testCases;\n        return diff;\n    }\n\n    Totals& Totals::operator += ( Totals const& other ) {\n        assertions += other.assertions;\n        testCases += other.testCases;\n        return *this;\n    }\n\n    Totals Totals::delta( Totals const& prevTotals ) const {\n        Totals diff = *this - prevTotals;\n        if( diff.assertions.failed > 0 )\n            ++diff.testCases.failed;\n        else if( diff.assertions.failedButOk > 0 )\n            ++diff.testCases.failedButOk;\n        else\n            ++diff.testCases.passed;\n        return diff;\n    }\n\n}\n// end catch_totals.cpp\n// start catch_uncaught_exceptions.cpp\n\n// start catch_config_uncaught_exceptions.hpp\n\n//              Copyright Catch2 Authors\n// Distributed under the Boost Software License, Version 1.0.\n//   (See accompanying file LICENSE_1_0.txt or copy at\n//        https://www.boost.org/LICENSE_1_0.txt)\n\n// SPDX-License-Identifier: BSL-1.0\n\n#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n\n#if defined(_MSC_VER)\n#  if _MSC_VER >= 1900 // Visual Studio 2015 or newer\n#    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#  endif\n#endif\n\n#include <exception>\n\n#if defined(__cpp_lib_uncaught_exceptions) \\\n    && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif // __cpp_lib_uncaught_exceptions\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif\n\n#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n// end catch_config_uncaught_exceptions.hpp\n#include <exception>\n\nnamespace Catch {\n    bool uncaught_exceptions() {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        return false;\n#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n        return std::uncaught_exceptions() > 0;\n#else\n        return std::uncaught_exception();\n#endif\n  }\n} // end namespace Catch\n// end catch_uncaught_exceptions.cpp\n// start catch_version.cpp\n\n#include <ostream>\n\nnamespace Catch {\n\n    Version::Version\n        (   unsigned int _majorVersion,\n            unsigned int _minorVersion,\n            unsigned int _patchNumber,\n            char const * const _branchName,\n            unsigned int _buildNumber )\n    :   majorVersion( _majorVersion ),\n        minorVersion( _minorVersion ),\n        patchNumber( _patchNumber ),\n        branchName( _branchName ),\n        buildNumber( _buildNumber )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, Version const& version ) {\n        os  << version.majorVersion << '.'\n            << version.minorVersion << '.'\n            << version.patchNumber;\n        // branchName is never null -> 0th char is \\0 if it is empty\n        if (version.branchName[0]) {\n            os << '-' << version.branchName\n               << '.' << version.buildNumber;\n        }\n        return os;\n    }\n\n    Version const& libraryVersion() {\n        static Version version( 2, 13, 9, \"\", 0 );\n        return version;\n    }\n\n}\n// end catch_version.cpp\n// start catch_wildcard_pattern.cpp\n\nnamespace Catch {\n\n    WildcardPattern::WildcardPattern( std::string const& pattern,\n                                      CaseSensitive::Choice caseSensitivity )\n    :   m_caseSensitivity( caseSensitivity ),\n        m_pattern( normaliseString( pattern ) )\n    {\n        if( startsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 1 );\n            m_wildcard = WildcardAtStart;\n        }\n        if( endsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );\n            m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );\n        }\n    }\n\n    bool WildcardPattern::matches( std::string const& str ) const {\n        switch( m_wildcard ) {\n            case NoWildcard:\n                return m_pattern == normaliseString( str );\n            case WildcardAtStart:\n                return endsWith( normaliseString( str ), m_pattern );\n            case WildcardAtEnd:\n                return startsWith( normaliseString( str ), m_pattern );\n            case WildcardAtBothEnds:\n                return contains( normaliseString( str ), m_pattern );\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown enum\" );\n        }\n    }\n\n    std::string WildcardPattern::normaliseString( std::string const& str ) const {\n        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );\n    }\n}\n// end catch_wildcard_pattern.cpp\n// start catch_xmlwriter.cpp\n\n#include <iomanip>\n#include <type_traits>\n\nnamespace Catch {\n\nnamespace {\n\n    size_t trailingBytes(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return 2;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return 3;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return 4;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    uint32_t headerValue(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return c & 0x1F;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return c & 0x0F;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return c & 0x07;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    void hexEscapeChar(std::ostream& os, unsigned char c) {\n        std::ios_base::fmtflags f(os.flags());\n        os << \"\\\\x\"\n            << std::uppercase << std::hex << std::setfill('0') << std::setw(2)\n            << static_cast<int>(c);\n        os.flags(f);\n    }\n\n    bool shouldNewline(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));\n    }\n\n    bool shouldIndent(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));\n    }\n\n} // anonymous namespace\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )\n    :   m_str( str ),\n        m_forWhat( forWhat )\n    {}\n\n    void XmlEncode::encodeTo( std::ostream& os ) const {\n        // Apostrophe escaping not necessary if we always use \" to write attributes\n        // (see: http://www.w3.org/TR/xml/#syntax)\n\n        for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {\n            unsigned char c = m_str[idx];\n            switch (c) {\n            case '<':   os << \"&lt;\"; break;\n            case '&':   os << \"&amp;\"; break;\n\n            case '>':\n                // See: http://www.w3.org/TR/xml/#syntax\n                if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')\n                    os << \"&gt;\";\n                else\n                    os << c;\n                break;\n\n            case '\\\"':\n                if (m_forWhat == ForAttributes)\n                    os << \"&quot;\";\n                else\n                    os << c;\n                break;\n\n            default:\n                // Check for control characters and invalid utf-8\n\n                // Escape control characters in standard ascii\n                // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // Plain ASCII: Write it to stream\n                if (c < 0x7F) {\n                    os << c;\n                    break;\n                }\n\n                // UTF-8 territory\n                // Check if the encoding is valid and if it is not, hex escape bytes.\n                // Important: We do not check the exact decoded values for validity, only the encoding format\n                // First check that this bytes is a valid lead byte:\n                // This means that it is not encoded as 1111 1XXX\n                // Or as 10XX XXXX\n                if (c <  0xC0 ||\n                    c >= 0xF8) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                auto encBytes = trailingBytes(c);\n                // Are there enough bytes left to avoid accessing out-of-bounds memory?\n                if (idx + encBytes - 1 >= m_str.size()) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n                // The header is valid, check data\n                // The next encBytes bytes must together be a valid utf-8\n                // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)\n                bool valid = true;\n                uint32_t value = headerValue(c);\n                for (std::size_t n = 1; n < encBytes; ++n) {\n                    unsigned char nc = m_str[idx + n];\n                    valid &= ((nc & 0xC0) == 0x80);\n                    value = (value << 6) | (nc & 0x3F);\n                }\n\n                if (\n                    // Wrong bit pattern of following bytes\n                    (!valid) ||\n                    // Overlong encodings\n                    (value < 0x80) ||\n                    (0x80 <= value && value < 0x800   && encBytes > 2) ||\n                    (0x800 < value && value < 0x10000 && encBytes > 3) ||\n                    // Encoded value out of range\n                    (value >= 0x110000)\n                    ) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // If we got here, this is in fact a valid(ish) utf-8 sequence\n                for (std::size_t n = 0; n < encBytes; ++n) {\n                    os << m_str[idx + n];\n                }\n                idx += encBytes - 1;\n                break;\n            }\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n        xmlEncode.encodeTo( os );\n        return os;\n    }\n\n    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )\n    :   m_writer( writer ),\n        m_fmt(fmt)\n    {}\n\n    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept\n    :   m_writer( other.m_writer ),\n        m_fmt(other.m_fmt)\n    {\n        other.m_writer = nullptr;\n        other.m_fmt = XmlFormatting::None;\n    }\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {\n        if ( m_writer ) {\n            m_writer->endElement();\n        }\n        m_writer = other.m_writer;\n        other.m_writer = nullptr;\n        m_fmt = other.m_fmt;\n        other.m_fmt = XmlFormatting::None;\n        return *this;\n    }\n\n    XmlWriter::ScopedElement::~ScopedElement() {\n        if (m_writer) {\n            m_writer->endElement(m_fmt);\n        }\n    }\n\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {\n        m_writer->writeText( text, fmt );\n        return *this;\n    }\n\n    XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )\n    {\n        writeDeclaration();\n    }\n\n    XmlWriter::~XmlWriter() {\n        while (!m_tags.empty()) {\n            endElement();\n        }\n        newlineIfNecessary();\n    }\n\n    XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {\n        ensureTagClosed();\n        newlineIfNecessary();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n            m_indent += \"  \";\n        }\n        m_os << '<' << name;\n        m_tags.push_back( name );\n        m_tagIsOpen = true;\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {\n        ScopedElement scoped( this, fmt );\n        startElement( name, fmt );\n        return scoped;\n    }\n\n    XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {\n        m_indent = m_indent.substr(0, m_indent.size() - 2);\n\n        if( m_tagIsOpen ) {\n            m_os << \"/>\";\n            m_tagIsOpen = false;\n        } else {\n            newlineIfNecessary();\n            if (shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << \"</\" << m_tags.back() << \">\";\n        }\n        m_os << std::flush;\n        applyFormatting(fmt);\n        m_tags.pop_back();\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {\n        if( !name.empty() && !attribute.empty() )\n            m_os << ' ' << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {\n        m_os << ' ' << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {\n        if( !text.empty() ){\n            bool tagWasOpen = m_tagIsOpen;\n            ensureTagClosed();\n            if (tagWasOpen && shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << XmlEncode( text );\n            applyFormatting(fmt);\n        }\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {\n        ensureTagClosed();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n        }\n        m_os << \"<!--\" << text << \"-->\";\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    void XmlWriter::writeStylesheetRef( std::string const& url ) {\n        m_os << \"<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" << url << \"\\\"?>\\n\";\n    }\n\n    XmlWriter& XmlWriter::writeBlankLine() {\n        ensureTagClosed();\n        m_os << '\\n';\n        return *this;\n    }\n\n    void XmlWriter::ensureTagClosed() {\n        if( m_tagIsOpen ) {\n            m_os << '>' << std::flush;\n            newlineIfNecessary();\n            m_tagIsOpen = false;\n        }\n    }\n\n    void XmlWriter::applyFormatting(XmlFormatting fmt) {\n        m_needsNewline = shouldNewline(fmt);\n    }\n\n    void XmlWriter::writeDeclaration() {\n        m_os << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n    }\n\n    void XmlWriter::newlineIfNecessary() {\n        if( m_needsNewline ) {\n            m_os << std::endl;\n            m_needsNewline = false;\n        }\n    }\n}\n// end catch_xmlwriter.cpp\n// start catch_reporter_bases.cpp\n\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result) {\n        result.getExpandedExpression();\n    }\n\n    // Because formatting using c++ streams is stateful, drop down to C is required\n    // Alternatively we could use stringstream, but its performance is... not good.\n    std::string getFormattedDuration( double duration ) {\n        // Max exponent + 1 is required to represent the whole part\n        // + 1 for decimal point\n        // + 3 for the 3 decimal places\n        // + 1 for null terminator\n        const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;\n        char buffer[maxDoubleSize];\n\n        // Save previous errno, to prevent sprintf from overwriting it\n        ErrnoGuard guard;\n#ifdef _MSC_VER\n        sprintf_s(buffer, \"%.3f\", duration);\n#else\n        std::sprintf(buffer, \"%.3f\", duration);\n#endif\n        return std::string(buffer);\n    }\n\n    bool shouldShowDuration( IConfig const& config, double duration ) {\n        if ( config.showDurations() == ShowDurations::Always ) {\n            return true;\n        }\n        if ( config.showDurations() == ShowDurations::Never ) {\n            return false;\n        }\n        const double min = config.minDuration();\n        return min >= 0 && duration >= min;\n    }\n\n    std::string serializeFilters( std::vector<std::string> const& container ) {\n        ReusableStringStream oss;\n        bool first = true;\n        for (auto&& filter : container)\n        {\n            if (!first)\n                oss << ' ';\n            else\n                first = false;\n\n            oss << filter;\n        }\n        return oss.str();\n    }\n\n    TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)\n        :StreamingReporterBase(_config) {}\n\n    std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {\n        return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };\n    }\n\n    void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}\n\n    bool TestEventListenerBase::assertionEnded(AssertionStats const &) {\n        return false;\n    }\n\n} // end namespace Catch\n// end catch_reporter_bases.cpp\n// start catch_reporter_compact.cpp\n\nnamespace {\n\n#ifdef CATCH_PLATFORM_MAC\n    const char* failedString() { return \"FAILED\"; }\n    const char* passedString() { return \"PASSED\"; }\n#else\n    const char* failedString() { return \"failed\"; }\n    const char* passedString() { return \"passed\"; }\n#endif\n\n    // Colour::LightGrey\n    Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }\n\n    std::string bothOrAll( std::size_t count ) {\n        return count == 1 ? std::string() :\n               count == 2 ? \"both \" : \"all \" ;\n    }\n\n} // anon namespace\n\nnamespace Catch {\nnamespace {\n// Colour, message variants:\n// - white: No tests ran.\n// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.\n// - white: Passed [both/all] N test cases (no assertions).\n// -   red: Failed N tests cases, failed M assertions.\n// - green: Passed [both/all] N tests cases with M assertions.\nvoid printTotals(std::ostream& out, const Totals& totals) {\n    if (totals.testCases.total() == 0) {\n        out << \"No tests ran.\";\n    } else if (totals.testCases.failed == totals.testCases.total()) {\n        Colour colour(Colour::ResultError);\n        const std::string qualify_assertions_failed =\n            totals.assertions.failed == totals.assertions.total() ?\n            bothOrAll(totals.assertions.failed) : std::string();\n        out <<\n            \"Failed \" << bothOrAll(totals.testCases.failed)\n            << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << qualify_assertions_failed <<\n            pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else if (totals.assertions.total() == 0) {\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.total())\n            << pluralise(totals.testCases.total(), \"test case\")\n            << \" (no assertions).\";\n    } else if (totals.assertions.failed) {\n        Colour colour(Colour::ResultError);\n        out <<\n            \"Failed \" << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else {\n        Colour colour(Colour::ResultSuccess);\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.passed)\n            << pluralise(totals.testCases.passed, \"test case\") <<\n            \" with \" << pluralise(totals.assertions.passed, \"assertion\") << '.';\n    }\n}\n\n// Implementation of CompactReporter formatting\nclass AssertionPrinter {\npublic:\n    AssertionPrinter& operator= (AssertionPrinter const&) = delete;\n    AssertionPrinter(AssertionPrinter const&) = delete;\n    AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream)\n        , result(_stats.assertionResult)\n        , messages(_stats.infoMessages)\n        , itMessage(_stats.infoMessages.begin())\n        , printInfoMessages(_printInfoMessages) {}\n\n    void print() {\n        printSourceInfo();\n\n        itMessage = messages.begin();\n\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            printResultType(Colour::ResultSuccess, passedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            if (!result.hasExpression())\n                printRemainingMessages(Colour::None);\n            else\n                printRemainingMessages();\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk())\n                printResultType(Colour::ResultSuccess, failedString() + std::string(\" - but was ok\"));\n            else\n                printResultType(Colour::Error, failedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            printRemainingMessages();\n            break;\n        case ResultWas::ThrewException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"unexpected exception with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::FatalErrorCondition:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"fatal error condition with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::DidntThrowException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"expected exception, got none\");\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::Info:\n            printResultType(Colour::None, \"info\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::Warning:\n            printResultType(Colour::None, \"warning\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::ExplicitFailure:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"explicitly\");\n            printRemainingMessages(Colour::None);\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            printResultType(Colour::Error, \"** internal error **\");\n            break;\n        }\n    }\n\nprivate:\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << ':';\n    }\n\n    void printResultType(Colour::Code colour, std::string const& passOrFail) const {\n        if (!passOrFail.empty()) {\n            {\n                Colour colourGuard(colour);\n                stream << ' ' << passOrFail;\n            }\n            stream << ':';\n        }\n    }\n\n    void printIssue(std::string const& issue) const {\n        stream << ' ' << issue;\n    }\n\n    void printExpressionWas() {\n        if (result.hasExpression()) {\n            stream << ';';\n            {\n                Colour colour(dimColour());\n                stream << \" expression was:\";\n            }\n            printOriginalExpression();\n        }\n    }\n\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            stream << ' ' << result.getExpression();\n        }\n    }\n\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            {\n                Colour colour(dimColour());\n                stream << \" for: \";\n            }\n            stream << result.getExpandedExpression();\n        }\n    }\n\n    void printMessage() {\n        if (itMessage != messages.end()) {\n            stream << \" '\" << itMessage->message << '\\'';\n            ++itMessage;\n        }\n    }\n\n    void printRemainingMessages(Colour::Code colour = dimColour()) {\n        if (itMessage == messages.end())\n            return;\n\n        const auto itEnd = messages.cend();\n        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));\n\n        {\n            Colour colourGuard(colour);\n            stream << \" with \" << pluralise(N, \"message\") << ':';\n        }\n\n        while (itMessage != itEnd) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || itMessage->type != ResultWas::Info) {\n                printMessage();\n                if (itMessage != itEnd) {\n                    Colour colourGuard(dimColour());\n                    stream << \" and\";\n                }\n                continue;\n            }\n            ++itMessage;\n        }\n    }\n\nprivate:\n    std::ostream& stream;\n    AssertionResult const& result;\n    std::vector<MessageInfo> messages;\n    std::vector<MessageInfo>::const_iterator itMessage;\n    bool printInfoMessages;\n};\n\n} // anon namespace\n\n        std::string CompactReporter::getDescription() {\n            return \"Reports test results on a single line, suitable for IDEs\";\n        }\n\n        void CompactReporter::noMatchingTestCases( std::string const& spec ) {\n            stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n        }\n\n        void CompactReporter::assertionStarting( AssertionInfo const& ) {}\n\n        bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n\n            stream << std::endl;\n            return true;\n        }\n\n        void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {\n            double dur = _sectionStats.durationInSeconds;\n            if ( shouldShowDuration( *m_config, dur ) ) {\n                stream << getFormattedDuration( dur ) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n            }\n        }\n\n        void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {\n            printTotals( stream, _testRunStats.totals );\n            stream << '\\n' << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n        CompactReporter::~CompactReporter() {}\n\n    CATCH_REGISTER_REPORTER( \"compact\", CompactReporter )\n\n} // end namespace Catch\n// end catch_reporter_compact.cpp\n// start catch_reporter_console.cpp\n\n#include <cfloat>\n#include <cstdio>\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n // Note that 4062 (not all labels are handled and default is missing) is enabled\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic push\n// For simplicity, benchmarking-only helpers are always enabled\n#  pragma clang diagnostic ignored \"-Wunused-function\"\n#endif\n\nnamespace Catch {\n\nnamespace {\n\n// Formatter impl for ConsoleReporter\nclass ConsoleAssertionPrinter {\npublic:\n    ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream),\n        stats(_stats),\n        result(_stats.assertionResult),\n        colour(Colour::None),\n        message(result.getMessage()),\n        messages(_stats.infoMessages),\n        printInfoMessages(_printInfoMessages) {\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            colour = Colour::Success;\n            passOrFail = \"PASSED\";\n            //if( result.hasMessage() )\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk()) {\n                colour = Colour::Success;\n                passOrFail = \"FAILED - but was ok\";\n            } else {\n                colour = Colour::Error;\n                passOrFail = \"FAILED\";\n            }\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ThrewException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to unexpected exception with \";\n            if (_stats.infoMessages.size() == 1)\n                messageLabel += \"message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel += \"messages\";\n            break;\n        case ResultWas::FatalErrorCondition:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to a fatal error condition\";\n            break;\n        case ResultWas::DidntThrowException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"because no exception was thrown where one was expected\";\n            break;\n        case ResultWas::Info:\n            messageLabel = \"info\";\n            break;\n        case ResultWas::Warning:\n            messageLabel = \"warning\";\n            break;\n        case ResultWas::ExplicitFailure:\n            passOrFail = \"FAILED\";\n            colour = Colour::Error;\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"explicitly with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"explicitly with messages\";\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            passOrFail = \"** internal error **\";\n            colour = Colour::Error;\n            break;\n        }\n    }\n\n    void print() const {\n        printSourceInfo();\n        if (stats.totals.assertions.total() > 0) {\n            printResultType();\n            printOriginalExpression();\n            printReconstructedExpression();\n        } else {\n            stream << '\\n';\n        }\n        printMessage();\n    }\n\nprivate:\n    void printResultType() const {\n        if (!passOrFail.empty()) {\n            Colour colourGuard(colour);\n            stream << passOrFail << \":\\n\";\n        }\n    }\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            Colour colourGuard(Colour::OriginalExpression);\n            stream << \"  \";\n            stream << result.getExpressionInMacro();\n            stream << '\\n';\n        }\n    }\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            stream << \"with expansion:\\n\";\n            Colour colourGuard(Colour::ReconstructedExpression);\n            stream << Column(result.getExpandedExpression()).indent(2) << '\\n';\n        }\n    }\n    void printMessage() const {\n        if (!messageLabel.empty())\n            stream << messageLabel << ':' << '\\n';\n        for (auto const& msg : messages) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || msg.type != ResultWas::Info)\n                stream << Column(msg.message).indent(2) << '\\n';\n        }\n    }\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << \": \";\n    }\n\n    std::ostream& stream;\n    AssertionStats const& stats;\n    AssertionResult const& result;\n    Colour::Code colour;\n    std::string passOrFail;\n    std::string messageLabel;\n    std::string message;\n    std::vector<MessageInfo> messages;\n    bool printInfoMessages;\n};\n\nstd::size_t makeRatio(std::size_t number, std::size_t total) {\n    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;\n    return (ratio == 0 && number > 0) ? 1 : ratio;\n}\n\nstd::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {\n    if (i > j && i > k)\n        return i;\n    else if (j > k)\n        return j;\n    else\n        return k;\n}\n\nstruct ColumnInfo {\n    enum Justification { Left, Right };\n    std::string name;\n    int width;\n    Justification justification;\n};\nstruct ColumnBreak {};\nstruct RowBreak {};\n\nclass Duration {\n    enum class Unit {\n        Auto,\n        Nanoseconds,\n        Microseconds,\n        Milliseconds,\n        Seconds,\n        Minutes\n    };\n    static const uint64_t s_nanosecondsInAMicrosecond = 1000;\n    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;\n    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;\n    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;\n\n    double m_inNanoseconds;\n    Unit m_units;\n\npublic:\n    explicit Duration(double inNanoseconds, Unit units = Unit::Auto)\n        : m_inNanoseconds(inNanoseconds),\n        m_units(units) {\n        if (m_units == Unit::Auto) {\n            if (m_inNanoseconds < s_nanosecondsInAMicrosecond)\n                m_units = Unit::Nanoseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMillisecond)\n                m_units = Unit::Microseconds;\n            else if (m_inNanoseconds < s_nanosecondsInASecond)\n                m_units = Unit::Milliseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMinute)\n                m_units = Unit::Seconds;\n            else\n                m_units = Unit::Minutes;\n        }\n\n    }\n\n    auto value() const -> double {\n        switch (m_units) {\n        case Unit::Microseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);\n        case Unit::Milliseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);\n        case Unit::Seconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);\n        case Unit::Minutes:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);\n        default:\n            return m_inNanoseconds;\n        }\n    }\n    auto unitsAsString() const -> std::string {\n        switch (m_units) {\n        case Unit::Nanoseconds:\n            return \"ns\";\n        case Unit::Microseconds:\n            return \"us\";\n        case Unit::Milliseconds:\n            return \"ms\";\n        case Unit::Seconds:\n            return \"s\";\n        case Unit::Minutes:\n            return \"m\";\n        default:\n            return \"** internal error **\";\n        }\n\n    }\n    friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {\n        return os << duration.value() << ' ' << duration.unitsAsString();\n    }\n};\n} // end anon namespace\n\nclass TablePrinter {\n    std::ostream& m_os;\n    std::vector<ColumnInfo> m_columnInfos;\n    std::ostringstream m_oss;\n    int m_currentColumn = -1;\n    bool m_isOpen = false;\n\npublic:\n    TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )\n    :   m_os( os ),\n        m_columnInfos( std::move( columnInfos ) ) {}\n\n    auto columnInfos() const -> std::vector<ColumnInfo> const& {\n        return m_columnInfos;\n    }\n\n    void open() {\n        if (!m_isOpen) {\n            m_isOpen = true;\n            *this << RowBreak();\n\n\t\t\tColumns headerCols;\n\t\t\tSpacer spacer(2);\n\t\t\tfor (auto const& info : m_columnInfos) {\n\t\t\t\theaderCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));\n\t\t\t\theaderCols += spacer;\n\t\t\t}\n\t\t\tm_os << headerCols << '\\n';\n\n            m_os << Catch::getLineOfChars<'-'>() << '\\n';\n        }\n    }\n    void close() {\n        if (m_isOpen) {\n            *this << RowBreak();\n            m_os << std::endl;\n            m_isOpen = false;\n        }\n    }\n\n    template<typename T>\n    friend TablePrinter& operator << (TablePrinter& tp, T const& value) {\n        tp.m_oss << value;\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {\n        auto colStr = tp.m_oss.str();\n        const auto strSize = colStr.size();\n        tp.m_oss.str(\"\");\n        tp.open();\n        if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {\n            tp.m_currentColumn = -1;\n            tp.m_os << '\\n';\n        }\n        tp.m_currentColumn++;\n\n        auto colInfo = tp.m_columnInfos[tp.m_currentColumn];\n        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))\n            ? std::string(colInfo.width - (strSize + 1), ' ')\n            : std::string();\n        if (colInfo.justification == ColumnInfo::Left)\n            tp.m_os << colStr << padding << ' ';\n        else\n            tp.m_os << padding << colStr << ' ';\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {\n        if (tp.m_currentColumn > 0) {\n            tp.m_os << '\\n';\n            tp.m_currentColumn = -1;\n        }\n        return tp;\n    }\n};\n\nConsoleReporter::ConsoleReporter(ReporterConfig const& config)\n    : StreamingReporterBase(config),\n    m_tablePrinter(new TablePrinter(config.stream(),\n        [&config]() -> std::vector<ColumnInfo> {\n        if (config.fullConfig()->benchmarkNoAnalysis())\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"     samples\", 14, ColumnInfo::Right },\n                { \"  iterations\", 14, ColumnInfo::Right },\n                { \"        mean\", 14, ColumnInfo::Right }\n            };\n        }\n        else\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"samples      mean       std dev\", 14, ColumnInfo::Right },\n                { \"iterations   low mean   low std dev\", 14, ColumnInfo::Right },\n                { \"estimated    high mean  high std dev\", 14, ColumnInfo::Right }\n            };\n        }\n    }())) {}\nConsoleReporter::~ConsoleReporter() = default;\n\nstd::string ConsoleReporter::getDescription() {\n    return \"Reports test results as plain lines of text\";\n}\n\nvoid ConsoleReporter::noMatchingTestCases(std::string const& spec) {\n    stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n}\n\nvoid ConsoleReporter::reportInvalidArguments(std::string const&arg){\n    stream << \"Invalid Filter: \" << arg << std::endl;\n}\n\nvoid ConsoleReporter::assertionStarting(AssertionInfo const&) {}\n\nbool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {\n    AssertionResult const& result = _assertionStats.assertionResult;\n\n    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n    // Drop out if result was successful but we're not printing them.\n    if (!includeResults && result.getResultType() != ResultWas::Warning)\n        return false;\n\n    lazyPrint();\n\n    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);\n    printer.print();\n    stream << std::endl;\n    return true;\n}\n\nvoid ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {\n    m_tablePrinter->close();\n    m_headerPrinted = false;\n    StreamingReporterBase::sectionStarting(_sectionInfo);\n}\nvoid ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {\n    m_tablePrinter->close();\n    if (_sectionStats.missingAssertions) {\n        lazyPrint();\n        Colour colour(Colour::ResultError);\n        if (m_sectionStack.size() > 1)\n            stream << \"\\nNo assertions in section\";\n        else\n            stream << \"\\nNo assertions in test case\";\n        stream << \" '\" << _sectionStats.sectionInfo.name << \"'\\n\" << std::endl;\n    }\n    double dur = _sectionStats.durationInSeconds;\n    if (shouldShowDuration(*m_config, dur)) {\n        stream << getFormattedDuration(dur) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n    }\n    if (m_headerPrinted) {\n        m_headerPrinted = false;\n    }\n    StreamingReporterBase::sectionEnded(_sectionStats);\n}\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\nvoid ConsoleReporter::benchmarkPreparing(std::string const& name) {\n\tlazyPrintWithoutClosingBenchmarkTable();\n\n\tauto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));\n\n\tbool firstLine = true;\n\tfor (auto line : nameCol) {\n\t\tif (!firstLine)\n\t\t\t(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();\n\t\telse\n\t\t\tfirstLine = false;\n\n\t\t(*m_tablePrinter) << line << ColumnBreak();\n\t}\n}\n\nvoid ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {\n    (*m_tablePrinter) << info.samples << ColumnBreak()\n        << info.iterations << ColumnBreak();\n    if (!m_config->benchmarkNoAnalysis())\n        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();\n}\nvoid ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {\n    if (m_config->benchmarkNoAnalysis())\n    {\n        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();\n    }\n    else\n    {\n        (*m_tablePrinter) << ColumnBreak()\n            << Duration(stats.mean.point.count()) << ColumnBreak()\n            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()\n            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();\n    }\n}\n\nvoid ConsoleReporter::benchmarkFailed(std::string const& error) {\n\tColour colour(Colour::Red);\n    (*m_tablePrinter)\n        << \"Benchmark failed (\" << error << ')'\n        << ColumnBreak() << RowBreak();\n}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nvoid ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {\n    m_tablePrinter->close();\n    StreamingReporterBase::testCaseEnded(_testCaseStats);\n    m_headerPrinted = false;\n}\nvoid ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {\n    if (currentGroupInfo.used) {\n        printSummaryDivider();\n        stream << \"Summary for group '\" << _testGroupStats.groupInfo.name << \"':\\n\";\n        printTotals(_testGroupStats.totals);\n        stream << '\\n' << std::endl;\n    }\n    StreamingReporterBase::testGroupEnded(_testGroupStats);\n}\nvoid ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {\n    printTotalsDivider(_testRunStats.totals);\n    printTotals(_testRunStats.totals);\n    stream << std::endl;\n    StreamingReporterBase::testRunEnded(_testRunStats);\n}\nvoid ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {\n    StreamingReporterBase::testRunStarting(_testInfo);\n    printTestFilters();\n}\n\nvoid ConsoleReporter::lazyPrint() {\n\n    m_tablePrinter->close();\n    lazyPrintWithoutClosingBenchmarkTable();\n}\n\nvoid ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {\n\n    if (!currentTestRunInfo.used)\n        lazyPrintRunInfo();\n    if (!currentGroupInfo.used)\n        lazyPrintGroupInfo();\n\n    if (!m_headerPrinted) {\n        printTestCaseAndSectionHeader();\n        m_headerPrinted = true;\n    }\n}\nvoid ConsoleReporter::lazyPrintRunInfo() {\n    stream << '\\n' << getLineOfChars<'~'>() << '\\n';\n    Colour colour(Colour::SecondaryText);\n    stream << currentTestRunInfo->name\n        << \" is a Catch v\" << libraryVersion() << \" host application.\\n\"\n        << \"Run with -? for options\\n\\n\";\n\n    if (m_config->rngSeed() != 0)\n        stream << \"Randomness seeded to: \" << m_config->rngSeed() << \"\\n\\n\";\n\n    currentTestRunInfo.used = true;\n}\nvoid ConsoleReporter::lazyPrintGroupInfo() {\n    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {\n        printClosedHeader(\"Group: \" + currentGroupInfo->name);\n        currentGroupInfo.used = true;\n    }\n}\nvoid ConsoleReporter::printTestCaseAndSectionHeader() {\n    assert(!m_sectionStack.empty());\n    printOpenHeader(currentTestCaseInfo->name);\n\n    if (m_sectionStack.size() > 1) {\n        Colour colourGuard(Colour::Headers);\n\n        auto\n            it = m_sectionStack.begin() + 1, // Skip first section (test case)\n            itEnd = m_sectionStack.end();\n        for (; it != itEnd; ++it)\n            printHeaderString(it->name, 2);\n    }\n\n    SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;\n\n    stream << getLineOfChars<'-'>() << '\\n';\n    Colour colourGuard(Colour::FileName);\n    stream << lineInfo << '\\n';\n    stream << getLineOfChars<'.'>() << '\\n' << std::endl;\n}\n\nvoid ConsoleReporter::printClosedHeader(std::string const& _name) {\n    printOpenHeader(_name);\n    stream << getLineOfChars<'.'>() << '\\n';\n}\nvoid ConsoleReporter::printOpenHeader(std::string const& _name) {\n    stream << getLineOfChars<'-'>() << '\\n';\n    {\n        Colour colourGuard(Colour::Headers);\n        printHeaderString(_name);\n    }\n}\n\n// if string has a : in first line will set indent to follow it on\n// subsequent lines\nvoid ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {\n    std::size_t i = _string.find(\": \");\n    if (i != std::string::npos)\n        i += 2;\n    else\n        i = 0;\n    stream << Column(_string).indent(indent + i).initialIndent(indent) << '\\n';\n}\n\nstruct SummaryColumn {\n\n    SummaryColumn( std::string _label, Colour::Code _colour )\n    :   label( std::move( _label ) ),\n        colour( _colour ) {}\n    SummaryColumn addRow( std::size_t count ) {\n        ReusableStringStream rss;\n        rss << count;\n        std::string row = rss.str();\n        for (auto& oldRow : rows) {\n            while (oldRow.size() < row.size())\n                oldRow = ' ' + oldRow;\n            while (oldRow.size() > row.size())\n                row = ' ' + row;\n        }\n        rows.push_back(row);\n        return *this;\n    }\n\n    std::string label;\n    Colour::Code colour;\n    std::vector<std::string> rows;\n\n};\n\nvoid ConsoleReporter::printTotals( Totals const& totals ) {\n    if (totals.testCases.total() == 0) {\n        stream << Colour(Colour::Warning) << \"No tests ran\\n\";\n    } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {\n        stream << Colour(Colour::ResultSuccess) << \"All tests passed\";\n        stream << \" (\"\n            << pluralise(totals.assertions.passed, \"assertion\") << \" in \"\n            << pluralise(totals.testCases.passed, \"test case\") << ')'\n            << '\\n';\n    } else {\n\n        std::vector<SummaryColumn> columns;\n        columns.push_back(SummaryColumn(\"\", Colour::None)\n                          .addRow(totals.testCases.total())\n                          .addRow(totals.assertions.total()));\n        columns.push_back(SummaryColumn(\"passed\", Colour::Success)\n                          .addRow(totals.testCases.passed)\n                          .addRow(totals.assertions.passed));\n        columns.push_back(SummaryColumn(\"failed\", Colour::ResultError)\n                          .addRow(totals.testCases.failed)\n                          .addRow(totals.assertions.failed));\n        columns.push_back(SummaryColumn(\"failed as expected\", Colour::ResultExpectedFailure)\n                          .addRow(totals.testCases.failedButOk)\n                          .addRow(totals.assertions.failedButOk));\n\n        printSummaryRow(\"test cases\", columns, 0);\n        printSummaryRow(\"assertions\", columns, 1);\n    }\n}\nvoid ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {\n    for (auto col : cols) {\n        std::string value = col.rows[row];\n        if (col.label.empty()) {\n            stream << label << \": \";\n            if (value != \"0\")\n                stream << value;\n            else\n                stream << Colour(Colour::Warning) << \"- none -\";\n        } else if (value != \"0\") {\n            stream << Colour(Colour::LightGrey) << \" | \";\n            stream << Colour(col.colour)\n                << value << ' ' << col.label;\n        }\n    }\n    stream << '\\n';\n}\n\nvoid ConsoleReporter::printTotalsDivider(Totals const& totals) {\n    if (totals.testCases.total() > 0) {\n        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());\n        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());\n        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());\n        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)++;\n        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)--;\n\n        stream << Colour(Colour::Error) << std::string(failedRatio, '=');\n        stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');\n        if (totals.testCases.allPassed())\n            stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');\n        else\n            stream << Colour(Colour::Success) << std::string(passedRatio, '=');\n    } else {\n        stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');\n    }\n    stream << '\\n';\n}\nvoid ConsoleReporter::printSummaryDivider() {\n    stream << getLineOfChars<'-'>() << '\\n';\n}\n\nvoid ConsoleReporter::printTestFilters() {\n    if (m_config->testSpec().hasFilters()) {\n        Colour guard(Colour::BrightYellow);\n        stream << \"Filters: \" << serializeFilters(m_config->getTestsOrTags()) << '\\n';\n    }\n}\n\nCATCH_REGISTER_REPORTER(\"console\", ConsoleReporter)\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic pop\n#endif\n// end catch_reporter_console.cpp\n// start catch_reporter_junit.cpp\n\n#include <cassert>\n#include <sstream>\n#include <ctime>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    namespace {\n        std::string getCurrentTimestamp() {\n            // Beware, this is not reentrant because of backward compatibility issues\n            // Also, UTC only, again because of backward compatibility (%z is C++11)\n            time_t rawtime;\n            std::time(&rawtime);\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &rawtime);\n#else\n            std::tm* timeInfo;\n            timeInfo = std::gmtime(&rawtime);\n#endif\n\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp, timeStampSize-1);\n        }\n\n        std::string fileNameTag(const std::vector<std::string> &tags) {\n            auto it = std::find_if(begin(tags),\n                                   end(tags),\n                                   [] (std::string const& tag) {return tag.front() == '#'; });\n            if (it != tags.end())\n                return it->substr(1);\n            return std::string();\n        }\n\n        // Formats the duration in seconds to 3 decimal places.\n        // This is done because some genius defined Maven Surefire schema\n        // in a way that only accepts 3 decimal places, and tools like\n        // Jenkins use that schema for validation JUnit reporter output.\n        std::string formatDuration( double seconds ) {\n            ReusableStringStream rss;\n            rss << std::fixed << std::setprecision( 3 ) << seconds;\n            return rss.str();\n        }\n\n    } // anonymous namespace\n\n    JunitReporter::JunitReporter( ReporterConfig const& _config )\n        :   CumulativeReporterBase( _config ),\n            xml( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n            m_reporterPrefs.shouldReportAllAssertions = true;\n        }\n\n    JunitReporter::~JunitReporter() {}\n\n    std::string JunitReporter::getDescription() {\n        return \"Reports test results in an XML format that looks like Ant's junitreport target\";\n    }\n\n    void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}\n\n    void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {\n        CumulativeReporterBase::testRunStarting( runInfo );\n        xml.startElement( \"testsuites\" );\n    }\n\n    void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        suiteTimer.start();\n        stdOutForSuite.clear();\n        stdErrForSuite.clear();\n        unexpectedExceptions = 0;\n        CumulativeReporterBase::testGroupStarting( groupInfo );\n    }\n\n    void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {\n        m_okToFail = testCaseInfo.okToFail();\n    }\n\n    bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )\n            unexpectedExceptions++;\n        return CumulativeReporterBase::assertionEnded( assertionStats );\n    }\n\n    void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        stdOutForSuite += testCaseStats.stdOut;\n        stdErrForSuite += testCaseStats.stdErr;\n        CumulativeReporterBase::testCaseEnded( testCaseStats );\n    }\n\n    void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        double suiteTime = suiteTimer.getElapsedSeconds();\n        CumulativeReporterBase::testGroupEnded( testGroupStats );\n        writeGroup( *m_testGroups.back(), suiteTime );\n    }\n\n    void JunitReporter::testRunEndedCumulative() {\n        xml.endElement();\n    }\n\n    void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {\n        XmlWriter::ScopedElement e = xml.scopedElement( \"testsuite\" );\n\n        TestGroupStats const& stats = groupNode.value;\n        xml.writeAttribute( \"name\", stats.groupInfo.name );\n        xml.writeAttribute( \"errors\", unexpectedExceptions );\n        xml.writeAttribute( \"failures\", stats.totals.assertions.failed-unexpectedExceptions );\n        xml.writeAttribute( \"tests\", stats.totals.assertions.total() );\n        xml.writeAttribute( \"hostname\", \"tbd\" ); // !TBD\n        if( m_config->showDurations() == ShowDurations::Never )\n            xml.writeAttribute( \"time\", \"\" );\n        else\n            xml.writeAttribute( \"time\", formatDuration( suiteTime ) );\n        xml.writeAttribute( \"timestamp\", getCurrentTimestamp() );\n\n        // Write properties if there are any\n        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {\n            auto properties = xml.scopedElement(\"properties\");\n            if (m_config->hasTestFilters()) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"filters\")\n                    .writeAttribute(\"value\", serializeFilters(m_config->getTestsOrTags()));\n            }\n            if (m_config->rngSeed() != 0) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"random-seed\")\n                    .writeAttribute(\"value\", m_config->rngSeed());\n            }\n        }\n\n        // Write test cases\n        for( auto const& child : groupNode.children )\n            writeTestCase( *child );\n\n        xml.scopedElement( \"system-out\" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );\n        xml.scopedElement( \"system-err\" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );\n    }\n\n    void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {\n        TestCaseStats const& stats = testCaseNode.value;\n\n        // All test cases have exactly one section - which represents the\n        // test case itself. That section may have 0-n nested sections\n        assert( testCaseNode.children.size() == 1 );\n        SectionNode const& rootSection = *testCaseNode.children.front();\n\n        std::string className = stats.testInfo.className;\n\n        if( className.empty() ) {\n            className = fileNameTag(stats.testInfo.tags);\n            if ( className.empty() )\n                className = \"global\";\n        }\n\n        if ( !m_config->name().empty() )\n            className = m_config->name() + \".\" + className;\n\n        writeSection( className, \"\", rootSection, stats.testInfo.okToFail() );\n    }\n\n    void JunitReporter::writeSection( std::string const& className,\n                                      std::string const& rootName,\n                                      SectionNode const& sectionNode,\n                                      bool testOkToFail) {\n        std::string name = trim( sectionNode.stats.sectionInfo.name );\n        if( !rootName.empty() )\n            name = rootName + '/' + name;\n\n        if( !sectionNode.assertions.empty() ||\n            !sectionNode.stdOut.empty() ||\n            !sectionNode.stdErr.empty() ) {\n            XmlWriter::ScopedElement e = xml.scopedElement( \"testcase\" );\n            if( className.empty() ) {\n                xml.writeAttribute( \"classname\", name );\n                xml.writeAttribute( \"name\", \"root\" );\n            }\n            else {\n                xml.writeAttribute( \"classname\", className );\n                xml.writeAttribute( \"name\", name );\n            }\n            xml.writeAttribute( \"time\", formatDuration( sectionNode.stats.durationInSeconds ) );\n            // This is not ideal, but it should be enough to mimic gtest's\n            // junit output.\n            // Ideally the JUnit reporter would also handle `skipTest`\n            // events and write those out appropriately.\n            xml.writeAttribute( \"status\", \"run\" );\n\n            if (sectionNode.stats.assertions.failedButOk) {\n                xml.scopedElement(\"skipped\")\n                    .writeAttribute(\"message\", \"TEST_CASE tagged with !mayfail\");\n            }\n\n            writeAssertions( sectionNode );\n\n            if( !sectionNode.stdOut.empty() )\n                xml.scopedElement( \"system-out\" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );\n            if( !sectionNode.stdErr.empty() )\n                xml.scopedElement( \"system-err\" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );\n        }\n        for( auto const& childNode : sectionNode.childSections )\n            if( className.empty() )\n                writeSection( name, \"\", *childNode, testOkToFail );\n            else\n                writeSection( className, name, *childNode, testOkToFail );\n    }\n\n    void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {\n        for( auto const& assertion : sectionNode.assertions )\n            writeAssertion( assertion );\n    }\n\n    void JunitReporter::writeAssertion( AssertionStats const& stats ) {\n        AssertionResult const& result = stats.assertionResult;\n        if( !result.isOk() ) {\n            std::string elementName;\n            switch( result.getResultType() ) {\n                case ResultWas::ThrewException:\n                case ResultWas::FatalErrorCondition:\n                    elementName = \"error\";\n                    break;\n                case ResultWas::ExplicitFailure:\n                case ResultWas::ExpressionFailed:\n                case ResultWas::DidntThrowException:\n                    elementName = \"failure\";\n                    break;\n\n                // We should never see these here:\n                case ResultWas::Info:\n                case ResultWas::Warning:\n                case ResultWas::Ok:\n                case ResultWas::Unknown:\n                case ResultWas::FailureBit:\n                case ResultWas::Exception:\n                    elementName = \"internalError\";\n                    break;\n            }\n\n            XmlWriter::ScopedElement e = xml.scopedElement( elementName );\n\n            xml.writeAttribute( \"message\", result.getExpression() );\n            xml.writeAttribute( \"type\", result.getTestMacroName() );\n\n            ReusableStringStream rss;\n            if (stats.totals.assertions.total() > 0) {\n                rss << \"FAILED\" << \":\\n\";\n                if (result.hasExpression()) {\n                    rss << \"  \";\n                    rss << result.getExpressionInMacro();\n                    rss << '\\n';\n                }\n                if (result.hasExpandedExpression()) {\n                    rss << \"with expansion:\\n\";\n                    rss << Column(result.getExpandedExpression()).indent(2) << '\\n';\n                }\n            } else {\n                rss << '\\n';\n            }\n\n            if( !result.getMessage().empty() )\n                rss << result.getMessage() << '\\n';\n            for( auto const& msg : stats.infoMessages )\n                if( msg.type == ResultWas::Info )\n                    rss << msg.message << '\\n';\n\n            rss << \"at \" << result.getSourceInfo();\n            xml.writeText( rss.str(), XmlFormatting::Newline );\n        }\n    }\n\n    CATCH_REGISTER_REPORTER( \"junit\", JunitReporter )\n\n} // end namespace Catch\n// end catch_reporter_junit.cpp\n// start catch_reporter_listening.cpp\n\n#include <cassert>\n\nnamespace Catch {\n\n    ListeningReporter::ListeningReporter() {\n        // We will assume that listeners will always want all assertions\n        m_preferences.shouldReportAllAssertions = true;\n    }\n\n    void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {\n        m_listeners.push_back( std::move( listener ) );\n    }\n\n    void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {\n        assert(!m_reporter && \"Listening reporter can wrap only 1 real reporter\");\n        m_reporter = std::move( reporter );\n        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;\n    }\n\n    ReporterPreferences ListeningReporter::getPreferences() const {\n        return m_preferences;\n    }\n\n    std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {\n        return std::set<Verbosity>{ };\n    }\n\n    void ListeningReporter::noMatchingTestCases( std::string const& spec ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->noMatchingTestCases( spec );\n        }\n        m_reporter->noMatchingTestCases( spec );\n    }\n\n    void ListeningReporter::reportInvalidArguments(std::string const&arg){\n        for ( auto const& listener : m_listeners ) {\n            listener->reportInvalidArguments( arg );\n        }\n        m_reporter->reportInvalidArguments( arg );\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void ListeningReporter::benchmarkPreparing( std::string const& name ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkPreparing(name);\n\t\t}\n\t\tm_reporter->benchmarkPreparing(name);\n\t}\n    void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkStarting( benchmarkInfo );\n        }\n        m_reporter->benchmarkStarting( benchmarkInfo );\n    }\n    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkEnded( benchmarkStats );\n        }\n        m_reporter->benchmarkEnded( benchmarkStats );\n    }\n\n\tvoid ListeningReporter::benchmarkFailed( std::string const& error ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkFailed(error);\n\t\t}\n\t\tm_reporter->benchmarkFailed(error);\n\t}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunStarting( testRunInfo );\n        }\n        m_reporter->testRunStarting( testRunInfo );\n    }\n\n    void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupStarting( groupInfo );\n        }\n        m_reporter->testGroupStarting( groupInfo );\n    }\n\n    void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseStarting( testInfo );\n        }\n        m_reporter->testCaseStarting( testInfo );\n    }\n\n    void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionStarting( sectionInfo );\n        }\n        m_reporter->sectionStarting( sectionInfo );\n    }\n\n    void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->assertionStarting( assertionInfo );\n        }\n        m_reporter->assertionStarting( assertionInfo );\n    }\n\n    // The return value indicates if the messages buffer should be cleared:\n    bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        for( auto const& listener : m_listeners ) {\n            static_cast<void>( listener->assertionEnded( assertionStats ) );\n        }\n        return m_reporter->assertionEnded( assertionStats );\n    }\n\n    void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionEnded( sectionStats );\n        }\n        m_reporter->sectionEnded( sectionStats );\n    }\n\n    void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseEnded( testCaseStats );\n        }\n        m_reporter->testCaseEnded( testCaseStats );\n    }\n\n    void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupEnded( testGroupStats );\n        }\n        m_reporter->testGroupEnded( testGroupStats );\n    }\n\n    void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunEnded( testRunStats );\n        }\n        m_reporter->testRunEnded( testRunStats );\n    }\n\n    void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->skipTest( testInfo );\n        }\n        m_reporter->skipTest( testInfo );\n    }\n\n    bool ListeningReporter::isMulti() const {\n        return true;\n    }\n\n} // end namespace Catch\n// end catch_reporter_listening.cpp\n// start catch_reporter_xml.cpp\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    XmlReporter::XmlReporter( ReporterConfig const& _config )\n    :   StreamingReporterBase( _config ),\n        m_xml(_config.stream())\n    {\n        m_reporterPrefs.shouldRedirectStdOut = true;\n        m_reporterPrefs.shouldReportAllAssertions = true;\n    }\n\n    XmlReporter::~XmlReporter() = default;\n\n    std::string XmlReporter::getDescription() {\n        return \"Reports test results as an XML document\";\n    }\n\n    std::string XmlReporter::getStylesheetRef() const {\n        return std::string();\n    }\n\n    void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {\n        m_xml\n            .writeAttribute( \"filename\", sourceInfo.file )\n            .writeAttribute( \"line\", sourceInfo.line );\n    }\n\n    void XmlReporter::noMatchingTestCases( std::string const& s ) {\n        StreamingReporterBase::noMatchingTestCases( s );\n    }\n\n    void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {\n        StreamingReporterBase::testRunStarting( testInfo );\n        std::string stylesheetRef = getStylesheetRef();\n        if( !stylesheetRef.empty() )\n            m_xml.writeStylesheetRef( stylesheetRef );\n        m_xml.startElement( \"Catch\" );\n        if( !m_config->name().empty() )\n            m_xml.writeAttribute( \"name\", m_config->name() );\n        if (m_config->testSpec().hasFilters())\n            m_xml.writeAttribute( \"filters\", serializeFilters( m_config->getTestsOrTags() ) );\n        if( m_config->rngSeed() != 0 )\n            m_xml.scopedElement( \"Randomness\" )\n                .writeAttribute( \"seed\", m_config->rngSeed() );\n    }\n\n    void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        StreamingReporterBase::testGroupStarting( groupInfo );\n        m_xml.startElement( \"Group\" )\n            .writeAttribute( \"name\", groupInfo.name );\n    }\n\n    void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        StreamingReporterBase::testCaseStarting(testInfo);\n        m_xml.startElement( \"TestCase\" )\n            .writeAttribute( \"name\", trim( testInfo.name ) )\n            .writeAttribute( \"description\", testInfo.description )\n            .writeAttribute( \"tags\", testInfo.tagsAsString() );\n\n        writeSourceInfo( testInfo.lineInfo );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            m_testCaseTimer.start();\n        m_xml.ensureTagClosed();\n    }\n\n    void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        StreamingReporterBase::sectionStarting( sectionInfo );\n        if( m_sectionDepth++ > 0 ) {\n            m_xml.startElement( \"Section\" )\n                .writeAttribute( \"name\", trim( sectionInfo.name ) );\n            writeSourceInfo( sectionInfo.lineInfo );\n            m_xml.ensureTagClosed();\n        }\n    }\n\n    void XmlReporter::assertionStarting( AssertionInfo const& ) { }\n\n    bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {\n\n        AssertionResult const& result = assertionStats.assertionResult;\n\n        bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n        if( includeResults || result.getResultType() == ResultWas::Warning ) {\n            // Print any info messages in <Info> tags.\n            for( auto const& msg : assertionStats.infoMessages ) {\n                if( msg.type == ResultWas::Info && includeResults ) {\n                    m_xml.scopedElement( \"Info\" )\n                            .writeText( msg.message );\n                } else if ( msg.type == ResultWas::Warning ) {\n                    m_xml.scopedElement( \"Warning\" )\n                            .writeText( msg.message );\n                }\n            }\n        }\n\n        // Drop out if result was successful but we're not printing them.\n        if( !includeResults && result.getResultType() != ResultWas::Warning )\n            return true;\n\n        // Print the expression if there is one.\n        if( result.hasExpression() ) {\n            m_xml.startElement( \"Expression\" )\n                .writeAttribute( \"success\", result.succeeded() )\n                .writeAttribute( \"type\", result.getTestMacroName() );\n\n            writeSourceInfo( result.getSourceInfo() );\n\n            m_xml.scopedElement( \"Original\" )\n                .writeText( result.getExpression() );\n            m_xml.scopedElement( \"Expanded\" )\n                .writeText( result.getExpandedExpression() );\n        }\n\n        // And... Print a result applicable to each result type.\n        switch( result.getResultType() ) {\n            case ResultWas::ThrewException:\n                m_xml.startElement( \"Exception\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::FatalErrorCondition:\n                m_xml.startElement( \"FatalErrorCondition\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::Info:\n                m_xml.scopedElement( \"Info\" )\n                    .writeText( result.getMessage() );\n                break;\n            case ResultWas::Warning:\n                // Warning will already have been written\n                break;\n            case ResultWas::ExplicitFailure:\n                m_xml.startElement( \"Failure\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            default:\n                break;\n        }\n\n        if( result.hasExpression() )\n            m_xml.endElement();\n\n        return true;\n    }\n\n    void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {\n        StreamingReporterBase::sectionEnded( sectionStats );\n        if( --m_sectionDepth > 0 ) {\n            XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResults\" );\n            e.writeAttribute( \"successes\", sectionStats.assertions.passed );\n            e.writeAttribute( \"failures\", sectionStats.assertions.failed );\n            e.writeAttribute( \"expectedFailures\", sectionStats.assertions.failedButOk );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                e.writeAttribute( \"durationInSeconds\", sectionStats.durationInSeconds );\n\n            m_xml.endElement();\n        }\n    }\n\n    void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        StreamingReporterBase::testCaseEnded( testCaseStats );\n        XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResult\" );\n        e.writeAttribute( \"success\", testCaseStats.totals.assertions.allOk() );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            e.writeAttribute( \"durationInSeconds\", m_testCaseTimer.getElapsedSeconds() );\n\n        if( !testCaseStats.stdOut.empty() )\n            m_xml.scopedElement( \"StdOut\" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );\n        if( !testCaseStats.stdErr.empty() )\n            m_xml.scopedElement( \"StdErr\" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );\n\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        StreamingReporterBase::testGroupEnded( testGroupStats );\n        // TODO: Check testGroupStats.aborting and act accordingly.\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testGroupStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testGroupStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        StreamingReporterBase::testRunEnded( testRunStats );\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testRunStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testRunStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void XmlReporter::benchmarkPreparing(std::string const& name) {\n        m_xml.startElement(\"BenchmarkResults\")\n            .writeAttribute(\"name\", name);\n    }\n\n    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {\n        m_xml.writeAttribute(\"samples\", info.samples)\n            .writeAttribute(\"resamples\", info.resamples)\n            .writeAttribute(\"iterations\", info.iterations)\n            .writeAttribute(\"clockResolution\", info.clockResolution)\n            .writeAttribute(\"estimatedDuration\", info.estimatedDuration)\n            .writeComment(\"All values in nano seconds\");\n    }\n\n    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {\n        m_xml.startElement(\"mean\")\n            .writeAttribute(\"value\", benchmarkStats.mean.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.mean.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.mean.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.mean.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"standardDeviation\")\n            .writeAttribute(\"value\", benchmarkStats.standardDeviation.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.standardDeviation.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.standardDeviation.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.standardDeviation.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"outliers\")\n            .writeAttribute(\"variance\", benchmarkStats.outlierVariance)\n            .writeAttribute(\"lowMild\", benchmarkStats.outliers.low_mild)\n            .writeAttribute(\"lowSevere\", benchmarkStats.outliers.low_severe)\n            .writeAttribute(\"highMild\", benchmarkStats.outliers.high_mild)\n            .writeAttribute(\"highSevere\", benchmarkStats.outliers.high_severe);\n        m_xml.endElement();\n        m_xml.endElement();\n    }\n\n    void XmlReporter::benchmarkFailed(std::string const &error) {\n        m_xml.scopedElement(\"failed\").\n            writeAttribute(\"message\", error);\n        m_xml.endElement();\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    CATCH_REGISTER_REPORTER( \"xml\", XmlReporter )\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n// end catch_reporter_xml.cpp\n\nnamespace Catch {\n    LeakDetector leakDetector;\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_impl.hpp\n#endif\n\n#ifdef CATCH_CONFIG_MAIN\n// start catch_default_main.hpp\n\n#ifndef __OBJC__\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)\n// Standard C/C++ Win32 Unicode wmain entry point\nextern \"C\" int wmain (int argc, wchar_t * argv[], wchar_t * []) {\n#else\n// Standard C/C++ main entry point\nint main (int argc, char * argv[]) {\n#endif\n\n    return Catch::Session().run( argc, argv );\n}\n\n#else // __OBJC__\n\n// Objective-C entry point\nint main (int argc, char * const argv[]) {\n#if !CATCH_ARC_ENABLED\n    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n#endif\n\n    Catch::registerTestMethods();\n    int result = Catch::Session().run( argc, (char**)argv );\n\n#if !CATCH_ARC_ENABLED\n    [pool drain];\n#endif\n\n    return result;\n}\n\n#endif // __OBJC__\n\n// end catch_default_main.hpp\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n\n#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED\n#  undef CLARA_CONFIG_MAIN\n#endif\n\n#if !defined(CATCH_CONFIG_DISABLE)\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"CATCH_REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CATCH_CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CATCH_CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CATCH_CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( \"CATCH_INFO\", msg )\n#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"CATCH_UNSCOPED_INFO\", msg )\n#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( \"CATCH_WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CATCH_CAPTURE\",__VA_ARGS__ )\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( \"CATCH_SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); CATCH_SUCCEED( #__VA_ARGS__ )\n#else\n#define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define CATCH_BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define CATCH_BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__  )\n#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CHECK( ... ) INTERNAL_CATCH_TEST( \"CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) INTERNAL_CATCH_INFO( \"INFO\", msg )\n#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"UNSCOPED_INFO\", msg )\n#define WARN( msg ) INTERNAL_CATCH_MSG( \"WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CAPTURE\",__VA_ARGS__ )\n\n#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define FAIL( ... ) INTERNAL_CATCH_MSG( \"FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define SUCCEED( ... ) INTERNAL_CATCH_MSG( \"SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); SUCCEED( \"!(\" #__VA_ARGS__ \")\" )\n#else\n#define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n\n#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nusing Catch::Detail::Approx;\n\n#else // CATCH_CONFIG_DISABLE\n\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... )        (void)(0)\n#define CATCH_REQUIRE_FALSE( ... )  (void)(0)\n\n#define CATCH_REQUIRE_THROWS( ... ) (void)(0)\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CATCH_CHECK( ... )         (void)(0)\n#define CATCH_CHECK_FALSE( ... )   (void)(0)\n#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)\n#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))\n#define CATCH_CHECK_NOFAIL( ... )  (void)(0)\n\n#define CATCH_CHECK_THROWS( ... )  (void)(0)\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher )   (void)(0)\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg )          (void)(0)\n#define CATCH_UNSCOPED_INFO( msg ) (void)(0)\n#define CATCH_WARN( msg )          (void)(0)\n#define CATCH_CAPTURE( msg )       (void)(0)\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_METHOD_AS_TEST_CASE( method, ... )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define CATCH_SECTION( ... )\n#define CATCH_DYNAMIC_SECTION( ... )\n#define CATCH_FAIL( ... ) (void)(0)\n#define CATCH_FAIL_CHECK( ... ) (void)(0)\n#define CATCH_SUCCEED( ... ) (void)(0)\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n#define CATCH_GIVEN( desc )\n#define CATCH_AND_GIVEN( desc )\n#define CATCH_WHEN( desc )\n#define CATCH_AND_WHEN( desc )\n#define CATCH_THEN( desc )\n#define CATCH_AND_THEN( desc )\n\n#define CATCH_STATIC_REQUIRE( ... )       (void)(0)\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... )       (void)(0)\n#define REQUIRE_FALSE( ... ) (void)(0)\n\n#define REQUIRE_THROWS( ... ) (void)(0)\n#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CHECK( ... ) (void)(0)\n#define CHECK_FALSE( ... ) (void)(0)\n#define CHECKED_IF( ... ) if (__VA_ARGS__)\n#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))\n#define CHECK_NOFAIL( ... ) (void)(0)\n\n#define CHECK_THROWS( ... )  (void)(0)\n#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) (void)(0)\n\n#define REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) (void)(0)\n#define UNSCOPED_INFO( msg ) (void)(0)\n#define WARN( msg ) (void)(0)\n#define CAPTURE( ... ) (void)(0)\n\n#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define METHOD_AS_TEST_CASE( method, ... )\n#define REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define SECTION( ... )\n#define DYNAMIC_SECTION( ... )\n#define FAIL( ... ) (void)(0)\n#define FAIL_CHECK( ... ) (void)(0)\n#define SUCCEED( ... ) (void)(0)\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n#define STATIC_REQUIRE( ... )       (void)(0)\n#define STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n\n#define GIVEN( desc )\n#define AND_GIVEN( desc )\n#define WHEN( desc )\n#define AND_WHEN( desc )\n#define THEN( desc )\n#define AND_THEN( desc )\n\nusing Catch::Detail::Approx;\n\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n// start catch_reenable_warnings.h\n\n\n#ifdef __clang__\n#    ifdef __ICC // icpc defines the __clang__ macro\n#        pragma warning(pop)\n#    else\n#        pragma clang diagnostic pop\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic pop\n#endif\n\n// end catch_reenable_warnings.h\n// end catch.hpp\n#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/conftest.py",
    "content": "\"\"\"pytest configuration\n\nExtends output capture as needed by pybind11: ignore constructors, optional unordered lines.\nAdds docstring and exceptions message sanitizers.\n\"\"\"\n\nimport contextlib\nimport difflib\nimport gc\nimport multiprocessing\nimport os\nimport re\nimport textwrap\n\nimport pytest\n\n# Early diagnostic for failed imports\nimport pybind11_tests\n\nif os.name != \"nt\":\n    # Full background: https://github.com/pybind/pybind11/issues/4105#issuecomment-1301004592\n    # In a nutshell: fork() after starting threads == flakiness in the form of deadlocks.\n    # It is actually a well-known pitfall, unfortunately without guard rails.\n    # \"forkserver\" is more performant than \"spawn\" (~9s vs ~13s for tests/test_gil_scoped.py,\n    # visit the issuecomment link above for details).\n    # Windows does not have fork() and the associated pitfall, therefore it is best left\n    # running with defaults.\n    multiprocessing.set_start_method(\"forkserver\")\n\n_long_marker = re.compile(r\"([0-9])L\")\n_hexadecimal = re.compile(r\"0x[0-9a-fA-F]+\")\n\n# Avoid collecting Python3 only files\ncollect_ignore = []\n\n\ndef _strip_and_dedent(s):\n    \"\"\"For triple-quote strings\"\"\"\n    return textwrap.dedent(s.lstrip(\"\\n\").rstrip())\n\n\ndef _split_and_sort(s):\n    \"\"\"For output which does not require specific line order\"\"\"\n    return sorted(_strip_and_dedent(s).splitlines())\n\n\ndef _make_explanation(a, b):\n    \"\"\"Explanation for a failed assert -- the a and b arguments are List[str]\"\"\"\n    return [\"--- actual / +++ expected\"] + [\n        line.strip(\"\\n\") for line in difflib.ndiff(a, b)\n    ]\n\n\nclass Output:\n    \"\"\"Basic output post-processing and comparison\"\"\"\n\n    def __init__(self, string):\n        self.string = string\n        self.explanation = []\n\n    def __str__(self):\n        return self.string\n\n    def __eq__(self, other):\n        # Ignore constructor/destructor output which is prefixed with \"###\"\n        a = [\n            line\n            for line in self.string.strip().splitlines()\n            if not line.startswith(\"###\")\n        ]\n        b = _strip_and_dedent(other).splitlines()\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a, b)\n            return False\n\n\nclass Unordered(Output):\n    \"\"\"Custom comparison for output without strict line ordering\"\"\"\n\n    def __eq__(self, other):\n        a = _split_and_sort(self.string)\n        b = _split_and_sort(other)\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a, b)\n            return False\n\n\nclass Capture:\n    def __init__(self, capfd):\n        self.capfd = capfd\n        self.out = \"\"\n        self.err = \"\"\n\n    def __enter__(self):\n        self.capfd.readouterr()\n        return self\n\n    def __exit__(self, *args):\n        self.out, self.err = self.capfd.readouterr()\n\n    def __eq__(self, other):\n        a = Output(self.out)\n        b = other\n        if a == b:\n            return True\n        else:\n            self.explanation = a.explanation\n            return False\n\n    def __str__(self):\n        return self.out\n\n    def __contains__(self, item):\n        return item in self.out\n\n    @property\n    def unordered(self):\n        return Unordered(self.out)\n\n    @property\n    def stderr(self):\n        return Output(self.err)\n\n\n@pytest.fixture\ndef capture(capsys):\n    \"\"\"Extended `capsys` with context manager and custom equality operators\"\"\"\n    return Capture(capsys)\n\n\nclass SanitizedString:\n    def __init__(self, sanitizer):\n        self.sanitizer = sanitizer\n        self.string = \"\"\n        self.explanation = []\n\n    def __call__(self, thing):\n        self.string = self.sanitizer(thing)\n        return self\n\n    def __eq__(self, other):\n        a = self.string\n        b = _strip_and_dedent(other)\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a.splitlines(), b.splitlines())\n            return False\n\n\ndef _sanitize_general(s):\n    s = s.strip()\n    s = s.replace(\"pybind11_tests.\", \"m.\")\n    s = _long_marker.sub(r\"\\1\", s)\n    return s\n\n\ndef _sanitize_docstring(thing):\n    s = thing.__doc__\n    s = _sanitize_general(s)\n    return s\n\n\n@pytest.fixture\ndef doc():\n    \"\"\"Sanitize docstrings and add custom failure explanation\"\"\"\n    return SanitizedString(_sanitize_docstring)\n\n\ndef _sanitize_message(thing):\n    s = str(thing)\n    s = _sanitize_general(s)\n    s = _hexadecimal.sub(\"0\", s)\n    return s\n\n\n@pytest.fixture\ndef msg():\n    \"\"\"Sanitize messages and add custom failure explanation\"\"\"\n    return SanitizedString(_sanitize_message)\n\n\n# noinspection PyUnusedLocal\ndef pytest_assertrepr_compare(op, left, right):\n    \"\"\"Hook to insert custom failure explanation\"\"\"\n    if hasattr(left, \"explanation\"):\n        return left.explanation\n\n\n@contextlib.contextmanager\ndef suppress(exception):\n    \"\"\"Suppress the desired exception\"\"\"\n    try:\n        yield\n    except exception:\n        pass\n\n\ndef gc_collect():\n    \"\"\"Run the garbage collector twice (needed when running\n    reference counting tests with PyPy)\"\"\"\n    gc.collect()\n    gc.collect()\n\n\ndef pytest_configure():\n    pytest.suppress = suppress\n    pytest.gc_collect = gc_collect\n\n\ndef pytest_report_header(config):\n    del config  # Unused.\n    assert (\n        pybind11_tests.compiler_info is not None\n    ), \"Please update pybind11_tests.cpp if this assert fails.\"\n    return (\n        \"C++ Info:\"\n        f\" {pybind11_tests.compiler_info}\"\n        f\" {pybind11_tests.cpp_std}\"\n        f\" {pybind11_tests.PYBIND11_INTERNALS_ID}\"\n        f\" PYBIND11_SIMPLE_GIL_MANAGEMENT={pybind11_tests.PYBIND11_SIMPLE_GIL_MANAGEMENT}\"\n    )\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/constructor_stats.h",
    "content": "#pragma once\n/*\n    tests/constructor_stats.h -- framework for printing and tracking object\n    instance lifetimes in example/test code.\n\n    Copyright (c) 2016 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n\nThis header provides a few useful tools for writing examples or tests that want to check and/or\ndisplay object instance lifetimes.  It requires that you include this header and add the following\nfunction calls to constructors:\n\n    class MyClass {\n        MyClass() { ...; print_default_created(this); }\n        ~MyClass() { ...; print_destroyed(this); }\n        MyClass(const MyClass &c) { ...; print_copy_created(this); }\n        MyClass(MyClass &&c) { ...; print_move_created(this); }\n        MyClass(int a, int b) { ...; print_created(this, a, b); }\n        MyClass &operator=(const MyClass &c) { ...; print_copy_assigned(this); }\n        MyClass &operator=(MyClass &&c) { ...; print_move_assigned(this); }\n\n        ...\n    }\n\nYou can find various examples of these in several of the existing testing .cpp files.  (Of course\nyou don't need to add any of the above constructors/operators that you don't actually have, except\nfor the destructor).\n\nEach of these will print an appropriate message such as:\n\n    ### MyClass @ 0x2801910 created via default constructor\n    ### MyClass @ 0x27fa780 created 100 200\n    ### MyClass @ 0x2801910 destroyed\n    ### MyClass @ 0x27fa780 destroyed\n\nYou can also include extra arguments (such as the 100, 200 in the output above, coming from the\nvalue constructor) for all of the above methods which will be included in the output.\n\nFor testing, each of these also keeps track the created instances and allows you to check how many\nof the various constructors have been invoked from the Python side via code such as:\n\n    from pybind11_tests import ConstructorStats\n    cstats = ConstructorStats.get(MyClass)\n    print(cstats.alive())\n    print(cstats.default_constructions)\n\nNote that `.alive()` should usually be the first thing you call as it invokes Python's garbage\ncollector to actually destroy objects that aren't yet referenced.\n\nFor everything except copy and move constructors and destructors, any extra values given to the\nprint_...() function is stored in a class-specific values list which you can retrieve and inspect\nfrom the ConstructorStats instance `.values()` method.\n\nIn some cases, when you need to track instances of a C++ class not registered with pybind11, you\nneed to add a function returning the ConstructorStats for the C++ class; this can be done with:\n\n    m.def(\"get_special_cstats\", &ConstructorStats::get<SpecialClass>,\npy::return_value_policy::reference)\n\nFinally, you can suppress the output messages, but keep the constructor tracking (for\ninspection/testing in python) by using the functions with `print_` replaced with `track_` (e.g.\n`track_copy_created(this)`).\n\n*/\n\n#include \"pybind11_tests.h\"\n\n#include <list>\n#include <sstream>\n#include <typeindex>\n#include <unordered_map>\n\nclass ConstructorStats {\nprotected:\n    std::unordered_map<void *, int> _instances; // Need a map rather than set because members can\n                                                // shared address with parents\n    std::list<std::string> _values;             // Used to track values\n                                                // (e.g. of value constructors)\npublic:\n    int default_constructions = 0;\n    int copy_constructions = 0;\n    int move_constructions = 0;\n    int copy_assignments = 0;\n    int move_assignments = 0;\n\n    void copy_created(void *inst) {\n        created(inst);\n        copy_constructions++;\n    }\n\n    void move_created(void *inst) {\n        created(inst);\n        move_constructions++;\n    }\n\n    void default_created(void *inst) {\n        created(inst);\n        default_constructions++;\n    }\n\n    void created(void *inst) { ++_instances[inst]; }\n\n    void destroyed(void *inst) {\n        if (--_instances[inst] < 0) {\n            throw std::runtime_error(\"cstats.destroyed() called with unknown \"\n                                     \"instance; potential double-destruction \"\n                                     \"or a missing cstats.created()\");\n        }\n    }\n\n    static void gc() {\n        // Force garbage collection to ensure any pending destructors are invoked:\n#if defined(PYPY_VERSION)\n        PyObject *globals = PyEval_GetGlobals();\n        PyObject *result = PyRun_String(\"import gc\\n\"\n                                        \"for i in range(2):\\n\"\n                                        \"    gc.collect()\\n\",\n                                        Py_file_input,\n                                        globals,\n                                        globals);\n        if (result == nullptr)\n            throw py::error_already_set();\n        Py_DECREF(result);\n#else\n        py::module_::import(\"gc\").attr(\"collect\")();\n#endif\n    }\n\n    int alive() {\n        gc();\n        int total = 0;\n        for (const auto &p : _instances) {\n            if (p.second > 0) {\n                total += p.second;\n            }\n        }\n        return total;\n    }\n\n    void value() {} // Recursion terminator\n    // Takes one or more values, converts them to strings, then stores them.\n    template <typename T, typename... Tmore>\n    void value(const T &v, Tmore &&...args) {\n        std::ostringstream oss;\n        oss << v;\n        _values.push_back(oss.str());\n        value(std::forward<Tmore>(args)...);\n    }\n\n    // Move out stored values\n    py::list values() {\n        py::list l;\n        for (const auto &v : _values) {\n            l.append(py::cast(v));\n        }\n        _values.clear();\n        return l;\n    }\n\n    // Gets constructor stats from a C++ type index\n    static ConstructorStats &get(std::type_index type) {\n        static std::unordered_map<std::type_index, ConstructorStats> all_cstats;\n        return all_cstats[type];\n    }\n\n    // Gets constructor stats from a C++ type\n    template <typename T>\n    static ConstructorStats &get() {\n#if defined(PYPY_VERSION)\n        gc();\n#endif\n        return get(typeid(T));\n    }\n\n    // Gets constructor stats from a Python class\n    static ConstructorStats &get(py::object class_) {\n        auto &internals = py::detail::get_internals();\n        const std::type_index *t1 = nullptr, *t2 = nullptr;\n        try {\n            auto *type_info\n                = internals.registered_types_py.at((PyTypeObject *) class_.ptr()).at(0);\n            for (auto &p : internals.registered_types_cpp) {\n                if (p.second == type_info) {\n                    if (t1) {\n                        t2 = &p.first;\n                        break;\n                    }\n                    t1 = &p.first;\n                }\n            }\n        } catch (const std::out_of_range &) {\n        }\n        if (!t1) {\n            throw std::runtime_error(\"Unknown class passed to ConstructorStats::get()\");\n        }\n        auto &cs1 = get(*t1);\n        // If we have both a t1 and t2 match, one is probably the trampoline class; return\n        // whichever has more constructions (typically one or the other will be 0)\n        if (t2) {\n            auto &cs2 = get(*t2);\n            int cs1_total = cs1.default_constructions + cs1.copy_constructions\n                            + cs1.move_constructions + (int) cs1._values.size();\n            int cs2_total = cs2.default_constructions + cs2.copy_constructions\n                            + cs2.move_constructions + (int) cs2._values.size();\n            if (cs2_total > cs1_total) {\n                return cs2;\n            }\n        }\n        return cs1;\n    }\n};\n\n// To track construction/destruction, you need to call these methods from the various\n// constructors/operators.  The ones that take extra values record the given values in the\n// constructor stats values for later inspection.\ntemplate <class T>\nvoid track_copy_created(T *inst) {\n    ConstructorStats::get<T>().copy_created(inst);\n}\ntemplate <class T>\nvoid track_move_created(T *inst) {\n    ConstructorStats::get<T>().move_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid track_copy_assigned(T *, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.copy_assignments++;\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_move_assigned(T *, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.move_assignments++;\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_default_created(T *inst, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.default_created(inst);\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_created(T *inst, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.created(inst);\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_destroyed(T *inst) {\n    ConstructorStats::get<T>().destroyed(inst);\n}\ntemplate <class T, typename... Values>\nvoid track_values(T *, Values &&...values) {\n    ConstructorStats::get<T>().value(std::forward<Values>(values)...);\n}\n\n/// Don't cast pointers to Python, print them as strings\ninline const char *format_ptrs(const char *p) { return p; }\ntemplate <typename T>\npy::str format_ptrs(T *p) {\n    return \"{:#x}\"_s.format(reinterpret_cast<std::uintptr_t>(p));\n}\ntemplate <typename T>\nauto format_ptrs(T &&x) -> decltype(std::forward<T>(x)) {\n    return std::forward<T>(x);\n}\n\ntemplate <class T, typename... Output>\nvoid print_constr_details(T *inst, const std::string &action, Output &&...output) {\n    py::print(\"###\",\n              py::type_id<T>(),\n              \"@\",\n              format_ptrs(inst),\n              action,\n              format_ptrs(std::forward<Output>(output))...);\n}\n\n// Verbose versions of the above:\ntemplate <class T, typename... Values>\nvoid print_copy_created(T *inst,\n                        Values &&...values) { // NB: this prints, but doesn't store, given values\n    print_constr_details(inst, \"created via copy constructor\", values...);\n    track_copy_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_move_created(T *inst,\n                        Values &&...values) { // NB: this prints, but doesn't store, given values\n    print_constr_details(inst, \"created via move constructor\", values...);\n    track_move_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_copy_assigned(T *inst, Values &&...values) {\n    print_constr_details(inst, \"assigned via copy assignment\", values...);\n    track_copy_assigned(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_move_assigned(T *inst, Values &&...values) {\n    print_constr_details(inst, \"assigned via move assignment\", values...);\n    track_move_assigned(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_default_created(T *inst, Values &&...values) {\n    print_constr_details(inst, \"created via default constructor\", values...);\n    track_default_created(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_created(T *inst, Values &&...values) {\n    print_constr_details(inst, \"created\", values...);\n    track_created(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_destroyed(T *inst, Values &&...values) { // Prints but doesn't store given values\n    print_constr_details(inst, \"destroyed\", values...);\n    track_destroyed(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_values(T *inst, Values &&...values) {\n    print_constr_details(inst, \":\", values...);\n    track_values(inst, values...);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/cross_module_gil_utils.cpp",
    "content": "/*\n    tests/cross_module_gil_utils.cpp -- tools for acquiring GIL from a different module\n\n    Copyright (c) 2019 Google LLC\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n#if defined(PYBIND11_INTERNALS_VERSION)\n#    undef PYBIND11_INTERNALS_VERSION\n#endif\n#define PYBIND11_INTERNALS_VERSION 21814642 // Ensure this module has its own `internals` instance.\n#include <pybind11/pybind11.h>\n\n#include <cstdint>\n#include <string>\n#include <thread>\n\n// This file mimics a DSO that makes pybind11 calls but does not define a\n// PYBIND11_MODULE. The purpose is to test that such a DSO can create a\n// py::gil_scoped_acquire when the running thread is in a GIL-released state.\n//\n// Note that we define a Python module here for convenience, but in general\n// this need not be the case. The typical scenario would be a DSO that implements\n// shared logic used internally by multiple pybind11 modules.\n\nnamespace {\n\nnamespace py = pybind11;\n\nvoid gil_acquire() { py::gil_scoped_acquire gil; }\n\nstd::string gil_multi_acquire_release(unsigned bits) {\n    if ((bits & 0x1u) != 0u) {\n        py::gil_scoped_acquire gil;\n    }\n    if ((bits & 0x2u) != 0u) {\n        py::gil_scoped_release gil;\n    }\n    if ((bits & 0x4u) != 0u) {\n        py::gil_scoped_acquire gil;\n    }\n    if ((bits & 0x8u) != 0u) {\n        py::gil_scoped_release gil;\n    }\n    return PYBIND11_INTERNALS_ID;\n}\n\nstruct CustomAutoGIL {\n    CustomAutoGIL() : gstate(PyGILState_Ensure()) {}\n    ~CustomAutoGIL() { PyGILState_Release(gstate); }\n\n    PyGILState_STATE gstate;\n};\nstruct CustomAutoNoGIL {\n    CustomAutoNoGIL() : save(PyEval_SaveThread()) {}\n    ~CustomAutoNoGIL() { PyEval_RestoreThread(save); }\n\n    PyThreadState *save;\n};\n\ntemplate <typename Acquire, typename Release>\nvoid gil_acquire_inner() {\n    Acquire acquire_outer;\n    Acquire acquire_inner;\n    Release release;\n}\n\ntemplate <typename Acquire, typename Release>\nvoid gil_acquire_nested() {\n    Acquire acquire_outer;\n    Acquire acquire_inner;\n    Release release;\n    auto thread = std::thread(&gil_acquire_inner<Acquire, Release>);\n    thread.join();\n}\n\nconstexpr char kModuleName[] = \"cross_module_gil_utils\";\n\nstruct PyModuleDef moduledef = {\n    PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};\n\n} // namespace\n\n#define ADD_FUNCTION(Name, ...)                                                                   \\\n    PyModule_AddObject(m, Name, PyLong_FromVoidPtr(reinterpret_cast<void *>(&__VA_ARGS__)));\n\nextern \"C\" PYBIND11_EXPORT PyObject *PyInit_cross_module_gil_utils() {\n\n    PyObject *m = PyModule_Create(&moduledef);\n\n    if (m != nullptr) {\n        static_assert(sizeof(&gil_acquire) == sizeof(void *),\n                      \"Function pointer must have the same size as void*\");\n        ADD_FUNCTION(\"gil_acquire_funcaddr\", gil_acquire)\n        ADD_FUNCTION(\"gil_multi_acquire_release_funcaddr\", gil_multi_acquire_release)\n        ADD_FUNCTION(\"gil_acquire_inner_custom_funcaddr\",\n                     gil_acquire_inner<CustomAutoGIL, CustomAutoNoGIL>)\n        ADD_FUNCTION(\"gil_acquire_nested_custom_funcaddr\",\n                     gil_acquire_nested<CustomAutoGIL, CustomAutoNoGIL>)\n        ADD_FUNCTION(\"gil_acquire_inner_pybind11_funcaddr\",\n                     gil_acquire_inner<py::gil_scoped_acquire, py::gil_scoped_release>)\n        ADD_FUNCTION(\"gil_acquire_nested_pybind11_funcaddr\",\n                     gil_acquire_nested<py::gil_scoped_acquire, py::gil_scoped_release>)\n    }\n\n    return m;\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/cross_module_interleaved_error_already_set.cpp",
    "content": "/*\n    Copyright (c) 2022 Google LLC\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/pybind11.h>\n\n// This file mimics a DSO that makes pybind11 calls but does not define a PYBIND11_MODULE,\n// so that the first call of cross_module_error_already_set() triggers the first call of\n// pybind11::detail::get_internals().\n\nnamespace {\n\nnamespace py = pybind11;\n\nvoid interleaved_error_already_set() {\n    PyErr_SetString(PyExc_RuntimeError, \"1st error.\");\n    try {\n        throw py::error_already_set();\n    } catch (const py::error_already_set &) {\n        // The 2nd error could be conditional in a real application.\n        PyErr_SetString(PyExc_RuntimeError, \"2nd error.\");\n    } // Here the 1st error is destroyed before the 2nd error is fetched.\n    // The error_already_set dtor triggers a pybind11::detail::get_internals()\n    // call via pybind11::gil_scoped_acquire.\n    if (PyErr_Occurred()) {\n        throw py::error_already_set();\n    }\n}\n\nconstexpr char kModuleName[] = \"cross_module_interleaved_error_already_set\";\n\nstruct PyModuleDef moduledef = {\n    PyModuleDef_HEAD_INIT, kModuleName, nullptr, 0, nullptr, nullptr, nullptr, nullptr, nullptr};\n\n} // namespace\n\nextern \"C\" PYBIND11_EXPORT PyObject *PyInit_cross_module_interleaved_error_already_set() {\n    PyObject *m = PyModule_Create(&moduledef);\n    if (m != nullptr) {\n        static_assert(sizeof(&interleaved_error_already_set) == sizeof(void *),\n                      \"Function pointer must have the same size as void *\");\n        PyModule_AddObject(\n            m,\n            \"funcaddr\",\n            PyLong_FromVoidPtr(reinterpret_cast<void *>(&interleaved_error_already_set)));\n    }\n    return m;\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/env.py",
    "content": "import platform\nimport sys\n\nimport pytest\n\nLINUX = sys.platform.startswith(\"linux\")\nMACOS = sys.platform.startswith(\"darwin\")\nWIN = sys.platform.startswith(\"win32\") or sys.platform.startswith(\"cygwin\")\n\nCPYTHON = platform.python_implementation() == \"CPython\"\nPYPY = platform.python_implementation() == \"PyPy\"\n\n\ndef deprecated_call():\n    \"\"\"\n    pytest.deprecated_call() seems broken in pytest<3.9.x; concretely, it\n    doesn't work on CPython 3.8.0 with pytest==3.3.2 on Ubuntu 18.04 (#2922).\n\n    This is a narrowed reimplementation of the following PR :(\n    https://github.com/pytest-dev/pytest/pull/4104\n    \"\"\"\n    # TODO: Remove this when testing requires pytest>=3.9.\n    pieces = pytest.__version__.split(\".\")\n    pytest_major_minor = (int(pieces[0]), int(pieces[1]))\n    if pytest_major_minor < (3, 9):\n        return pytest.warns((DeprecationWarning, PendingDeprecationWarning))\n    else:\n        return pytest.deprecated_call()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/extra_python_package/pytest.ini",
    "content": ""
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/extra_python_package/test_files.py",
    "content": "import contextlib\nimport os\nimport string\nimport subprocess\nimport sys\nimport tarfile\nimport zipfile\n\n# These tests must be run explicitly\n# They require CMake 3.15+ (--install)\n\nDIR = os.path.abspath(os.path.dirname(__file__))\nMAIN_DIR = os.path.dirname(os.path.dirname(DIR))\n\nPKGCONFIG = \"\"\"\\\nprefix=${{pcfiledir}}/../../\nincludedir=${{prefix}}/include\n\nName: pybind11\nDescription: Seamless operability between C++11 and Python\nVersion: {VERSION}\nCflags: -I${{includedir}}\n\"\"\"\n\n\nmain_headers = {\n    \"include/pybind11/attr.h\",\n    \"include/pybind11/buffer_info.h\",\n    \"include/pybind11/cast.h\",\n    \"include/pybind11/chrono.h\",\n    \"include/pybind11/common.h\",\n    \"include/pybind11/complex.h\",\n    \"include/pybind11/eigen.h\",\n    \"include/pybind11/embed.h\",\n    \"include/pybind11/eval.h\",\n    \"include/pybind11/functional.h\",\n    \"include/pybind11/gil.h\",\n    \"include/pybind11/iostream.h\",\n    \"include/pybind11/numpy.h\",\n    \"include/pybind11/operators.h\",\n    \"include/pybind11/options.h\",\n    \"include/pybind11/pybind11.h\",\n    \"include/pybind11/pytypes.h\",\n    \"include/pybind11/stl.h\",\n    \"include/pybind11/stl_bind.h\",\n}\n\ndetail_headers = {\n    \"include/pybind11/detail/class.h\",\n    \"include/pybind11/detail/common.h\",\n    \"include/pybind11/detail/descr.h\",\n    \"include/pybind11/detail/init.h\",\n    \"include/pybind11/detail/internals.h\",\n    \"include/pybind11/detail/type_caster_base.h\",\n    \"include/pybind11/detail/typeid.h\",\n}\n\neigen_headers = {\n    \"include/pybind11/eigen/matrix.h\",\n    \"include/pybind11/eigen/tensor.h\",\n}\n\nstl_headers = {\n    \"include/pybind11/stl/filesystem.h\",\n}\n\ncmake_files = {\n    \"share/cmake/pybind11/FindPythonLibsNew.cmake\",\n    \"share/cmake/pybind11/pybind11Common.cmake\",\n    \"share/cmake/pybind11/pybind11Config.cmake\",\n    \"share/cmake/pybind11/pybind11ConfigVersion.cmake\",\n    \"share/cmake/pybind11/pybind11NewTools.cmake\",\n    \"share/cmake/pybind11/pybind11Targets.cmake\",\n    \"share/cmake/pybind11/pybind11Tools.cmake\",\n}\n\npkgconfig_files = {\n    \"share/pkgconfig/pybind11.pc\",\n}\n\npy_files = {\n    \"__init__.py\",\n    \"__main__.py\",\n    \"_version.py\",\n    \"commands.py\",\n    \"py.typed\",\n    \"setup_helpers.py\",\n}\n\nheaders = main_headers | detail_headers | eigen_headers | stl_headers\nsrc_files = headers | cmake_files | pkgconfig_files\nall_files = src_files | py_files\n\n\nsdist_files = {\n    \"pybind11\",\n    \"pybind11/include\",\n    \"pybind11/include/pybind11\",\n    \"pybind11/include/pybind11/detail\",\n    \"pybind11/include/pybind11/eigen\",\n    \"pybind11/include/pybind11/stl\",\n    \"pybind11/share\",\n    \"pybind11/share/cmake\",\n    \"pybind11/share/cmake/pybind11\",\n    \"pybind11/share/pkgconfig\",\n    \"pyproject.toml\",\n    \"setup.cfg\",\n    \"setup.py\",\n    \"LICENSE\",\n    \"MANIFEST.in\",\n    \"README.rst\",\n    \"PKG-INFO\",\n}\n\nlocal_sdist_files = {\n    \".egg-info\",\n    \".egg-info/PKG-INFO\",\n    \".egg-info/SOURCES.txt\",\n    \".egg-info/dependency_links.txt\",\n    \".egg-info/not-zip-safe\",\n    \".egg-info/top_level.txt\",\n}\n\n\ndef read_tz_file(tar: tarfile.TarFile, name: str) -> bytes:\n    start = tar.getnames()[0] + \"/\"\n    inner_file = tar.extractfile(tar.getmember(f\"{start}{name}\"))\n    assert inner_file\n    with contextlib.closing(inner_file) as f:\n        return f.read()\n\n\ndef normalize_line_endings(value: bytes) -> bytes:\n    return value.replace(os.linesep.encode(\"utf-8\"), b\"\\n\")\n\n\ndef test_build_sdist(monkeypatch, tmpdir):\n\n    monkeypatch.chdir(MAIN_DIR)\n\n    subprocess.run(\n        [sys.executable, \"-m\", \"build\", \"--sdist\", f\"--outdir={tmpdir}\"], check=True\n    )\n\n    (sdist,) = tmpdir.visit(\"*.tar.gz\")\n\n    with tarfile.open(str(sdist), \"r:gz\") as tar:\n        start = tar.getnames()[0] + \"/\"\n        version = start[9:-1]\n        simpler = {n.split(\"/\", 1)[-1] for n in tar.getnames()[1:]}\n\n        setup_py = read_tz_file(tar, \"setup.py\")\n        pyproject_toml = read_tz_file(tar, \"pyproject.toml\")\n        pkgconfig = read_tz_file(tar, \"pybind11/share/pkgconfig/pybind11.pc\")\n        cmake_cfg = read_tz_file(\n            tar, \"pybind11/share/cmake/pybind11/pybind11Config.cmake\"\n        )\n\n    assert (\n        'set(pybind11_INCLUDE_DIR \"${PACKAGE_PREFIX_DIR}/include\")'\n        in cmake_cfg.decode(\"utf-8\")\n    )\n\n    files = {f\"pybind11/{n}\" for n in all_files}\n    files |= sdist_files\n    files |= {f\"pybind11{n}\" for n in local_sdist_files}\n    files.add(\"pybind11.egg-info/entry_points.txt\")\n    files.add(\"pybind11.egg-info/requires.txt\")\n    assert simpler == files\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"setup_main.py.in\"), \"rb\") as f:\n        contents = (\n            string.Template(f.read().decode(\"utf-8\"))\n            .substitute(version=version, extra_cmd=\"\")\n            .encode(\"utf-8\")\n        )\n    assert setup_py == contents\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"pyproject.toml\"), \"rb\") as f:\n        contents = f.read()\n    assert pyproject_toml == contents\n\n    simple_version = \".\".join(version.split(\".\")[:3])\n    pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode(\"utf-8\")\n    assert normalize_line_endings(pkgconfig) == pkgconfig_expected\n\n\ndef test_build_global_dist(monkeypatch, tmpdir):\n\n    monkeypatch.chdir(MAIN_DIR)\n    monkeypatch.setenv(\"PYBIND11_GLOBAL_SDIST\", \"1\")\n    subprocess.run(\n        [sys.executable, \"-m\", \"build\", \"--sdist\", \"--outdir\", str(tmpdir)], check=True\n    )\n\n    (sdist,) = tmpdir.visit(\"*.tar.gz\")\n\n    with tarfile.open(str(sdist), \"r:gz\") as tar:\n        start = tar.getnames()[0] + \"/\"\n        version = start[16:-1]\n        simpler = {n.split(\"/\", 1)[-1] for n in tar.getnames()[1:]}\n\n        setup_py = read_tz_file(tar, \"setup.py\")\n        pyproject_toml = read_tz_file(tar, \"pyproject.toml\")\n        pkgconfig = read_tz_file(tar, \"pybind11/share/pkgconfig/pybind11.pc\")\n        cmake_cfg = read_tz_file(\n            tar, \"pybind11/share/cmake/pybind11/pybind11Config.cmake\"\n        )\n\n    assert (\n        'set(pybind11_INCLUDE_DIR \"${PACKAGE_PREFIX_DIR}/include\")'\n        in cmake_cfg.decode(\"utf-8\")\n    )\n\n    files = {f\"pybind11/{n}\" for n in all_files}\n    files |= sdist_files\n    files |= {f\"pybind11_global{n}\" for n in local_sdist_files}\n    assert simpler == files\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"setup_global.py.in\"), \"rb\") as f:\n        contents = (\n            string.Template(f.read().decode())\n            .substitute(version=version, extra_cmd=\"\")\n            .encode(\"utf-8\")\n        )\n        assert setup_py == contents\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"pyproject.toml\"), \"rb\") as f:\n        contents = f.read()\n        assert pyproject_toml == contents\n\n    simple_version = \".\".join(version.split(\".\")[:3])\n    pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode(\"utf-8\")\n    assert normalize_line_endings(pkgconfig) == pkgconfig_expected\n\n\ndef tests_build_wheel(monkeypatch, tmpdir):\n    monkeypatch.chdir(MAIN_DIR)\n\n    subprocess.run(\n        [sys.executable, \"-m\", \"pip\", \"wheel\", \".\", \"-w\", str(tmpdir)], check=True\n    )\n\n    (wheel,) = tmpdir.visit(\"*.whl\")\n\n    files = {f\"pybind11/{n}\" for n in all_files}\n    files |= {\n        \"dist-info/LICENSE\",\n        \"dist-info/METADATA\",\n        \"dist-info/RECORD\",\n        \"dist-info/WHEEL\",\n        \"dist-info/entry_points.txt\",\n        \"dist-info/top_level.txt\",\n    }\n\n    with zipfile.ZipFile(str(wheel)) as z:\n        names = z.namelist()\n\n    trimmed = {n for n in names if \"dist-info\" not in n}\n    trimmed |= {f\"dist-info/{n.split('/', 1)[-1]}\" for n in names if \"dist-info\" in n}\n    assert files == trimmed\n\n\ndef tests_build_global_wheel(monkeypatch, tmpdir):\n    monkeypatch.chdir(MAIN_DIR)\n    monkeypatch.setenv(\"PYBIND11_GLOBAL_SDIST\", \"1\")\n\n    subprocess.run(\n        [sys.executable, \"-m\", \"pip\", \"wheel\", \".\", \"-w\", str(tmpdir)], check=True\n    )\n\n    (wheel,) = tmpdir.visit(\"*.whl\")\n\n    files = {f\"data/data/{n}\" for n in src_files}\n    files |= {f\"data/headers/{n[8:]}\" for n in headers}\n    files |= {\n        \"dist-info/LICENSE\",\n        \"dist-info/METADATA\",\n        \"dist-info/WHEEL\",\n        \"dist-info/top_level.txt\",\n        \"dist-info/RECORD\",\n    }\n\n    with zipfile.ZipFile(str(wheel)) as z:\n        names = z.namelist()\n\n    beginning = names[0].split(\"/\", 1)[0].rsplit(\".\", 1)[0]\n    trimmed = {n[len(beginning) + 1 :] for n in names}\n\n    assert files == trimmed\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/extra_setuptools/pytest.ini",
    "content": ""
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/extra_setuptools/test_setuphelper.py",
    "content": "import os\nimport subprocess\nimport sys\nfrom textwrap import dedent\n\nimport pytest\n\nDIR = os.path.abspath(os.path.dirname(__file__))\nMAIN_DIR = os.path.dirname(os.path.dirname(DIR))\nWIN = sys.platform.startswith(\"win32\") or sys.platform.startswith(\"cygwin\")\n\n\n@pytest.mark.parametrize(\"parallel\", [False, True])\n@pytest.mark.parametrize(\"std\", [11, 0])\ndef test_simple_setup_py(monkeypatch, tmpdir, parallel, std):\n    monkeypatch.chdir(tmpdir)\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    (tmpdir / \"setup.py\").write_text(\n        dedent(\n            f\"\"\"\\\n            import sys\n            sys.path.append({MAIN_DIR!r})\n\n            from setuptools import setup, Extension\n            from pybind11.setup_helpers import build_ext, Pybind11Extension\n\n            std = {std}\n\n            ext_modules = [\n                Pybind11Extension(\n                    \"simple_setup\",\n                    sorted([\"main.cpp\"]),\n                    cxx_std=std,\n                ),\n            ]\n\n            cmdclass = dict()\n            if std == 0:\n                cmdclass[\"build_ext\"] = build_ext\n\n\n            parallel = {parallel}\n            if parallel:\n                from pybind11.setup_helpers import ParallelCompile\n                ParallelCompile().install()\n\n            setup(\n                name=\"simple_setup_package\",\n                cmdclass=cmdclass,\n                ext_modules=ext_modules,\n            )\n            \"\"\"\n        ),\n        encoding=\"ascii\",\n    )\n\n    (tmpdir / \"main.cpp\").write_text(\n        dedent(\n            \"\"\"\\\n            #include <pybind11/pybind11.h>\n\n            int f(int x) {\n                return x * 3;\n            }\n            PYBIND11_MODULE(simple_setup, m) {\n                m.def(\"f\", &f);\n            }\n            \"\"\"\n        ),\n        encoding=\"ascii\",\n    )\n\n    out = subprocess.check_output(\n        [sys.executable, \"setup.py\", \"build_ext\", \"--inplace\"],\n    )\n    if not WIN:\n        assert b\"-g0\" in out\n    out = subprocess.check_output(\n        [sys.executable, \"setup.py\", \"build_ext\", \"--inplace\", \"--force\"],\n        env=dict(os.environ, CFLAGS=\"-g\"),\n    )\n    if not WIN:\n        assert b\"-g0\" not in out\n\n    # Debug helper printout, normally hidden\n    print(out)\n    for item in tmpdir.listdir():\n        print(item.basename)\n\n    assert (\n        len([f for f in tmpdir.listdir() if f.basename.startswith(\"simple_setup\")]) == 1\n    )\n    assert len(list(tmpdir.listdir())) == 4  # two files + output + build_dir\n\n    (tmpdir / \"test.py\").write_text(\n        dedent(\n            \"\"\"\\\n            import simple_setup\n            assert simple_setup.f(3) == 9\n            \"\"\"\n        ),\n        encoding=\"ascii\",\n    )\n\n    subprocess.check_call(\n        [sys.executable, \"test.py\"], stdout=sys.stdout, stderr=sys.stderr\n    )\n\n\ndef test_intree_extensions(monkeypatch, tmpdir):\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    from pybind11.setup_helpers import intree_extensions\n\n    monkeypatch.chdir(tmpdir)\n    root = tmpdir\n    root.ensure_dir()\n    subdir = root / \"dir\"\n    subdir.ensure_dir()\n    src = subdir / \"ext.cpp\"\n    src.ensure()\n    relpath = src.relto(tmpdir)\n    (ext,) = intree_extensions([relpath])\n    assert ext.name == \"ext\"\n    subdir.ensure(\"__init__.py\")\n    (ext,) = intree_extensions([relpath])\n    assert ext.name == \"dir.ext\"\n\n\ndef test_intree_extensions_package_dir(monkeypatch, tmpdir):\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    from pybind11.setup_helpers import intree_extensions\n\n    monkeypatch.chdir(tmpdir)\n    root = tmpdir / \"src\"\n    root.ensure_dir()\n    subdir = root / \"dir\"\n    subdir.ensure_dir()\n    src = subdir / \"ext.cpp\"\n    src.ensure()\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"\": \"src\"})\n    assert ext.name == \"dir.ext\"\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"foo\": \"src\"})\n    assert ext.name == \"foo.dir.ext\"\n    subdir.ensure(\"__init__.py\")\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"\": \"src\"})\n    assert ext.name == \"dir.ext\"\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"foo\": \"src\"})\n    assert ext.name == \"foo.dir.ext\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/local_bindings.h",
    "content": "#pragma once\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\n/// Simple class used to test py::local:\ntemplate <int>\nclass LocalBase {\npublic:\n    explicit LocalBase(int i) : i(i) {}\n    int i = -1;\n};\n\n/// Registered with py::module_local in both main and secondary modules:\nusing LocalType = LocalBase<0>;\n/// Registered without py::module_local in both modules:\nusing NonLocalType = LocalBase<1>;\n/// A second non-local type (for stl_bind tests):\nusing NonLocal2 = LocalBase<2>;\n/// Tests within-module, different-compilation-unit local definition conflict:\nusing LocalExternal = LocalBase<3>;\n/// Mixed: registered local first, then global\nusing MixedLocalGlobal = LocalBase<4>;\n/// Mixed: global first, then local\nusing MixedGlobalLocal = LocalBase<5>;\n\n/// Registered with py::module_local only in the secondary module:\nusing ExternalType1 = LocalBase<6>;\nusing ExternalType2 = LocalBase<7>;\n\nusing LocalVec = std::vector<LocalType>;\nusing LocalVec2 = std::vector<NonLocal2>;\nusing LocalMap = std::unordered_map<std::string, LocalType>;\nusing NonLocalVec = std::vector<NonLocalType>;\nusing NonLocalVec2 = std::vector<NonLocal2>;\nusing NonLocalMap = std::unordered_map<std::string, NonLocalType>;\nusing NonLocalMap2 = std::unordered_map<std::string, uint8_t>;\n\n// Exception that will be caught via the module local translator.\nclass LocalException : public std::exception {\npublic:\n    explicit LocalException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// Exception that will be registered with register_local_exception_translator\nclass LocalSimpleException : public std::exception {\npublic:\n    explicit LocalSimpleException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\nPYBIND11_MAKE_OPAQUE(LocalVec);\nPYBIND11_MAKE_OPAQUE(LocalVec2);\nPYBIND11_MAKE_OPAQUE(LocalMap);\nPYBIND11_MAKE_OPAQUE(NonLocalVec);\n// PYBIND11_MAKE_OPAQUE(NonLocalVec2); // same type as LocalVec2\nPYBIND11_MAKE_OPAQUE(NonLocalMap);\nPYBIND11_MAKE_OPAQUE(NonLocalMap2);\n\n// Simple bindings (used with the above):\ntemplate <typename T, int Adjust = 0, typename... Args>\npy::class_<T> bind_local(Args &&...args) {\n    return py::class_<T>(std::forward<Args>(args)...).def(py::init<int>()).def(\"get\", [](T &i) {\n        return i.i + Adjust;\n    });\n};\n\n// Simulate a foreign library base class (to match the example in the docs):\nnamespace pets {\nclass Pet {\npublic:\n    explicit Pet(std::string name) : name_(std::move(name)) {}\n    std::string name_;\n    const std::string &name() const { return name_; }\n};\n} // namespace pets\n\nstruct MixGL {\n    int i;\n    explicit MixGL(int i) : i{i} {}\n};\nstruct MixGL2 {\n    int i;\n    explicit MixGL2(int i) : i{i} {}\n};\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/object.h",
    "content": "#if !defined(__OBJECT_H)\n#    define __OBJECT_H\n\n#    include \"constructor_stats.h\"\n\n#    include <atomic>\n\n/// Reference counted object base class\nclass Object {\npublic:\n    /// Default constructor\n    Object() { print_default_created(this); }\n\n    /// Copy constructor\n    Object(const Object &) : m_refCount(0) { print_copy_created(this); }\n\n    /// Return the current reference count\n    int getRefCount() const { return m_refCount; };\n\n    /// Increase the object's reference count by one\n    void incRef() const { ++m_refCount; }\n\n    /** \\brief Decrease the reference count of\n     * the object and possibly deallocate it.\n     *\n     * The object will automatically be deallocated once\n     * the reference count reaches zero.\n     */\n    void decRef(bool dealloc = true) const {\n        --m_refCount;\n        if (m_refCount == 0 && dealloc) {\n            delete this;\n        } else if (m_refCount < 0) {\n            throw std::runtime_error(\"Internal error: reference count < 0!\");\n        }\n    }\n\n    virtual std::string toString() const = 0;\n\nprotected:\n    /** \\brief Virtual protected deconstructor.\n     * (Will only be called by \\ref ref)\n     */\n    virtual ~Object() { print_destroyed(this); }\n\nprivate:\n    mutable std::atomic<int> m_refCount{0};\n};\n\n// Tag class used to track constructions of ref objects.  When we track constructors, below, we\n// track and print out the actual class (e.g. ref<MyObject>), and *also* add a fake tracker for\n// ref_tag.  This lets us check that the total number of ref<Anything> constructors/destructors is\n// correct without having to check each individual ref<Whatever> type individually.\nclass ref_tag {};\n\n/**\n * \\brief Reference counting helper\n *\n * The \\a ref refeference template is a simple wrapper to store a\n * pointer to an object. It takes care of increasing and decreasing\n * the reference count of the object. When the last reference goes\n * out of scope, the associated object will be deallocated.\n *\n * \\ingroup libcore\n */\ntemplate <typename T>\nclass ref {\npublic:\n    /// Create a nullptr reference\n    ref() : m_ptr(nullptr) {\n        print_default_created(this);\n        track_default_created((ref_tag *) this);\n    }\n\n    /// Construct a reference from a pointer\n    explicit ref(T *ptr) : m_ptr(ptr) {\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n\n        print_created(this, \"from pointer\", m_ptr);\n        track_created((ref_tag *) this, \"from pointer\");\n    }\n\n    /// Copy constructor\n    ref(const ref &r) : m_ptr(r.m_ptr) {\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n\n        print_copy_created(this, \"with pointer\", m_ptr);\n        track_copy_created((ref_tag *) this);\n    }\n\n    /// Move constructor\n    ref(ref &&r) noexcept : m_ptr(r.m_ptr) {\n        r.m_ptr = nullptr;\n\n        print_move_created(this, \"with pointer\", m_ptr);\n        track_move_created((ref_tag *) this);\n    }\n\n    /// Destroy this reference\n    ~ref() {\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n\n        print_destroyed(this);\n        track_destroyed((ref_tag *) this);\n    }\n\n    /// Move another reference into the current one\n    ref &operator=(ref &&r) noexcept {\n        print_move_assigned(this, \"pointer\", r.m_ptr);\n        track_move_assigned((ref_tag *) this);\n\n        if (*this == r) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = r.m_ptr;\n        r.m_ptr = nullptr;\n        return *this;\n    }\n\n    /// Overwrite this reference with another reference\n    ref &operator=(const ref &r) {\n        if (this == &r) {\n            return *this;\n        }\n        print_copy_assigned(this, \"pointer\", r.m_ptr);\n        track_copy_assigned((ref_tag *) this);\n\n        if (m_ptr == r.m_ptr) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = r.m_ptr;\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n        return *this;\n    }\n\n    /// Overwrite this reference with a pointer to another object\n    ref &operator=(T *ptr) {\n        print_values(this, \"assigned pointer\");\n        track_values((ref_tag *) this, \"assigned pointer\");\n\n        if (m_ptr == ptr) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = ptr;\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n        return *this;\n    }\n\n    /// Compare this reference with another reference\n    bool operator==(const ref &r) const { return m_ptr == r.m_ptr; }\n\n    /// Compare this reference with another reference\n    bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; }\n\n    /// Compare this reference with a pointer\n    bool operator==(const T *ptr) const { return m_ptr == ptr; }\n\n    /// Compare this reference with a pointer\n    bool operator!=(const T *ptr) const { return m_ptr != ptr; }\n\n    /// Access the object referenced by this reference\n    T *operator->() { return m_ptr; }\n\n    /// Access the object referenced by this reference\n    const T *operator->() const { return m_ptr; }\n\n    /// Return a C++ reference to the referenced object\n    T &operator*() { return *m_ptr; }\n\n    /// Return a const C++ reference to the referenced object\n    const T &operator*() const { return *m_ptr; }\n\n    /// Return a pointer to the referenced object\n    explicit operator T *() { return m_ptr; }\n\n    /// Return a const pointer to the referenced object\n    T *get_ptr() { return m_ptr; }\n\n    /// Return a pointer to the referenced object\n    const T *get_ptr() const { return m_ptr; }\n\nprivate:\n    T *m_ptr;\n};\n\n#endif /* __OBJECT_H */\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/pybind11_cross_module_tests.cpp",
    "content": "/*\n    tests/pybind11_cross_module_tests.cpp -- contains tests that require multiple modules\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl_bind.h>\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n#include \"test_exceptions.h\"\n\n#include <numeric>\n#include <utility>\n\nPYBIND11_MODULE(pybind11_cross_module_tests, m) {\n    m.doc() = \"pybind11 cross-module test module\";\n\n    // test_local_bindings.py tests:\n    //\n    // Definitions here are tested by importing both this module and the\n    // relevant pybind11_tests submodule from a test_whatever.py\n\n    // test_load_external\n    bind_local<ExternalType1>(m, \"ExternalType1\", py::module_local());\n    bind_local<ExternalType2>(m, \"ExternalType2\", py::module_local());\n\n    // test_exceptions.py\n    py::register_local_exception<LocalSimpleException>(m, \"LocalSimpleException\");\n    m.def(\"raise_runtime_error\", []() {\n        PyErr_SetString(PyExc_RuntimeError, \"My runtime error\");\n        throw py::error_already_set();\n    });\n    m.def(\"raise_value_error\", []() {\n        PyErr_SetString(PyExc_ValueError, \"My value error\");\n        throw py::error_already_set();\n    });\n    m.def(\"throw_pybind_value_error\", []() { throw py::value_error(\"pybind11 value error\"); });\n    m.def(\"throw_pybind_type_error\", []() { throw py::type_error(\"pybind11 type error\"); });\n    m.def(\"throw_stop_iteration\", []() { throw py::stop_iteration(); });\n    m.def(\"throw_local_error\", []() { throw LocalException(\"just local\"); });\n    m.def(\"throw_local_simple_error\", []() { throw LocalSimpleException(\"external mod\"); });\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const shared_exception &e) {\n            PyErr_SetString(PyExc_KeyError, e.what());\n        }\n    });\n\n    // translate the local exception into a key error but only in this module\n    py::register_local_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const LocalException &e) {\n            PyErr_SetString(PyExc_KeyError, e.what());\n        }\n    });\n\n    // test_local_bindings.py\n    // Local to both:\n    bind_local<LocalType, 1>(m, \"LocalType\", py::module_local()).def(\"get2\", [](LocalType &t) {\n        return t.i + 2;\n    });\n\n    // Can only be called with our python type:\n    m.def(\"local_value\", [](LocalType &l) { return l.i; });\n\n    // test_nonlocal_failure\n    // This registration will fail (global registration when LocalFail is already registered\n    // globally in the main test module):\n    m.def(\"register_nonlocal\", [m]() { bind_local<NonLocalType, 0>(m, \"NonLocalType\"); });\n\n    // test_stl_bind_local\n    // stl_bind.h binders defaults to py::module_local if the types are local or converting:\n    py::bind_vector<LocalVec>(m, \"LocalVec\");\n    py::bind_map<LocalMap>(m, \"LocalMap\");\n\n    // test_stl_bind_global\n    // and global if the type (or one of the types, for the map) is global (so these will fail,\n    // assuming pybind11_tests is already loaded):\n    m.def(\"register_nonlocal_vec\", [m]() { py::bind_vector<NonLocalVec>(m, \"NonLocalVec\"); });\n    m.def(\"register_nonlocal_map\", [m]() { py::bind_map<NonLocalMap>(m, \"NonLocalMap\"); });\n    // The default can, however, be overridden to global using `py::module_local()` or\n    // `py::module_local(false)`.\n    // Explicitly made local:\n    py::bind_vector<NonLocalVec2>(m, \"NonLocalVec2\", py::module_local());\n    // Explicitly made global (and so will fail to bind):\n    m.def(\"register_nonlocal_map2\",\n          [m]() { py::bind_map<NonLocalMap2>(m, \"NonLocalMap2\", py::module_local(false)); });\n\n    // test_mixed_local_global\n    // We try this both with the global type registered first and vice versa (the order shouldn't\n    // matter).\n    m.def(\"register_mixed_global_local\",\n          [m]() { bind_local<MixedGlobalLocal, 200>(m, \"MixedGlobalLocal\", py::module_local()); });\n    m.def(\"register_mixed_local_global\", [m]() {\n        bind_local<MixedLocalGlobal, 2000>(m, \"MixedLocalGlobal\", py::module_local(false));\n    });\n    m.def(\"get_mixed_gl\", [](int i) { return MixedGlobalLocal(i); });\n    m.def(\"get_mixed_lg\", [](int i) { return MixedLocalGlobal(i); });\n\n    // test_internal_locals_differ\n    m.def(\"local_cpp_types_addr\",\n          []() { return (uintptr_t) &py::detail::get_local_internals().registered_types_cpp; });\n\n    // test_stl_caster_vs_stl_bind\n    py::bind_vector<std::vector<int>>(m, \"VectorInt\");\n\n    m.def(\"load_vector_via_binding\",\n          [](std::vector<int> &v) { return std::accumulate(v.begin(), v.end(), 0); });\n\n    // test_cross_module_calls\n    m.def(\"return_self\", [](LocalVec *v) { return v; });\n    m.def(\"return_copy\", [](const LocalVec &v) { return LocalVec(v); });\n\n    class Dog : public pets::Pet {\n    public:\n        explicit Dog(std::string name) : Pet(std::move(name)) {}\n    };\n    py::class_<pets::Pet>(m, \"Pet\", py::module_local()).def(\"name\", &pets::Pet::name);\n    // Binding for local extending class:\n    py::class_<Dog, pets::Pet>(m, \"Dog\").def(py::init<std::string>());\n    m.def(\"pet_name\", [](pets::Pet &p) { return p.name(); });\n\n    py::class_<MixGL>(m, \"MixGL\", py::module_local()).def(py::init<int>());\n    m.def(\"get_gl_value\", [](MixGL &o) { return o.i + 100; });\n\n    py::class_<MixGL2>(m, \"MixGL2\", py::module_local()).def(py::init<int>());\n\n    // test_vector_bool\n    // We can't test both stl.h and stl_bind.h conversions of `std::vector<bool>` within\n    // the same module (it would be an ODR violation). Therefore `bind_vector` of `bool`\n    // is defined here and tested in `test_stl_binders.py`.\n    py::bind_vector<std::vector<bool>>(m, \"VectorBool\");\n\n    // test_missing_header_message\n    // The main module already includes stl.h, but we need to test the error message\n    // which appears when this header is missing.\n    m.def(\"missing_header_arg\", [](const std::vector<float> &) {});\n    m.def(\"missing_header_return\", []() { return std::vector<float>(); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/pybind11_tests.cpp",
    "content": "/*\n    tests/pybind11_tests.cpp -- pybind example plugin\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n#include \"constructor_stats.h\"\n\n#include <functional>\n#include <list>\n\n/*\nFor testing purposes, we define a static global variable here in a function that each individual\ntest .cpp calls with its initialization lambda.  It's convenient here because we can just not\ncompile some test files to disable/ignore some of the test code.\n\nIt is NOT recommended as a way to use pybind11 in practice, however: the initialization order will\nbe essentially random, which is okay for our test scripts (there are no dependencies between the\nindividual pybind11 test .cpp files), but most likely not what you want when using pybind11\nproductively.\n\nInstead, see the \"How can I reduce the build time?\" question in the \"Frequently asked questions\"\nsection of the documentation for good practice on splitting binding code over multiple files.\n*/\nstd::list<std::function<void(py::module_ &)>> &initializers() {\n    static std::list<std::function<void(py::module_ &)>> inits;\n    return inits;\n}\n\ntest_initializer::test_initializer(Initializer init) { initializers().emplace_back(init); }\n\ntest_initializer::test_initializer(const char *submodule_name, Initializer init) {\n    initializers().emplace_back([=](py::module_ &parent) {\n        auto m = parent.def_submodule(submodule_name);\n        init(m);\n    });\n}\n\nvoid bind_ConstructorStats(py::module_ &m) {\n    py::class_<ConstructorStats>(m, \"ConstructorStats\")\n        .def(\"alive\", &ConstructorStats::alive)\n        .def(\"values\", &ConstructorStats::values)\n        .def_readwrite(\"default_constructions\", &ConstructorStats::default_constructions)\n        .def_readwrite(\"copy_assignments\", &ConstructorStats::copy_assignments)\n        .def_readwrite(\"move_assignments\", &ConstructorStats::move_assignments)\n        .def_readwrite(\"copy_constructions\", &ConstructorStats::copy_constructions)\n        .def_readwrite(\"move_constructions\", &ConstructorStats::move_constructions)\n        .def_static(\"get\",\n                    (ConstructorStats & (*) (py::object)) & ConstructorStats::get,\n                    py::return_value_policy::reference_internal)\n\n        // Not exactly ConstructorStats, but related: expose the internal pybind number of\n        // registered instances to allow instance cleanup checks (invokes a GC first)\n        .def_static(\"detail_reg_inst\", []() {\n            ConstructorStats::gc();\n            return py::detail::get_internals().registered_instances.size();\n        });\n}\n\nconst char *cpp_std() {\n    return\n#if defined(PYBIND11_CPP20)\n        \"C++20\";\n#elif defined(PYBIND11_CPP17)\n        \"C++17\";\n#elif defined(PYBIND11_CPP14)\n        \"C++14\";\n#else\n        \"C++11\";\n#endif\n}\n\nPYBIND11_MODULE(pybind11_tests, m) {\n    m.doc() = \"pybind11 test module\";\n\n    // Intentionally kept minimal to not create a maintenance chore\n    // (\"just enough\" to be conclusive).\n#if defined(_MSC_FULL_VER)\n    m.attr(\"compiler_info\") = \"MSVC \" PYBIND11_TOSTRING(_MSC_FULL_VER);\n#elif defined(__VERSION__)\n    m.attr(\"compiler_info\") = __VERSION__;\n#else\n    m.attr(\"compiler_info\") = py::none();\n#endif\n    m.attr(\"cpp_std\") = cpp_std();\n    m.attr(\"PYBIND11_INTERNALS_ID\") = PYBIND11_INTERNALS_ID;\n    m.attr(\"PYBIND11_SIMPLE_GIL_MANAGEMENT\") =\n#if defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)\n        true;\n#else\n        false;\n#endif\n\n    bind_ConstructorStats(m);\n\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n    m.attr(\"detailed_error_messages_enabled\") = true;\n#else\n    m.attr(\"detailed_error_messages_enabled\") = false;\n#endif\n\n    py::class_<UserType>(m, \"UserType\", \"A `py::class_` type for testing\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(\"get_value\", &UserType::value, \"Get value using a method\")\n        .def(\"set_value\", &UserType::set, \"Set value using a method\")\n        .def_property(\"value\", &UserType::value, &UserType::set, \"Get/set value using a property\")\n        .def(\"__repr__\", [](const UserType &u) { return \"UserType({})\"_s.format(u.value()); });\n\n    py::class_<IncType, UserType>(m, \"IncType\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(\"__repr__\", [](const IncType &u) { return \"IncType({})\"_s.format(u.value()); });\n\n    for (const auto &initializer : initializers()) {\n        initializer(m);\n    }\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/pybind11_tests.h",
    "content": "#pragma once\n\n#include <pybind11/eval.h>\n#include <pybind11/pybind11.h>\n\nnamespace py = pybind11;\nusing namespace pybind11::literals;\n\nclass test_initializer {\n    using Initializer = void (*)(py::module_ &);\n\npublic:\n    explicit test_initializer(Initializer init);\n    test_initializer(const char *submodule_name, Initializer init);\n};\n\n#define TEST_SUBMODULE(name, variable)                                                            \\\n    void test_submodule_##name(py::module_ &);                                                    \\\n    test_initializer name(#name, test_submodule_##name);                                          \\\n    void test_submodule_##name(py::module_ &(variable))\n\n/// Dummy type which is not exported anywhere -- something to trigger a conversion error\nstruct UnregisteredType {};\n\n/// A user-defined type which is exported and can be used by any test\nclass UserType {\npublic:\n    UserType() = default;\n    explicit UserType(int i) : i(i) {}\n\n    int value() const { return i; }\n    void set(int set) { i = set; }\n\nprivate:\n    int i = -1;\n};\n\n/// Like UserType, but increments `value` on copy for quick reference vs. copy tests\nclass IncType : public UserType {\npublic:\n    using UserType::UserType;\n    IncType() = default;\n    IncType(const IncType &other) : IncType(other.value() + 1) {}\n    IncType(IncType &&) = delete;\n    IncType &operator=(const IncType &) = delete;\n    IncType &operator=(IncType &&) = delete;\n};\n\n/// A simple union for basic testing\nunion IntFloat {\n    int i;\n    float f;\n};\n\n/// Custom cast-only type that casts to a string \"rvalue\" or \"lvalue\" depending on the cast\n/// context. Used to test recursive casters (e.g. std::tuple, stl containers).\nstruct RValueCaster {};\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nclass type_caster<RValueCaster> {\npublic:\n    PYBIND11_TYPE_CASTER(RValueCaster, const_name(\"RValueCaster\"));\n    static handle cast(RValueCaster &&, return_value_policy, handle) {\n        return py::str(\"rvalue\").release();\n    }\n    static handle cast(const RValueCaster &, return_value_policy, handle) {\n        return py::str(\"lvalue\").release();\n    }\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\ntemplate <typename F>\nvoid ignoreOldStyleInitWarnings(F &&body) {\n    py::exec(R\"(\n    message = \"pybind11-bound class '.+' is using an old-style placement-new '(?:__init__|__setstate__)' which has been deprecated\"\n\n    import warnings\n    with warnings.catch_warnings():\n        warnings.filterwarnings(\"ignore\", message=message, category=FutureWarning)\n        body()\n    )\",\n             py::dict(py::arg(\"body\") = py::cpp_function(body)));\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/pytest.ini",
    "content": "[pytest]\nminversion = 3.10\nnorecursedirs = test_* extra_*\nxfail_strict = True\naddopts =\n    # show summary of tests\n    -ra\n    # capture only Python print and C++ py::print, but not C output (low-level Python errors)\n    --capture=sys\n    # Show local info when a failure occurs\n    --showlocals\nlog_cli_level = info\nfilterwarnings =\n    # make warnings into errors but ignore certain third-party extension issues\n    error\n    # somehow, some DeprecationWarnings do not get turned into errors\n    always::DeprecationWarning\n    # importing scipy submodules on some version of Python\n    ignore::ImportWarning\n    # bogus numpy ABI warning (see numpy/#432)\n    ignore:.*numpy.dtype size changed.*:RuntimeWarning\n    ignore:.*numpy.ufunc size changed.*:RuntimeWarning\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/requirements.txt",
    "content": "build==0.8.0\nnumpy==1.21.5; platform_python_implementation==\"PyPy\" and sys_platform==\"linux\" and python_version==\"3.7\"\nnumpy==1.19.3; platform_python_implementation!=\"PyPy\" and python_version==\"3.6\"\nnumpy==1.21.5; platform_python_implementation!=\"PyPy\" and python_version>=\"3.7\" and python_version<\"3.10\"\nnumpy==1.22.2; platform_python_implementation!=\"PyPy\" and python_version>=\"3.10\" and python_version<\"3.11\"\npytest==7.0.0\npytest-timeout\nscipy==1.5.4; platform_python_implementation!=\"PyPy\" and python_version<\"3.10\"\nscipy==1.8.0; platform_python_implementation!=\"PyPy\" and python_version==\"3.10\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_async.cpp",
    "content": "/*\n    tests/test_async.cpp -- __await__ support\n\n    Copyright (c) 2019 Google Inc.\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(async_module, m) {\n    struct DoesNotSupportAsync {};\n    py::class_<DoesNotSupportAsync>(m, \"DoesNotSupportAsync\").def(py::init<>());\n    struct SupportsAsync {};\n    py::class_<SupportsAsync>(m, \"SupportsAsync\")\n        .def(py::init<>())\n        .def(\"__await__\", [](const SupportsAsync &self) -> py::object {\n            static_cast<void>(self);\n            py::object loop = py::module_::import(\"asyncio.events\").attr(\"get_event_loop\")();\n            py::object f = loop.attr(\"create_future\")();\n            f.attr(\"set_result\")(5);\n            return f.attr(\"__await__\")();\n        });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_async.py",
    "content": "import pytest\n\nasyncio = pytest.importorskip(\"asyncio\")\nm = pytest.importorskip(\"pybind11_tests.async_module\")\n\n\n@pytest.fixture\ndef event_loop():\n    loop = asyncio.new_event_loop()\n    yield loop\n    loop.close()\n\n\nasync def get_await_result(x):\n    return await x\n\n\ndef test_await(event_loop):\n    assert 5 == event_loop.run_until_complete(get_await_result(m.SupportsAsync()))\n\n\ndef test_await_missing(event_loop):\n    with pytest.raises(TypeError):\n        event_loop.run_until_complete(get_await_result(m.DoesNotSupportAsync()))\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_buffers.cpp",
    "content": "/*\n    tests/test_buffers.cpp -- supporting Pythons' buffer protocol\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(buffers, m) {\n    // test_from_python / test_to_python:\n    class Matrix {\n    public:\n        Matrix(py::ssize_t rows, py::ssize_t cols) : m_rows(rows), m_cols(cols) {\n            print_created(this, std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[(size_t) (rows * cols)];\n            memset(m_data, 0, sizeof(float) * (size_t) (rows * cols));\n        }\n\n        Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) {\n            print_copy_created(this,\n                               std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[(size_t) (m_rows * m_cols)];\n            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));\n        }\n\n        Matrix(Matrix &&s) noexcept : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) {\n            print_move_created(this);\n            s.m_rows = 0;\n            s.m_cols = 0;\n            s.m_data = nullptr;\n        }\n\n        ~Matrix() {\n            print_destroyed(this,\n                            std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            delete[] m_data;\n        }\n\n        Matrix &operator=(const Matrix &s) {\n            if (this == &s) {\n                return *this;\n            }\n            print_copy_assigned(this,\n                                std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            delete[] m_data;\n            m_rows = s.m_rows;\n            m_cols = s.m_cols;\n            m_data = new float[(size_t) (m_rows * m_cols)];\n            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));\n            return *this;\n        }\n\n        Matrix &operator=(Matrix &&s) noexcept {\n            print_move_assigned(this,\n                                std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            if (&s != this) {\n                delete[] m_data;\n                m_rows = s.m_rows;\n                m_cols = s.m_cols;\n                m_data = s.m_data;\n                s.m_rows = 0;\n                s.m_cols = 0;\n                s.m_data = nullptr;\n            }\n            return *this;\n        }\n\n        float operator()(py::ssize_t i, py::ssize_t j) const {\n            return m_data[(size_t) (i * m_cols + j)];\n        }\n\n        float &operator()(py::ssize_t i, py::ssize_t j) {\n            return m_data[(size_t) (i * m_cols + j)];\n        }\n\n        float *data() { return m_data; }\n\n        py::ssize_t rows() const { return m_rows; }\n        py::ssize_t cols() const { return m_cols; }\n\n    private:\n        py::ssize_t m_rows;\n        py::ssize_t m_cols;\n        float *m_data;\n    };\n    py::class_<Matrix>(m, \"Matrix\", py::buffer_protocol())\n        .def(py::init<py::ssize_t, py::ssize_t>())\n        /// Construct from a buffer\n        .def(py::init([](const py::buffer &b) {\n            py::buffer_info info = b.request();\n            if (info.format != py::format_descriptor<float>::format() || info.ndim != 2) {\n                throw std::runtime_error(\"Incompatible buffer format!\");\n            }\n\n            auto *v = new Matrix(info.shape[0], info.shape[1]);\n            memcpy(v->data(), info.ptr, sizeof(float) * (size_t) (v->rows() * v->cols()));\n            return v;\n        }))\n\n        .def(\"rows\", &Matrix::rows)\n        .def(\"cols\", &Matrix::cols)\n\n        /// Bare bones interface\n        .def(\"__getitem__\",\n             [](const Matrix &m, std::pair<py::ssize_t, py::ssize_t> i) {\n                 if (i.first >= m.rows() || i.second >= m.cols()) {\n                     throw py::index_error();\n                 }\n                 return m(i.first, i.second);\n             })\n        .def(\"__setitem__\",\n             [](Matrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {\n                 if (i.first >= m.rows() || i.second >= m.cols()) {\n                     throw py::index_error();\n                 }\n                 m(i.first, i.second) = v;\n             })\n        /// Provide buffer access\n        .def_buffer([](Matrix &m) -> py::buffer_info {\n            return py::buffer_info(\n                m.data(),                          /* Pointer to buffer */\n                {m.rows(), m.cols()},              /* Buffer dimensions */\n                {sizeof(float) * size_t(m.cols()), /* Strides (in bytes) for each index */\n                 sizeof(float)});\n        });\n\n    // test_inherited_protocol\n    class SquareMatrix : public Matrix {\n    public:\n        explicit SquareMatrix(py::ssize_t n) : Matrix(n, n) {}\n    };\n    // Derived classes inherit the buffer protocol and the buffer access function\n    py::class_<SquareMatrix, Matrix>(m, \"SquareMatrix\").def(py::init<py::ssize_t>());\n\n    // test_pointer_to_member_fn\n    // Tests that passing a pointer to member to the base class works in\n    // the derived class.\n    struct Buffer {\n        int32_t value = 0;\n\n        py::buffer_info get_buffer_info() {\n            return py::buffer_info(\n                &value, sizeof(value), py::format_descriptor<int32_t>::format(), 1);\n        }\n    };\n    py::class_<Buffer>(m, \"Buffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", &Buffer::value)\n        .def_buffer(&Buffer::get_buffer_info);\n\n    class ConstBuffer {\n        std::unique_ptr<int32_t> value;\n\n    public:\n        int32_t get_value() const { return *value; }\n        void set_value(int32_t v) { *value = v; }\n\n        py::buffer_info get_buffer_info() const {\n            return py::buffer_info(\n                value.get(), sizeof(*value), py::format_descriptor<int32_t>::format(), 1);\n        }\n\n        ConstBuffer() : value(new int32_t{0}) {}\n    };\n    py::class_<ConstBuffer>(m, \"ConstBuffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_property(\"value\", &ConstBuffer::get_value, &ConstBuffer::set_value)\n        .def_buffer(&ConstBuffer::get_buffer_info);\n\n    struct DerivedBuffer : public Buffer {};\n    py::class_<DerivedBuffer>(m, \"DerivedBuffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", (int32_t DerivedBuffer::*) &DerivedBuffer::value)\n        .def_buffer(&DerivedBuffer::get_buffer_info);\n\n    struct BufferReadOnly {\n        const uint8_t value = 0;\n        explicit BufferReadOnly(uint8_t value) : value(value) {}\n\n        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1); }\n    };\n    py::class_<BufferReadOnly>(m, \"BufferReadOnly\", py::buffer_protocol())\n        .def(py::init<uint8_t>())\n        .def_buffer(&BufferReadOnly::get_buffer_info);\n\n    struct BufferReadOnlySelect {\n        uint8_t value = 0;\n        bool readonly = false;\n\n        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1, readonly); }\n    };\n    py::class_<BufferReadOnlySelect>(m, \"BufferReadOnlySelect\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", &BufferReadOnlySelect::value)\n        .def_readwrite(\"readonly\", &BufferReadOnlySelect::readonly)\n        .def_buffer(&BufferReadOnlySelect::get_buffer_info);\n\n    // Expose buffer_info for testing.\n    py::class_<py::buffer_info>(m, \"buffer_info\")\n        .def(py::init<>())\n        .def_readonly(\"itemsize\", &py::buffer_info::itemsize)\n        .def_readonly(\"size\", &py::buffer_info::size)\n        .def_readonly(\"format\", &py::buffer_info::format)\n        .def_readonly(\"ndim\", &py::buffer_info::ndim)\n        .def_readonly(\"shape\", &py::buffer_info::shape)\n        .def_readonly(\"strides\", &py::buffer_info::strides)\n        .def_readonly(\"readonly\", &py::buffer_info::readonly)\n        .def(\"__repr__\", [](py::handle self) {\n            return py::str(\"itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, \"\n                           \"ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, \"\n                           \"readonly={0.readonly!r}\")\n                .format(self);\n        });\n\n    m.def(\"get_buffer_info\", [](const py::buffer &buffer) { return buffer.request(); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_buffers.py",
    "content": "import ctypes\nimport io\nimport struct\n\nimport pytest\n\nimport env\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import buffers as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_from_python():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.Matrix(np.array([1, 2, 3]))  # trying to assign a 1D array\n    assert str(excinfo.value) == \"Incompatible buffer format!\"\n\n    m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)\n    m4 = m.Matrix(m3)\n\n    for i in range(m4.rows()):\n        for j in range(m4.cols()):\n            assert m3[i, j] == m4[i, j]\n\n    cstats = ConstructorStats.get(m.Matrix)\n    assert cstats.alive() == 1\n    del m3, m4\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"2x3 matrix\"]\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0  # Don't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2444\n# TODO: fix on recent PyPy\n@pytest.mark.xfail(\n    env.PYPY, reason=\"PyPy 7.3.7 doesn't clear this anymore\", strict=False\n)\ndef test_to_python():\n    mat = m.Matrix(5, 4)\n    assert memoryview(mat).shape == (5, 4)\n\n    assert mat[2, 3] == 0\n    mat[2, 3] = 4.0\n    mat[3, 2] = 7.0\n    assert mat[2, 3] == 4\n    assert mat[3, 2] == 7\n    assert struct.unpack_from(\"f\", mat, (3 * 4 + 2) * 4) == (7,)\n    assert struct.unpack_from(\"f\", mat, (2 * 4 + 3) * 4) == (4,)\n\n    mat2 = np.array(mat, copy=False)\n    assert mat2.shape == (5, 4)\n    assert abs(mat2).sum() == 11\n    assert mat2[2, 3] == 4 and mat2[3, 2] == 7\n    mat2[2, 3] = 5\n    assert mat2[2, 3] == 5\n\n    cstats = ConstructorStats.get(m.Matrix)\n    assert cstats.alive() == 1\n    del mat\n    pytest.gc_collect()\n    assert cstats.alive() == 1\n    del mat2  # holds a mat reference\n    pytest.gc_collect()\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"5x4 matrix\"]\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0  # Don't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_inherited_protocol():\n    \"\"\"SquareMatrix is derived from Matrix and inherits the buffer protocol\"\"\"\n\n    matrix = m.SquareMatrix(5)\n    assert memoryview(matrix).shape == (5, 5)\n    assert np.asarray(matrix).shape == (5, 5)\n\n\ndef test_pointer_to_member_fn():\n    for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]:\n        buf = cls()\n        buf.value = 0x12345678\n        value = struct.unpack(\"i\", bytearray(buf))[0]\n        assert value == 0x12345678\n\n\ndef test_readonly_buffer():\n    buf = m.BufferReadOnly(0x64)\n    view = memoryview(buf)\n    assert view[0] == 0x64\n    assert view.readonly\n    with pytest.raises(TypeError):\n        view[0] = 0\n\n\ndef test_selective_readonly_buffer():\n    buf = m.BufferReadOnlySelect()\n\n    memoryview(buf)[0] = 0x64\n    assert buf.value == 0x64\n\n    io.BytesIO(b\"A\").readinto(buf)\n    assert buf.value == ord(b\"A\")\n\n    buf.readonly = True\n    with pytest.raises(TypeError):\n        memoryview(buf)[0] = 0\n    with pytest.raises(TypeError):\n        io.BytesIO(b\"1\").readinto(buf)\n\n\ndef test_ctypes_array_1d():\n    char1d = (ctypes.c_char * 10)()\n    int1d = (ctypes.c_int * 15)()\n    long1d = (ctypes.c_long * 7)()\n\n    for carray in (char1d, int1d, long1d):\n        info = m.get_buffer_info(carray)\n        assert info.itemsize == ctypes.sizeof(carray._type_)\n        assert info.size == len(carray)\n        assert info.ndim == 1\n        assert info.shape == [info.size]\n        assert info.strides == [info.itemsize]\n        assert not info.readonly\n\n\ndef test_ctypes_array_2d():\n    char2d = ((ctypes.c_char * 10) * 4)()\n    int2d = ((ctypes.c_int * 15) * 3)()\n    long2d = ((ctypes.c_long * 7) * 2)()\n\n    for carray in (char2d, int2d, long2d):\n        info = m.get_buffer_info(carray)\n        assert info.itemsize == ctypes.sizeof(carray[0]._type_)\n        assert info.size == len(carray) * len(carray[0])\n        assert info.ndim == 2\n        assert info.shape == [len(carray), len(carray[0])]\n        assert info.strides == [info.itemsize * len(carray[0]), info.itemsize]\n        assert not info.readonly\n\n\ndef test_ctypes_from_buffer():\n    test_pystr = b\"0123456789\"\n    for pyarray in (test_pystr, bytearray(test_pystr)):\n        pyinfo = m.get_buffer_info(pyarray)\n\n        if pyinfo.readonly:\n            cbytes = (ctypes.c_char * len(pyarray)).from_buffer_copy(pyarray)\n            cinfo = m.get_buffer_info(cbytes)\n        else:\n            cbytes = (ctypes.c_char * len(pyarray)).from_buffer(pyarray)\n            cinfo = m.get_buffer_info(cbytes)\n\n        assert cinfo.size == pyinfo.size\n        assert cinfo.ndim == pyinfo.ndim\n        assert cinfo.shape == pyinfo.shape\n        assert cinfo.strides == pyinfo.strides\n        assert not cinfo.readonly\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_builtin_casters.cpp",
    "content": "/*\n    tests/test_builtin_casters.cpp -- Casters available without any additional headers\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/complex.h>\n\n#include \"pybind11_tests.h\"\n\nstruct ConstRefCasted {\n    int tag;\n};\n\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nclass type_caster<ConstRefCasted> {\npublic:\n    static constexpr auto name = const_name<ConstRefCasted>();\n\n    // Input is unimportant, a new value will always be constructed based on the\n    // cast operator.\n    bool load(handle, bool) { return true; }\n\n    explicit operator ConstRefCasted &&() {\n        value = {1};\n        // NOLINTNEXTLINE(performance-move-const-arg)\n        return std::move(value);\n    }\n    explicit operator ConstRefCasted &() {\n        value = {2};\n        return value;\n    }\n    explicit operator ConstRefCasted *() {\n        value = {3};\n        return &value;\n    }\n\n    explicit operator const ConstRefCasted &() {\n        value = {4};\n        return value;\n    }\n    explicit operator const ConstRefCasted *() {\n        value = {5};\n        return &value;\n    }\n\n    // custom cast_op to explicitly propagate types to the conversion operators.\n    template <typename T_>\n    using cast_op_type =\n        /// const\n        conditional_t<\n            std::is_same<remove_reference_t<T_>, const ConstRefCasted *>::value,\n            const ConstRefCasted *,\n            conditional_t<\n                std::is_same<T_, const ConstRefCasted &>::value,\n                const ConstRefCasted &,\n                /// non-const\n                conditional_t<std::is_same<remove_reference_t<T_>, ConstRefCasted *>::value,\n                              ConstRefCasted *,\n                              conditional_t<std::is_same<T_, ConstRefCasted &>::value,\n                                            ConstRefCasted &,\n                                            /* else */ ConstRefCasted &&>>>>;\n\nprivate:\n    ConstRefCasted value = {0};\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\nTEST_SUBMODULE(builtin_casters, m) {\n    // test_simple_string\n    m.def(\"string_roundtrip\", [](const char *s) { return s; });\n\n    // test_unicode_conversion\n    // Some test characters in utf16 and utf32 encodings.  The last one (the 𝐀) contains a null\n    // byte\n    char32_t a32 = 0x61 /*a*/, z32 = 0x7a /*z*/, ib32 = 0x203d /*‽*/, cake32 = 0x1f382 /*🎂*/,\n             mathbfA32 = 0x1d400 /*𝐀*/;\n    char16_t b16 = 0x62 /*b*/, z16 = 0x7a, ib16 = 0x203d, cake16_1 = 0xd83c, cake16_2 = 0xdf82,\n             mathbfA16_1 = 0xd835, mathbfA16_2 = 0xdc00;\n    std::wstring wstr;\n    wstr.push_back(0x61);   // a\n    wstr.push_back(0x2e18); // ⸘\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {\n        wstr.push_back(mathbfA16_1);\n        wstr.push_back(mathbfA16_2);\n    } // 𝐀, utf16\n    else {\n        wstr.push_back((wchar_t) mathbfA32);\n    }                     // 𝐀, utf32\n    wstr.push_back(0x7a); // z\n\n    m.def(\"good_utf8_string\", []() {\n        return std::string((const char *) u8\"Say utf8\\u203d \\U0001f382 \\U0001d400\");\n    }); // Say utf8‽ 🎂 𝐀\n    m.def(\"good_utf16_string\", [=]() {\n        return std::u16string({b16, ib16, cake16_1, cake16_2, mathbfA16_1, mathbfA16_2, z16});\n    }); // b‽🎂𝐀z\n    m.def(\"good_utf32_string\", [=]() {\n        return std::u32string({a32, mathbfA32, cake32, ib32, z32});\n    });                                                 // a𝐀🎂‽z\n    m.def(\"good_wchar_string\", [=]() { return wstr; }); // a‽𝐀z\n    m.def(\"bad_utf8_string\", []() {\n        return std::string(\"abc\\xd0\"\n                           \"def\");\n    });\n    m.def(\"bad_utf16_string\", [=]() { return std::u16string({b16, char16_t(0xd800), z16}); });\n    // Under Python 2.7, invalid unicode UTF-32 characters didn't appear to trigger\n    // UnicodeDecodeError\n    m.def(\"bad_utf32_string\", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {\n        m.def(\"bad_wchar_string\", [=]() {\n            return std::wstring({wchar_t(0x61), wchar_t(0xd800)});\n        });\n    }\n    m.def(\"u8_Z\", []() -> char { return 'Z'; });\n    m.def(\"u8_eacute\", []() -> char { return '\\xe9'; });\n    m.def(\"u16_ibang\", [=]() -> char16_t { return ib16; });\n    m.def(\"u32_mathbfA\", [=]() -> char32_t { return mathbfA32; });\n    m.def(\"wchar_heart\", []() -> wchar_t { return 0x2665; });\n\n    // test_single_char_arguments\n    m.attr(\"wchar_size\") = py::cast(sizeof(wchar_t));\n    m.def(\"ord_char\", [](char c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char_lv\", [](char &c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char16\", [](char16_t c) -> uint16_t { return c; });\n    m.def(\"ord_char16_lv\", [](char16_t &c) -> uint16_t { return c; });\n    m.def(\"ord_char32\", [](char32_t c) -> uint32_t { return c; });\n    m.def(\"ord_wchar\", [](wchar_t c) -> int { return c; });\n\n    // test_bytes_to_string\n    m.def(\"strlen\", [](char *s) { return strlen(s); });\n    m.def(\"string_length\", [](const std::string &s) { return s.length(); });\n\n#ifdef PYBIND11_HAS_U8STRING\n    m.attr(\"has_u8string\") = true;\n    m.def(\"good_utf8_u8string\", []() {\n        return std::u8string(u8\"Say utf8\\u203d \\U0001f382 \\U0001d400\");\n    }); // Say utf8‽ 🎂 𝐀\n    m.def(\"bad_utf8_u8string\", []() {\n        return std::u8string((const char8_t *) \"abc\\xd0\"\n                                               \"def\");\n    });\n\n    m.def(\"u8_char8_Z\", []() -> char8_t { return u8'Z'; });\n\n    // test_single_char_arguments\n    m.def(\"ord_char8\", [](char8_t c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char8_lv\", [](char8_t &c) -> int { return static_cast<unsigned char>(c); });\n#endif\n\n    // test_string_view\n#ifdef PYBIND11_HAS_STRING_VIEW\n    m.attr(\"has_string_view\") = true;\n    m.def(\"string_view_print\", [](std::string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view16_print\", [](std::u16string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view32_print\", [](std::u32string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view_chars\", [](std::string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((std::uint8_t) c);\n        }\n        return l;\n    });\n    m.def(\"string_view16_chars\", [](std::u16string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((int) c);\n        }\n        return l;\n    });\n    m.def(\"string_view32_chars\", [](std::u32string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((int) c);\n        }\n        return l;\n    });\n    m.def(\"string_view_return\",\n          []() { return std::string_view((const char *) u8\"utf8 secret \\U0001f382\"); });\n    m.def(\"string_view16_return\",\n          []() { return std::u16string_view(u\"utf16 secret \\U0001f382\"); });\n    m.def(\"string_view32_return\",\n          []() { return std::u32string_view(U\"utf32 secret \\U0001f382\"); });\n\n    // The inner lambdas here are to also test implicit conversion\n    using namespace std::literals;\n    m.def(\"string_view_bytes\",\n          []() { return [](py::bytes b) { return b; }(\"abc \\x80\\x80 def\"sv); });\n    m.def(\"string_view_str\",\n          []() { return [](py::str s) { return s; }(\"abc \\342\\200\\275 def\"sv); });\n    m.def(\"string_view_from_bytes\",\n          [](const py::bytes &b) { return [](std::string_view s) { return s; }(b); });\n    m.def(\"string_view_memoryview\", []() {\n        static constexpr auto val = \"Have some \\360\\237\\216\\202\"sv;\n        return py::memoryview::from_memory(val);\n    });\n\n#    ifdef PYBIND11_HAS_U8STRING\n    m.def(\"string_view8_print\", [](std::u8string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view8_chars\", [](std::u8string_view s) {\n        py::list l;\n        for (auto c : s)\n            l.append((std::uint8_t) c);\n        return l;\n    });\n    m.def(\"string_view8_return\", []() { return std::u8string_view(u8\"utf8 secret \\U0001f382\"); });\n    m.def(\"string_view8_str\", []() { return py::str{std::u8string_view{u8\"abc ‽ def\"}}; });\n#    endif\n\n    struct TypeWithBothOperatorStringAndStringView {\n        // NOLINTNEXTLINE(google-explicit-constructor)\n        operator std::string() const { return \"success\"; }\n        // NOLINTNEXTLINE(google-explicit-constructor)\n        operator std::string_view() const { return \"failure\"; }\n    };\n    m.def(\"bytes_from_type_with_both_operator_string_and_string_view\",\n          []() { return py::bytes(TypeWithBothOperatorStringAndStringView()); });\n    m.def(\"str_from_type_with_both_operator_string_and_string_view\",\n          []() { return py::str(TypeWithBothOperatorStringAndStringView()); });\n#endif\n\n    // test_integer_casting\n    m.def(\"i32_str\", [](std::int32_t v) { return std::to_string(v); });\n    m.def(\"u32_str\", [](std::uint32_t v) { return std::to_string(v); });\n    m.def(\"i64_str\", [](std::int64_t v) { return std::to_string(v); });\n    m.def(\"u64_str\", [](std::uint64_t v) { return std::to_string(v); });\n\n    // test_int_convert\n    m.def(\"int_passthrough\", [](int arg) { return arg; });\n    m.def(\n        \"int_passthrough_noconvert\", [](int arg) { return arg; }, py::arg{}.noconvert());\n\n    // test_tuple\n    m.def(\n        \"pair_passthrough\",\n        [](const std::pair<bool, std::string> &input) {\n            return std::make_pair(input.second, input.first);\n        },\n        \"Return a pair in reversed order\");\n    m.def(\n        \"tuple_passthrough\",\n        [](std::tuple<bool, std::string, int> input) {\n            return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input));\n        },\n        \"Return a triple in reversed order\");\n    m.def(\"empty_tuple\", []() { return std::tuple<>(); });\n    static std::pair<RValueCaster, RValueCaster> lvpair;\n    static std::tuple<RValueCaster, RValueCaster, RValueCaster> lvtuple;\n    static std::pair<RValueCaster, std::tuple<RValueCaster, std::pair<RValueCaster, RValueCaster>>>\n        lvnested;\n    m.def(\"rvalue_pair\", []() { return std::make_pair(RValueCaster{}, RValueCaster{}); });\n    m.def(\"lvalue_pair\", []() -> const decltype(lvpair) & { return lvpair; });\n    m.def(\"rvalue_tuple\",\n          []() { return std::make_tuple(RValueCaster{}, RValueCaster{}, RValueCaster{}); });\n    m.def(\"lvalue_tuple\", []() -> const decltype(lvtuple) & { return lvtuple; });\n    m.def(\"rvalue_nested\", []() {\n        return std::make_pair(\n            RValueCaster{},\n            std::make_tuple(RValueCaster{}, std::make_pair(RValueCaster{}, RValueCaster{})));\n    });\n    m.def(\"lvalue_nested\", []() -> const decltype(lvnested) & { return lvnested; });\n\n    m.def(\n        \"int_string_pair\",\n        []() {\n            // Using no-destructor idiom to side-step warnings from overzealous compilers.\n            static auto *int_string_pair = new std::pair<int, std::string>{2, \"items\"};\n            return int_string_pair;\n        },\n        py::return_value_policy::reference);\n\n    // test_builtins_cast_return_none\n    m.def(\"return_none_string\", []() -> std::string * { return nullptr; });\n    m.def(\"return_none_char\", []() -> const char * { return nullptr; });\n    m.def(\"return_none_bool\", []() -> bool * { return nullptr; });\n    m.def(\"return_none_int\", []() -> int * { return nullptr; });\n    m.def(\"return_none_float\", []() -> float * { return nullptr; });\n    m.def(\"return_none_pair\", []() -> std::pair<int, int> * { return nullptr; });\n\n    // test_none_deferred\n    m.def(\"defer_none_cstring\", [](char *) { return false; });\n    m.def(\"defer_none_cstring\", [](const py::none &) { return true; });\n    m.def(\"defer_none_custom\", [](UserType *) { return false; });\n    m.def(\"defer_none_custom\", [](const py::none &) { return true; });\n    m.def(\"nodefer_none_void\", [](void *) { return true; });\n    m.def(\"nodefer_none_void\", [](const py::none &) { return false; });\n\n    // test_void_caster\n    m.def(\"load_nullptr_t\", [](std::nullptr_t) {}); // not useful, but it should still compile\n    m.def(\"cast_nullptr_t\", []() { return std::nullptr_t{}; });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_bool_caster\n    m.def(\"bool_passthrough\", [](bool arg) { return arg; });\n    m.def(\n        \"bool_passthrough_noconvert\", [](bool arg) { return arg; }, py::arg{}.noconvert());\n\n    // TODO: This should be disabled and fixed in future Intel compilers\n#if !defined(__INTEL_COMPILER)\n    // Test \"bool_passthrough_noconvert\" again, but using () instead of {} to construct py::arg\n    // When compiled with the Intel compiler, this results in segmentation faults when importing\n    // the module. Tested with icc (ICC) 2021.1 Beta 20200827, this should be tested again when\n    // a newer version of icc is available.\n    m.def(\n        \"bool_passthrough_noconvert2\", [](bool arg) { return arg; }, py::arg().noconvert());\n#endif\n\n    // test_reference_wrapper\n    m.def(\"refwrap_builtin\", [](std::reference_wrapper<int> p) { return 10 * p.get(); });\n    m.def(\"refwrap_usertype\", [](std::reference_wrapper<UserType> p) { return p.get().value(); });\n    m.def(\"refwrap_usertype_const\",\n          [](std::reference_wrapper<const UserType> p) { return p.get().value(); });\n\n    m.def(\"refwrap_lvalue\", []() -> std::reference_wrapper<UserType> {\n        static UserType x(1);\n        return std::ref(x);\n    });\n    m.def(\"refwrap_lvalue_const\", []() -> std::reference_wrapper<const UserType> {\n        static UserType x(1);\n        return std::cref(x);\n    });\n\n    // Not currently supported (std::pair caster has return-by-value cast operator);\n    // triggers static_assert failure.\n    // m.def(\"refwrap_pair\", [](std::reference_wrapper<std::pair<int, int>>) { });\n\n    m.def(\n        \"refwrap_list\",\n        [](bool copy) {\n            static IncType x1(1), x2(2);\n            py::list l;\n            for (const auto &f : {std::ref(x1), std::ref(x2)}) {\n                l.append(py::cast(\n                    f, copy ? py::return_value_policy::copy : py::return_value_policy::reference));\n            }\n            return l;\n        },\n        \"copy\"_a);\n\n    m.def(\"refwrap_iiw\", [](const IncType &w) { return w.value(); });\n    m.def(\"refwrap_call_iiw\", [](IncType &w, const py::function &f) {\n        py::list l;\n        l.append(f(std::ref(w)));\n        l.append(f(std::cref(w)));\n        IncType x(w.value());\n        l.append(f(std::ref(x)));\n        IncType y(w.value());\n        auto r3 = std::ref(y);\n        l.append(f(r3));\n        return l;\n    });\n\n    // test_complex\n    m.def(\"complex_cast\", [](float x) { return \"{}\"_s.format(x); });\n    m.def(\"complex_cast\",\n          [](std::complex<float> x) { return \"({}, {})\"_s.format(x.real(), x.imag()); });\n\n    // test int vs. long (Python 2)\n    m.def(\"int_cast\", []() { return (int) 42; });\n    m.def(\"long_cast\", []() { return (long) 42; });\n    m.def(\"longlong_cast\", []() { return ULLONG_MAX; });\n\n    /// test void* cast operator\n    m.def(\"test_void_caster\", []() -> bool {\n        void *v = (void *) 0xabcd;\n        py::object o = py::cast(v);\n        return py::cast<void *>(o) == v;\n    });\n\n    // Tests const/non-const propagation in cast_op.\n    m.def(\"takes\", [](ConstRefCasted x) { return x.tag; });\n    m.def(\"takes_move\", [](ConstRefCasted &&x) { return x.tag; });\n    m.def(\"takes_ptr\", [](ConstRefCasted *x) { return x->tag; });\n    m.def(\"takes_ref\", [](ConstRefCasted &x) { return x.tag; });\n    m.def(\"takes_ref_wrap\", [](std::reference_wrapper<ConstRefCasted> x) { return x.get().tag; });\n    m.def(\"takes_const_ptr\", [](const ConstRefCasted *x) { return x->tag; });\n    m.def(\"takes_const_ref\", [](const ConstRefCasted &x) { return x.tag; });\n    m.def(\"takes_const_ref_wrap\",\n          [](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_builtin_casters.py",
    "content": "import sys\n\nimport pytest\n\nimport env\nfrom pybind11_tests import IncType, UserType\nfrom pybind11_tests import builtin_casters as m\n\n\ndef test_simple_string():\n    assert m.string_roundtrip(\"const char *\") == \"const char *\"\n\n\ndef test_unicode_conversion():\n    \"\"\"Tests unicode conversion and error reporting.\"\"\"\n    assert m.good_utf8_string() == \"Say utf8‽ 🎂 𝐀\"\n    assert m.good_utf16_string() == \"b‽🎂𝐀z\"\n    assert m.good_utf32_string() == \"a𝐀🎂‽z\"\n    assert m.good_wchar_string() == \"a⸘𝐀z\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.good_utf8_u8string() == \"Say utf8‽ 🎂 𝐀\"\n\n    with pytest.raises(UnicodeDecodeError):\n        m.bad_utf8_string()\n\n    with pytest.raises(UnicodeDecodeError):\n        m.bad_utf16_string()\n\n    # These are provided only if they actually fail (they don't when 32-bit)\n    if hasattr(m, \"bad_utf32_string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_utf32_string()\n    if hasattr(m, \"bad_wchar_string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_wchar_string()\n    if hasattr(m, \"has_u8string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_utf8_u8string()\n\n    assert m.u8_Z() == \"Z\"\n    assert m.u8_eacute() == \"é\"\n    assert m.u16_ibang() == \"‽\"\n    assert m.u32_mathbfA() == \"𝐀\"\n    assert m.wchar_heart() == \"♥\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.u8_char8_Z() == \"Z\"\n\n\ndef test_single_char_arguments():\n    \"\"\"Tests failures for passing invalid inputs to char-accepting functions\"\"\"\n\n    def toobig_message(r):\n        return f\"Character code point not in range({r:#x})\"\n\n    toolong_message = \"Expected a character, but multi-character string found\"\n\n    assert m.ord_char(\"a\") == 0x61  # simple ASCII\n    assert m.ord_char_lv(\"b\") == 0x62\n    assert (\n        m.ord_char(\"é\") == 0xE9\n    )  # requires 2 bytes in utf-8, but can be stuffed in a char\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char(\"Ā\") == 0x100  # requires 2 bytes, doesn't fit in a char\n    assert str(excinfo.value) == toobig_message(0x100)\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char(\"ab\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_char16(\"a\") == 0x61\n    assert m.ord_char16(\"é\") == 0xE9\n    assert m.ord_char16_lv(\"ê\") == 0xEA\n    assert m.ord_char16(\"Ā\") == 0x100\n    assert m.ord_char16(\"‽\") == 0x203D\n    assert m.ord_char16(\"♥\") == 0x2665\n    assert m.ord_char16_lv(\"♡\") == 0x2661\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char16(\"🎂\") == 0x1F382  # requires surrogate pair\n    assert str(excinfo.value) == toobig_message(0x10000)\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char16(\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_char32(\"a\") == 0x61\n    assert m.ord_char32(\"é\") == 0xE9\n    assert m.ord_char32(\"Ā\") == 0x100\n    assert m.ord_char32(\"‽\") == 0x203D\n    assert m.ord_char32(\"♥\") == 0x2665\n    assert m.ord_char32(\"🎂\") == 0x1F382\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char32(\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_wchar(\"a\") == 0x61\n    assert m.ord_wchar(\"é\") == 0xE9\n    assert m.ord_wchar(\"Ā\") == 0x100\n    assert m.ord_wchar(\"‽\") == 0x203D\n    assert m.ord_wchar(\"♥\") == 0x2665\n    if m.wchar_size == 2:\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_wchar(\"🎂\") == 0x1F382  # requires surrogate pair\n        assert str(excinfo.value) == toobig_message(0x10000)\n    else:\n        assert m.ord_wchar(\"🎂\") == 0x1F382\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_wchar(\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    if hasattr(m, \"has_u8string\"):\n        assert m.ord_char8(\"a\") == 0x61  # simple ASCII\n        assert m.ord_char8_lv(\"b\") == 0x62\n        assert (\n            m.ord_char8(\"é\") == 0xE9\n        )  # requires 2 bytes in utf-8, but can be stuffed in a char\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_char8(\"Ā\") == 0x100  # requires 2 bytes, doesn't fit in a char\n        assert str(excinfo.value) == toobig_message(0x100)\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_char8(\"ab\")\n        assert str(excinfo.value) == toolong_message\n\n\ndef test_bytes_to_string():\n    \"\"\"Tests the ability to pass bytes to C++ string-accepting functions.  Note that this is\n    one-way: the only way to return bytes to Python is via the pybind11::bytes class.\"\"\"\n    # Issue #816\n\n    assert m.strlen(b\"hi\") == 2\n    assert m.string_length(b\"world\") == 5\n    assert m.string_length(\"a\\x00b\".encode()) == 3\n    assert m.strlen(\"a\\x00b\".encode()) == 1  # C-string limitation\n\n    # passing in a utf8 encoded string should work\n    assert m.string_length(\"💩\".encode()) == 4\n\n\ndef test_bytearray_to_string():\n    \"\"\"Tests the ability to pass bytearray to C++ string-accepting functions\"\"\"\n    assert m.string_length(bytearray(b\"Hi\")) == 2\n    assert m.strlen(bytearray(b\"bytearray\")) == 9\n    assert m.string_length(bytearray()) == 0\n    assert m.string_length(bytearray(\"🦜\", \"utf-8\", \"strict\")) == 4\n    assert m.string_length(bytearray(b\"\\x80\")) == 1\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_string_view\"), reason=\"no <string_view>\")\ndef test_string_view(capture):\n    \"\"\"Tests support for C++17 string_view arguments and return values\"\"\"\n    assert m.string_view_chars(\"Hi\") == [72, 105]\n    assert m.string_view_chars(\"Hi 🎂\") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]\n    assert m.string_view16_chars(\"Hi 🎂\") == [72, 105, 32, 0xD83C, 0xDF82]\n    assert m.string_view32_chars(\"Hi 🎂\") == [72, 105, 32, 127874]\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_chars(\"Hi\") == [72, 105]\n        assert m.string_view8_chars(\"Hi 🎂\") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]\n\n    assert m.string_view_return() == \"utf8 secret 🎂\"\n    assert m.string_view16_return() == \"utf16 secret 🎂\"\n    assert m.string_view32_return() == \"utf32 secret 🎂\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_return() == \"utf8 secret 🎂\"\n\n    with capture:\n        m.string_view_print(\"Hi\")\n        m.string_view_print(\"utf8 🎂\")\n        m.string_view16_print(\"utf16 🎂\")\n        m.string_view32_print(\"utf32 🎂\")\n    assert (\n        capture\n        == \"\"\"\n        Hi 2\n        utf8 🎂 9\n        utf16 🎂 8\n        utf32 🎂 7\n    \"\"\"\n    )\n    if hasattr(m, \"has_u8string\"):\n        with capture:\n            m.string_view8_print(\"Hi\")\n            m.string_view8_print(\"utf8 🎂\")\n        assert (\n            capture\n            == \"\"\"\n            Hi 2\n            utf8 🎂 9\n        \"\"\"\n        )\n\n    with capture:\n        m.string_view_print(\"Hi, ascii\")\n        m.string_view_print(\"Hi, utf8 🎂\")\n        m.string_view16_print(\"Hi, utf16 🎂\")\n        m.string_view32_print(\"Hi, utf32 🎂\")\n    assert (\n        capture\n        == \"\"\"\n        Hi, ascii 9\n        Hi, utf8 🎂 13\n        Hi, utf16 🎂 12\n        Hi, utf32 🎂 11\n    \"\"\"\n    )\n    if hasattr(m, \"has_u8string\"):\n        with capture:\n            m.string_view8_print(\"Hi, ascii\")\n            m.string_view8_print(\"Hi, utf8 🎂\")\n        assert (\n            capture\n            == \"\"\"\n            Hi, ascii 9\n            Hi, utf8 🎂 13\n        \"\"\"\n        )\n\n    assert m.string_view_bytes() == b\"abc \\x80\\x80 def\"\n    assert m.string_view_str() == \"abc ‽ def\"\n    assert m.string_view_from_bytes(\"abc ‽ def\".encode()) == \"abc ‽ def\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_str() == \"abc ‽ def\"\n    assert m.string_view_memoryview() == \"Have some 🎂\".encode()\n\n    assert m.bytes_from_type_with_both_operator_string_and_string_view() == b\"success\"\n    assert m.str_from_type_with_both_operator_string_and_string_view() == \"success\"\n\n\ndef test_integer_casting():\n    \"\"\"Issue #929 - out-of-range integer values shouldn't be accepted\"\"\"\n    assert m.i32_str(-1) == \"-1\"\n    assert m.i64_str(-1) == \"-1\"\n    assert m.i32_str(2000000000) == \"2000000000\"\n    assert m.u32_str(2000000000) == \"2000000000\"\n    assert m.i64_str(-999999999999) == \"-999999999999\"\n    assert m.u64_str(999999999999) == \"999999999999\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.u32_str(-1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.u64_str(-1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.i32_str(-3000000000)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.i32_str(3000000000)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_int_convert():\n    class Int:\n        def __int__(self):\n            return 42\n\n    class NotInt:\n        pass\n\n    class Float:\n        def __float__(self):\n            return 41.99999\n\n    class Index:\n        def __index__(self):\n            return 42\n\n    class IntAndIndex:\n        def __int__(self):\n            return 42\n\n        def __index__(self):\n            return 0\n\n    class RaisingTypeErrorOnIndex:\n        def __index__(self):\n            raise TypeError\n\n        def __int__(self):\n            return 42\n\n    class RaisingValueErrorOnIndex:\n        def __index__(self):\n            raise ValueError\n\n        def __int__(self):\n            return 42\n\n    convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert\n\n    def requires_conversion(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    assert convert(7) == 7\n    assert noconvert(7) == 7\n    cant_convert(3.14159)\n    # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)\n    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)\n    if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:\n        with env.deprecated_call():\n            assert convert(Int()) == 42\n    else:\n        assert convert(Int()) == 42\n    requires_conversion(Int())\n    cant_convert(NotInt())\n    cant_convert(Float())\n\n    # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`,\n    # but pybind11 \"backports\" this behavior.\n    assert convert(Index()) == 42\n    assert noconvert(Index()) == 42\n    assert convert(IntAndIndex()) == 0  # Fishy; `int(DoubleThought)` == 42\n    assert noconvert(IntAndIndex()) == 0\n    assert convert(RaisingTypeErrorOnIndex()) == 42\n    requires_conversion(RaisingTypeErrorOnIndex())\n    assert convert(RaisingValueErrorOnIndex()) == 42\n    requires_conversion(RaisingValueErrorOnIndex())\n\n\ndef test_numpy_int_convert():\n    np = pytest.importorskip(\"numpy\")\n\n    convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert\n\n    def require_implicit(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    # `np.intc` is an alias that corresponds to a C++ `int`\n    assert convert(np.intc(42)) == 42\n    assert noconvert(np.intc(42)) == 42\n\n    # The implicit conversion from np.float32 is undesirable but currently accepted.\n    # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)\n    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)\n    # https://github.com/pybind/pybind11/issues/3408\n    if (3, 8) <= sys.version_info < (3, 10) and env.CPYTHON:\n        with env.deprecated_call():\n            assert convert(np.float32(3.14159)) == 3\n    else:\n        assert convert(np.float32(3.14159)) == 3\n    require_implicit(np.float32(3.14159))\n\n\ndef test_tuple(doc):\n    \"\"\"std::pair <-> tuple & std::tuple <-> tuple\"\"\"\n    assert m.pair_passthrough((True, \"test\")) == (\"test\", True)\n    assert m.tuple_passthrough((True, \"test\", 5)) == (5, \"test\", True)\n    # Any sequence can be cast to a std::pair or std::tuple\n    assert m.pair_passthrough([True, \"test\"]) == (\"test\", True)\n    assert m.tuple_passthrough([True, \"test\", 5]) == (5, \"test\", True)\n    assert m.empty_tuple() == ()\n\n    assert (\n        doc(m.pair_passthrough)\n        == \"\"\"\n        pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]\n\n        Return a pair in reversed order\n    \"\"\"\n    )\n    assert (\n        doc(m.tuple_passthrough)\n        == \"\"\"\n        tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]\n\n        Return a triple in reversed order\n    \"\"\"\n    )\n\n    assert m.rvalue_pair() == (\"rvalue\", \"rvalue\")\n    assert m.lvalue_pair() == (\"lvalue\", \"lvalue\")\n    assert m.rvalue_tuple() == (\"rvalue\", \"rvalue\", \"rvalue\")\n    assert m.lvalue_tuple() == (\"lvalue\", \"lvalue\", \"lvalue\")\n    assert m.rvalue_nested() == (\"rvalue\", (\"rvalue\", (\"rvalue\", \"rvalue\")))\n    assert m.lvalue_nested() == (\"lvalue\", (\"lvalue\", (\"lvalue\", \"lvalue\")))\n\n    assert m.int_string_pair() == (2, \"items\")\n\n\ndef test_builtins_cast_return_none():\n    \"\"\"Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None\"\"\"\n    assert m.return_none_string() is None\n    assert m.return_none_char() is None\n    assert m.return_none_bool() is None\n    assert m.return_none_int() is None\n    assert m.return_none_float() is None\n    assert m.return_none_pair() is None\n\n\ndef test_none_deferred():\n    \"\"\"None passed as various argument types should defer to other overloads\"\"\"\n    assert not m.defer_none_cstring(\"abc\")\n    assert m.defer_none_cstring(None)\n    assert not m.defer_none_custom(UserType())\n    assert m.defer_none_custom(None)\n    assert m.nodefer_none_void(None)\n\n\ndef test_void_caster():\n    assert m.load_nullptr_t(None) is None\n    assert m.cast_nullptr_t() is None\n\n\ndef test_reference_wrapper():\n    \"\"\"std::reference_wrapper for builtin and user types\"\"\"\n    assert m.refwrap_builtin(42) == 420\n    assert m.refwrap_usertype(UserType(42)) == 42\n    assert m.refwrap_usertype_const(UserType(42)) == 42\n\n    with pytest.raises(TypeError) as excinfo:\n        m.refwrap_builtin(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.refwrap_usertype(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.refwrap_lvalue().value == 1\n    assert m.refwrap_lvalue_const().value == 1\n\n    a1 = m.refwrap_list(copy=True)\n    a2 = m.refwrap_list(copy=True)\n    assert [x.value for x in a1] == [2, 3]\n    assert [x.value for x in a2] == [2, 3]\n    assert not a1[0] is a2[0] and not a1[1] is a2[1]\n\n    b1 = m.refwrap_list(copy=False)\n    b2 = m.refwrap_list(copy=False)\n    assert [x.value for x in b1] == [1, 2]\n    assert [x.value for x in b2] == [1, 2]\n    assert b1[0] is b2[0] and b1[1] is b2[1]\n\n    assert m.refwrap_iiw(IncType(5)) == 5\n    assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]\n\n\ndef test_complex_cast():\n    \"\"\"std::complex casts\"\"\"\n    assert m.complex_cast(1) == \"1.0\"\n    assert m.complex_cast(2j) == \"(0.0, 2.0)\"\n\n\ndef test_bool_caster():\n    \"\"\"Test bool caster implicit conversions.\"\"\"\n    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert\n\n    def require_implicit(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    # straight up bool\n    assert convert(True) is True\n    assert convert(False) is False\n    assert noconvert(True) is True\n    assert noconvert(False) is False\n\n    # None requires implicit conversion\n    require_implicit(None)\n    assert convert(None) is False\n\n    class A:\n        def __init__(self, x):\n            self.x = x\n\n        def __nonzero__(self):\n            return self.x\n\n        def __bool__(self):\n            return self.x\n\n    class B:\n        pass\n\n    # Arbitrary objects are not accepted\n    cant_convert(object())\n    cant_convert(B())\n\n    # Objects with __nonzero__ / __bool__ defined can be converted\n    require_implicit(A(True))\n    assert convert(A(True)) is True\n    assert convert(A(False)) is False\n\n\ndef test_numpy_bool():\n    np = pytest.importorskip(\"numpy\")\n\n    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    # np.bool_ is not considered implicit\n    assert convert(np.bool_(True)) is True\n    assert convert(np.bool_(False)) is False\n    assert noconvert(np.bool_(True)) is True\n    assert noconvert(np.bool_(False)) is False\n    cant_convert(np.zeros(2, dtype=\"int\"))\n\n\ndef test_int_long():\n    assert isinstance(m.int_cast(), int)\n    assert isinstance(m.long_cast(), int)\n    assert isinstance(m.longlong_cast(), int)\n\n\ndef test_void_caster_2():\n    assert m.test_void_caster()\n\n\ndef test_const_ref_caster():\n    \"\"\"Verifies that const-ref is propagated through type_caster cast_op.\n    The returned ConstRefCasted type is a minimal type that is constructed to\n    reference the casting mode used.\n    \"\"\"\n    x = False\n    assert m.takes(x) == 1\n    assert m.takes_move(x) == 1\n\n    assert m.takes_ptr(x) == 3\n    assert m.takes_ref(x) == 2\n    assert m.takes_ref_wrap(x) == 2\n\n    assert m.takes_const_ptr(x) == 5\n    assert m.takes_const_ref(x) == 4\n    assert m.takes_const_ref_wrap(x) == 4\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_call_policies.cpp",
    "content": "/*\n    tests/test_call_policies.cpp -- keep_alive and call_guard\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nstruct CustomGuard {\n    static bool enabled;\n\n    CustomGuard() { enabled = true; }\n    ~CustomGuard() { enabled = false; }\n\n    static const char *report_status() { return enabled ? \"guarded\" : \"unguarded\"; }\n};\nbool CustomGuard::enabled = false;\n\nstruct DependentGuard {\n    static bool enabled;\n\n    DependentGuard() { enabled = CustomGuard::enabled; }\n    ~DependentGuard() { enabled = false; }\n\n    static const char *report_status() { return enabled ? \"guarded\" : \"unguarded\"; }\n};\nbool DependentGuard::enabled = false;\n\nTEST_SUBMODULE(call_policies, m) {\n    // Parent/Child are used in:\n    // test_keep_alive_argument, test_keep_alive_return_value, test_alive_gc_derived,\n    // test_alive_gc_multi_derived, test_return_none, test_keep_alive_constructor\n    class Child {\n    public:\n        Child() { py::print(\"Allocating child.\"); }\n        Child(const Child &) = default;\n        Child(Child &&) = default;\n        ~Child() { py::print(\"Releasing child.\"); }\n    };\n    py::class_<Child>(m, \"Child\").def(py::init<>());\n\n    class Parent {\n    public:\n        Parent() { py::print(\"Allocating parent.\"); }\n        Parent(const Parent &parent) = default;\n        ~Parent() { py::print(\"Releasing parent.\"); }\n        void addChild(Child *) {}\n        Child *returnChild() { return new Child(); }\n        Child *returnNullChild() { return nullptr; }\n        static Child *staticFunction(Parent *) { return new Child(); }\n    };\n    py::class_<Parent>(m, \"Parent\")\n        .def(py::init<>())\n        .def(py::init([](Child *) { return new Parent(); }), py::keep_alive<1, 2>())\n        .def(\"addChild\", &Parent::addChild)\n        .def(\"addChildKeepAlive\", &Parent::addChild, py::keep_alive<1, 2>())\n        .def(\"returnChild\", &Parent::returnChild)\n        .def(\"returnChildKeepAlive\", &Parent::returnChild, py::keep_alive<1, 0>())\n        .def(\"returnNullChildKeepAliveChild\", &Parent::returnNullChild, py::keep_alive<1, 0>())\n        .def(\"returnNullChildKeepAliveParent\", &Parent::returnNullChild, py::keep_alive<0, 1>())\n        .def_static(\"staticFunction\", &Parent::staticFunction, py::keep_alive<1, 0>());\n\n    m.def(\n        \"free_function\", [](Parent *, Child *) {}, py::keep_alive<1, 2>());\n    m.def(\n        \"invalid_arg_index\", [] {}, py::keep_alive<0, 1>());\n\n#if !defined(PYPY_VERSION)\n    // test_alive_gc\n    class ParentGC : public Parent {\n    public:\n        using Parent::Parent;\n    };\n    py::class_<ParentGC, Parent>(m, \"ParentGC\", py::dynamic_attr()).def(py::init<>());\n#endif\n\n    // test_call_guard\n    m.def(\"unguarded_call\", &CustomGuard::report_status);\n    m.def(\"guarded_call\", &CustomGuard::report_status, py::call_guard<CustomGuard>());\n\n    m.def(\n        \"multiple_guards_correct_order\",\n        []() {\n            return CustomGuard::report_status() + std::string(\" & \")\n                   + DependentGuard::report_status();\n        },\n        py::call_guard<CustomGuard, DependentGuard>());\n\n    m.def(\n        \"multiple_guards_wrong_order\",\n        []() {\n            return DependentGuard::report_status() + std::string(\" & \")\n                   + CustomGuard::report_status();\n        },\n        py::call_guard<DependentGuard, CustomGuard>());\n\n#if defined(WITH_THREAD) && !defined(PYPY_VERSION)\n    // `py::call_guard<py::gil_scoped_release>()` should work in PyPy as well,\n    // but it's unclear how to test it without `PyGILState_GetThisThreadState`.\n    auto report_gil_status = []() {\n        auto is_gil_held = false;\n        if (auto *tstate = py::detail::get_thread_state_unchecked()) {\n            is_gil_held = (tstate == PyGILState_GetThisThreadState());\n        }\n\n        return is_gil_held ? \"GIL held\" : \"GIL released\";\n    };\n\n    m.def(\"with_gil\", report_gil_status);\n    m.def(\"without_gil\", report_gil_status, py::call_guard<py::gil_scoped_release>());\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_call_policies.py",
    "content": "import pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import call_policies as m\n\n\n@pytest.mark.xfail(\"env.PYPY\", reason=\"sometimes comes out 1 off on PyPy\", strict=False)\ndef test_keep_alive_argument(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.addChild(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Releasing child.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.addChildKeepAlive(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n    p = m.Parent()\n    c = m.Child()\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    m.free_function(p, c)\n    del c\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    del p\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.invalid_arg_index()\n    assert str(excinfo.value) == \"Could not activate keep_alive!\"\n\n\ndef test_keep_alive_return_value(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnChild()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Releasing child.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnChildKeepAlive()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n    p = m.Parent()\n    assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    with capture:\n        m.Parent.staticFunction(p)\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\", reason=\"_PyObject_GetDictPtr is unimplemented\")\ndef test_alive_gc(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = m.ParentGC()\n    p.addChildKeepAlive(m.Child())\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_alive_gc_derived(capture):\n    class Derived(m.Parent):\n        pass\n\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = Derived()\n    p.addChildKeepAlive(m.Child())\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_alive_gc_multi_derived(capture):\n    class Derived(m.Parent, m.Child):\n        def __init__(self):\n            m.Parent.__init__(self)\n            m.Child.__init__(self)\n\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = Derived()\n    p.addChildKeepAlive(m.Child())\n    # +3 rather than +2 because Derived corresponds to two registered instances\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_return_none(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnNullChildKeepAliveChild()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert capture == \"\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnNullChildKeepAliveParent()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert capture == \"\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n\ndef test_keep_alive_constructor(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    with capture:\n        p = m.Parent(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Allocating parent.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_call_guard():\n    assert m.unguarded_call() == \"unguarded\"\n    assert m.guarded_call() == \"guarded\"\n\n    assert m.multiple_guards_correct_order() == \"guarded & guarded\"\n    assert m.multiple_guards_wrong_order() == \"unguarded & guarded\"\n\n    if hasattr(m, \"with_gil\"):\n        assert m.with_gil() == \"GIL held\"\n        assert m.without_gil() == \"GIL released\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_callbacks.cpp",
    "content": "/*\n    tests/test_callbacks.cpp -- callbacks\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <thread>\n\nint dummy_function(int i) { return i + 1; }\n\nTEST_SUBMODULE(callbacks, m) {\n    // test_callbacks, test_function_signatures\n    m.def(\"test_callback1\", [](const py::object &func) { return func(); });\n    m.def(\"test_callback2\", [](const py::object &func) { return func(\"Hello\", 'x', true, 5); });\n    m.def(\"test_callback3\", [](const std::function<int(int)> &func) {\n        return \"func(43) = \" + std::to_string(func(43));\n    });\n    m.def(\"test_callback4\",\n          []() -> std::function<int(int)> { return [](int i) { return i + 1; }; });\n    m.def(\"test_callback5\",\n          []() { return py::cpp_function([](int i) { return i + 1; }, py::arg(\"number\")); });\n\n    // test_keyword_args_and_generalized_unpacking\n    m.def(\"test_tuple_unpacking\", [](const py::function &f) {\n        auto t1 = py::make_tuple(2, 3);\n        auto t2 = py::make_tuple(5, 6);\n        return f(\"positional\", 1, *t1, 4, *t2);\n    });\n\n    m.def(\"test_dict_unpacking\", [](const py::function &f) {\n        auto d1 = py::dict(\"key\"_a = \"value\", \"a\"_a = 1);\n        auto d2 = py::dict();\n        auto d3 = py::dict(\"b\"_a = 2);\n        return f(\"positional\", 1, **d1, **d2, **d3);\n    });\n\n    m.def(\"test_keyword_args\", [](const py::function &f) { return f(\"x\"_a = 10, \"y\"_a = 20); });\n\n    m.def(\"test_unpacking_and_keywords1\", [](const py::function &f) {\n        auto args = py::make_tuple(2);\n        auto kwargs = py::dict(\"d\"_a = 4);\n        return f(1, *args, \"c\"_a = 3, **kwargs);\n    });\n\n    m.def(\"test_unpacking_and_keywords2\", [](const py::function &f) {\n        auto kwargs1 = py::dict(\"a\"_a = 1);\n        auto kwargs2 = py::dict(\"c\"_a = 3, \"d\"_a = 4);\n        return f(\"positional\",\n                 *py::make_tuple(1),\n                 2,\n                 *py::make_tuple(3, 4),\n                 5,\n                 \"key\"_a = \"value\",\n                 **kwargs1,\n                 \"b\"_a = 2,\n                 **kwargs2,\n                 \"e\"_a = 5);\n    });\n\n    m.def(\"test_unpacking_error1\", [](const py::function &f) {\n        auto kwargs = py::dict(\"x\"_a = 3);\n        return f(\"x\"_a = 1, \"y\"_a = 2, **kwargs); // duplicate ** after keyword\n    });\n\n    m.def(\"test_unpacking_error2\", [](const py::function &f) {\n        auto kwargs = py::dict(\"x\"_a = 3);\n        return f(**kwargs, \"x\"_a = 1); // duplicate keyword after **\n    });\n\n    m.def(\"test_arg_conversion_error1\",\n          [](const py::function &f) { f(234, UnregisteredType(), \"kw\"_a = 567); });\n\n    m.def(\"test_arg_conversion_error2\", [](const py::function &f) {\n        f(234, \"expected_name\"_a = UnregisteredType(), \"kw\"_a = 567);\n    });\n\n    // test_lambda_closure_cleanup\n    struct Payload {\n        Payload() { print_default_created(this); }\n        ~Payload() { print_destroyed(this); }\n        Payload(const Payload &) { print_copy_created(this); }\n        Payload(Payload &&) noexcept { print_move_created(this); }\n    };\n    // Export the payload constructor statistics for testing purposes:\n    m.def(\"payload_cstats\", &ConstructorStats::get<Payload>);\n    m.def(\"test_lambda_closure_cleanup\", []() -> std::function<void()> {\n        Payload p;\n\n        // In this situation, `Func` in the implementation of\n        // `cpp_function::initialize` is NOT trivially destructible.\n        return [p]() {\n            /* p should be cleaned up when the returned function is garbage collected */\n            (void) p;\n        };\n    });\n\n    class CppCallable {\n    public:\n        CppCallable() { track_default_created(this); }\n        ~CppCallable() { track_destroyed(this); }\n        CppCallable(const CppCallable &) { track_copy_created(this); }\n        CppCallable(CppCallable &&) noexcept { track_move_created(this); }\n        void operator()() {}\n    };\n\n    m.def(\"test_cpp_callable_cleanup\", []() {\n        // Related issue: https://github.com/pybind/pybind11/issues/3228\n        // Related PR: https://github.com/pybind/pybind11/pull/3229\n        py::list alive_counts;\n        ConstructorStats &stat = ConstructorStats::get<CppCallable>();\n        alive_counts.append(stat.alive());\n        {\n            CppCallable cpp_callable;\n            alive_counts.append(stat.alive());\n            {\n                // In this situation, `Func` in the implementation of\n                // `cpp_function::initialize` IS trivially destructible,\n                // only `capture` is not.\n                py::cpp_function py_func(cpp_callable);\n                py::detail::silence_unused_warnings(py_func);\n                alive_counts.append(stat.alive());\n            }\n            alive_counts.append(stat.alive());\n            {\n                py::cpp_function py_func(std::move(cpp_callable));\n                py::detail::silence_unused_warnings(py_func);\n                alive_counts.append(stat.alive());\n            }\n            alive_counts.append(stat.alive());\n        }\n        alive_counts.append(stat.alive());\n        return alive_counts;\n    });\n\n    // test_cpp_function_roundtrip\n    /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */\n    m.def(\"dummy_function\", &dummy_function);\n    m.def(\"dummy_function_overloaded\", [](int i, int j) { return i + j; });\n    m.def(\"dummy_function_overloaded\", &dummy_function);\n    m.def(\"dummy_function2\", [](int i, int j) { return i + j; });\n    m.def(\n        \"roundtrip\",\n        [](std::function<int(int)> f, bool expect_none = false) {\n            if (expect_none && f) {\n                throw std::runtime_error(\"Expected None to be converted to empty std::function\");\n            }\n            return f;\n        },\n        py::arg(\"f\"),\n        py::arg(\"expect_none\") = false);\n    m.def(\"test_dummy_function\", [](const std::function<int(int)> &f) -> std::string {\n        using fn_type = int (*)(int);\n        const auto *result = f.target<fn_type>();\n        if (!result) {\n            auto r = f(1);\n            return \"can't convert to function pointer: eval(1) = \" + std::to_string(r);\n        }\n        if (*result == dummy_function) {\n            auto r = (*result)(1);\n            return \"matches dummy_function: eval(1) = \" + std::to_string(r);\n        }\n        return \"argument does NOT match dummy_function. This should never happen!\";\n    });\n\n    class AbstractBase {\n    public:\n        // [workaround(intel)] = default does not work here\n        // Defaulting this destructor results in linking errors with the Intel compiler\n        // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)\n        virtual ~AbstractBase() {} // NOLINT(modernize-use-equals-default)\n        virtual unsigned int func() = 0;\n    };\n    m.def(\"func_accepting_func_accepting_base\",\n          [](const std::function<double(AbstractBase &)> &) {});\n\n    struct MovableObject {\n        bool valid = true;\n\n        MovableObject() = default;\n        MovableObject(const MovableObject &) = default;\n        MovableObject &operator=(const MovableObject &) = default;\n        MovableObject(MovableObject &&o) noexcept : valid(o.valid) { o.valid = false; }\n        MovableObject &operator=(MovableObject &&o) noexcept {\n            valid = o.valid;\n            o.valid = false;\n            return *this;\n        }\n    };\n    py::class_<MovableObject>(m, \"MovableObject\");\n\n    // test_movable_object\n    m.def(\"callback_with_movable\", [](const std::function<void(MovableObject &)> &f) {\n        auto x = MovableObject();\n        f(x);           // lvalue reference shouldn't move out object\n        return x.valid; // must still return `true`\n    });\n\n    // test_bound_method_callback\n    struct CppBoundMethodTest {};\n    py::class_<CppBoundMethodTest>(m, \"CppBoundMethodTest\")\n        .def(py::init<>())\n        .def(\"triple\", [](CppBoundMethodTest &, int val) { return 3 * val; });\n\n    // This checks that builtin functions can be passed as callbacks\n    // rather than throwing RuntimeError due to trying to extract as capsule\n    m.def(\"test_sum_builtin\",\n          [](const std::function<double(py::iterable)> &sum_builtin, const py::iterable &i) {\n              return sum_builtin(i);\n          });\n\n    // test async Python callbacks\n    using callback_f = std::function<void(int)>;\n    m.def(\"test_async_callback\", [](const callback_f &f, const py::list &work) {\n        // make detached thread that calls `f` with piece of work after a little delay\n        auto start_f = [f](int j) {\n            auto invoke_f = [f, j] {\n                std::this_thread::sleep_for(std::chrono::milliseconds(50));\n                f(j);\n            };\n            auto t = std::thread(std::move(invoke_f));\n            t.detach();\n        };\n\n        // spawn worker threads\n        for (auto i : work) {\n            start_f(py::cast<int>(i));\n        }\n    });\n\n    m.def(\"callback_num_times\", [](const py::function &f, std::size_t num) {\n        for (std::size_t i = 0; i < num; i++) {\n            f();\n        }\n    });\n\n    auto *custom_def = []() {\n        static PyMethodDef def;\n        def.ml_name = \"example_name\";\n        def.ml_doc = \"Example doc\";\n        def.ml_meth = [](PyObject *, PyObject *args) -> PyObject * {\n            if (PyTuple_Size(args) != 1) {\n                throw std::runtime_error(\"Invalid number of arguments for example_name\");\n            }\n            PyObject *first = PyTuple_GetItem(args, 0);\n            if (!PyLong_Check(first)) {\n                throw std::runtime_error(\"Invalid argument to example_name\");\n            }\n            auto result = py::cast(PyLong_AsLong(first) * 9);\n            return result.release().ptr();\n        };\n        def.ml_flags = METH_VARARGS;\n        return &def;\n    }();\n\n    // rec_capsule with name that has the same value (but not pointer) as our internal one\n    // This capsule should be detected by our code as foreign and not inspected as the pointers\n    // shouldn't match\n    constexpr const char *rec_capsule_name\n        = pybind11::detail::internals_function_record_capsule_name;\n    py::capsule rec_capsule(std::malloc(1), [](void *data) { std::free(data); });\n    rec_capsule.set_name(rec_capsule_name);\n    m.add_object(\"custom_function\", PyCFunction_New(custom_def, rec_capsule.ptr()));\n\n    // This test requires a new ABI version to pass\n#if PYBIND11_INTERNALS_VERSION > 4\n    // rec_capsule with nullptr name\n    py::capsule rec_capsule2(std::malloc(1), [](void *data) { std::free(data); });\n    m.add_object(\"custom_function2\", PyCFunction_New(custom_def, rec_capsule2.ptr()));\n#else\n    m.add_object(\"custom_function2\", py::none());\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_callbacks.py",
    "content": "import time\nfrom threading import Thread\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import callbacks as m\n\n\ndef test_callbacks():\n    from functools import partial\n\n    def func1():\n        return \"func1\"\n\n    def func2(a, b, c, d):\n        return \"func2\", a, b, c, d\n\n    def func3(a):\n        return f\"func3({a})\"\n\n    assert m.test_callback1(func1) == \"func1\"\n    assert m.test_callback2(func2) == (\"func2\", \"Hello\", \"x\", True, 5)\n    assert m.test_callback1(partial(func2, 1, 2, 3, 4)) == (\"func2\", 1, 2, 3, 4)\n    assert m.test_callback1(partial(func3, \"partial\")) == \"func3(partial)\"\n    assert m.test_callback3(lambda i: i + 1) == \"func(43) = 44\"\n\n    f = m.test_callback4()\n    assert f(43) == 44\n    f = m.test_callback5()\n    assert f(number=43) == 44\n\n\ndef test_bound_method_callback():\n    # Bound Python method:\n    class MyClass:\n        def double(self, val):\n            return 2 * val\n\n    z = MyClass()\n    assert m.test_callback3(z.double) == \"func(43) = 86\"\n\n    z = m.CppBoundMethodTest()\n    assert m.test_callback3(z.triple) == \"func(43) = 129\"\n\n\ndef test_keyword_args_and_generalized_unpacking():\n    def f(*args, **kwargs):\n        return args, kwargs\n\n    assert m.test_tuple_unpacking(f) == ((\"positional\", 1, 2, 3, 4, 5, 6), {})\n    assert m.test_dict_unpacking(f) == (\n        (\"positional\", 1),\n        {\"key\": \"value\", \"a\": 1, \"b\": 2},\n    )\n    assert m.test_keyword_args(f) == ((), {\"x\": 10, \"y\": 20})\n    assert m.test_unpacking_and_keywords1(f) == ((1, 2), {\"c\": 3, \"d\": 4})\n    assert m.test_unpacking_and_keywords2(f) == (\n        (\"positional\", 1, 2, 3, 4, 5),\n        {\"key\": \"value\", \"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4, \"e\": 5},\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_unpacking_error1(f)\n    assert \"Got multiple values for keyword argument\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_unpacking_error2(f)\n    assert \"Got multiple values for keyword argument\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_arg_conversion_error1(f)\n    assert \"Unable to convert call argument\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_arg_conversion_error2(f)\n    assert \"Unable to convert call argument\" in str(excinfo.value)\n\n\ndef test_lambda_closure_cleanup():\n    m.test_lambda_closure_cleanup()\n    cstats = m.payload_cstats()\n    assert cstats.alive() == 0\n    assert cstats.copy_constructions == 1\n    assert cstats.move_constructions >= 1\n\n\ndef test_cpp_callable_cleanup():\n    alive_counts = m.test_cpp_callable_cleanup()\n    assert alive_counts == [0, 1, 2, 1, 2, 1, 0]\n\n\ndef test_cpp_function_roundtrip():\n    \"\"\"Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer\"\"\"\n\n    assert (\n        m.test_dummy_function(m.dummy_function) == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert (\n        m.test_dummy_function(m.roundtrip(m.dummy_function))\n        == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert (\n        m.test_dummy_function(m.dummy_function_overloaded)\n        == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert m.roundtrip(None, expect_none=True) is None\n    assert (\n        m.test_dummy_function(lambda x: x + 2)\n        == \"can't convert to function pointer: eval(1) = 3\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_dummy_function(m.dummy_function2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_dummy_function(lambda x, y: x + y)\n    assert any(\n        s in str(excinfo.value)\n        for s in (\"missing 1 required positional argument\", \"takes exactly 2 arguments\")\n    )\n\n\ndef test_function_signatures(doc):\n    assert doc(m.test_callback3) == \"test_callback3(arg0: Callable[[int], int]) -> str\"\n    assert doc(m.test_callback4) == \"test_callback4() -> Callable[[int], int]\"\n\n\ndef test_movable_object():\n    assert m.callback_with_movable(lambda _: None) is True\n\n\n@pytest.mark.skipif(\n    \"env.PYPY\",\n    reason=\"PyPy segfaults on here. See discussion on #1413.\",\n)\ndef test_python_builtins():\n    \"\"\"Test if python builtins like sum() can be used as callbacks\"\"\"\n    assert m.test_sum_builtin(sum, [1, 2, 3]) == 6\n    assert m.test_sum_builtin(sum, []) == 0\n\n\ndef test_async_callbacks():\n    # serves as state for async callback\n    class Item:\n        def __init__(self, value):\n            self.value = value\n\n    res = []\n\n    # generate stateful lambda that will store result in `res`\n    def gen_f():\n        s = Item(3)\n        return lambda j: res.append(s.value + j)\n\n    # do some work async\n    work = [1, 2, 3, 4]\n    m.test_async_callback(gen_f(), work)\n    # wait until work is done\n    from time import sleep\n\n    sleep(0.5)\n    assert sum(res) == sum(x + 3 for x in work)\n\n\ndef test_async_async_callbacks():\n    t = Thread(target=test_async_callbacks)\n    t.start()\n    t.join()\n\n\ndef test_callback_num_times():\n    # Super-simple micro-benchmarking related to PR #2919.\n    # Example runtimes (Intel Xeon 2.2GHz, fully optimized):\n    #   num_millions  1, repeats  2:  0.1 secs\n    #   num_millions 20, repeats 10: 11.5 secs\n    one_million = 1000000\n    num_millions = 1  # Try 20 for actual micro-benchmarking.\n    repeats = 2  # Try 10.\n    rates = []\n    for rep in range(repeats):\n        t0 = time.time()\n        m.callback_num_times(lambda: None, num_millions * one_million)\n        td = time.time() - t0\n        rate = num_millions / td if td else 0\n        rates.append(rate)\n        if not rep:\n            print()\n        print(\n            f\"callback_num_times: {num_millions:d} million / {td:.3f} seconds = {rate:.3f} million / second\"\n        )\n    if len(rates) > 1:\n        print(\"Min    Mean   Max\")\n        print(f\"{min(rates):6.3f} {sum(rates) / len(rates):6.3f} {max(rates):6.3f}\")\n\n\ndef test_custom_func():\n    assert m.custom_function(4) == 36\n    assert m.roundtrip(m.custom_function)(4) == 36\n\n\n@pytest.mark.skipif(\n    m.custom_function2 is None, reason=\"Current PYBIND11_INTERNALS_VERSION too low\"\n)\ndef test_custom_func2():\n    assert m.custom_function2(3) == 27\n    assert m.roundtrip(m.custom_function2)(3) == 27\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_chrono.cpp",
    "content": "/*\n    tests/test_chrono.cpp -- test conversions to/from std::chrono types\n\n    Copyright (c) 2016 Trent Houliston <trent@houliston.me> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/chrono.h>\n\n#include \"pybind11_tests.h\"\n\n#include <chrono>\n\nstruct different_resolutions {\n    using time_point_h = std::chrono::time_point<std::chrono::system_clock, std::chrono::hours>;\n    using time_point_m = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;\n    using time_point_s = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;\n    using time_point_ms\n        = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>;\n    using time_point_us\n        = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;\n    time_point_h timestamp_h;\n    time_point_m timestamp_m;\n    time_point_s timestamp_s;\n    time_point_ms timestamp_ms;\n    time_point_us timestamp_us;\n};\n\nTEST_SUBMODULE(chrono, m) {\n    using system_time = std::chrono::system_clock::time_point;\n    using steady_time = std::chrono::steady_clock::time_point;\n\n    using timespan = std::chrono::duration<int64_t, std::nano>;\n    using timestamp = std::chrono::time_point<std::chrono::system_clock, timespan>;\n\n    // test_chrono_system_clock\n    // Return the current time off the wall clock\n    m.def(\"test_chrono1\", []() { return std::chrono::system_clock::now(); });\n\n    // test_chrono_system_clock_roundtrip\n    // Round trip the passed in system clock time\n    m.def(\"test_chrono2\", [](system_time t) { return t; });\n\n    // test_chrono_duration_roundtrip\n    // Round trip the passed in duration\n    m.def(\"test_chrono3\", [](std::chrono::system_clock::duration d) { return d; });\n\n    // test_chrono_duration_subtraction_equivalence\n    // Difference between two passed in time_points\n    m.def(\"test_chrono4\", [](system_time a, system_time b) { return a - b; });\n\n    // test_chrono_steady_clock\n    // Return the current time off the steady_clock\n    m.def(\"test_chrono5\", []() { return std::chrono::steady_clock::now(); });\n\n    // test_chrono_steady_clock_roundtrip\n    // Round trip a steady clock timepoint\n    m.def(\"test_chrono6\", [](steady_time t) { return t; });\n\n    // test_floating_point_duration\n    // Roundtrip a duration in microseconds from a float argument\n    m.def(\"test_chrono7\", [](std::chrono::microseconds t) { return t; });\n    // Float durations (issue #719)\n    m.def(\"test_chrono_float_diff\",\n          [](std::chrono::duration<float> a, std::chrono::duration<float> b) { return a - b; });\n\n    m.def(\"test_nano_timepoint\",\n          [](timestamp start, timespan delta) -> timestamp { return start + delta; });\n\n    // Test different resolutions\n    py::class_<different_resolutions>(m, \"different_resolutions\")\n        .def(py::init<>())\n        .def_readwrite(\"timestamp_h\", &different_resolutions::timestamp_h)\n        .def_readwrite(\"timestamp_m\", &different_resolutions::timestamp_m)\n        .def_readwrite(\"timestamp_s\", &different_resolutions::timestamp_s)\n        .def_readwrite(\"timestamp_ms\", &different_resolutions::timestamp_ms)\n        .def_readwrite(\"timestamp_us\", &different_resolutions::timestamp_us);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_chrono.py",
    "content": "import datetime\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import chrono as m\n\n\ndef test_chrono_system_clock():\n\n    # Get the time from both c++ and datetime\n    date0 = datetime.datetime.today()\n    date1 = m.test_chrono1()\n    date2 = datetime.datetime.today()\n\n    # The returned value should be a datetime\n    assert isinstance(date1, datetime.datetime)\n\n    # The numbers should vary by a very small amount (time it took to execute)\n    diff_python = abs(date2 - date0)\n    diff = abs(date1 - date2)\n\n    # There should never be a days difference\n    assert diff.days == 0\n\n    # Since datetime.datetime.today() calls time.time(), and on some platforms\n    # that has 1 second accuracy, we compare this way\n    assert diff.seconds <= diff_python.seconds\n\n\ndef test_chrono_system_clock_roundtrip():\n    date1 = datetime.datetime.today()\n\n    # Roundtrip the time\n    date2 = m.test_chrono2(date1)\n\n    # The returned value should be a datetime\n    assert isinstance(date2, datetime.datetime)\n\n    # They should be identical (no information lost on roundtrip)\n    diff = abs(date1 - date2)\n    assert diff == datetime.timedelta(0)\n\n\ndef test_chrono_system_clock_roundtrip_date():\n    date1 = datetime.date.today()\n\n    # Roundtrip the time\n    datetime2 = m.test_chrono2(date1)\n    date2 = datetime2.date()\n    time2 = datetime2.time()\n\n    # The returned value should be a datetime\n    assert isinstance(datetime2, datetime.datetime)\n    assert isinstance(date2, datetime.date)\n    assert isinstance(time2, datetime.time)\n\n    # They should be identical (no information lost on roundtrip)\n    diff = abs(date1 - date2)\n    assert diff.days == 0\n    assert diff.seconds == 0\n    assert diff.microseconds == 0\n\n    # Year, Month & Day should be the same after the round trip\n    assert date1 == date2\n\n    # There should be no time information\n    assert time2.hour == 0\n    assert time2.minute == 0\n    assert time2.second == 0\n    assert time2.microsecond == 0\n\n\nSKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(\n    \"env.WIN\", reason=\"TZ environment variable only supported on POSIX\"\n)\n\n\n@pytest.mark.parametrize(\n    \"time1\",\n    [\n        datetime.datetime.today().time(),\n        datetime.time(0, 0, 0),\n        datetime.time(0, 0, 0, 1),\n        datetime.time(0, 28, 45, 109827),\n        datetime.time(0, 59, 59, 999999),\n        datetime.time(1, 0, 0),\n        datetime.time(5, 59, 59, 0),\n        datetime.time(5, 59, 59, 1),\n    ],\n)\n@pytest.mark.parametrize(\n    \"tz\",\n    [\n        None,\n        pytest.param(\"Europe/Brussels\", marks=SKIP_TZ_ENV_ON_WIN),\n        pytest.param(\"Asia/Pyongyang\", marks=SKIP_TZ_ENV_ON_WIN),\n        pytest.param(\"America/New_York\", marks=SKIP_TZ_ENV_ON_WIN),\n    ],\n)\ndef test_chrono_system_clock_roundtrip_time(time1, tz, monkeypatch):\n    if tz is not None:\n        monkeypatch.setenv(\"TZ\", f\"/usr/share/zoneinfo/{tz}\")\n\n    # Roundtrip the time\n    datetime2 = m.test_chrono2(time1)\n    date2 = datetime2.date()\n    time2 = datetime2.time()\n\n    # The returned value should be a datetime\n    assert isinstance(datetime2, datetime.datetime)\n    assert isinstance(date2, datetime.date)\n    assert isinstance(time2, datetime.time)\n\n    # Hour, Minute, Second & Microsecond should be the same after the round trip\n    assert time1 == time2\n\n    # There should be no date information (i.e. date = python base date)\n    assert date2.year == 1970\n    assert date2.month == 1\n    assert date2.day == 1\n\n\ndef test_chrono_duration_roundtrip():\n\n    # Get the difference between two times (a timedelta)\n    date1 = datetime.datetime.today()\n    date2 = datetime.datetime.today()\n    diff = date2 - date1\n\n    # Make sure this is a timedelta\n    assert isinstance(diff, datetime.timedelta)\n\n    cpp_diff = m.test_chrono3(diff)\n\n    assert cpp_diff == diff\n\n    # Negative timedelta roundtrip\n    diff = datetime.timedelta(microseconds=-1)\n    cpp_diff = m.test_chrono3(diff)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_duration_subtraction_equivalence():\n\n    date1 = datetime.datetime.today()\n    date2 = datetime.datetime.today()\n\n    diff = date2 - date1\n    cpp_diff = m.test_chrono4(date2, date1)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_duration_subtraction_equivalence_date():\n\n    date1 = datetime.date.today()\n    date2 = datetime.date.today()\n\n    diff = date2 - date1\n    cpp_diff = m.test_chrono4(date2, date1)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_steady_clock():\n    time1 = m.test_chrono5()\n    assert isinstance(time1, datetime.timedelta)\n\n\ndef test_chrono_steady_clock_roundtrip():\n    time1 = datetime.timedelta(days=10, seconds=10, microseconds=100)\n    time2 = m.test_chrono6(time1)\n\n    assert isinstance(time2, datetime.timedelta)\n\n    # They should be identical (no information lost on roundtrip)\n    assert time1 == time2\n\n\ndef test_floating_point_duration():\n    # Test using a floating point number in seconds\n    time = m.test_chrono7(35.525123)\n\n    assert isinstance(time, datetime.timedelta)\n\n    assert time.seconds == 35\n    assert 525122 <= time.microseconds <= 525123\n\n    diff = m.test_chrono_float_diff(43.789012, 1.123456)\n    assert diff.seconds == 42\n    assert 665556 <= diff.microseconds <= 665557\n\n\ndef test_nano_timepoint():\n    time = datetime.datetime.now()\n    time1 = m.test_nano_timepoint(time, datetime.timedelta(seconds=60))\n    assert time1 == time + datetime.timedelta(seconds=60)\n\n\ndef test_chrono_different_resolutions():\n    resolutions = m.different_resolutions()\n    time = datetime.datetime.now()\n    resolutions.timestamp_h = time\n    resolutions.timestamp_m = time\n    resolutions.timestamp_s = time\n    resolutions.timestamp_ms = time\n    resolutions.timestamp_us = time\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_class.cpp",
    "content": "/*\n    tests/test_class.cpp -- test py::class_ definitions and basic functionality\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#if defined(__INTEL_COMPILER) && __cplusplus >= 201703L\n// Intel compiler requires a separate header file to support aligned new operators\n// and does not set the __cpp_aligned_new feature macro.\n// This header needs to be included before pybind11.\n#    include <aligned_new>\n#endif\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\n#if defined(_MSC_VER)\n#    pragma warning(disable : 4324)\n//     warning C4324: structure was padded due to alignment specifier\n#endif\n\n// test_brace_initialization\nstruct NoBraceInitialization {\n    explicit NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}\n    template <typename T>\n    NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}\n\n    std::vector<int> vec;\n};\n\nnamespace test_class {\nnamespace pr4220_tripped_over_this { // PR #4227\n\ntemplate <int>\nstruct SoEmpty {};\n\ntemplate <typename T>\nstd::string get_msg(const T &) {\n    return \"This is really only meant to exercise successful compilation.\";\n}\n\nusing Empty0 = SoEmpty<0x0>;\n\nvoid bind_empty0(py::module_ &m) {\n    py::class_<Empty0>(m, \"Empty0\").def(py::init<>()).def(\"get_msg\", get_msg<Empty0>);\n}\n\n} // namespace pr4220_tripped_over_this\n} // namespace test_class\n\nTEST_SUBMODULE(class_, m) {\n    // test_instance\n    struct NoConstructor {\n        NoConstructor() = default;\n        NoConstructor(const NoConstructor &) = default;\n        NoConstructor(NoConstructor &&) = default;\n        static NoConstructor *new_instance() {\n            auto *ptr = new NoConstructor();\n            print_created(ptr, \"via new_instance\");\n            return ptr;\n        }\n        ~NoConstructor() { print_destroyed(this); }\n    };\n    struct NoConstructorNew {\n        NoConstructorNew() = default;\n        NoConstructorNew(const NoConstructorNew &) = default;\n        NoConstructorNew(NoConstructorNew &&) = default;\n        static NoConstructorNew *new_instance() {\n            auto *ptr = new NoConstructorNew();\n            print_created(ptr, \"via new_instance\");\n            return ptr;\n        }\n        ~NoConstructorNew() { print_destroyed(this); }\n    };\n\n    py::class_<NoConstructor>(m, \"NoConstructor\")\n        .def_static(\"new_instance\", &NoConstructor::new_instance, \"Return an instance\");\n\n    py::class_<NoConstructorNew>(m, \"NoConstructorNew\")\n        .def(py::init([](const NoConstructorNew &self) { return self; })) // Need a NOOP __init__\n        .def_static(\"__new__\",\n                    [](const py::object &) { return NoConstructorNew::new_instance(); });\n\n    // test_inheritance\n    class Pet {\n    public:\n        Pet(const std::string &name, const std::string &species)\n            : m_name(name), m_species(species) {}\n        std::string name() const { return m_name; }\n        std::string species() const { return m_species; }\n\n    private:\n        std::string m_name;\n        std::string m_species;\n    };\n\n    class Dog : public Pet {\n    public:\n        explicit Dog(const std::string &name) : Pet(name, \"dog\") {}\n        std::string bark() const { return \"Woof!\"; }\n    };\n\n    class Rabbit : public Pet {\n    public:\n        explicit Rabbit(const std::string &name) : Pet(name, \"parrot\") {}\n    };\n\n    class Hamster : public Pet {\n    public:\n        explicit Hamster(const std::string &name) : Pet(name, \"rodent\") {}\n    };\n\n    class Chimera : public Pet {\n        Chimera() : Pet(\"Kimmy\", \"chimera\") {}\n    };\n\n    py::class_<Pet> pet_class(m, \"Pet\");\n    pet_class.def(py::init<std::string, std::string>())\n        .def(\"name\", &Pet::name)\n        .def(\"species\", &Pet::species);\n\n    /* One way of declaring a subclass relationship: reference parent's class_ object */\n    py::class_<Dog>(m, \"Dog\", pet_class).def(py::init<std::string>());\n\n    /* Another way of declaring a subclass relationship: reference parent's C++ type */\n    py::class_<Rabbit, Pet>(m, \"Rabbit\").def(py::init<std::string>());\n\n    /* And another: list parent in class template arguments */\n    py::class_<Hamster, Pet>(m, \"Hamster\").def(py::init<std::string>());\n\n    /* Constructors are not inherited by default */\n    py::class_<Chimera, Pet>(m, \"Chimera\");\n\n    m.def(\"pet_name_species\",\n          [](const Pet &pet) { return pet.name() + \" is a \" + pet.species(); });\n    m.def(\"dog_bark\", [](const Dog &dog) { return dog.bark(); });\n\n    // test_automatic_upcasting\n    struct BaseClass {\n        BaseClass() = default;\n        BaseClass(const BaseClass &) = default;\n        BaseClass(BaseClass &&) = default;\n        virtual ~BaseClass() = default;\n    };\n    struct DerivedClass1 : BaseClass {};\n    struct DerivedClass2 : BaseClass {};\n\n    py::class_<BaseClass>(m, \"BaseClass\").def(py::init<>());\n    py::class_<DerivedClass1>(m, \"DerivedClass1\").def(py::init<>());\n    py::class_<DerivedClass2>(m, \"DerivedClass2\").def(py::init<>());\n\n    m.def(\"return_class_1\", []() -> BaseClass * { return new DerivedClass1(); });\n    m.def(\"return_class_2\", []() -> BaseClass * { return new DerivedClass2(); });\n    m.def(\"return_class_n\", [](int n) -> BaseClass * {\n        if (n == 1) {\n            return new DerivedClass1();\n        }\n        if (n == 2) {\n            return new DerivedClass2();\n        }\n        return new BaseClass();\n    });\n    m.def(\"return_none\", []() -> BaseClass * { return nullptr; });\n\n    // test_isinstance\n    m.def(\"check_instances\", [](const py::list &l) {\n        return py::make_tuple(py::isinstance<py::tuple>(l[0]),\n                              py::isinstance<py::dict>(l[1]),\n                              py::isinstance<Pet>(l[2]),\n                              py::isinstance<Pet>(l[3]),\n                              py::isinstance<Dog>(l[4]),\n                              py::isinstance<Rabbit>(l[5]),\n                              py::isinstance<UnregisteredType>(l[6]));\n    });\n\n    struct Invalid {};\n\n    // test_type\n    m.def(\"check_type\", [](int category) {\n        // Currently not supported (via a fail at compile time)\n        // See https://github.com/pybind/pybind11/issues/2486\n        // if (category == 2)\n        //     return py::type::of<int>();\n        if (category == 1) {\n            return py::type::of<DerivedClass1>();\n        }\n        return py::type::of<Invalid>();\n    });\n\n    m.def(\"get_type_of\", [](py::object ob) { return py::type::of(std::move(ob)); });\n\n    m.def(\"get_type_classic\", [](py::handle h) { return h.get_type(); });\n\n    m.def(\"as_type\", [](const py::object &ob) { return py::type(ob); });\n\n    // test_mismatched_holder\n    struct MismatchBase1 {};\n    struct MismatchDerived1 : MismatchBase1 {};\n\n    struct MismatchBase2 {};\n    struct MismatchDerived2 : MismatchBase2 {};\n\n    m.def(\"mismatched_holder_1\", []() {\n        auto mod = py::module_::import(\"__main__\");\n        py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, \"MismatchBase1\");\n        py::class_<MismatchDerived1, MismatchBase1>(mod, \"MismatchDerived1\");\n    });\n    m.def(\"mismatched_holder_2\", []() {\n        auto mod = py::module_::import(\"__main__\");\n        py::class_<MismatchBase2>(mod, \"MismatchBase2\");\n        py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, MismatchBase2>(\n            mod, \"MismatchDerived2\");\n    });\n\n    // test_override_static\n    // #511: problem with inheritance + overwritten def_static\n    struct MyBase {\n        static std::unique_ptr<MyBase> make() { return std::unique_ptr<MyBase>(new MyBase()); }\n    };\n\n    struct MyDerived : MyBase {\n        static std::unique_ptr<MyDerived> make() {\n            return std::unique_ptr<MyDerived>(new MyDerived());\n        }\n    };\n\n    py::class_<MyBase>(m, \"MyBase\").def_static(\"make\", &MyBase::make);\n\n    py::class_<MyDerived, MyBase>(m, \"MyDerived\")\n        .def_static(\"make\", &MyDerived::make)\n        .def_static(\"make2\", &MyDerived::make);\n\n    // test_implicit_conversion_life_support\n    struct ConvertibleFromUserType {\n        int i;\n\n        explicit ConvertibleFromUserType(UserType u) : i(u.value()) {}\n    };\n\n    py::class_<ConvertibleFromUserType>(m, \"AcceptsUserType\").def(py::init<UserType>());\n    py::implicitly_convertible<UserType, ConvertibleFromUserType>();\n\n    m.def(\"implicitly_convert_argument\", [](const ConvertibleFromUserType &r) { return r.i; });\n    m.def(\"implicitly_convert_variable\", [](const py::object &o) {\n        // `o` is `UserType` and `r` is a reference to a temporary created by implicit\n        // conversion. This is valid when called inside a bound function because the temp\n        // object is attached to the same life support system as the arguments.\n        const auto &r = o.cast<const ConvertibleFromUserType &>();\n        return r.i;\n    });\n    m.add_object(\"implicitly_convert_variable_fail\", [&] {\n        auto f = [](PyObject *, PyObject *args) -> PyObject * {\n            auto o = py::reinterpret_borrow<py::tuple>(args)[0];\n            try { // It should fail here because there is no life support.\n                o.cast<const ConvertibleFromUserType &>();\n            } catch (const py::cast_error &e) {\n                return py::str(e.what()).release().ptr();\n            }\n            return py::str().release().ptr();\n        };\n\n        auto *def = new PyMethodDef{\"f\", f, METH_VARARGS, nullptr};\n        py::capsule def_capsule(def,\n                                [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });\n        return py::reinterpret_steal<py::object>(\n            PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));\n    }());\n\n    // test_operator_new_delete\n    struct HasOpNewDel {\n        std::uint64_t i;\n        static void *operator new(size_t s) {\n            py::print(\"A new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"A placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p) {\n            py::print(\"A delete\");\n            return ::operator delete(p);\n        }\n    };\n    struct HasOpNewDelSize {\n        std::uint32_t i;\n        static void *operator new(size_t s) {\n            py::print(\"B new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"B placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"B delete\", s);\n            return ::operator delete(p);\n        }\n    };\n    struct AliasedHasOpNewDelSize {\n        std::uint64_t i;\n        static void *operator new(size_t s) {\n            py::print(\"C new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"C placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"C delete\", s);\n            return ::operator delete(p);\n        }\n        virtual ~AliasedHasOpNewDelSize() = default;\n        AliasedHasOpNewDelSize() = default;\n        AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize &) = delete;\n    };\n    struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {\n        PyAliasedHasOpNewDelSize() = default;\n        explicit PyAliasedHasOpNewDelSize(int) {}\n        std::uint64_t j;\n    };\n    struct HasOpNewDelBoth {\n        std::uint32_t i[8];\n        static void *operator new(size_t s) {\n            py::print(\"D new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"D placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p) {\n            py::print(\"D delete\");\n            return ::operator delete(p);\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"D wrong delete\", s);\n            return ::operator delete(p);\n        }\n    };\n    py::class_<HasOpNewDel>(m, \"HasOpNewDel\").def(py::init<>());\n    py::class_<HasOpNewDelSize>(m, \"HasOpNewDelSize\").def(py::init<>());\n    py::class_<HasOpNewDelBoth>(m, \"HasOpNewDelBoth\").def(py::init<>());\n    py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m,\n                                                                         \"AliasedHasOpNewDelSize\");\n    aliased.def(py::init<>());\n    aliased.attr(\"size_noalias\") = py::int_(sizeof(AliasedHasOpNewDelSize));\n    aliased.attr(\"size_alias\") = py::int_(sizeof(PyAliasedHasOpNewDelSize));\n\n    // This test is actually part of test_local_bindings (test_duplicate_local), but we need a\n    // definition in a different compilation unit within the same module:\n    bind_local<LocalExternal, 17>(m, \"LocalExternal\", py::module_local());\n\n    // test_bind_protected_functions\n    class ProtectedA {\n    protected:\n        int foo() const { return value; }\n\n    private:\n        int value = 42;\n    };\n\n    class PublicistA : public ProtectedA {\n    public:\n        using ProtectedA::foo;\n    };\n\n    py::class_<ProtectedA>(m, \"ProtectedA\").def(py::init<>()).def(\"foo\", &PublicistA::foo);\n\n    class ProtectedB {\n    public:\n        virtual ~ProtectedB() = default;\n        ProtectedB() = default;\n        ProtectedB(const ProtectedB &) = delete;\n\n    protected:\n        virtual int foo() const { return value; }\n        virtual void *void_foo() { return static_cast<void *>(&value); }\n        virtual void *get_self() { return static_cast<void *>(this); }\n\n    private:\n        int value = 42;\n    };\n\n    class TrampolineB : public ProtectedB {\n    public:\n        int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }\n        void *void_foo() override { PYBIND11_OVERRIDE(void *, ProtectedB, void_foo, ); }\n        void *get_self() override { PYBIND11_OVERRIDE(void *, ProtectedB, get_self, ); }\n    };\n\n    class PublicistB : public ProtectedB {\n    public:\n        // [workaround(intel)] = default does not work here\n        // Removing or defaulting this destructor results in linking errors with the Intel compiler\n        // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)\n        ~PublicistB() override{}; // NOLINT(modernize-use-equals-default)\n        using ProtectedB::foo;\n        using ProtectedB::get_self;\n        using ProtectedB::void_foo;\n    };\n\n    m.def(\"read_foo\", [](const void *original) {\n        const int *ptr = reinterpret_cast<const int *>(original);\n        return *ptr;\n    });\n\n    m.def(\"pointers_equal\",\n          [](const void *original, const void *comparison) { return original == comparison; });\n\n    py::class_<ProtectedB, TrampolineB>(m, \"ProtectedB\")\n        .def(py::init<>())\n        .def(\"foo\", &PublicistB::foo)\n        .def(\"void_foo\", &PublicistB::void_foo)\n        .def(\"get_self\", &PublicistB::get_self);\n\n    // test_brace_initialization\n    struct BraceInitialization {\n        int field1;\n        std::string field2;\n    };\n\n    py::class_<BraceInitialization>(m, \"BraceInitialization\")\n        .def(py::init<int, const std::string &>())\n        .def_readwrite(\"field1\", &BraceInitialization::field1)\n        .def_readwrite(\"field2\", &BraceInitialization::field2);\n    // We *don't* want to construct using braces when the given constructor argument maps to a\n    // constructor, because brace initialization could go to the wrong place (in particular when\n    // there is also an `initializer_list<T>`-accept constructor):\n    py::class_<NoBraceInitialization>(m, \"NoBraceInitialization\")\n        .def(py::init<std::vector<int>>())\n        .def_readonly(\"vec\", &NoBraceInitialization::vec);\n\n    // test_reentrant_implicit_conversion_failure\n    // #1035: issue with runaway reentrant implicit conversion\n    struct BogusImplicitConversion {\n        BogusImplicitConversion(const BogusImplicitConversion &) = default;\n    };\n\n    py::class_<BogusImplicitConversion>(m, \"BogusImplicitConversion\")\n        .def(py::init<const BogusImplicitConversion &>());\n\n    py::implicitly_convertible<int, BogusImplicitConversion>();\n\n    // test_qualname\n    // #1166: nested class docstring doesn't show nested name\n    // Also related: tests that __qualname__ is set properly\n    struct NestBase {};\n    struct Nested {};\n    py::class_<NestBase> base(m, \"NestBase\");\n    base.def(py::init<>());\n    py::class_<Nested>(base, \"Nested\")\n        .def(py::init<>())\n        .def(\"fn\", [](Nested &, int, NestBase &, Nested &) {})\n        .def(\n            \"fa\", [](Nested &, int, NestBase &, Nested &) {}, \"a\"_a, \"b\"_a, \"c\"_a);\n    base.def(\"g\", [](NestBase &, Nested &) {});\n    base.def(\"h\", []() { return NestBase(); });\n\n    // test_error_after_conversion\n    // The second-pass path through dispatcher() previously didn't\n    // remember which overload was used, and would crash trying to\n    // generate a useful error message\n\n    struct NotRegistered {};\n    struct StringWrapper {\n        std::string str;\n    };\n    m.def(\"test_error_after_conversions\", [](int) {});\n    m.def(\"test_error_after_conversions\",\n          [](const StringWrapper &) -> NotRegistered { return {}; });\n    py::class_<StringWrapper>(m, \"StringWrapper\").def(py::init<std::string>());\n    py::implicitly_convertible<std::string, StringWrapper>();\n\n#if defined(PYBIND11_CPP17)\n    struct alignas(1024) Aligned {\n        std::uintptr_t ptr() const { return (uintptr_t) this; }\n    };\n    py::class_<Aligned>(m, \"Aligned\").def(py::init<>()).def(\"ptr\", &Aligned::ptr);\n#endif\n\n    // test_final\n    struct IsFinal final {};\n    py::class_<IsFinal>(m, \"IsFinal\", py::is_final());\n\n    // test_non_final_final\n    struct IsNonFinalFinal {};\n    py::class_<IsNonFinalFinal>(m, \"IsNonFinalFinal\", py::is_final());\n\n    // test_exception_rvalue_abort\n    struct PyPrintDestructor {\n        PyPrintDestructor() = default;\n        ~PyPrintDestructor() { py::print(\"Print from destructor\"); }\n        void throw_something() { throw std::runtime_error(\"error\"); }\n    };\n    py::class_<PyPrintDestructor>(m, \"PyPrintDestructor\")\n        .def(py::init<>())\n        .def(\"throw_something\", &PyPrintDestructor::throw_something);\n\n    // test_multiple_instances_with_same_pointer\n    struct SamePointer {};\n    static SamePointer samePointer;\n    py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, \"SamePointer\")\n        .def(py::init([]() { return &samePointer; }));\n\n    struct Empty {};\n    py::class_<Empty>(m, \"Empty\").def(py::init<>());\n\n    // test_base_and_derived_nested_scope\n    struct BaseWithNested {\n        struct Nested {};\n    };\n\n    struct DerivedWithNested : BaseWithNested {\n        struct Nested {};\n    };\n\n    py::class_<BaseWithNested> baseWithNested_class(m, \"BaseWithNested\");\n    py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, \"DerivedWithNested\");\n    py::class_<BaseWithNested::Nested>(baseWithNested_class, \"Nested\")\n        .def_static(\"get_name\", []() { return \"BaseWithNested::Nested\"; });\n    py::class_<DerivedWithNested::Nested>(derivedWithNested_class, \"Nested\")\n        .def_static(\"get_name\", []() { return \"DerivedWithNested::Nested\"; });\n\n    // test_register_duplicate_class\n    struct Duplicate {};\n    struct OtherDuplicate {};\n    struct DuplicateNested {};\n    struct OtherDuplicateNested {};\n\n    m.def(\"register_duplicate_class_name\", [](const py::module_ &m) {\n        py::class_<Duplicate>(m, \"Duplicate\");\n        py::class_<OtherDuplicate>(m, \"Duplicate\");\n    });\n    m.def(\"register_duplicate_class_type\", [](const py::module_ &m) {\n        py::class_<OtherDuplicate>(m, \"OtherDuplicate\");\n        py::class_<OtherDuplicate>(m, \"YetAnotherDuplicate\");\n    });\n    m.def(\"register_duplicate_nested_class_name\", [](const py::object &gt) {\n        py::class_<DuplicateNested>(gt, \"DuplicateNested\");\n        py::class_<OtherDuplicateNested>(gt, \"DuplicateNested\");\n    });\n    m.def(\"register_duplicate_nested_class_type\", [](const py::object &gt) {\n        py::class_<OtherDuplicateNested>(gt, \"OtherDuplicateNested\");\n        py::class_<OtherDuplicateNested>(gt, \"YetAnotherDuplicateNested\");\n    });\n\n    test_class::pr4220_tripped_over_this::bind_empty0(m);\n}\n\ntemplate <int N>\nclass BreaksBase {\npublic:\n    virtual ~BreaksBase() = default;\n    BreaksBase() = default;\n    BreaksBase(const BreaksBase &) = delete;\n};\ntemplate <int N>\nclass BreaksTramp : public BreaksBase<N> {};\n// These should all compile just fine:\nusing DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;\nusing DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;\nusing DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;\nusing DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;\nusing DoesntBreak5 = py::class_<BreaksBase<5>>;\nusing DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;\nusing DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;\nusing DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;\n#define CHECK_BASE(N)                                                                             \\\n    static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<(N)>>::value,            \\\n                  \"DoesntBreak\" #N \" has wrong type!\")\nCHECK_BASE(1);\nCHECK_BASE(2);\nCHECK_BASE(3);\nCHECK_BASE(4);\nCHECK_BASE(5);\nCHECK_BASE(6);\nCHECK_BASE(7);\nCHECK_BASE(8);\n#define CHECK_ALIAS(N)                                                                            \\\n    static_assert(                                                                                \\\n        DoesntBreak##N::has_alias                                                                 \\\n            && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<(N)>>::value,        \\\n        \"DoesntBreak\" #N \" has wrong type_alias!\")\n#define CHECK_NOALIAS(N)                                                                          \\\n    static_assert(!DoesntBreak##N::has_alias                                                      \\\n                      && std::is_void<typename DoesntBreak##N::type_alias>::value,                \\\n                  \"DoesntBreak\" #N \" has type alias, but shouldn't!\")\nCHECK_ALIAS(1);\nCHECK_ALIAS(2);\nCHECK_NOALIAS(3);\nCHECK_ALIAS(4);\nCHECK_NOALIAS(5);\nCHECK_ALIAS(6);\nCHECK_ALIAS(7);\nCHECK_NOALIAS(8);\n#define CHECK_HOLDER(N, TYPE)                                                                     \\\n    static_assert(std::is_same<typename DoesntBreak##N::holder_type,                              \\\n                               std::TYPE##_ptr<BreaksBase<(N)>>>::value,                          \\\n                  \"DoesntBreak\" #N \" has wrong holder_type!\")\nCHECK_HOLDER(1, unique);\nCHECK_HOLDER(2, unique);\nCHECK_HOLDER(3, unique);\nCHECK_HOLDER(4, unique);\nCHECK_HOLDER(5, unique);\nCHECK_HOLDER(6, shared);\nCHECK_HOLDER(7, shared);\nCHECK_HOLDER(8, shared);\n\n// There's no nice way to test that these fail because they fail to compile; leave them here,\n// though, so that they can be manually tested by uncommenting them (and seeing that compilation\n// failures occurs).\n\n// We have to actually look into the type: the typedef alone isn't enough to instantiate the type:\n#define CHECK_BROKEN(N)                                                                           \\\n    static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value,                \\\n                  \"Breaks1 has wrong type!\");\n\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n// Two holder classes:\ntypedef py::\n    class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>>\n        Breaks1;\nCHECK_BROKEN(1);\n// Two aliases:\ntypedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;\nCHECK_BROKEN(2);\n// Holder + 2 aliases\ntypedef py::\n    class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>>\n        Breaks3;\nCHECK_BROKEN(3);\n// Alias + 2 holders\ntypedef py::class_<BreaksBase<-4>,\n                   std::unique_ptr<BreaksBase<-4>>,\n                   BreaksTramp<-4>,\n                   std::shared_ptr<BreaksBase<-4>>>\n    Breaks4;\nCHECK_BROKEN(4);\n// Invalid option (not a subclass or holder)\ntypedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;\nCHECK_BROKEN(5);\n// Invalid option: multiple inheritance not supported:\ntemplate <>\nstruct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};\ntypedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;\nCHECK_BROKEN(8);\n#endif\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_class.py",
    "content": "import pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import class_ as m\n\n\ndef test_repr():\n    assert \"pybind11_type\" in repr(type(UserType))\n    assert \"UserType\" in repr(UserType)\n\n\ndef test_instance(msg):\n    with pytest.raises(TypeError) as excinfo:\n        m.NoConstructor()\n    assert msg(excinfo.value) == \"m.class_.NoConstructor: No constructor defined!\"\n\n    instance = m.NoConstructor.new_instance()\n\n    cstats = ConstructorStats.get(m.NoConstructor)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n\ndef test_instance_new(msg):\n    instance = m.NoConstructorNew()  # .__new__(m.NoConstructor.__class__)\n    cstats = ConstructorStats.get(m.NoConstructorNew)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n\ndef test_type():\n    assert m.check_type(1) == m.DerivedClass1\n    with pytest.raises(RuntimeError) as execinfo:\n        m.check_type(0)\n\n    assert \"pybind11::detail::get_type_info: unable to find type info\" in str(\n        execinfo.value\n    )\n    assert \"Invalid\" in str(execinfo.value)\n\n    # Currently not supported\n    # See https://github.com/pybind/pybind11/issues/2486\n    # assert m.check_type(2) == int\n\n\ndef test_type_of_py():\n    assert m.get_type_of(1) == int\n    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1\n    assert m.get_type_of(int) == type\n\n\ndef test_type_of_classic():\n    assert m.get_type_classic(1) == int\n    assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1\n    assert m.get_type_classic(int) == type\n\n\ndef test_type_of_py_nodelete():\n    # If the above test deleted the class, this will segfault\n    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1\n\n\ndef test_as_type_py():\n    assert m.as_type(int) == int\n\n    with pytest.raises(TypeError):\n        assert m.as_type(1) == int\n\n    with pytest.raises(TypeError):\n        assert m.as_type(m.DerivedClass1()) == m.DerivedClass1\n\n\ndef test_docstrings(doc):\n    assert doc(UserType) == \"A `py::class_` type for testing\"\n    assert UserType.__name__ == \"UserType\"\n    assert UserType.__module__ == \"pybind11_tests\"\n    assert UserType.get_value.__name__ == \"get_value\"\n    assert UserType.get_value.__module__ == \"pybind11_tests\"\n\n    assert (\n        doc(UserType.get_value)\n        == \"\"\"\n        get_value(self: m.UserType) -> int\n\n        Get value using a method\n    \"\"\"\n    )\n    assert doc(UserType.value) == \"Get/set value using a property\"\n\n    assert (\n        doc(m.NoConstructor.new_instance)\n        == \"\"\"\n        new_instance() -> m.class_.NoConstructor\n\n        Return an instance\n    \"\"\"\n    )\n\n\ndef test_qualname(doc):\n    \"\"\"Tests that a properly qualified name is set in __qualname__ and that\n    generated docstrings properly use it and the module name\"\"\"\n    assert m.NestBase.__qualname__ == \"NestBase\"\n    assert m.NestBase.Nested.__qualname__ == \"NestBase.Nested\"\n\n    assert (\n        doc(m.NestBase.__init__)\n        == \"\"\"\n        __init__(self: m.class_.NestBase) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.g)\n        == \"\"\"\n        g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.Nested.__init__)\n        == \"\"\"\n        __init__(self: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.Nested.fn)\n        == \"\"\"\n        fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.Nested.fa)\n        == \"\"\"\n        fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert m.NestBase.__module__ == \"pybind11_tests.class_\"\n    assert m.NestBase.Nested.__module__ == \"pybind11_tests.class_\"\n\n\ndef test_inheritance(msg):\n    roger = m.Rabbit(\"Rabbit\")\n    assert roger.name() + \" is a \" + roger.species() == \"Rabbit is a parrot\"\n    assert m.pet_name_species(roger) == \"Rabbit is a parrot\"\n\n    polly = m.Pet(\"Polly\", \"parrot\")\n    assert polly.name() + \" is a \" + polly.species() == \"Polly is a parrot\"\n    assert m.pet_name_species(polly) == \"Polly is a parrot\"\n\n    molly = m.Dog(\"Molly\")\n    assert molly.name() + \" is a \" + molly.species() == \"Molly is a dog\"\n    assert m.pet_name_species(molly) == \"Molly is a dog\"\n\n    fred = m.Hamster(\"Fred\")\n    assert fred.name() + \" is a \" + fred.species() == \"Fred is a rodent\"\n\n    assert m.dog_bark(molly) == \"Woof!\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.dog_bark(polly)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        dog_bark(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: m.class_.Dog) -> str\n\n        Invoked with: <m.class_.Pet object at 0>\n    \"\"\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.Chimera(\"lion\", \"goat\")\n    assert \"No constructor defined!\" in str(excinfo.value)\n\n\ndef test_inheritance_init(msg):\n\n    # Single base\n    class Python(m.Pet):\n        def __init__(self):\n            pass\n\n    with pytest.raises(TypeError) as exc_info:\n        Python()\n    expected = \"m.class_.Pet.__init__() must be called when overriding __init__\"\n    assert msg(exc_info.value) == expected\n\n    # Multiple bases\n    class RabbitHamster(m.Rabbit, m.Hamster):\n        def __init__(self):\n            m.Rabbit.__init__(self, \"RabbitHamster\")\n\n    with pytest.raises(TypeError) as exc_info:\n        RabbitHamster()\n    expected = \"m.class_.Hamster.__init__() must be called when overriding __init__\"\n    assert msg(exc_info.value) == expected\n\n\ndef test_automatic_upcasting():\n    assert type(m.return_class_1()).__name__ == \"DerivedClass1\"\n    assert type(m.return_class_2()).__name__ == \"DerivedClass2\"\n    assert type(m.return_none()).__name__ == \"NoneType\"\n    # Repeat these a few times in a random order to ensure no invalid caching is applied\n    assert type(m.return_class_n(1)).__name__ == \"DerivedClass1\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(0)).__name__ == \"BaseClass\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(0)).__name__ == \"BaseClass\"\n    assert type(m.return_class_n(1)).__name__ == \"DerivedClass1\"\n\n\ndef test_isinstance():\n    objects = [tuple(), dict(), m.Pet(\"Polly\", \"parrot\")] + [m.Dog(\"Molly\")] * 4\n    expected = (True, True, True, True, True, False, False)\n    assert m.check_instances(objects) == expected\n\n\ndef test_mismatched_holder():\n    import re\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.mismatched_holder_1()\n    assert re.match(\n        'generic_type: type \".*MismatchDerived1\" does not have a non-default '\n        'holder type while its base \".*MismatchBase1\" does',\n        str(excinfo.value),\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.mismatched_holder_2()\n    assert re.match(\n        'generic_type: type \".*MismatchDerived2\" has a non-default holder type '\n        'while its base \".*MismatchBase2\" does not',\n        str(excinfo.value),\n    )\n\n\ndef test_override_static():\n    \"\"\"#511: problem with inheritance + overwritten def_static\"\"\"\n    b = m.MyBase.make()\n    d1 = m.MyDerived.make2()\n    d2 = m.MyDerived.make()\n\n    assert isinstance(b, m.MyBase)\n    assert isinstance(d1, m.MyDerived)\n    assert isinstance(d2, m.MyDerived)\n\n\ndef test_implicit_conversion_life_support():\n    \"\"\"Ensure the lifetime of temporary objects created for implicit conversions\"\"\"\n    assert m.implicitly_convert_argument(UserType(5)) == 5\n    assert m.implicitly_convert_variable(UserType(5)) == 5\n\n    assert \"outside a bound function\" in m.implicitly_convert_variable_fail(UserType(5))\n\n\ndef test_operator_new_delete(capture):\n    \"\"\"Tests that class-specific operator new/delete functions are invoked\"\"\"\n\n    class SubAliased(m.AliasedHasOpNewDelSize):\n        pass\n\n    with capture:\n        a = m.HasOpNewDel()\n        b = m.HasOpNewDelSize()\n        d = m.HasOpNewDelBoth()\n    assert (\n        capture\n        == \"\"\"\n        A new 8\n        B new 4\n        D new 32\n    \"\"\"\n    )\n    sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)\n    sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)\n    with capture:\n        c = m.AliasedHasOpNewDelSize()\n        c2 = SubAliased()\n    assert capture == (\"C new \" + sz_noalias + \"\\n\" + \"C new \" + sz_alias + \"\\n\")\n\n    with capture:\n        del a\n        pytest.gc_collect()\n        del b\n        pytest.gc_collect()\n        del d\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        A delete\n        B delete 4\n        D delete\n    \"\"\"\n    )\n\n    with capture:\n        del c\n        pytest.gc_collect()\n        del c2\n        pytest.gc_collect()\n    assert capture == (\"C delete \" + sz_noalias + \"\\n\" + \"C delete \" + sz_alias + \"\\n\")\n\n\ndef test_bind_protected_functions():\n    \"\"\"Expose protected member functions to Python using a helper class\"\"\"\n    a = m.ProtectedA()\n    assert a.foo() == 42\n\n    b = m.ProtectedB()\n    assert b.foo() == 42\n    assert m.read_foo(b.void_foo()) == 42\n    assert m.pointers_equal(b.get_self(), b)\n\n    class C(m.ProtectedB):\n        def __init__(self):\n            m.ProtectedB.__init__(self)\n\n        def foo(self):\n            return 0\n\n    c = C()\n    assert c.foo() == 0\n\n\ndef test_brace_initialization():\n    \"\"\"Tests that simple POD classes can be constructed using C++11 brace initialization\"\"\"\n    a = m.BraceInitialization(123, \"test\")\n    assert a.field1 == 123\n    assert a.field2 == \"test\"\n\n    # Tests that a non-simple class doesn't get brace initialization (if the\n    # class defines an initializer_list constructor, in particular, it would\n    # win over the expected constructor).\n    b = m.NoBraceInitialization([123, 456])\n    assert b.vec == [123, 456]\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_class_refcount():\n    \"\"\"Instances must correctly increase/decrease the reference count of their types (#1029)\"\"\"\n    from sys import getrefcount\n\n    class PyDog(m.Dog):\n        pass\n\n    for cls in m.Dog, PyDog:\n        refcount_1 = getrefcount(cls)\n        molly = [cls(\"Molly\") for _ in range(10)]\n        refcount_2 = getrefcount(cls)\n\n        del molly\n        pytest.gc_collect()\n        refcount_3 = getrefcount(cls)\n\n        assert refcount_1 == refcount_3\n        assert refcount_2 > refcount_1\n\n\ndef test_reentrant_implicit_conversion_failure(msg):\n    # ensure that there is no runaway reentrant implicit conversion (#1035)\n    with pytest.raises(TypeError) as excinfo:\n        m.BogusImplicitConversion(0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)\n\n        Invoked with: 0\n    \"\"\"\n    )\n\n\ndef test_error_after_conversions():\n    with pytest.raises(TypeError) as exc_info:\n        m.test_error_after_conversions(\"hello\")\n    assert str(exc_info.value).startswith(\n        \"Unable to convert function return value to a Python type!\"\n    )\n\n\ndef test_aligned():\n    if hasattr(m, \"Aligned\"):\n        p = m.Aligned().ptr()\n        assert p % 1024 == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2742\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_final():\n    with pytest.raises(TypeError) as exc_info:\n\n        class PyFinalChild(m.IsFinal):\n            pass\n\n    assert str(exc_info.value).endswith(\"is not an acceptable base type\")\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2742\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_non_final_final():\n    with pytest.raises(TypeError) as exc_info:\n\n        class PyNonFinalFinalChild(m.IsNonFinalFinal):\n            pass\n\n    assert str(exc_info.value).endswith(\"is not an acceptable base type\")\n\n\n# https://github.com/pybind/pybind11/issues/1878\ndef test_exception_rvalue_abort():\n    with pytest.raises(RuntimeError):\n        m.PyPrintDestructor().throw_something()\n\n\n# https://github.com/pybind/pybind11/issues/1568\ndef test_multiple_instances_with_same_pointer(capture):\n    n = 100\n    instances = [m.SamePointer() for _ in range(n)]\n    for i in range(n):\n        # We need to reuse the same allocated memory for with a different type,\n        # to ensure the bug in `deregister_instance_impl` is detected. Otherwise\n        # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though\n        # the `instance` is already deleted.\n        instances[i] = m.Empty()\n    # No assert: if this does not trigger the error\n    #   pybind11_fail(\"pybind11_object_dealloc(): Tried to deallocate unregistered instance!\");\n    # and just completes without crashing, we're good.\n\n\n# https://github.com/pybind/pybind11/issues/1624\ndef test_base_and_derived_nested_scope():\n    assert issubclass(m.DerivedWithNested, m.BaseWithNested)\n    assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested\n    assert m.BaseWithNested.Nested.get_name() == \"BaseWithNested::Nested\"\n    assert m.DerivedWithNested.Nested.get_name() == \"DerivedWithNested::Nested\"\n\n\ndef test_register_duplicate_class():\n    import types\n\n    module_scope = types.ModuleType(\"module_scope\")\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_class_name(module_scope)\n    expected = (\n        'generic_type: cannot initialize type \"Duplicate\": '\n        \"an object with that name is already defined\"\n    )\n    assert str(exc_info.value) == expected\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_class_type(module_scope)\n    expected = 'generic_type: type \"YetAnotherDuplicate\" is already registered!'\n    assert str(exc_info.value) == expected\n\n    class ClassScope:\n        pass\n\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_nested_class_name(ClassScope)\n    expected = (\n        'generic_type: cannot initialize type \"DuplicateNested\": '\n        \"an object with that name is already defined\"\n    )\n    assert str(exc_info.value) == expected\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_nested_class_type(ClassScope)\n    expected = 'generic_type: type \"YetAnotherDuplicateNested\" is already registered!'\n    assert str(exc_info.value) == expected\n\n\ndef test_pr4220_tripped_over_this():\n    assert (\n        m.Empty0().get_msg()\n        == \"This is really only meant to exercise successful compilation.\"\n    )\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/CMakeLists.txt",
    "content": "# Built-in in CMake 3.5+\ninclude(CMakeParseArguments)\n\nadd_custom_target(test_cmake_build)\n\nfunction(pybind11_add_build_test name)\n  cmake_parse_arguments(ARG \"INSTALL\" \"\" \"\" ${ARGN})\n\n  set(build_options \"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\")\n\n  if(PYBIND11_FINDPYTHON)\n    list(APPEND build_options \"-DPYBIND11_FINDPYTHON=${PYBIND11_FINDPYTHON}\")\n\n    if(DEFINED Python_ROOT_DIR)\n      list(APPEND build_options \"-DPython_ROOT_DIR=${Python_ROOT_DIR}\")\n    endif()\n\n    list(APPEND build_options \"-DPython_EXECUTABLE=${Python_EXECUTABLE}\")\n  else()\n    list(APPEND build_options \"-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\")\n  endif()\n\n  if(DEFINED CMAKE_CXX_STANDARD)\n    list(APPEND build_options \"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}\")\n  endif()\n\n  if(NOT ARG_INSTALL)\n    list(APPEND build_options \"-Dpybind11_SOURCE_DIR=${pybind11_SOURCE_DIR}\")\n  else()\n    list(APPEND build_options \"-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install\")\n  endif()\n\n  add_custom_target(\n    test_build_${name}\n    ${CMAKE_CTEST_COMMAND}\n    --build-and-test\n    \"${CMAKE_CURRENT_SOURCE_DIR}/${name}\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${name}\"\n    --build-config\n    Release\n    --build-noclean\n    --build-generator\n    ${CMAKE_GENERATOR}\n    $<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:--build-generator-platform>\n    ${CMAKE_GENERATOR_PLATFORM}\n    --build-makeprogram\n    ${CMAKE_MAKE_PROGRAM}\n    --build-target\n    check_${name}\n    --build-options\n    ${build_options})\n  if(ARG_INSTALL)\n    add_dependencies(test_build_${name} mock_install)\n  endif()\n  add_dependencies(test_cmake_build test_build_${name})\nendfunction()\n\npossibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)\n\npybind11_add_build_test(subdirectory_function)\npybind11_add_build_test(subdirectory_target)\nif(\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\")\n  message(STATUS \"Skipping embed test on PyPy\")\nelse()\n  pybind11_add_build_test(subdirectory_embed)\nendif()\n\nif(PYBIND11_INSTALL)\n  add_custom_target(\n    mock_install ${CMAKE_COMMAND} \"-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install\" -P\n                 \"${pybind11_BINARY_DIR}/cmake_install.cmake\")\n\n  pybind11_add_build_test(installed_function INSTALL)\n  pybind11_add_build_test(installed_target INSTALL)\n  if(NOT (\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\"\n         ))\n    pybind11_add_build_test(installed_embed INSTALL)\n  endif()\nendif()\n\nadd_dependencies(check test_cmake_build)\n\nadd_subdirectory(subdirectory_target EXCLUDE_FROM_ALL)\nadd_subdirectory(subdirectory_embed EXCLUDE_FROM_ALL)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/embed.cpp",
    "content": "#include <pybind11/embed.h>\nnamespace py = pybind11;\n\nPYBIND11_EMBEDDED_MODULE(test_cmake_build, m) {\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n\nint main(int argc, char *argv[]) {\n    if (argc != 2) {\n        throw std::runtime_error(\"Expected test.py file as the first argument\");\n    }\n    auto *test_py_file = argv[1];\n\n    py::scoped_interpreter guard{};\n\n    auto m = py::module_::import(\"test_cmake_build\");\n    if (m.attr(\"add\")(1, 2).cast<int>() != 3) {\n        throw std::runtime_error(\"embed.cpp failed\");\n    }\n\n    py::module_::import(\"sys\").attr(\"argv\") = py::make_tuple(\"test.py\", \"embed.cpp\");\n    py::eval_file(test_py_file, py::globals());\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/installed_embed/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_embed CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(STATUS \"Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}\")\n\nadd_executable(test_installed_embed ../embed.cpp)\ntarget_link_libraries(test_installed_embed PRIVATE pybind11::embed)\nset_target_properties(test_installed_embed PROPERTIES OUTPUT_NAME test_cmake_build)\n\n# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::embed).\n# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.\nset_target_properties(test_installed_embed PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)\n\nadd_custom_target(\n  check_installed_embed\n  $<TARGET_FILE:test_installed_embed> ${PROJECT_SOURCE_DIR}/../test.py\n  DEPENDS test_installed_embed)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/installed_function/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\nproject(test_installed_module CXX)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_function CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(\n  STATUS \"Found pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}: ${pybind11_INCLUDE_DIRS}\")\n\npybind11_add_module(test_installed_function SHARED NO_EXTRAS ../main.cpp)\nset_target_properties(test_installed_function PROPERTIES OUTPUT_NAME test_cmake_build)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_installed_function\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_installed_function>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_installed_function)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/installed_target/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_target CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(STATUS \"Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}\")\n\nadd_library(test_installed_target MODULE ../main.cpp)\n\ntarget_link_libraries(test_installed_target PRIVATE pybind11::module)\nset_target_properties(test_installed_target PROPERTIES OUTPUT_NAME test_cmake_build)\n\n# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib\npybind11_extension(test_installed_target)\n\n# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module).\n# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.\nset_target_properties(test_installed_target PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_installed_target\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_installed_target>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_installed_target)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/main.cpp",
    "content": "#include <pybind11/pybind11.h>\nnamespace py = pybind11;\n\nPYBIND11_MODULE(test_cmake_build, m) {\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_embed CXX)\n\nset(PYBIND11_INSTALL\n    ON\n    CACHE BOOL \"\")\nset(PYBIND11_EXPORT_NAME test_export)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\n\n# Test basic target functionality\nadd_executable(test_subdirectory_embed ../embed.cpp)\ntarget_link_libraries(test_subdirectory_embed PRIVATE pybind11::embed)\nset_target_properties(test_subdirectory_embed PROPERTIES OUTPUT_NAME test_cmake_build)\n\nadd_custom_target(\n  check_subdirectory_embed\n  $<TARGET_FILE:test_subdirectory_embed> \"${PROJECT_SOURCE_DIR}/../test.py\"\n  DEPENDS test_subdirectory_embed)\n\n# Test custom export group -- PYBIND11_EXPORT_NAME\nadd_library(test_embed_lib ../embed.cpp)\ntarget_link_libraries(test_embed_lib PRIVATE pybind11::embed)\n\ninstall(\n  TARGETS test_embed_lib\n  EXPORT test_export\n  ARCHIVE DESTINATION bin\n  LIBRARY DESTINATION lib\n  RUNTIME DESTINATION lib)\ninstall(EXPORT test_export DESTINATION lib/cmake/test_export/test_export-Targets.cmake)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/subdirectory_function/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_function CXX)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\npybind11_add_module(test_subdirectory_function ../main.cpp)\nset_target_properties(test_subdirectory_function PROPERTIES OUTPUT_NAME test_cmake_build)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_subdirectory_function\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_function>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_subdirectory_function)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/subdirectory_target/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_target CXX)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\n\nadd_library(test_subdirectory_target MODULE ../main.cpp)\nset_target_properties(test_subdirectory_target PROPERTIES OUTPUT_NAME test_cmake_build)\n\ntarget_link_libraries(test_subdirectory_target PRIVATE pybind11::module)\n\n# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib\npybind11_extension(test_subdirectory_target)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_subdirectory_target\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_target>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_subdirectory_target)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_cmake_build/test.py",
    "content": "import sys\n\nimport test_cmake_build\n\nassert isinstance(__file__, str)  # Test this is properly set\n\nassert test_cmake_build.add(1, 2) == 3\nprint(f\"{sys.argv[1]} imports, runs, and adds: 1 + 2 = 3\")\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_const_name.cpp",
    "content": "// Copyright (c) 2021 The Pybind Development Team.\n// All rights reserved. Use of this source code is governed by a\n// BSD-style license that can be found in the LICENSE file.\n\n#include \"pybind11_tests.h\"\n\n// IUT = Implementation Under Test\n#define CONST_NAME_TESTS(TEST_FUNC, IUT)                                                          \\\n    std::string TEST_FUNC(int selector) {                                                         \\\n        switch (selector) {                                                                       \\\n            case 0:                                                                               \\\n                return IUT(\"\").text;                                                              \\\n            case 1:                                                                               \\\n                return IUT(\"A\").text;                                                             \\\n            case 2:                                                                               \\\n                return IUT(\"Bd\").text;                                                            \\\n            case 3:                                                                               \\\n                return IUT(\"Cef\").text;                                                           \\\n            case 4:                                                                               \\\n                return IUT<int>().text; /*NOLINT(bugprone-macro-parentheses)*/                    \\\n            case 5:                                                                               \\\n                return IUT<std::string>().text; /*NOLINT(bugprone-macro-parentheses)*/            \\\n            case 6:                                                                               \\\n                return IUT<true>(\"T1\", \"T2\").text; /*NOLINT(bugprone-macro-parentheses)*/         \\\n            case 7:                                                                               \\\n                return IUT<false>(\"U1\", \"U2\").text; /*NOLINT(bugprone-macro-parentheses)*/        \\\n            case 8:                                                                               \\\n                /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/                                    \\\n                return IUT<true>(IUT(\"D1\"), IUT(\"D2\")).text;                                      \\\n            case 9:                                                                               \\\n                /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/                                    \\\n                return IUT<false>(IUT(\"E1\"), IUT(\"E2\")).text;                                     \\\n            case 10:                                                                              \\\n                return IUT(\"KeepAtEnd\").text;                                                     \\\n            default:                                                                              \\\n                break;                                                                            \\\n        }                                                                                         \\\n        throw std::runtime_error(\"Invalid selector value.\");                                      \\\n    }\n\nCONST_NAME_TESTS(const_name_tests, py::detail::const_name)\n\n#ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\nCONST_NAME_TESTS(underscore_tests, py::detail::_)\n#endif\n\nTEST_SUBMODULE(const_name, m) {\n    m.def(\"const_name_tests\", const_name_tests);\n\n#if defined(PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY)\n    m.def(\"underscore_tests\", underscore_tests);\n#else\n    m.attr(\"underscore_tests\") = \"PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY not defined.\";\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_const_name.py",
    "content": "import pytest\n\nfrom pybind11_tests import const_name as m\n\n\n@pytest.mark.parametrize(\"func\", (m.const_name_tests, m.underscore_tests))\n@pytest.mark.parametrize(\n    \"selector, expected\",\n    enumerate(\n        (\n            \"\",\n            \"A\",\n            \"Bd\",\n            \"Cef\",\n            \"%\",\n            \"%\",\n            \"T1\",\n            \"U2\",\n            \"D1\",\n            \"E2\",\n            \"KeepAtEnd\",\n        )\n    ),\n)\ndef test_const_name(func, selector, expected):\n    if isinstance(func, str):\n        pytest.skip(func)\n    text = func(selector)\n    assert text == expected\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_constants_and_functions.cpp",
    "content": "/*\n    tests/test_constants_and_functions.cpp -- global constants and functions, enumerations, raw\n    byte strings\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nenum MyEnum { EFirstEntry = 1, ESecondEntry };\n\nstd::string test_function1() { return \"test_function()\"; }\n\nstd::string test_function2(MyEnum k) { return \"test_function(enum=\" + std::to_string(k) + \")\"; }\n\nstd::string test_function3(int i) { return \"test_function(\" + std::to_string(i) + \")\"; }\n\npy::str test_function4() { return \"test_function()\"; }\npy::str test_function4(char *) { return \"test_function(char *)\"; }\npy::str test_function4(int, float) { return \"test_function(int, float)\"; }\npy::str test_function4(float, int) { return \"test_function(float, int)\"; }\n\npy::bytes return_bytes() {\n    const char *data = \"\\x01\\x00\\x02\\x00\";\n    return std::string(data, 4);\n}\n\nstd::string print_bytes(const py::bytes &bytes) {\n    std::string ret = \"bytes[\";\n    const auto value = static_cast<std::string>(bytes);\n    for (char c : value) {\n        ret += std::to_string(static_cast<int>(c)) + ' ';\n    }\n    ret.back() = ']';\n    return ret;\n}\n\n// Test that we properly handle C++17 exception specifiers (which are part of the function\n// signature in C++17).  These should all still work before C++17, but don't affect the function\n// signature.\nnamespace test_exc_sp {\n// [workaround(intel)] Unable to use noexcept instead of noexcept(true)\n// Make the f1 test basically the same as the f2 test in C++17 mode for the Intel compiler as\n// it fails to compile with a plain noexcept (tested with icc (ICC) 2021.1 Beta 20200827).\n#if defined(__INTEL_COMPILER) && defined(PYBIND11_CPP17)\nint f1(int x) noexcept(true) { return x + 1; }\n#else\nint f1(int x) noexcept { return x + 1; }\n#endif\nint f2(int x) noexcept(true) { return x + 2; }\nint f3(int x) noexcept(false) { return x + 3; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wdeprecated\"\n#endif\n// NOLINTNEXTLINE(modernize-use-noexcept)\nint f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\nstruct C {\n    int m1(int x) noexcept { return x - 1; }\n    int m2(int x) const noexcept { return x - 2; }\n    int m3(int x) noexcept(true) { return x - 3; }\n    int m4(int x) const noexcept(true) { return x - 4; }\n    int m5(int x) noexcept(false) { return x - 5; }\n    int m6(int x) const noexcept(false) { return x - 6; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wdeprecated\"\n#endif\n    // NOLINTNEXTLINE(modernize-use-noexcept)\n    int m7(int x) throw() { return x - 7; }\n    // NOLINTNEXTLINE(modernize-use-noexcept)\n    int m8(int x) const throw() { return x - 8; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n};\n} // namespace test_exc_sp\n\nTEST_SUBMODULE(constants_and_functions, m) {\n    // test_constants\n    m.attr(\"some_constant\") = py::int_(14);\n\n    // test_function_overloading\n    m.def(\"test_function\", &test_function1);\n    m.def(\"test_function\", &test_function2);\n    m.def(\"test_function\", &test_function3);\n\n#if defined(PYBIND11_OVERLOAD_CAST)\n    m.def(\"test_function\", py::overload_cast<>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<char *>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<int, float>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<float, int>(&test_function4));\n#else\n    m.def(\"test_function\", static_cast<py::str (*)()>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(char *)>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(int, float)>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(float, int)>(&test_function4));\n#endif\n\n    py::enum_<MyEnum>(m, \"MyEnum\")\n        .value(\"EFirstEntry\", EFirstEntry)\n        .value(\"ESecondEntry\", ESecondEntry)\n        .export_values();\n\n    // test_bytes\n    m.def(\"return_bytes\", &return_bytes);\n    m.def(\"print_bytes\", &print_bytes);\n\n    // test_exception_specifiers\n    using namespace test_exc_sp;\n    py::class_<C>(m, \"C\")\n        .def(py::init<>())\n        .def(\"m1\", &C::m1)\n        .def(\"m2\", &C::m2)\n        .def(\"m3\", &C::m3)\n        .def(\"m4\", &C::m4)\n        .def(\"m5\", &C::m5)\n        .def(\"m6\", &C::m6)\n        .def(\"m7\", &C::m7)\n        .def(\"m8\", &C::m8);\n    m.def(\"f1\", f1);\n    m.def(\"f2\", f2);\n#if defined(__INTEL_COMPILER)\n#    pragma warning push\n#    pragma warning disable 878 // incompatible exception specifications\n#endif\n    m.def(\"f3\", f3);\n#if defined(__INTEL_COMPILER)\n#    pragma warning pop\n#endif\n    m.def(\"f4\", f4);\n\n    // test_function_record_leaks\n    m.def(\"register_large_capture_with_invalid_arguments\", [](py::module_ m) {\n        // This should always be enough to trigger the alternative branch\n        // where `sizeof(capture) > sizeof(rec->data)`\n        uint64_t capture[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};\n#if defined(__GNUC__) && __GNUC__ == 4 // CentOS7\n        py::detail::silence_unused_warnings(capture);\n#endif\n        m.def(\n            \"should_raise\", [capture](int) { return capture[9] + 33; }, py::kw_only(), py::arg());\n    });\n    m.def(\"register_with_raising_repr\", [](py::module_ m, const py::object &default_value) {\n        m.def(\n            \"should_raise\",\n            [](int, int, const py::object &) { return 42; },\n            \"some docstring\",\n            py::arg_v(\"x\", 42),\n            py::arg_v(\"y\", 42, \"<the answer>\"),\n            py::arg_v(\"z\", default_value));\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_constants_and_functions.py",
    "content": "import pytest\n\nm = pytest.importorskip(\"pybind11_tests.constants_and_functions\")\n\n\ndef test_constants():\n    assert m.some_constant == 14\n\n\ndef test_function_overloading():\n    assert m.test_function() == \"test_function()\"\n    assert m.test_function(7) == \"test_function(7)\"\n    assert m.test_function(m.MyEnum.EFirstEntry) == \"test_function(enum=1)\"\n    assert m.test_function(m.MyEnum.ESecondEntry) == \"test_function(enum=2)\"\n\n    assert m.test_function() == \"test_function()\"\n    assert m.test_function(\"abcd\") == \"test_function(char *)\"\n    assert m.test_function(1, 1.0) == \"test_function(int, float)\"\n    assert m.test_function(1, 1.0) == \"test_function(int, float)\"\n    assert m.test_function(2.0, 2) == \"test_function(float, int)\"\n\n\ndef test_bytes():\n    assert m.print_bytes(m.return_bytes()) == \"bytes[1 0 2 0]\"\n\n\ndef test_exception_specifiers():\n    c = m.C()\n    assert c.m1(2) == 1\n    assert c.m2(3) == 1\n    assert c.m3(5) == 2\n    assert c.m4(7) == 3\n    assert c.m5(10) == 5\n    assert c.m6(14) == 8\n    assert c.m7(20) == 13\n    assert c.m8(29) == 21\n\n    assert m.f1(33) == 34\n    assert m.f2(53) == 55\n    assert m.f3(86) == 89\n    assert m.f4(140) == 144\n\n\ndef test_function_record_leaks():\n    class RaisingRepr:\n        def __repr__(self):\n            raise RuntimeError(\"Surprise!\")\n\n    with pytest.raises(RuntimeError):\n        m.register_large_capture_with_invalid_arguments(m)\n    with pytest.raises(RuntimeError):\n        m.register_with_raising_repr(m, RaisingRepr())\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_copy_move.cpp",
    "content": "/*\n    tests/test_copy_move_policies.cpp -- 'copy' and 'move' return value policies\n                                         and related tests\n\n    Copyright (c) 2016 Ben North <ben@redfrontdoor.org>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\ntemplate <typename derived>\nstruct empty {\n    static const derived &get_one() { return instance_; }\n    static derived instance_;\n};\n\nstruct lacking_copy_ctor : public empty<lacking_copy_ctor> {\n    lacking_copy_ctor() = default;\n    lacking_copy_ctor(const lacking_copy_ctor &other) = delete;\n};\n\ntemplate <>\nlacking_copy_ctor empty<lacking_copy_ctor>::instance_ = {};\n\nstruct lacking_move_ctor : public empty<lacking_move_ctor> {\n    lacking_move_ctor() = default;\n    lacking_move_ctor(const lacking_move_ctor &other) = delete;\n    lacking_move_ctor(lacking_move_ctor &&other) = delete;\n};\n\ntemplate <>\nlacking_move_ctor empty<lacking_move_ctor>::instance_ = {};\n\n/* Custom type caster move/copy test classes */\nclass MoveOnlyInt {\npublic:\n    MoveOnlyInt() { print_default_created(this); }\n    explicit MoveOnlyInt(int v) : value{v} { print_created(this, value); }\n    MoveOnlyInt(MoveOnlyInt &&m) noexcept {\n        print_move_created(this, m.value);\n        std::swap(value, m.value);\n    }\n    MoveOnlyInt &operator=(MoveOnlyInt &&m) noexcept {\n        print_move_assigned(this, m.value);\n        std::swap(value, m.value);\n        return *this;\n    }\n    MoveOnlyInt(const MoveOnlyInt &) = delete;\n    MoveOnlyInt &operator=(const MoveOnlyInt &) = delete;\n    ~MoveOnlyInt() { print_destroyed(this); }\n\n    int value;\n};\nclass MoveOrCopyInt {\npublic:\n    MoveOrCopyInt() { print_default_created(this); }\n    explicit MoveOrCopyInt(int v) : value{v} { print_created(this, value); }\n    MoveOrCopyInt(MoveOrCopyInt &&m) noexcept {\n        print_move_created(this, m.value);\n        std::swap(value, m.value);\n    }\n    MoveOrCopyInt &operator=(MoveOrCopyInt &&m) noexcept {\n        print_move_assigned(this, m.value);\n        std::swap(value, m.value);\n        return *this;\n    }\n    MoveOrCopyInt(const MoveOrCopyInt &c) {\n        print_copy_created(this, c.value);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = c.value;\n    }\n    MoveOrCopyInt &operator=(const MoveOrCopyInt &c) {\n        print_copy_assigned(this, c.value);\n        value = c.value;\n        return *this;\n    }\n    ~MoveOrCopyInt() { print_destroyed(this); }\n\n    int value;\n};\nclass CopyOnlyInt {\npublic:\n    CopyOnlyInt() { print_default_created(this); }\n    explicit CopyOnlyInt(int v) : value{v} { print_created(this, value); }\n    CopyOnlyInt(const CopyOnlyInt &c) {\n        print_copy_created(this, c.value);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = c.value;\n    }\n    CopyOnlyInt &operator=(const CopyOnlyInt &c) {\n        print_copy_assigned(this, c.value);\n        value = c.value;\n        return *this;\n    }\n    ~CopyOnlyInt() { print_destroyed(this); }\n\n    int value;\n};\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nstruct type_caster<MoveOnlyInt> {\n    PYBIND11_TYPE_CASTER(MoveOnlyInt, const_name(\"MoveOnlyInt\"));\n    bool load(handle src, bool) {\n        value = MoveOnlyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const MoveOnlyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n};\n\ntemplate <>\nstruct type_caster<MoveOrCopyInt> {\n    PYBIND11_TYPE_CASTER(MoveOrCopyInt, const_name(\"MoveOrCopyInt\"));\n    bool load(handle src, bool) {\n        value = MoveOrCopyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const MoveOrCopyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n};\n\ntemplate <>\nstruct type_caster<CopyOnlyInt> {\nprotected:\n    CopyOnlyInt value;\n\npublic:\n    static constexpr auto name = const_name(\"CopyOnlyInt\");\n    bool load(handle src, bool) {\n        value = CopyOnlyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const CopyOnlyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n    static handle cast(const CopyOnlyInt *src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().release();\n        }\n        return cast(*src, policy, parent);\n    }\n    explicit operator CopyOnlyInt *() { return &value; }\n    explicit operator CopyOnlyInt &() { return value; }\n    template <typename T>\n    using cast_op_type = pybind11::detail::cast_op_type<T>;\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\nTEST_SUBMODULE(copy_move_policies, m) {\n    // test_lacking_copy_ctor\n    py::class_<lacking_copy_ctor>(m, \"lacking_copy_ctor\")\n        .def_static(\"get_one\", &lacking_copy_ctor::get_one, py::return_value_policy::copy);\n    // test_lacking_move_ctor\n    py::class_<lacking_move_ctor>(m, \"lacking_move_ctor\")\n        .def_static(\"get_one\", &lacking_move_ctor::get_one, py::return_value_policy::move);\n\n    // test_move_and_copy_casts\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"move_and_copy_casts\", [](const py::object &o) {\n        int r = 0;\n        r += py::cast<MoveOrCopyInt>(o).value; /* moves */\n        r += py::cast<MoveOnlyInt>(o).value;   /* moves */\n        r += py::cast<CopyOnlyInt>(o).value;   /* copies */\n        auto m1(py::cast<MoveOrCopyInt>(o));   /* moves */\n        auto m2(py::cast<MoveOnlyInt>(o));     /* moves */\n        auto m3(py::cast<CopyOnlyInt>(o));     /* copies */\n        r += m1.value + m2.value + m3.value;\n\n        return r;\n    });\n\n    // test_move_and_copy_loads\n    m.def(\"move_only\", [](MoveOnlyInt m) { return m.value; });\n    // Changing this breaks the existing test: needs careful review.\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"move_or_copy\", [](MoveOrCopyInt m) { return m.value; });\n    // Changing this breaks the existing test: needs careful review.\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"copy_only\", [](CopyOnlyInt m) { return m.value; });\n    m.def(\"move_pair\",\n          [](std::pair<MoveOnlyInt, MoveOrCopyInt> p) { return p.first.value + p.second.value; });\n    m.def(\"move_tuple\", [](std::tuple<MoveOnlyInt, MoveOrCopyInt, MoveOnlyInt> t) {\n        return std::get<0>(t).value + std::get<1>(t).value + std::get<2>(t).value;\n    });\n    m.def(\"copy_tuple\", [](std::tuple<CopyOnlyInt, CopyOnlyInt> t) {\n        return std::get<0>(t).value + std::get<1>(t).value;\n    });\n    m.def(\"move_copy_nested\",\n          [](std::pair<MoveOnlyInt,\n                       std::pair<std::tuple<MoveOrCopyInt, CopyOnlyInt, std::tuple<MoveOnlyInt>>,\n                                 MoveOrCopyInt>> x) {\n              return x.first.value + std::get<0>(x.second.first).value\n                     + std::get<1>(x.second.first).value\n                     + std::get<0>(std::get<2>(x.second.first)).value + x.second.second.value;\n          });\n    m.def(\"move_and_copy_cstats\", []() {\n        ConstructorStats::gc();\n        // Reset counts to 0 so that previous tests don't affect later ones:\n        auto &mc = ConstructorStats::get<MoveOrCopyInt>();\n        mc.move_assignments = mc.move_constructions = mc.copy_assignments = mc.copy_constructions\n            = 0;\n        auto &mo = ConstructorStats::get<MoveOnlyInt>();\n        mo.move_assignments = mo.move_constructions = mo.copy_assignments = mo.copy_constructions\n            = 0;\n        auto &co = ConstructorStats::get<CopyOnlyInt>();\n        co.move_assignments = co.move_constructions = co.copy_assignments = co.copy_constructions\n            = 0;\n        py::dict d;\n        d[\"MoveOrCopyInt\"] = py::cast(mc, py::return_value_policy::reference);\n        d[\"MoveOnlyInt\"] = py::cast(mo, py::return_value_policy::reference);\n        d[\"CopyOnlyInt\"] = py::cast(co, py::return_value_policy::reference);\n        return d;\n    });\n#ifdef PYBIND11_HAS_OPTIONAL\n    // test_move_and_copy_load_optional\n    m.attr(\"has_optional\") = true;\n    m.def(\"move_optional\", [](std::optional<MoveOnlyInt> o) { return o->value; });\n    m.def(\"move_or_copy_optional\", [](std::optional<MoveOrCopyInt> o) { return o->value; });\n    m.def(\"copy_optional\", [](std::optional<CopyOnlyInt> o) { return o->value; });\n    m.def(\"move_optional_tuple\",\n          [](std::optional<std::tuple<MoveOrCopyInt, MoveOnlyInt, CopyOnlyInt>> x) {\n              return std::get<0>(*x).value + std::get<1>(*x).value + std::get<2>(*x).value;\n          });\n#else\n    m.attr(\"has_optional\") = false;\n#endif\n\n    // #70 compilation issue if operator new is not public - simple body added\n    // but not needed on most compilers; MSVC and nvcc don't like a local\n    // struct not having a method defined when declared, since it can not be\n    // added later.\n    struct PrivateOpNew {\n        int value = 1;\n\n    private:\n        void *operator new(size_t bytes) {\n            void *ptr = std::malloc(bytes);\n            if (ptr) {\n                return ptr;\n            }\n            throw std::bad_alloc{};\n        }\n    };\n    py::class_<PrivateOpNew>(m, \"PrivateOpNew\").def_readonly(\"value\", &PrivateOpNew::value);\n    m.def(\"private_op_new_value\", []() { return PrivateOpNew(); });\n    m.def(\n        \"private_op_new_reference\",\n        []() -> const PrivateOpNew & {\n            static PrivateOpNew x{};\n            return x;\n        },\n        py::return_value_policy::reference);\n\n    // test_move_fallback\n    // #389: rvp::move should fall-through to copy on non-movable objects\n    struct MoveIssue1 {\n        int v;\n        explicit MoveIssue1(int v) : v{v} {}\n        MoveIssue1(const MoveIssue1 &c) = default;\n        MoveIssue1(MoveIssue1 &&) = delete;\n    };\n    py::class_<MoveIssue1>(m, \"MoveIssue1\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MoveIssue1::v);\n\n    struct MoveIssue2 {\n        int v;\n        explicit MoveIssue2(int v) : v{v} {}\n        MoveIssue2(MoveIssue2 &&) = default;\n    };\n    py::class_<MoveIssue2>(m, \"MoveIssue2\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MoveIssue2::v);\n\n    // #2742: Don't expect ownership of raw pointer to `new`ed object to be transferred with\n    // `py::return_value_policy::move`\n    m.def(\n        \"get_moveissue1\",\n        [](int i) { return std::unique_ptr<MoveIssue1>(new MoveIssue1(i)); },\n        py::return_value_policy::move);\n    m.def(\n        \"get_moveissue2\", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);\n\n    // Make sure that cast from pytype rvalue to other pytype works\n    m.def(\"get_pytype_rvalue_castissue\", [](double i) { return py::float_(i).cast<py::int_>(); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_copy_move.py",
    "content": "import pytest\n\nfrom pybind11_tests import copy_move_policies as m\n\n\ndef test_lacking_copy_ctor():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.lacking_copy_ctor.get_one()\n    assert \"is non-copyable!\" in str(excinfo.value)\n\n\ndef test_lacking_move_ctor():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.lacking_move_ctor.get_one()\n    assert \"is neither movable nor copyable!\" in str(excinfo.value)\n\n\ndef test_move_and_copy_casts():\n    \"\"\"Cast some values in C++ via custom type casters and count the number of moves/copies.\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    # The type move constructions/assignments below each get incremented: the move assignment comes\n    # from the type_caster load; the move construction happens when extracting that via a cast or\n    # loading into an argument.\n    assert m.move_and_copy_casts(3) == 18\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 2\n    assert c_m.move_constructions >= 2\n    assert c_mc.alive() == 0\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 2\n    assert c_mc.move_constructions >= 2\n    assert c_c.alive() == 0\n    assert c_c.copy_assignments == 2\n    assert c_c.copy_constructions >= 2\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\ndef test_move_and_copy_loads():\n    \"\"\"Call some functions that load arguments via custom type casters and count the number of\n    moves/copies.\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    assert m.move_only(10) == 10  # 1 move, c_m\n    assert m.move_or_copy(11) == 11  # 1 move, c_mc\n    assert m.copy_only(12) == 12  # 1 copy, c_c\n    assert m.move_pair((13, 14)) == 27  # 1 c_m move, 1 c_mc move\n    assert m.move_tuple((15, 16, 17)) == 48  # 2 c_m moves, 1 c_mc move\n    assert m.copy_tuple((18, 19)) == 37  # 2 c_c copies\n    # Direct constructions: 2 c_m moves, 2 c_mc moves, 1 c_c copy\n    # Extra moves/copies when moving pairs/tuples: 3 c_m, 3 c_mc, 2 c_c\n    assert m.move_copy_nested((1, ((2, 3, (4,)), 5))) == 15\n\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 6\n    assert c_m.move_constructions == 9\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 5\n    assert c_mc.move_constructions == 8\n    assert c_c.copy_assignments == 4\n    assert c_c.copy_constructions == 6\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\n@pytest.mark.skipif(not m.has_optional, reason=\"no <optional>\")\ndef test_move_and_copy_load_optional():\n    \"\"\"Tests move/copy loads of std::optional arguments\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    # The extra move/copy constructions below come from the std::optional move (which has to move\n    # its arguments):\n    assert m.move_optional(10) == 10  # c_m: 1 move assign, 2 move construct\n    assert m.move_or_copy_optional(11) == 11  # c_mc: 1 move assign, 2 move construct\n    assert m.copy_optional(12) == 12  # c_c: 1 copy assign, 2 copy construct\n    # 1 move assign + move construct moves each of c_m, c_mc, 1 c_c copy\n    # +1 move/copy construct each from moving the tuple\n    # +1 move/copy construct each from moving the optional (which moves the tuple again)\n    assert m.move_optional_tuple((3, 4, 5)) == 12\n\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 2\n    assert c_m.move_constructions == 5\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 2\n    assert c_mc.move_constructions == 5\n    assert c_c.copy_assignments == 2\n    assert c_c.copy_constructions == 5\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\ndef test_private_op_new():\n    \"\"\"An object with a private `operator new` cannot be returned by value\"\"\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.private_op_new_value()\n    assert \"is neither movable nor copyable\" in str(excinfo.value)\n\n    assert m.private_op_new_reference().value == 1\n\n\ndef test_move_fallback():\n    \"\"\"#389: rvp::move should fall-through to copy on non-movable objects\"\"\"\n\n    m1 = m.get_moveissue1(1)\n    assert m1.value == 1\n    m2 = m.get_moveissue2(2)\n    assert m2.value == 2\n\n\ndef test_pytype_rvalue_cast():\n    \"\"\"Make sure that cast from pytype rvalue to other pytype works\"\"\"\n\n    value = m.get_pytype_rvalue_castissue(1.0)\n    assert value == 1\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_custom_type_casters.cpp",
    "content": "/*\n    tests/test_custom_type_casters.cpp -- tests type_caster<T>\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n// py::arg/py::arg_v testing: these arguments just record their argument when invoked\nclass ArgInspector1 {\npublic:\n    std::string arg = \"(default arg inspector 1)\";\n};\nclass ArgInspector2 {\npublic:\n    std::string arg = \"(default arg inspector 2)\";\n};\nclass ArgAlwaysConverts {};\n\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <>\nstruct type_caster<ArgInspector1> {\npublic:\n    // Classic\n#ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\n    PYBIND11_TYPE_CASTER(ArgInspector1, _(\"ArgInspector1\"));\n#else\n    PYBIND11_TYPE_CASTER(ArgInspector1, const_name(\"ArgInspector1\"));\n#endif\n\n    bool load(handle src, bool convert) {\n        value.arg = \"loading ArgInspector1 argument \" + std::string(convert ? \"WITH\" : \"WITHOUT\")\n                    + \" conversion allowed.  \"\n                      \"Argument value = \"\n                    + (std::string) str(src);\n        return true;\n    }\n\n    static handle cast(const ArgInspector1 &src, return_value_policy, handle) {\n        return str(src.arg).release();\n    }\n};\ntemplate <>\nstruct type_caster<ArgInspector2> {\npublic:\n    PYBIND11_TYPE_CASTER(ArgInspector2, const_name(\"ArgInspector2\"));\n\n    bool load(handle src, bool convert) {\n        value.arg = \"loading ArgInspector2 argument \" + std::string(convert ? \"WITH\" : \"WITHOUT\")\n                    + \" conversion allowed.  \"\n                      \"Argument value = \"\n                    + (std::string) str(src);\n        return true;\n    }\n\n    static handle cast(const ArgInspector2 &src, return_value_policy, handle) {\n        return str(src.arg).release();\n    }\n};\ntemplate <>\nstruct type_caster<ArgAlwaysConverts> {\npublic:\n    PYBIND11_TYPE_CASTER(ArgAlwaysConverts, const_name(\"ArgAlwaysConverts\"));\n\n    bool load(handle, bool convert) { return convert; }\n\n    static handle cast(const ArgAlwaysConverts &, return_value_policy, handle) {\n        return py::none().release();\n    }\n};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n\n// test_custom_caster_destruction\nclass DestructionTester {\npublic:\n    DestructionTester() { print_default_created(this); }\n    ~DestructionTester() { print_destroyed(this); }\n    DestructionTester(const DestructionTester &) { print_copy_created(this); }\n    DestructionTester(DestructionTester &&) noexcept { print_move_created(this); }\n    DestructionTester &operator=(const DestructionTester &) {\n        print_copy_assigned(this);\n        return *this;\n    }\n    DestructionTester &operator=(DestructionTester &&) noexcept {\n        print_move_assigned(this);\n        return *this;\n    }\n};\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <>\nstruct type_caster<DestructionTester> {\n    PYBIND11_TYPE_CASTER(DestructionTester, const_name(\"DestructionTester\"));\n    bool load(handle, bool) { return true; }\n\n    static handle cast(const DestructionTester &, return_value_policy, handle) {\n        return py::bool_(true).release();\n    }\n};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n\n// Define type caster outside of `pybind11::detail` and then alias it.\nnamespace other_lib {\nstruct MyType {};\n// Corrupt `py` shorthand alias for surrounding context.\nnamespace py {}\n// Corrupt unqualified relative `pybind11` namespace.\nnamespace PYBIND11_NAMESPACE {}\n// Correct alias.\nnamespace py_ = ::pybind11;\n// Define caster. This is effectively no-op, we only ensure it compiles and we\n// don't have any symbol collision when using macro mixin.\nstruct my_caster {\n    PYBIND11_TYPE_CASTER(MyType, py_::detail::const_name(\"MyType\"));\n    bool load(py_::handle, bool) { return true; }\n\n    static py_::handle cast(const MyType &, py_::return_value_policy, py_::handle) {\n        return py_::bool_(true).release();\n    }\n};\n} // namespace other_lib\n// Effectively \"alias\" it into correct namespace (via inheritance).\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <>\nstruct type_caster<other_lib::MyType> : public other_lib::my_caster {};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n\nTEST_SUBMODULE(custom_type_casters, m) {\n    // test_custom_type_casters\n\n    // test_noconvert_args\n    //\n    // Test converting.  The ArgAlwaysConverts is just there to make the first no-conversion pass\n    // fail so that our call always ends up happening via the second dispatch (the one that allows\n    // some conversion).\n    class ArgInspector {\n    public:\n        ArgInspector1 f(ArgInspector1 a, ArgAlwaysConverts) { return a; }\n        std::string g(const ArgInspector1 &a,\n                      const ArgInspector1 &b,\n                      int c,\n                      ArgInspector2 *d,\n                      ArgAlwaysConverts) {\n            return a.arg + \"\\n\" + b.arg + \"\\n\" + std::to_string(c) + \"\\n\" + d->arg;\n        }\n        static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }\n    };\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n    py::class_<ArgInspector>(m, \"ArgInspector\")\n        .def(py::init<>())\n        .def(\"f\", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())\n        .def(\"g\",\n             &ArgInspector::g,\n             \"a\"_a.noconvert(),\n             \"b\"_a,\n             \"c\"_a.noconvert() = 13,\n             \"d\"_a = ArgInspector2(),\n             py::arg() = ArgAlwaysConverts())\n        .def_static(\"h\", &ArgInspector::h, py::arg{}.noconvert(), py::arg() = ArgAlwaysConverts());\n    m.def(\n        \"arg_inspect_func\",\n        [](const ArgInspector2 &a, const ArgInspector1 &b, ArgAlwaysConverts) {\n            return a.arg + \"\\n\" + b.arg;\n        },\n        py::arg{}.noconvert(false),\n        py::arg_v(nullptr, ArgInspector1()).noconvert(true),\n        py::arg() = ArgAlwaysConverts());\n\n    m.def(\n        \"floats_preferred\", [](double f) { return 0.5 * f; }, \"f\"_a);\n    m.def(\n        \"floats_only\", [](double f) { return 0.5 * f; }, \"f\"_a.noconvert());\n    m.def(\n        \"ints_preferred\", [](int i) { return i / 2; }, \"i\"_a);\n    m.def(\n        \"ints_only\", [](int i) { return i / 2; }, \"i\"_a.noconvert());\n\n    // test_custom_caster_destruction\n    // Test that `take_ownership` works on types with a custom type caster when given a pointer\n\n    // default policy: don't take ownership:\n    m.def(\"custom_caster_no_destroy\", []() {\n        static auto *dt = new DestructionTester();\n        return dt;\n    });\n\n    m.def(\n        \"custom_caster_destroy\",\n        []() { return new DestructionTester(); },\n        py::return_value_policy::take_ownership); // Takes ownership: destroy when finished\n    m.def(\n        \"custom_caster_destroy_const\",\n        []() -> const DestructionTester * { return new DestructionTester(); },\n        py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)\n    m.def(\"destruction_tester_cstats\",\n          &ConstructorStats::get<DestructionTester>,\n          py::return_value_policy::reference);\n\n    m.def(\"other_lib_type\", [](other_lib::MyType x) { return x; });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_custom_type_casters.py",
    "content": "import pytest\n\nfrom pybind11_tests import custom_type_casters as m\n\n\ndef test_noconvert_args(msg):\n    a = m.ArgInspector()\n    assert (\n        msg(a.f(\"hi\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = hi\n    \"\"\"\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        13\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = (default arg inspector 2)\n    \"\"\"\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\", 42))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        42\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = (default arg inspector 2)\n    \"\"\"\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\", 42, \"this is d\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        42\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = this is d\n    \"\"\"\n    )\n    assert (\n        a.h(\"arg 1\")\n        == \"loading ArgInspector2 argument WITHOUT conversion allowed.  Argument value = arg 1\"\n    )\n    assert (\n        msg(m.arg_inspect_func(\"A1\", \"A2\"))\n        == \"\"\"\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = A1\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = A2\n    \"\"\"\n    )\n\n    assert m.floats_preferred(4) == 2.0\n    assert m.floats_only(4.0) == 2.0\n    with pytest.raises(TypeError) as excinfo:\n        m.floats_only(4)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        floats_only(): incompatible function arguments. The following argument types are supported:\n            1. (f: float) -> float\n\n        Invoked with: 4\n    \"\"\"\n    )\n\n    assert m.ints_preferred(4) == 2\n    assert m.ints_preferred(True) == 0\n    with pytest.raises(TypeError) as excinfo:\n        m.ints_preferred(4.0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ints_preferred(): incompatible function arguments. The following argument types are supported:\n            1. (i: int) -> int\n\n        Invoked with: 4.0\n    \"\"\"\n    )\n\n    assert m.ints_only(4) == 2\n    with pytest.raises(TypeError) as excinfo:\n        m.ints_only(4.0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ints_only(): incompatible function arguments. The following argument types are supported:\n            1. (i: int) -> int\n\n        Invoked with: 4.0\n    \"\"\"\n    )\n\n\ndef test_custom_caster_destruction():\n    \"\"\"Tests that returning a pointer to a type that gets converted with a custom type caster gets\n    destroyed when the function has py::return_value_policy::take_ownership policy applied.\"\"\"\n\n    cstats = m.destruction_tester_cstats()\n    # This one *doesn't* have take_ownership: the pointer should be used but not destroyed:\n    z = m.custom_caster_no_destroy()\n    assert cstats.alive() == 1 and cstats.default_constructions == 1\n    assert z\n\n    # take_ownership applied: this constructs a new object, casts it, then destroys it:\n    z = m.custom_caster_destroy()\n    assert z\n    assert cstats.default_constructions == 2\n\n    # Same, but with a const pointer return (which should *not* inhibit destruction):\n    z = m.custom_caster_destroy_const()\n    assert z\n    assert cstats.default_constructions == 3\n\n    # Make sure we still only have the original object (from ..._no_destroy()) alive:\n    assert cstats.alive() == 1\n\n\ndef test_custom_caster_other_lib():\n    assert m.other_lib_type(True)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_custom_type_setup.cpp",
    "content": "/*\n    tests/test_custom_type_setup.cpp -- Tests `pybind11::custom_type_setup`\n\n    Copyright (c) Google LLC\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/pybind11.h>\n\n#include \"pybind11_tests.h\"\n\nnamespace py = pybind11;\n\nnamespace {\n\nstruct OwnsPythonObjects {\n    py::object value = py::none();\n};\n} // namespace\n\nTEST_SUBMODULE(custom_type_setup, m) {\n    py::class_<OwnsPythonObjects> cls(\n        m, \"OwnsPythonObjects\", py::custom_type_setup([](PyHeapTypeObject *heap_type) {\n            auto *type = &heap_type->ht_type;\n            type->tp_flags |= Py_TPFLAGS_HAVE_GC;\n            type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {\n                auto &self = py::cast<OwnsPythonObjects &>(py::handle(self_base));\n                Py_VISIT(self.value.ptr());\n                return 0;\n            };\n            type->tp_clear = [](PyObject *self_base) {\n                auto &self = py::cast<OwnsPythonObjects &>(py::handle(self_base));\n                self.value = py::none();\n                return 0;\n            };\n        }));\n    cls.def(py::init<>());\n    cls.def_readwrite(\"value\", &OwnsPythonObjects::value);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_custom_type_setup.py",
    "content": "import gc\nimport weakref\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import custom_type_setup as m\n\n\n@pytest.fixture\ndef gc_tester():\n    \"\"\"Tests that an object is garbage collected.\n\n    Assumes that any unreferenced objects are fully collected after calling\n    `gc.collect()`.  That is true on CPython, but does not appear to reliably\n    hold on PyPy.\n    \"\"\"\n\n    weak_refs = []\n\n    def add_ref(obj):\n        # PyPy does not support `gc.is_tracked`.\n        if hasattr(gc, \"is_tracked\"):\n            assert gc.is_tracked(obj)\n        weak_refs.append(weakref.ref(obj))\n\n    yield add_ref\n\n    gc.collect()\n    for ref in weak_refs:\n        assert ref() is None\n\n\n# PyPy does not seem to reliably garbage collect.\n@pytest.mark.skipif(\"env.PYPY\")\ndef test_self_cycle(gc_tester):\n    obj = m.OwnsPythonObjects()\n    obj.value = obj\n    gc_tester(obj)\n\n\n# PyPy does not seem to reliably garbage collect.\n@pytest.mark.skipif(\"env.PYPY\")\ndef test_indirect_cycle(gc_tester):\n    obj = m.OwnsPythonObjects()\n    obj_list = [obj]\n    obj.value = obj_list\n    gc_tester(obj)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_docstring_options.cpp",
    "content": "/*\n    tests/test_docstring_options.cpp -- generation of docstrings and signatures\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(docstring_options, m) {\n    // test_docstring_options\n    {\n        py::options options;\n        options.disable_function_signatures();\n\n        m.def(\n            \"test_function1\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"));\n        m.def(\n            \"test_function2\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        m.def(\n            \"test_overloaded1\", [](int) {}, py::arg(\"i\"), \"Overload docstring\");\n        m.def(\n            \"test_overloaded1\", [](double) {}, py::arg(\"d\"));\n\n        m.def(\n            \"test_overloaded2\", [](int) {}, py::arg(\"i\"), \"overload docstring 1\");\n        m.def(\n            \"test_overloaded2\", [](double) {}, py::arg(\"d\"), \"overload docstring 2\");\n\n        m.def(\n            \"test_overloaded3\", [](int) {}, py::arg(\"i\"));\n        m.def(\n            \"test_overloaded3\", [](double) {}, py::arg(\"d\"), \"Overload docstr\");\n\n        options.enable_function_signatures();\n\n        m.def(\n            \"test_function3\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"));\n        m.def(\n            \"test_function4\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        options.disable_function_signatures().disable_user_defined_docstrings();\n\n        m.def(\n            \"test_function5\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        {\n            py::options nested_options;\n            nested_options.enable_user_defined_docstrings();\n            m.def(\n                \"test_function6\",\n                [](int, int) {},\n                py::arg(\"a\"),\n                py::arg(\"b\"),\n                \"A custom docstring\");\n        }\n    }\n\n    m.def(\n        \"test_function7\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n    {\n        py::options options;\n        options.disable_user_defined_docstrings();\n        options.disable_function_signatures();\n\n        m.def(\"test_function8\", []() {});\n    }\n\n    {\n        py::options options;\n        options.disable_user_defined_docstrings();\n\n        struct DocstringTestFoo {\n            int value;\n            void setValue(int v) { value = v; }\n            int getValue() const { return value; }\n        };\n        py::class_<DocstringTestFoo>(m, \"DocstringTestFoo\", \"This is a class docstring\")\n            .def_property(\"value_prop\",\n                          &DocstringTestFoo::getValue,\n                          &DocstringTestFoo::setValue,\n                          \"This is a property docstring\");\n    }\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_docstring_options.py",
    "content": "from pybind11_tests import docstring_options as m\n\n\ndef test_docstring_options():\n    # options.disable_function_signatures()\n    assert not m.test_function1.__doc__\n\n    assert m.test_function2.__doc__ == \"A custom docstring\"\n\n    # docstring specified on just the first overload definition:\n    assert m.test_overloaded1.__doc__ == \"Overload docstring\"\n\n    # docstring on both overloads:\n    assert m.test_overloaded2.__doc__ == \"overload docstring 1\\noverload docstring 2\"\n\n    # docstring on only second overload:\n    assert m.test_overloaded3.__doc__ == \"Overload docstr\"\n\n    # options.enable_function_signatures()\n    assert m.test_function3.__doc__.startswith(\"test_function3(a: int, b: int) -> None\")\n\n    assert m.test_function4.__doc__.startswith(\"test_function4(a: int, b: int) -> None\")\n    assert m.test_function4.__doc__.endswith(\"A custom docstring\\n\")\n\n    # options.disable_function_signatures()\n    # options.disable_user_defined_docstrings()\n    assert not m.test_function5.__doc__\n\n    # nested options.enable_user_defined_docstrings()\n    assert m.test_function6.__doc__ == \"A custom docstring\"\n\n    # RAII destructor\n    assert m.test_function7.__doc__.startswith(\"test_function7(a: int, b: int) -> None\")\n    assert m.test_function7.__doc__.endswith(\"A custom docstring\\n\")\n\n    # when all options are disabled, no docstring (instead of an empty one) should be generated\n    assert m.test_function8.__doc__ is None\n\n    # Suppression of user-defined docstrings for non-function objects\n    assert not m.DocstringTestFoo.__doc__\n    assert not m.DocstringTestFoo.value_prop.__doc__\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_matrix.cpp",
    "content": "/*\n    tests/eigen.cpp -- automatic conversion of Eigen types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/eigen/matrix.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#if defined(_MSC_VER)\n#    pragma warning(disable : 4996) // C4996: std::unary_negation is deprecated\n#endif\n\n#include <Eigen/Cholesky>\n\nusing MatrixXdR = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;\n\n// Sets/resets a testing reference matrix to have values of 10*r + c, where r and c are the\n// (1-based) row/column number.\ntemplate <typename M>\nvoid reset_ref(M &x) {\n    for (int i = 0; i < x.rows(); i++) {\n        for (int j = 0; j < x.cols(); j++) {\n            x(i, j) = 11 + 10 * i + j;\n        }\n    }\n}\n\n// Returns a static, column-major matrix\nEigen::MatrixXd &get_cm() {\n    static Eigen::MatrixXd *x;\n    if (!x) {\n        x = new Eigen::MatrixXd(3, 3);\n        reset_ref(*x);\n    }\n    return *x;\n}\n// Likewise, but row-major\nMatrixXdR &get_rm() {\n    static MatrixXdR *x;\n    if (!x) {\n        x = new MatrixXdR(3, 3);\n        reset_ref(*x);\n    }\n    return *x;\n}\n// Resets the values of the static matrices returned by get_cm()/get_rm()\nvoid reset_refs() {\n    reset_ref(get_cm());\n    reset_ref(get_rm());\n}\n\n// Returns element 2,1 from a matrix (used to test copy/nocopy)\ndouble get_elem(const Eigen::Ref<const Eigen::MatrixXd> &m) { return m(2, 1); };\n\n// Returns a matrix with 10*r + 100*c added to each matrix element (to help test that the matrix\n// reference is referencing rows/columns correctly).\ntemplate <typename MatrixArgType>\nEigen::MatrixXd adjust_matrix(MatrixArgType m) {\n    Eigen::MatrixXd ret(m);\n    for (int c = 0; c < m.cols(); c++) {\n        for (int r = 0; r < m.rows(); r++) {\n            ret(r, c) += 10 * r + 100 * c; // NOLINT(clang-analyzer-core.uninitialized.Assign)\n        }\n    }\n    return ret;\n}\n\nstruct CustomOperatorNew {\n    CustomOperatorNew() = default;\n\n    Eigen::Matrix4d a = Eigen::Matrix4d::Zero();\n    Eigen::Matrix4d b = Eigen::Matrix4d::Identity();\n\n    EIGEN_MAKE_ALIGNED_OPERATOR_NEW;\n};\n\nTEST_SUBMODULE(eigen_matrix, m) {\n    using FixedMatrixR = Eigen::Matrix<float, 5, 6, Eigen::RowMajor>;\n    using FixedMatrixC = Eigen::Matrix<float, 5, 6>;\n    using DenseMatrixR = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;\n    using DenseMatrixC = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>;\n    using FourRowMatrixC = Eigen::Matrix<float, 4, Eigen::Dynamic>;\n    using FourColMatrixC = Eigen::Matrix<float, Eigen::Dynamic, 4>;\n    using FourRowMatrixR = Eigen::Matrix<float, 4, Eigen::Dynamic>;\n    using FourColMatrixR = Eigen::Matrix<float, Eigen::Dynamic, 4>;\n    using SparseMatrixR = Eigen::SparseMatrix<float, Eigen::RowMajor>;\n    using SparseMatrixC = Eigen::SparseMatrix<float>;\n\n    // various tests\n    m.def(\"double_col\", [](const Eigen::VectorXf &x) -> Eigen::VectorXf { return 2.0f * x; });\n    m.def(\"double_row\",\n          [](const Eigen::RowVectorXf &x) -> Eigen::RowVectorXf { return 2.0f * x; });\n    m.def(\"double_complex\",\n          [](const Eigen::VectorXcf &x) -> Eigen::VectorXcf { return 2.0f * x; });\n    m.def(\"double_threec\", [](py::EigenDRef<Eigen::Vector3f> x) { x *= 2; });\n    m.def(\"double_threer\", [](py::EigenDRef<Eigen::RowVector3f> x) { x *= 2; });\n    m.def(\"double_mat_cm\", [](const Eigen::MatrixXf &x) -> Eigen::MatrixXf { return 2.0f * x; });\n    m.def(\"double_mat_rm\", [](const DenseMatrixR &x) -> DenseMatrixR { return 2.0f * x; });\n\n    // test_eigen_ref_to_python\n    // Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended\n    m.def(\"cholesky1\",\n          [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });\n    m.def(\"cholesky2\", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {\n        return x.llt().matrixL();\n    });\n    m.def(\"cholesky3\",\n          [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });\n    m.def(\"cholesky4\", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {\n        return x.llt().matrixL();\n    });\n\n    // test_eigen_ref_mutators\n    // Mutators: these add some value to the given element using Eigen, but Eigen should be mapping\n    // into the numpy array data and so the result should show up there.  There are three versions:\n    // one that works on a contiguous-row matrix (numpy's default), one for a contiguous-column\n    // matrix, and one for any matrix.\n    auto add_rm = [](Eigen::Ref<MatrixXdR> x, int r, int c, double v) { x(r, c) += v; };\n    auto add_cm = [](Eigen::Ref<Eigen::MatrixXd> x, int r, int c, double v) { x(r, c) += v; };\n\n    // Mutators (Eigen maps into numpy variables):\n    m.def(\"add_rm\", add_rm); // Only takes row-contiguous\n    m.def(\"add_cm\", add_cm); // Only takes column-contiguous\n    // Overloaded versions that will accept either row or column contiguous:\n    m.def(\"add1\", add_rm);\n    m.def(\"add1\", add_cm);\n    m.def(\"add2\", add_cm);\n    m.def(\"add2\", add_rm);\n    // This one accepts a matrix of any stride:\n    m.def(\"add_any\",\n          [](py::EigenDRef<Eigen::MatrixXd> x, int r, int c, double v) { x(r, c) += v; });\n\n    // Return mutable references (numpy maps into eigen variables)\n    m.def(\"get_cm_ref\", []() { return Eigen::Ref<Eigen::MatrixXd>(get_cm()); });\n    m.def(\"get_rm_ref\", []() { return Eigen::Ref<MatrixXdR>(get_rm()); });\n    // The same references, but non-mutable (numpy maps into eigen variables, but is !writeable)\n    m.def(\"get_cm_const_ref\", []() { return Eigen::Ref<const Eigen::MatrixXd>(get_cm()); });\n    m.def(\"get_rm_const_ref\", []() { return Eigen::Ref<const MatrixXdR>(get_rm()); });\n\n    m.def(\"reset_refs\", reset_refs); // Restores get_{cm,rm}_ref to original values\n\n    // Increments and returns ref to (same) matrix\n    m.def(\n        \"incr_matrix\",\n        [](Eigen::Ref<Eigen::MatrixXd> m, double v) {\n            m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);\n            return m;\n        },\n        py::return_value_policy::reference);\n\n    // Same, but accepts a matrix of any strides\n    m.def(\n        \"incr_matrix_any\",\n        [](py::EigenDRef<Eigen::MatrixXd> m, double v) {\n            m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);\n            return m;\n        },\n        py::return_value_policy::reference);\n\n    // Returns an eigen slice of even rows\n    m.def(\n        \"even_rows\",\n        [](py::EigenDRef<Eigen::MatrixXd> m) {\n            return py::EigenDMap<Eigen::MatrixXd>(\n                m.data(),\n                (m.rows() + 1) / 2,\n                m.cols(),\n                py::EigenDStride(m.outerStride(), 2 * m.innerStride()));\n        },\n        py::return_value_policy::reference);\n\n    // Returns an eigen slice of even columns\n    m.def(\n        \"even_cols\",\n        [](py::EigenDRef<Eigen::MatrixXd> m) {\n            return py::EigenDMap<Eigen::MatrixXd>(\n                m.data(),\n                m.rows(),\n                (m.cols() + 1) / 2,\n                py::EigenDStride(2 * m.outerStride(), m.innerStride()));\n        },\n        py::return_value_policy::reference);\n\n    // Returns diagonals: a vector-like object with an inner stride != 1\n    m.def(\"diagonal\", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal(); });\n    m.def(\"diagonal_1\",\n          [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal<1>(); });\n    m.def(\"diagonal_n\",\n          [](const Eigen::Ref<const Eigen::MatrixXd> &x, int index) { return x.diagonal(index); });\n\n    // Return a block of a matrix (gives non-standard strides)\n    m.def(\"block\",\n          [m](const py::object &x_obj,\n              int start_row,\n              int start_col,\n              int block_rows,\n              int block_cols) {\n              return m.attr(\"_block\")(x_obj, x_obj, start_row, start_col, block_rows, block_cols);\n          });\n\n    m.def(\n        \"_block\",\n        [](const py::object &x_obj,\n           const Eigen::Ref<const Eigen::MatrixXd> &x,\n           int start_row,\n           int start_col,\n           int block_rows,\n           int block_cols) {\n            // See PR #4217 for background. This test is a bit over the top, but might be useful\n            // as a concrete example to point to when explaining the dangling reference trap.\n            auto i0 = py::make_tuple(0, 0);\n            auto x0_orig = x_obj[*i0].cast<double>();\n            if (x(0, 0) != x0_orig) {\n                throw std::runtime_error(\n                    \"Something in the type_caster for Eigen::Ref is terribly wrong.\");\n            }\n            double x0_mod = x0_orig + 1;\n            x_obj[*i0] = x0_mod;\n            auto copy_detected = (x(0, 0) != x0_mod);\n            x_obj[*i0] = x0_orig;\n            if (copy_detected) {\n                throw std::runtime_error(\"type_caster for Eigen::Ref made a copy.\");\n            }\n            return x.block(start_row, start_col, block_rows, block_cols);\n        },\n        py::keep_alive<0, 1>());\n\n    // test_eigen_return_references, test_eigen_keepalive\n    // return value referencing/copying tests:\n    class ReturnTester {\n        Eigen::MatrixXd mat = create();\n\n    public:\n        ReturnTester() { print_created(this); }\n        ~ReturnTester() { print_destroyed(this); }\n        static Eigen::MatrixXd create() { return Eigen::MatrixXd::Ones(10, 10); }\n        // NOLINTNEXTLINE(readability-const-return-type)\n        static const Eigen::MatrixXd createConst() { return Eigen::MatrixXd::Ones(10, 10); }\n        Eigen::MatrixXd &get() { return mat; }\n        Eigen::MatrixXd *getPtr() { return &mat; }\n        const Eigen::MatrixXd &view() { return mat; }\n        const Eigen::MatrixXd *viewPtr() { return &mat; }\n        Eigen::Ref<Eigen::MatrixXd> ref() { return mat; }\n        Eigen::Ref<const Eigen::MatrixXd> refConst() { return mat; }\n        Eigen::Block<Eigen::MatrixXd> block(int r, int c, int nrow, int ncol) {\n            return mat.block(r, c, nrow, ncol);\n        }\n        Eigen::Block<const Eigen::MatrixXd> blockConst(int r, int c, int nrow, int ncol) const {\n            return mat.block(r, c, nrow, ncol);\n        }\n        py::EigenDMap<Eigen::Matrix2d> corners() {\n            return py::EigenDMap<Eigen::Matrix2d>(\n                mat.data(),\n                py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),\n                                 mat.innerStride() * (mat.innerSize() - 1)));\n        }\n        py::EigenDMap<const Eigen::Matrix2d> cornersConst() const {\n            return py::EigenDMap<const Eigen::Matrix2d>(\n                mat.data(),\n                py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),\n                                 mat.innerStride() * (mat.innerSize() - 1)));\n        }\n    };\n    using rvp = py::return_value_policy;\n    py::class_<ReturnTester>(m, \"ReturnTester\")\n        .def(py::init<>())\n        .def_static(\"create\", &ReturnTester::create)\n        .def_static(\"create_const\", &ReturnTester::createConst)\n        .def(\"get\", &ReturnTester::get, rvp::reference_internal)\n        .def(\"get_ptr\", &ReturnTester::getPtr, rvp::reference_internal)\n        .def(\"view\", &ReturnTester::view, rvp::reference_internal)\n        .def(\"view_ptr\", &ReturnTester::view, rvp::reference_internal)\n        .def(\"copy_get\", &ReturnTester::get)       // Default rvp: copy\n        .def(\"copy_view\", &ReturnTester::view)     //         \"\n        .def(\"ref\", &ReturnTester::ref)            // Default for Ref is to reference\n        .def(\"ref_const\", &ReturnTester::refConst) // Likewise, but const\n        .def(\"ref_safe\", &ReturnTester::ref, rvp::reference_internal)\n        .def(\"ref_const_safe\", &ReturnTester::refConst, rvp::reference_internal)\n        .def(\"copy_ref\", &ReturnTester::ref, rvp::copy)\n        .def(\"copy_ref_const\", &ReturnTester::refConst, rvp::copy)\n        .def(\"block\", &ReturnTester::block)\n        .def(\"block_safe\", &ReturnTester::block, rvp::reference_internal)\n        .def(\"block_const\", &ReturnTester::blockConst, rvp::reference_internal)\n        .def(\"copy_block\", &ReturnTester::block, rvp::copy)\n        .def(\"corners\", &ReturnTester::corners, rvp::reference_internal)\n        .def(\"corners_const\", &ReturnTester::cornersConst, rvp::reference_internal);\n\n    // test_special_matrix_objects\n    // Returns a DiagonalMatrix with diagonal (1,2,3,...)\n    m.def(\"incr_diag\", [](int k) {\n        Eigen::DiagonalMatrix<int, Eigen::Dynamic> m(k);\n        for (int i = 0; i < k; i++) {\n            m.diagonal()[i] = i + 1;\n        }\n        return m;\n    });\n\n    // Returns a SelfAdjointView referencing the lower triangle of m\n    m.def(\"symmetric_lower\",\n          [](const Eigen::MatrixXi &m) { return m.selfadjointView<Eigen::Lower>(); });\n    // Returns a SelfAdjointView referencing the lower triangle of m\n    m.def(\"symmetric_upper\",\n          [](const Eigen::MatrixXi &m) { return m.selfadjointView<Eigen::Upper>(); });\n\n    // Test matrix for various functions below.\n    Eigen::MatrixXf mat(5, 6);\n    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,\n        0, 8, 11;\n\n    // test_fixed, and various other tests\n    m.def(\"fixed_r\", [mat]() -> FixedMatrixR { return FixedMatrixR(mat); });\n    // Our Eigen does a hack which respects constness through the numpy writeable flag.\n    // Therefore, the const return actually affects this type despite being an rvalue.\n    // NOLINTNEXTLINE(readability-const-return-type)\n    m.def(\"fixed_r_const\", [mat]() -> const FixedMatrixR { return FixedMatrixR(mat); });\n    m.def(\"fixed_c\", [mat]() -> FixedMatrixC { return FixedMatrixC(mat); });\n    m.def(\"fixed_copy_r\", [](const FixedMatrixR &m) -> FixedMatrixR { return m; });\n    m.def(\"fixed_copy_c\", [](const FixedMatrixC &m) -> FixedMatrixC { return m; });\n    // test_mutator_descriptors\n    m.def(\"fixed_mutator_r\", [](const Eigen::Ref<FixedMatrixR> &) {});\n    m.def(\"fixed_mutator_c\", [](const Eigen::Ref<FixedMatrixC> &) {});\n    m.def(\"fixed_mutator_a\", [](const py::EigenDRef<FixedMatrixC> &) {});\n    // test_dense\n    m.def(\"dense_r\", [mat]() -> DenseMatrixR { return DenseMatrixR(mat); });\n    m.def(\"dense_c\", [mat]() -> DenseMatrixC { return DenseMatrixC(mat); });\n    m.def(\"dense_copy_r\", [](const DenseMatrixR &m) -> DenseMatrixR { return m; });\n    m.def(\"dense_copy_c\", [](const DenseMatrixC &m) -> DenseMatrixC { return m; });\n    // test_sparse, test_sparse_signature\n    m.def(\"sparse_r\", [mat]() -> SparseMatrixR {\n        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)\n        return Eigen::SparseView<Eigen::MatrixXf>(mat);\n    });\n    m.def(\"sparse_c\",\n          [mat]() -> SparseMatrixC { return Eigen::SparseView<Eigen::MatrixXf>(mat); });\n    m.def(\"sparse_copy_r\", [](const SparseMatrixR &m) -> SparseMatrixR { return m; });\n    m.def(\"sparse_copy_c\", [](const SparseMatrixC &m) -> SparseMatrixC { return m; });\n    // test_partially_fixed\n    m.def(\"partial_copy_four_rm_r\", [](const FourRowMatrixR &m) -> FourRowMatrixR { return m; });\n    m.def(\"partial_copy_four_rm_c\", [](const FourColMatrixR &m) -> FourColMatrixR { return m; });\n    m.def(\"partial_copy_four_cm_r\", [](const FourRowMatrixC &m) -> FourRowMatrixC { return m; });\n    m.def(\"partial_copy_four_cm_c\", [](const FourColMatrixC &m) -> FourColMatrixC { return m; });\n\n    // test_cpp_casting\n    // Test that we can cast a numpy object to a Eigen::MatrixXd explicitly\n    m.def(\"cpp_copy\", [](py::handle m) { return m.cast<Eigen::MatrixXd>()(1, 0); });\n    m.def(\"cpp_ref_c\", [](py::handle m) { return m.cast<Eigen::Ref<Eigen::MatrixXd>>()(1, 0); });\n    m.def(\"cpp_ref_r\", [](py::handle m) { return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });\n    m.def(\"cpp_ref_any\",\n          [](py::handle m) { return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_nocopy_wrapper\n    // Test that we can prevent copying into an argument that would normally copy: First a version\n    // that would allow copying (if types or strides don't match) for comparison:\n    m.def(\"get_elem\", &get_elem);\n    // Now this alternative that calls the tells pybind to fail rather than copy:\n    m.def(\n        \"get_elem_nocopy\",\n        [](const Eigen::Ref<const Eigen::MatrixXd> &m) -> double { return get_elem(m); },\n        py::arg{}.noconvert());\n    // Also test a row-major-only no-copy const ref:\n    m.def(\n        \"get_elem_rm_nocopy\",\n        [](Eigen::Ref<const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) -> long {\n            return m(2, 1);\n        },\n        py::arg{}.noconvert());\n\n    // test_issue738, test_zero_length\n    // Issue #738: 1×N or N×1 2D matrices were neither accepted nor properly copied with an\n    // incompatible stride value on the length-1 dimension--but that should be allowed (without\n    // requiring a copy!) because the stride value can be safely ignored on a size-1 dimension.\n    // Similarly, 0×N or N×0 matrices were not accepted--again, these should be allowed since\n    // they contain no data. This particularly affects numpy ≥ 1.23, which sets the strides to\n    // 0 if any dimension size is 0.\n    m.def(\"iss738_f1\",\n          &adjust_matrix<const Eigen::Ref<const Eigen::MatrixXd> &>,\n          py::arg{}.noconvert());\n    m.def(\"iss738_f2\",\n          &adjust_matrix<const Eigen::Ref<const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>,\n          py::arg{}.noconvert());\n\n    // test_issue1105\n    // Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense\n    // eigen Vector or RowVector, the argument would fail to load because the numpy copy would\n    // fail: numpy won't broadcast a Nx1 into a 1-dimensional vector.\n    m.def(\"iss1105_col\", [](const Eigen::VectorXd &) { return true; });\n    m.def(\"iss1105_row\", [](const Eigen::RowVectorXd &) { return true; });\n\n    // test_named_arguments\n    // Make sure named arguments are working properly:\n    m.def(\n        \"matrix_multiply\",\n        [](const py::EigenDRef<const Eigen::MatrixXd> &A,\n           const py::EigenDRef<const Eigen::MatrixXd> &B) -> Eigen::MatrixXd {\n            if (A.cols() != B.rows()) {\n                throw std::domain_error(\"Nonconformable matrices!\");\n            }\n            return A * B;\n        },\n        py::arg(\"A\"),\n        py::arg(\"B\"));\n\n    // test_custom_operator_new\n    py::class_<CustomOperatorNew>(m, \"CustomOperatorNew\")\n        .def(py::init<>())\n        .def_readonly(\"a\", &CustomOperatorNew::a)\n        .def_readonly(\"b\", &CustomOperatorNew::b);\n\n    // test_eigen_ref_life_support\n    // In case of a failure (the caster's temp array does not live long enough), creating\n    // a new array (np.ones(10)) increases the chances that the temp array will be garbage\n    // collected and/or that its memory will be overridden with different values.\n    m.def(\"get_elem_direct\", [](const Eigen::Ref<const Eigen::VectorXd> &v) {\n        py::module_::import(\"numpy\").attr(\"ones\")(10);\n        return v(5);\n    });\n    m.def(\"get_elem_indirect\", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) {\n        py::module_::import(\"numpy\").attr(\"ones\")(10);\n        return v[0](5);\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_matrix.py",
    "content": "import pytest\n\nfrom pybind11_tests import ConstructorStats\n\nnp = pytest.importorskip(\"numpy\")\nm = pytest.importorskip(\"pybind11_tests.eigen_matrix\")\n\n\nref = np.array(\n    [\n        [0.0, 3, 0, 0, 0, 11],\n        [22, 0, 0, 0, 17, 11],\n        [7, 5, 0, 1, 0, 11],\n        [0, 0, 0, 0, 0, 11],\n        [0, 0, 14, 0, 8, 11],\n    ]\n)\n\n\ndef assert_equal_ref(mat):\n    np.testing.assert_array_equal(mat, ref)\n\n\ndef assert_sparse_equal_ref(sparse_mat):\n    assert_equal_ref(sparse_mat.toarray())\n\n\ndef test_fixed():\n    assert_equal_ref(m.fixed_c())\n    assert_equal_ref(m.fixed_r())\n    assert_equal_ref(m.fixed_copy_r(m.fixed_r()))\n    assert_equal_ref(m.fixed_copy_c(m.fixed_c()))\n    assert_equal_ref(m.fixed_copy_r(m.fixed_c()))\n    assert_equal_ref(m.fixed_copy_c(m.fixed_r()))\n\n\ndef test_dense():\n    assert_equal_ref(m.dense_r())\n    assert_equal_ref(m.dense_c())\n    assert_equal_ref(m.dense_copy_r(m.dense_r()))\n    assert_equal_ref(m.dense_copy_c(m.dense_c()))\n    assert_equal_ref(m.dense_copy_r(m.dense_c()))\n    assert_equal_ref(m.dense_copy_c(m.dense_r()))\n\n\ndef test_partially_fixed():\n    ref2 = np.array([[0.0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])\n    np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2[:, 1]), ref2[:, [1]])\n    np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2[0, :]), ref2[[0], :])\n    np.testing.assert_array_equal(\n        m.partial_copy_four_rm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]\n    )\n    np.testing.assert_array_equal(\n        m.partial_copy_four_rm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]\n    )\n\n    np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2[:, 1]), ref2[:, [1]])\n    np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2[0, :]), ref2[[0], :])\n    np.testing.assert_array_equal(\n        m.partial_copy_four_cm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]\n    )\n    np.testing.assert_array_equal(\n        m.partial_copy_four_cm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]\n    )\n\n    # TypeError should be raise for a shape mismatch\n    functions = [\n        m.partial_copy_four_rm_r,\n        m.partial_copy_four_rm_c,\n        m.partial_copy_four_cm_r,\n        m.partial_copy_four_cm_c,\n    ]\n    matrix_with_wrong_shape = [[1, 2], [3, 4]]\n    for f in functions:\n        with pytest.raises(TypeError) as excinfo:\n            f(matrix_with_wrong_shape)\n        assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_mutator_descriptors():\n    zr = np.arange(30, dtype=\"float32\").reshape(5, 6)  # row-major\n    zc = zr.reshape(6, 5).transpose()  # column-major\n\n    m.fixed_mutator_r(zr)\n    m.fixed_mutator_c(zc)\n    m.fixed_mutator_a(zr)\n    m.fixed_mutator_a(zc)\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_r(zc)\n    assert (\n        \"(arg0: numpy.ndarray[numpy.float32[5, 6],\"\n        \" flags.writeable, flags.c_contiguous]) -> None\" in str(excinfo.value)\n    )\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_c(zr)\n    assert (\n        \"(arg0: numpy.ndarray[numpy.float32[5, 6],\"\n        \" flags.writeable, flags.f_contiguous]) -> None\" in str(excinfo.value)\n    )\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_a(np.array([[1, 2], [3, 4]], dtype=\"float32\"))\n    assert \"(arg0: numpy.ndarray[numpy.float32[5, 6], flags.writeable]) -> None\" in str(\n        excinfo.value\n    )\n    zr.flags.writeable = False\n    with pytest.raises(TypeError):\n        m.fixed_mutator_r(zr)\n    with pytest.raises(TypeError):\n        m.fixed_mutator_a(zr)\n\n\ndef test_cpp_casting():\n    assert m.cpp_copy(m.fixed_r()) == 22.0\n    assert m.cpp_copy(m.fixed_c()) == 22.0\n    z = np.array([[5.0, 6], [7, 8]])\n    assert m.cpp_copy(z) == 7.0\n    assert m.cpp_copy(m.get_cm_ref()) == 21.0\n    assert m.cpp_copy(m.get_rm_ref()) == 21.0\n    assert m.cpp_ref_c(m.get_cm_ref()) == 21.0\n    assert m.cpp_ref_r(m.get_rm_ref()) == 21.0\n    with pytest.raises(RuntimeError) as excinfo:\n        # Can't reference m.fixed_c: it contains floats, m.cpp_ref_any wants doubles\n        m.cpp_ref_any(m.fixed_c())\n    assert \"Unable to cast Python instance\" in str(excinfo.value)\n    with pytest.raises(RuntimeError) as excinfo:\n        # Can't reference m.fixed_r: it contains floats, m.cpp_ref_any wants doubles\n        m.cpp_ref_any(m.fixed_r())\n    assert \"Unable to cast Python instance\" in str(excinfo.value)\n    assert m.cpp_ref_any(m.ReturnTester.create()) == 1.0\n\n    assert m.cpp_ref_any(m.get_cm_ref()) == 21.0\n    assert m.cpp_ref_any(m.get_cm_ref()) == 21.0\n\n\ndef test_pass_readonly_array():\n    z = np.full((5, 6), 42.0)\n    z.flags.writeable = False\n    np.testing.assert_array_equal(z, m.fixed_copy_r(z))\n    np.testing.assert_array_equal(m.fixed_r_const(), m.fixed_r())\n    assert not m.fixed_r_const().flags.writeable\n    np.testing.assert_array_equal(m.fixed_copy_r(m.fixed_r_const()), m.fixed_r_const())\n\n\ndef test_nonunit_stride_from_python():\n    counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))\n    second_row = counting_mat[1, :]\n    second_col = counting_mat[:, 1]\n    np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)\n\n    counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))\n    slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]\n    for ref_mat in slices:\n        np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)\n        np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)\n\n    # Mutator:\n    m.double_threer(second_row)\n    m.double_threec(second_col)\n    np.testing.assert_array_equal(counting_mat, [[0.0, 2, 2], [6, 16, 10], [6, 14, 8]])\n\n\ndef test_negative_stride_from_python(msg):\n    \"\"\"Eigen doesn't support (as of yet) negative strides. When a function takes an Eigen matrix by\n    copy or const reference, we can pass a numpy array that has negative strides.  Otherwise, an\n    exception will be thrown as Eigen will not be able to map the numpy array.\"\"\"\n\n    counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))\n    counting_mat = counting_mat[::-1, ::-1]\n    second_row = counting_mat[1, :]\n    second_col = counting_mat[:, 1]\n    np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)\n\n    counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))\n    counting_3d = counting_3d[::-1, ::-1, ::-1]\n    slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]\n    for ref_mat in slices:\n        np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)\n        np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)\n\n    # Mutator:\n    with pytest.raises(TypeError) as excinfo:\n        m.double_threer(second_row)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        double_threer(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float32[1, 3], flags.writeable]) -> None\n\n        Invoked with: \"\"\"\n        + repr(np.array([5.0, 4.0, 3.0], dtype=\"float32\"))\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.double_threec(second_col)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        double_threec(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float32[3, 1], flags.writeable]) -> None\n\n        Invoked with: \"\"\"\n        + repr(np.array([7.0, 4.0, 1.0], dtype=\"float32\"))\n    )\n\n\ndef test_block_runtime_error_type_caster_eigen_ref_made_a_copy():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.block(ref, 0, 0, 0, 0)\n    assert str(excinfo.value) == \"type_caster for Eigen::Ref made a copy.\"\n\n\ndef test_nonunit_stride_to_python():\n    assert np.all(m.diagonal(ref) == ref.diagonal())\n    assert np.all(m.diagonal_1(ref) == ref.diagonal(1))\n    for i in range(-5, 7):\n        assert np.all(m.diagonal_n(ref, i) == ref.diagonal(i)), f\"m.diagonal_n({i})\"\n\n    # Must be order=\"F\", otherwise the type_caster will make a copy and\n    # m.block() will return a dangling reference (heap-use-after-free).\n    rof = np.asarray(ref, order=\"F\")\n    assert np.all(m.block(rof, 2, 1, 3, 3) == rof[2:5, 1:4])\n    assert np.all(m.block(rof, 1, 4, 4, 2) == rof[1:, 4:])\n    assert np.all(m.block(rof, 1, 4, 3, 2) == rof[1:4, 4:])\n\n\ndef test_eigen_ref_to_python():\n    chols = [m.cholesky1, m.cholesky2, m.cholesky3, m.cholesky4]\n    for i, chol in enumerate(chols, start=1):\n        mymat = chol(np.array([[1.0, 2, 4], [2, 13, 23], [4, 23, 77]]))\n        assert np.all(\n            mymat == np.array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])\n        ), f\"cholesky{i}\"\n\n\ndef assign_both(a1, a2, r, c, v):\n    a1[r, c] = v\n    a2[r, c] = v\n\n\ndef array_copy_but_one(a, r, c, v):\n    z = np.array(a, copy=True)\n    z[r, c] = v\n    return z\n\n\ndef test_eigen_return_references():\n    \"\"\"Tests various ways of returning references and non-referencing copies\"\"\"\n\n    primary = np.ones((10, 10))\n    a = m.ReturnTester()\n    a_get1 = a.get()\n    assert not a_get1.flags.owndata and a_get1.flags.writeable\n    assign_both(a_get1, primary, 3, 3, 5)\n    a_get2 = a.get_ptr()\n    assert not a_get2.flags.owndata and a_get2.flags.writeable\n    assign_both(a_get1, primary, 2, 3, 6)\n\n    a_view1 = a.view()\n    assert not a_view1.flags.owndata and not a_view1.flags.writeable\n    with pytest.raises(ValueError):\n        a_view1[2, 3] = 4\n    a_view2 = a.view_ptr()\n    assert not a_view2.flags.owndata and not a_view2.flags.writeable\n    with pytest.raises(ValueError):\n        a_view2[2, 3] = 4\n\n    a_copy1 = a.copy_get()\n    assert a_copy1.flags.owndata and a_copy1.flags.writeable\n    np.testing.assert_array_equal(a_copy1, primary)\n    a_copy1[7, 7] = -44  # Shouldn't affect anything else\n    c1want = array_copy_but_one(primary, 7, 7, -44)\n    a_copy2 = a.copy_view()\n    assert a_copy2.flags.owndata and a_copy2.flags.writeable\n    np.testing.assert_array_equal(a_copy2, primary)\n    a_copy2[4, 4] = -22  # Shouldn't affect anything else\n    c2want = array_copy_but_one(primary, 4, 4, -22)\n\n    a_ref1 = a.ref()\n    assert not a_ref1.flags.owndata and a_ref1.flags.writeable\n    assign_both(a_ref1, primary, 1, 1, 15)\n    a_ref2 = a.ref_const()\n    assert not a_ref2.flags.owndata and not a_ref2.flags.writeable\n    with pytest.raises(ValueError):\n        a_ref2[5, 5] = 33\n    a_ref3 = a.ref_safe()\n    assert not a_ref3.flags.owndata and a_ref3.flags.writeable\n    assign_both(a_ref3, primary, 0, 7, 99)\n    a_ref4 = a.ref_const_safe()\n    assert not a_ref4.flags.owndata and not a_ref4.flags.writeable\n    with pytest.raises(ValueError):\n        a_ref4[7, 0] = 987654321\n\n    a_copy3 = a.copy_ref()\n    assert a_copy3.flags.owndata and a_copy3.flags.writeable\n    np.testing.assert_array_equal(a_copy3, primary)\n    a_copy3[8, 1] = 11\n    c3want = array_copy_but_one(primary, 8, 1, 11)\n    a_copy4 = a.copy_ref_const()\n    assert a_copy4.flags.owndata and a_copy4.flags.writeable\n    np.testing.assert_array_equal(a_copy4, primary)\n    a_copy4[8, 4] = 88\n    c4want = array_copy_but_one(primary, 8, 4, 88)\n\n    a_block1 = a.block(3, 3, 2, 2)\n    assert not a_block1.flags.owndata and a_block1.flags.writeable\n    a_block1[0, 0] = 55\n    primary[3, 3] = 55\n    a_block2 = a.block_safe(2, 2, 3, 2)\n    assert not a_block2.flags.owndata and a_block2.flags.writeable\n    a_block2[2, 1] = -123\n    primary[4, 3] = -123\n    a_block3 = a.block_const(6, 7, 4, 3)\n    assert not a_block3.flags.owndata and not a_block3.flags.writeable\n    with pytest.raises(ValueError):\n        a_block3[2, 2] = -44444\n\n    a_copy5 = a.copy_block(2, 2, 2, 3)\n    assert a_copy5.flags.owndata and a_copy5.flags.writeable\n    np.testing.assert_array_equal(a_copy5, primary[2:4, 2:5])\n    a_copy5[1, 1] = 777\n    c5want = array_copy_but_one(primary[2:4, 2:5], 1, 1, 777)\n\n    a_corn1 = a.corners()\n    assert not a_corn1.flags.owndata and a_corn1.flags.writeable\n    a_corn1 *= 50\n    a_corn1[1, 1] = 999\n    primary[0, 0] = 50\n    primary[0, 9] = 50\n    primary[9, 0] = 50\n    primary[9, 9] = 999\n    a_corn2 = a.corners_const()\n    assert not a_corn2.flags.owndata and not a_corn2.flags.writeable\n    with pytest.raises(ValueError):\n        a_corn2[1, 0] = 51\n\n    # All of the changes made all the way along should be visible everywhere\n    # now (except for the copies, of course)\n    np.testing.assert_array_equal(a_get1, primary)\n    np.testing.assert_array_equal(a_get2, primary)\n    np.testing.assert_array_equal(a_view1, primary)\n    np.testing.assert_array_equal(a_view2, primary)\n    np.testing.assert_array_equal(a_ref1, primary)\n    np.testing.assert_array_equal(a_ref2, primary)\n    np.testing.assert_array_equal(a_ref3, primary)\n    np.testing.assert_array_equal(a_ref4, primary)\n    np.testing.assert_array_equal(a_block1, primary[3:5, 3:5])\n    np.testing.assert_array_equal(a_block2, primary[2:5, 2:4])\n    np.testing.assert_array_equal(a_block3, primary[6:10, 7:10])\n    np.testing.assert_array_equal(\n        a_corn1, primary[0 :: primary.shape[0] - 1, 0 :: primary.shape[1] - 1]\n    )\n    np.testing.assert_array_equal(\n        a_corn2, primary[0 :: primary.shape[0] - 1, 0 :: primary.shape[1] - 1]\n    )\n\n    np.testing.assert_array_equal(a_copy1, c1want)\n    np.testing.assert_array_equal(a_copy2, c2want)\n    np.testing.assert_array_equal(a_copy3, c3want)\n    np.testing.assert_array_equal(a_copy4, c4want)\n    np.testing.assert_array_equal(a_copy5, c5want)\n\n\ndef assert_keeps_alive(cl, method, *args):\n    cstats = ConstructorStats.get(cl)\n    start_with = cstats.alive()\n    a = cl()\n    assert cstats.alive() == start_with + 1\n    z = method(a, *args)\n    assert cstats.alive() == start_with + 1\n    del a\n    # Here's the keep alive in action:\n    assert cstats.alive() == start_with + 1\n    del z\n    # Keep alive should have expired:\n    assert cstats.alive() == start_with\n\n\ndef test_eigen_keepalive():\n    a = m.ReturnTester()\n    cstats = ConstructorStats.get(m.ReturnTester)\n    assert cstats.alive() == 1\n    unsafe = [a.ref(), a.ref_const(), a.block(1, 2, 3, 4)]\n    copies = [\n        a.copy_get(),\n        a.copy_view(),\n        a.copy_ref(),\n        a.copy_ref_const(),\n        a.copy_block(4, 3, 2, 1),\n    ]\n    del a\n    assert cstats.alive() == 0\n    del unsafe\n    del copies\n\n    for meth in [\n        m.ReturnTester.get,\n        m.ReturnTester.get_ptr,\n        m.ReturnTester.view,\n        m.ReturnTester.view_ptr,\n        m.ReturnTester.ref_safe,\n        m.ReturnTester.ref_const_safe,\n        m.ReturnTester.corners,\n        m.ReturnTester.corners_const,\n    ]:\n        assert_keeps_alive(m.ReturnTester, meth)\n\n    for meth in [m.ReturnTester.block_safe, m.ReturnTester.block_const]:\n        assert_keeps_alive(m.ReturnTester, meth, 4, 3, 2, 1)\n\n\ndef test_eigen_ref_mutators():\n    \"\"\"Tests Eigen's ability to mutate numpy values\"\"\"\n\n    orig = np.array([[1.0, 2, 3], [4, 5, 6], [7, 8, 9]])\n    zr = np.array(orig)\n    zc = np.array(orig, order=\"F\")\n    m.add_rm(zr, 1, 0, 100)\n    assert np.all(zr == np.array([[1.0, 2, 3], [104, 5, 6], [7, 8, 9]]))\n    m.add_cm(zc, 1, 0, 200)\n    assert np.all(zc == np.array([[1.0, 2, 3], [204, 5, 6], [7, 8, 9]]))\n\n    m.add_any(zr, 1, 0, 20)\n    assert np.all(zr == np.array([[1.0, 2, 3], [124, 5, 6], [7, 8, 9]]))\n    m.add_any(zc, 1, 0, 10)\n    assert np.all(zc == np.array([[1.0, 2, 3], [214, 5, 6], [7, 8, 9]]))\n\n    # Can't reference a col-major array with a row-major Ref, and vice versa:\n    with pytest.raises(TypeError):\n        m.add_rm(zc, 1, 0, 1)\n    with pytest.raises(TypeError):\n        m.add_cm(zr, 1, 0, 1)\n\n    # Overloads:\n    m.add1(zr, 1, 0, -100)\n    m.add2(zr, 1, 0, -20)\n    assert np.all(zr == orig)\n    m.add1(zc, 1, 0, -200)\n    m.add2(zc, 1, 0, -10)\n    assert np.all(zc == orig)\n\n    # a non-contiguous slice (this won't work on either the row- or\n    # column-contiguous refs, but should work for the any)\n    cornersr = zr[0::2, 0::2]\n    cornersc = zc[0::2, 0::2]\n\n    assert np.all(cornersr == np.array([[1.0, 3], [7, 9]]))\n    assert np.all(cornersc == np.array([[1.0, 3], [7, 9]]))\n\n    with pytest.raises(TypeError):\n        m.add_rm(cornersr, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_cm(cornersr, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_rm(cornersc, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_cm(cornersc, 0, 1, 25)\n    m.add_any(cornersr, 0, 1, 25)\n    m.add_any(cornersc, 0, 1, 44)\n    assert np.all(zr == np.array([[1.0, 2, 28], [4, 5, 6], [7, 8, 9]]))\n    assert np.all(zc == np.array([[1.0, 2, 47], [4, 5, 6], [7, 8, 9]]))\n\n    # You shouldn't be allowed to pass a non-writeable array to a mutating Eigen method:\n    zro = zr[0:4, 0:4]\n    zro.flags.writeable = False\n    with pytest.raises(TypeError):\n        m.add_rm(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add_any(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add1(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add2(zro, 0, 0, 0)\n\n    # integer array shouldn't be passable to a double-matrix-accepting mutating func:\n    zi = np.array([[1, 2], [3, 4]])\n    with pytest.raises(TypeError):\n        m.add_rm(zi)\n\n\ndef test_numpy_ref_mutators():\n    \"\"\"Tests numpy mutating Eigen matrices (for returned Eigen::Ref<...>s)\"\"\"\n\n    m.reset_refs()  # In case another test already changed it\n\n    zc = m.get_cm_ref()\n    zcro = m.get_cm_const_ref()\n    zr = m.get_rm_ref()\n    zrro = m.get_rm_const_ref()\n\n    assert [zc[1, 2], zcro[1, 2], zr[1, 2], zrro[1, 2]] == [23] * 4\n\n    assert not zc.flags.owndata and zc.flags.writeable\n    assert not zr.flags.owndata and zr.flags.writeable\n    assert not zcro.flags.owndata and not zcro.flags.writeable\n    assert not zrro.flags.owndata and not zrro.flags.writeable\n\n    zc[1, 2] = 99\n    expect = np.array([[11.0, 12, 13], [21, 22, 99], [31, 32, 33]])\n    # We should have just changed zc, of course, but also zcro and the original eigen matrix\n    assert np.all(zc == expect)\n    assert np.all(zcro == expect)\n    assert np.all(m.get_cm_ref() == expect)\n\n    zr[1, 2] = 99\n    assert np.all(zr == expect)\n    assert np.all(zrro == expect)\n    assert np.all(m.get_rm_ref() == expect)\n\n    # Make sure the readonly ones are numpy-readonly:\n    with pytest.raises(ValueError):\n        zcro[1, 2] = 6\n    with pytest.raises(ValueError):\n        zrro[1, 2] = 6\n\n    # We should be able to explicitly copy like this (and since we're copying,\n    # the const should drop away)\n    y1 = np.array(m.get_cm_const_ref())\n\n    assert y1.flags.owndata and y1.flags.writeable\n    # We should get copies of the eigen data, which was modified above:\n    assert y1[1, 2] == 99\n    y1[1, 2] += 12\n    assert y1[1, 2] == 111\n    assert zc[1, 2] == 99  # Make sure we aren't referencing the original\n\n\ndef test_both_ref_mutators():\n    \"\"\"Tests a complex chain of nested eigen/numpy references\"\"\"\n\n    m.reset_refs()  # In case another test already changed it\n\n    z = m.get_cm_ref()  # numpy -> eigen\n    z[0, 2] -= 3\n    z2 = m.incr_matrix(z, 1)  # numpy -> eigen -> numpy -> eigen\n    z2[1, 1] += 6\n    z3 = m.incr_matrix(z, 2)  # (numpy -> eigen)^3\n    z3[2, 2] += -5\n    z4 = m.incr_matrix(z, 3)  # (numpy -> eigen)^4\n    z4[1, 1] -= 1\n    z5 = m.incr_matrix(z, 4)  # (numpy -> eigen)^5\n    z5[0, 0] = 0\n    assert np.all(z == z2)\n    assert np.all(z == z3)\n    assert np.all(z == z4)\n    assert np.all(z == z5)\n    expect = np.array([[0.0, 22, 20], [31, 37, 33], [41, 42, 38]])\n    assert np.all(z == expect)\n\n    y = np.array(range(100), dtype=\"float64\").reshape(10, 10)\n    y2 = m.incr_matrix_any(y, 10)  # np -> eigen -> np\n    y3 = m.incr_matrix_any(\n        y2[0::2, 0::2], -33\n    )  # np -> eigen -> np slice -> np -> eigen -> np\n    y4 = m.even_rows(y3)  # numpy -> eigen slice -> (... y3)\n    y5 = m.even_cols(y4)  # numpy -> eigen slice -> (... y4)\n    y6 = m.incr_matrix_any(y5, 1000)  # numpy -> eigen -> (... y5)\n\n    # Apply same mutations using just numpy:\n    yexpect = np.array(range(100), dtype=\"float64\").reshape(10, 10)\n    yexpect += 10\n    yexpect[0::2, 0::2] -= 33\n    yexpect[0::4, 0::4] += 1000\n    assert np.all(y6 == yexpect[0::4, 0::4])\n    assert np.all(y5 == yexpect[0::4, 0::4])\n    assert np.all(y4 == yexpect[0::4, 0::2])\n    assert np.all(y3 == yexpect[0::2, 0::2])\n    assert np.all(y2 == yexpect)\n    assert np.all(y == yexpect)\n\n\ndef test_nocopy_wrapper():\n    # get_elem requires a column-contiguous matrix reference, but should be\n    # callable with other types of matrix (via copying):\n    int_matrix_colmajor = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], order=\"F\")\n    dbl_matrix_colmajor = np.array(\n        int_matrix_colmajor, dtype=\"double\", order=\"F\", copy=True\n    )\n    int_matrix_rowmajor = np.array(int_matrix_colmajor, order=\"C\", copy=True)\n    dbl_matrix_rowmajor = np.array(\n        int_matrix_rowmajor, dtype=\"double\", order=\"C\", copy=True\n    )\n\n    # All should be callable via get_elem:\n    assert m.get_elem(int_matrix_colmajor) == 8\n    assert m.get_elem(dbl_matrix_colmajor) == 8\n    assert m.get_elem(int_matrix_rowmajor) == 8\n    assert m.get_elem(dbl_matrix_rowmajor) == 8\n\n    # All but the second should fail with m.get_elem_nocopy:\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(int_matrix_colmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n    assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(int_matrix_rowmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(dbl_matrix_rowmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n\n    # For the row-major test, we take a long matrix in row-major, so only the third is allowed:\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(int_matrix_colmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(dbl_matrix_colmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n    assert m.get_elem_rm_nocopy(int_matrix_rowmajor) == 8\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(dbl_matrix_rowmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n\n\ndef test_eigen_ref_life_support():\n    \"\"\"Ensure the lifetime of temporary arrays created by the `Ref` caster\n\n    The `Ref` caster sometimes creates a copy which needs to stay alive. This needs to\n    happen both for directs casts (just the array) or indirectly (e.g. list of arrays).\n    \"\"\"\n\n    a = np.full(shape=10, fill_value=8, dtype=np.int8)\n    assert m.get_elem_direct(a) == 8\n\n    list_of_a = [a]\n    assert m.get_elem_indirect(list_of_a) == 8\n\n\ndef test_special_matrix_objects():\n    assert np.all(m.incr_diag(7) == np.diag([1.0, 2, 3, 4, 5, 6, 7]))\n\n    asymm = np.array([[1.0, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])\n    symm_lower = np.array(asymm)\n    symm_upper = np.array(asymm)\n    for i in range(4):\n        for j in range(i + 1, 4):\n            symm_lower[i, j] = symm_lower[j, i]\n            symm_upper[j, i] = symm_upper[i, j]\n\n    assert np.all(m.symmetric_lower(asymm) == symm_lower)\n    assert np.all(m.symmetric_upper(asymm) == symm_upper)\n\n\ndef test_dense_signature(doc):\n    assert (\n        doc(m.double_col)\n        == \"\"\"\n        double_col(arg0: numpy.ndarray[numpy.float32[m, 1]]) -> numpy.ndarray[numpy.float32[m, 1]]\n    \"\"\"\n    )\n    assert (\n        doc(m.double_row)\n        == \"\"\"\n        double_row(arg0: numpy.ndarray[numpy.float32[1, n]]) -> numpy.ndarray[numpy.float32[1, n]]\n    \"\"\"\n    )\n    assert doc(m.double_complex) == (\n        \"\"\"\n        double_complex(arg0: numpy.ndarray[numpy.complex64[m, 1]])\"\"\"\n        \"\"\" -> numpy.ndarray[numpy.complex64[m, 1]]\n    \"\"\"\n    )\n    assert doc(m.double_mat_rm) == (\n        \"\"\"\n        double_mat_rm(arg0: numpy.ndarray[numpy.float32[m, n]])\"\"\"\n        \"\"\" -> numpy.ndarray[numpy.float32[m, n]]\n    \"\"\"\n    )\n\n\ndef test_named_arguments():\n    a = np.array([[1.0, 2], [3, 4], [5, 6]])\n    b = np.ones((2, 1))\n\n    assert np.all(m.matrix_multiply(a, b) == np.array([[3.0], [7], [11]]))\n    assert np.all(m.matrix_multiply(A=a, B=b) == np.array([[3.0], [7], [11]]))\n    assert np.all(m.matrix_multiply(B=b, A=a) == np.array([[3.0], [7], [11]]))\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(b, a)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(A=b, B=a)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(B=a, A=b)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n\ndef test_sparse():\n    pytest.importorskip(\"scipy\")\n    assert_sparse_equal_ref(m.sparse_r())\n    assert_sparse_equal_ref(m.sparse_c())\n    assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_r()))\n    assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_c()))\n    assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_c()))\n    assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_r()))\n\n\ndef test_sparse_signature(doc):\n    pytest.importorskip(\"scipy\")\n    assert (\n        doc(m.sparse_copy_r)\n        == \"\"\"\n        sparse_copy_r(arg0: scipy.sparse.csr_matrix[numpy.float32]) -> scipy.sparse.csr_matrix[numpy.float32]\n    \"\"\"\n    )\n    assert (\n        doc(m.sparse_copy_c)\n        == \"\"\"\n        sparse_copy_c(arg0: scipy.sparse.csc_matrix[numpy.float32]) -> scipy.sparse.csc_matrix[numpy.float32]\n    \"\"\"\n    )\n\n\ndef test_issue738():\n    \"\"\"Ignore strides on a length-1 dimension (even if they would be incompatible length > 1)\"\"\"\n    assert np.all(m.iss738_f1(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))\n    assert np.all(\n        m.iss738_f1(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])\n    )\n\n    assert np.all(m.iss738_f2(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))\n    assert np.all(\n        m.iss738_f2(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])\n    )\n\n\n@pytest.mark.parametrize(\"func\", [m.iss738_f1, m.iss738_f2])\n@pytest.mark.parametrize(\"sizes\", [(0, 2), (2, 0)])\ndef test_zero_length(func, sizes):\n    \"\"\"Ignore strides on a length-0 dimension (even if they would be incompatible length > 1)\"\"\"\n    assert np.all(func(np.zeros(sizes)) == np.zeros(sizes))\n\n\ndef test_issue1105():\n    \"\"\"Issue 1105: 1xN or Nx1 input arrays weren't accepted for eigen\n    compile-time row vectors or column vector\"\"\"\n    assert m.iss1105_row(np.ones((1, 7)))\n    assert m.iss1105_col(np.ones((7, 1)))\n\n    # These should still fail (incompatible dimensions):\n    with pytest.raises(TypeError) as excinfo:\n        m.iss1105_row(np.ones((7, 1)))\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.iss1105_col(np.ones((1, 7)))\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_custom_operator_new():\n    \"\"\"Using Eigen types as member variables requires a class-specific\n    operator new with proper alignment\"\"\"\n\n    o = m.CustomOperatorNew()\n    np.testing.assert_allclose(o.a, 0.0)\n    np.testing.assert_allclose(o.b.diagonal(), 1.0)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_tensor.cpp",
    "content": "/*\n    tests/eigen_tensor.cpp -- automatic conversion of Eigen Tensor\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\nconstexpr const char *test_eigen_tensor_module_name = \"eigen_tensor\";\n\n#define PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE eigen_tensor\n\n#ifdef EIGEN_AVOID_STL_ARRAY\n#    undef EIGEN_AVOID_STL_ARRAY\n#endif\n\n#include \"test_eigen_tensor.inl\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_tensor.inl",
    "content": "/*\n    tests/eigen_tensor.cpp -- automatic conversion of Eigen Tensor\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/eigen/tensor.h>\n\n#include \"pybind11_tests.h\"\n\nnamespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE {\n\ntemplate <typename M>\nvoid reset_tensor(M &x) {\n    for (int i = 0; i < x.dimension(0); i++) {\n        for (int j = 0; j < x.dimension(1); j++) {\n            for (int k = 0; k < x.dimension(2); k++) {\n                x(i, j, k) = i * (5 * 2) + j * 2 + k;\n            }\n        }\n    }\n}\n\ntemplate <typename M>\nbool check_tensor(M &x) {\n    for (int i = 0; i < x.dimension(0); i++) {\n        for (int j = 0; j < x.dimension(1); j++) {\n            for (int k = 0; k < x.dimension(2); k++) {\n                if (x(i, j, k) != (i * (5 * 2) + j * 2 + k)) {\n                    return false;\n                }\n            }\n        }\n    }\n    return true;\n}\n\ntemplate <int Options>\nEigen::Tensor<double, 3, Options> &get_tensor() {\n    static Eigen::Tensor<double, 3, Options> *x;\n\n    if (!x) {\n        x = new Eigen::Tensor<double, 3, Options>(3, 5, 2);\n        reset_tensor(*x);\n    }\n\n    return *x;\n}\n\ntemplate <int Options>\nEigen::TensorMap<Eigen::Tensor<double, 3, Options>> &get_tensor_map() {\n    static Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> *x;\n\n    if (!x) {\n        x = new Eigen::TensorMap<Eigen::Tensor<double, 3, Options>>(get_tensor<Options>());\n    }\n\n    return *x;\n}\n\ntemplate <int Options>\nEigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> &get_fixed_tensor() {\n    static Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> *x;\n\n    if (!x) {\n        Eigen::aligned_allocator<Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>\n            allocator;\n        x = new (allocator.allocate(1))\n            Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>();\n        reset_tensor(*x);\n    }\n\n    return *x;\n}\n\ntemplate <int Options>\nconst Eigen::Tensor<double, 3, Options> &get_const_tensor() {\n    return get_tensor<Options>();\n}\n\ntemplate <int Options>\nstruct CustomExample {\n    CustomExample() : member(get_tensor<Options>()), view_member(member) {}\n\n    Eigen::Tensor<double, 3, Options> member;\n    Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> view_member;\n};\n\ntemplate <int Options>\nvoid init_tensor_module(pybind11::module &m) {\n    const char *needed_options = \"\";\n    if (PYBIND11_SILENCE_MSVC_C4127(Options == Eigen::ColMajor)) {\n        needed_options = \"F\";\n    } else {\n        needed_options = \"C\";\n    }\n    m.attr(\"needed_options\") = needed_options;\n\n    m.def(\"setup\", []() {\n        reset_tensor(get_tensor<Options>());\n        reset_tensor(get_fixed_tensor<Options>());\n    });\n\n    m.def(\"is_ok\", []() {\n        return check_tensor(get_tensor<Options>()) && check_tensor(get_fixed_tensor<Options>());\n    });\n\n    py::class_<CustomExample<Options>>(m, \"CustomExample\")\n        .def(py::init<>())\n        .def_readonly(\n            \"member\", &CustomExample<Options>::member, py::return_value_policy::reference_internal)\n        .def_readonly(\"member_view\",\n                      &CustomExample<Options>::view_member,\n                      py::return_value_policy::reference_internal);\n\n    m.def(\n        \"copy_fixed_tensor\",\n        []() { return &get_fixed_tensor<Options>(); },\n        py::return_value_policy::copy);\n\n    m.def(\n        \"copy_tensor\", []() { return &get_tensor<Options>(); }, py::return_value_policy::copy);\n\n    m.def(\n        \"copy_const_tensor\",\n        []() { return &get_const_tensor<Options>(); },\n        py::return_value_policy::copy);\n\n    m.def(\n        \"move_fixed_tensor_copy\",\n        []() -> Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> {\n            return get_fixed_tensor<Options>();\n        },\n        py::return_value_policy::move);\n\n    m.def(\n        \"move_tensor_copy\",\n        []() -> Eigen::Tensor<double, 3, Options> { return get_tensor<Options>(); },\n        py::return_value_policy::move);\n\n    m.def(\n        \"move_const_tensor\",\n        []() -> const Eigen::Tensor<double, 3, Options> & { return get_const_tensor<Options>(); },\n        py::return_value_policy::move);\n\n    m.def(\n        \"take_fixed_tensor\",\n\n        []() {\n            Eigen::aligned_allocator<\n                Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>\n                allocator;\n            return new (allocator.allocate(1))\n                Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>(\n                    get_fixed_tensor<Options>());\n        },\n        py::return_value_policy::take_ownership);\n\n    m.def(\n        \"take_tensor\",\n        []() { return new Eigen::Tensor<double, 3, Options>(get_tensor<Options>()); },\n        py::return_value_policy::take_ownership);\n\n    m.def(\n        \"take_const_tensor\",\n        []() -> const Eigen::Tensor<double, 3, Options> * {\n            return new Eigen::Tensor<double, 3, Options>(get_tensor<Options>());\n        },\n        py::return_value_policy::take_ownership);\n\n    m.def(\n        \"take_view_tensor\",\n        []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {\n            return new Eigen::TensorMap<Eigen::Tensor<double, 3, Options>>(get_tensor<Options>());\n        },\n        py::return_value_policy::take_ownership);\n\n    m.def(\n        \"reference_tensor\",\n        []() { return &get_tensor<Options>(); },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_tensor_v2\",\n        []() -> Eigen::Tensor<double, 3, Options> & { return get_tensor<Options>(); },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_tensor_internal\",\n        []() { return &get_tensor<Options>(); },\n        py::return_value_policy::reference_internal);\n\n    m.def(\n        \"reference_fixed_tensor\",\n        []() { return &get_tensor<Options>(); },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_const_tensor\",\n        []() { return &get_const_tensor<Options>(); },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_const_tensor_v2\",\n        []() -> const Eigen::Tensor<double, 3, Options> & { return get_const_tensor<Options>(); },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor\",\n        []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> {\n            return get_tensor_map<Options>();\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor_v2\",\n        // NOLINTNEXTLINE(readability-const-return-type)\n        []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> {\n            return get_tensor_map<Options>(); // NOLINT(readability-const-return-type)\n        },                                    // NOLINT(readability-const-return-type)\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor_v3\",\n        []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {\n            return &get_tensor_map<Options>();\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor_v4\",\n        []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> * {\n            return &get_tensor_map<Options>();\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor_v5\",\n        []() -> Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> & {\n            return get_tensor_map<Options>();\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_tensor_v6\",\n        []() -> const Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> & {\n            return get_tensor_map<Options>();\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"reference_view_of_fixed_tensor\",\n        []() {\n            return Eigen::TensorMap<\n                Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options>>(\n                get_fixed_tensor<Options>());\n        },\n        py::return_value_policy::reference);\n\n    m.def(\"round_trip_tensor\",\n          [](const Eigen::Tensor<double, 3, Options> &tensor) { return tensor; });\n\n    m.def(\n        \"round_trip_tensor_noconvert\",\n        [](const Eigen::Tensor<double, 3, Options> &tensor) { return tensor; },\n        py::arg(\"tensor\").noconvert());\n\n    m.def(\"round_trip_tensor2\",\n          [](const Eigen::Tensor<int32_t, 3, Options> &tensor) { return tensor; });\n\n    m.def(\"round_trip_fixed_tensor\",\n          [](const Eigen::TensorFixedSize<double, Eigen::Sizes<3, 5, 2>, Options> &tensor) {\n              return tensor;\n          });\n\n    m.def(\n        \"round_trip_view_tensor\",\n        [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> view) { return view; },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"round_trip_view_tensor_ref\",\n        [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> &view) { return view; },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"round_trip_view_tensor_ptr\",\n        [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>> *view) { return view; },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"round_trip_aligned_view_tensor\",\n        [](Eigen::TensorMap<Eigen::Tensor<double, 3, Options>, Eigen::Aligned> view) {\n            return view;\n        },\n        py::return_value_policy::reference);\n\n    m.def(\n        \"round_trip_const_view_tensor\",\n        [](Eigen::TensorMap<const Eigen::Tensor<double, 3, Options>> view) {\n            return Eigen::Tensor<double, 3, Options>(view);\n        },\n        py::return_value_policy::move);\n\n    m.def(\n        \"round_trip_rank_0\",\n        [](const Eigen::Tensor<double, 0, Options> &tensor) { return tensor; },\n        py::return_value_policy::move);\n\n    m.def(\n        \"round_trip_rank_0_noconvert\",\n        [](const Eigen::Tensor<double, 0, Options> &tensor) { return tensor; },\n        py::arg(\"tensor\").noconvert(),\n        py::return_value_policy::move);\n\n    m.def(\n        \"round_trip_rank_0_view\",\n        [](Eigen::TensorMap<Eigen::Tensor<double, 0, Options>> &tensor) { return tensor; },\n        py::return_value_policy::reference);\n}\n\nvoid test_module(py::module_ &);\ntest_initializer name(test_eigen_tensor_module_name, test_module);\nvoid test_module(py::module_ &m) {\n    auto f_style = m.def_submodule(\"f_style\");\n    auto c_style = m.def_submodule(\"c_style\");\n\n    init_tensor_module<Eigen::ColMajor>(f_style);\n    init_tensor_module<Eigen::RowMajor>(c_style);\n}\n\n} // namespace PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_tensor.py",
    "content": "import sys\n\nimport pytest\n\nnp = pytest.importorskip(\"numpy\")\neigen_tensor = pytest.importorskip(\"pybind11_tests.eigen_tensor\")\nsubmodules = [eigen_tensor.c_style, eigen_tensor.f_style]\ntry:\n    from pybind11_tests import eigen_tensor_avoid_stl_array as avoid\n\n    submodules += [avoid.c_style, avoid.f_style]\nexcept ImportError as e:\n    # Ensure config, build, toolchain, etc. issues are not masked here:\n    raise RuntimeError(\n        \"import pybind11_tests.eigen_tensor_avoid_stl_array FAILED, while \"\n        \"import pybind11_tests.eigen_tensor succeeded. \"\n        \"Please ensure that \"\n        \"test_eigen_tensor.cpp & \"\n        \"test_eigen_tensor_avoid_stl_array.cpp \"\n        \"are built together (or both are not built if Eigen is not available).\"\n    ) from e\n\ntensor_ref = np.empty((3, 5, 2), dtype=np.int64)\n\nfor i in range(tensor_ref.shape[0]):\n    for j in range(tensor_ref.shape[1]):\n        for k in range(tensor_ref.shape[2]):\n            tensor_ref[i, j, k] = i * (5 * 2) + j * 2 + k\n\nindices = (2, 3, 1)\n\n\n@pytest.fixture(autouse=True)\ndef cleanup():\n    for module in submodules:\n        module.setup()\n\n    yield\n\n    for module in submodules:\n        assert module.is_ok()\n\n\ndef test_import_avoid_stl_array():\n    pytest.importorskip(\"pybind11_tests.eigen_tensor_avoid_stl_array\")\n    assert len(submodules) == 4\n\n\ndef assert_equal_tensor_ref(mat, writeable=True, modified=None):\n    assert mat.flags.writeable == writeable\n\n    copy = np.array(tensor_ref)\n    if modified is not None:\n        copy[indices] = modified\n\n    np.testing.assert_array_equal(mat, copy)\n\n\n@pytest.mark.parametrize(\"m\", submodules)\n@pytest.mark.parametrize(\"member_name\", [\"member\", \"member_view\"])\ndef test_reference_internal(m, member_name):\n\n    if not hasattr(sys, \"getrefcount\"):\n        pytest.skip(\"No reference counting\")\n    foo = m.CustomExample()\n    counts = sys.getrefcount(foo)\n    mem = getattr(foo, member_name)\n    assert_equal_tensor_ref(mem, writeable=False)\n    new_counts = sys.getrefcount(foo)\n    assert new_counts == counts + 1\n    assert_equal_tensor_ref(mem, writeable=False)\n    del mem\n    assert sys.getrefcount(foo) == counts\n\n\nassert_equal_funcs = [\n    \"copy_tensor\",\n    \"copy_fixed_tensor\",\n    \"copy_const_tensor\",\n    \"move_tensor_copy\",\n    \"move_fixed_tensor_copy\",\n    \"take_tensor\",\n    \"take_fixed_tensor\",\n    \"reference_tensor\",\n    \"reference_tensor_v2\",\n    \"reference_fixed_tensor\",\n    \"reference_view_of_tensor\",\n    \"reference_view_of_tensor_v3\",\n    \"reference_view_of_tensor_v5\",\n    \"reference_view_of_fixed_tensor\",\n]\n\nassert_equal_const_funcs = [\n    \"reference_view_of_tensor_v2\",\n    \"reference_view_of_tensor_v4\",\n    \"reference_view_of_tensor_v6\",\n    \"reference_const_tensor\",\n    \"reference_const_tensor_v2\",\n]\n\n\n@pytest.mark.parametrize(\"m\", submodules)\n@pytest.mark.parametrize(\"func_name\", assert_equal_funcs + assert_equal_const_funcs)\ndef test_convert_tensor_to_py(m, func_name):\n    writeable = func_name in assert_equal_funcs\n    assert_equal_tensor_ref(getattr(m, func_name)(), writeable=writeable)\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_bad_cpp_to_python_casts(m):\n\n    with pytest.raises(\n        RuntimeError, match=\"Cannot use reference internal when there is no parent\"\n    ):\n        m.reference_tensor_internal()\n\n    with pytest.raises(RuntimeError, match=\"Cannot move from a constant reference\"):\n        m.move_const_tensor()\n\n    with pytest.raises(\n        RuntimeError, match=\"Cannot take ownership of a const reference\"\n    ):\n        m.take_const_tensor()\n\n    with pytest.raises(\n        RuntimeError,\n        match=\"Invalid return_value_policy for Eigen Map type, must be either reference or reference_internal\",\n    ):\n        m.take_view_tensor()\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_bad_python_to_cpp_casts(m):\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_tensor\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_tensor(np.zeros((2, 3)))\n\n    with pytest.raises(TypeError, match=r\"^Cannot cast array data from dtype\"):\n        m.round_trip_tensor(np.zeros(dtype=np.str_, shape=(2, 3, 1)))\n\n    with pytest.raises(\n        TypeError,\n        match=r\"^round_trip_tensor_noconvert\\(\\): incompatible function arguments\",\n    ):\n        m.round_trip_tensor_noconvert(tensor_ref)\n\n    assert_equal_tensor_ref(\n        m.round_trip_tensor_noconvert(tensor_ref.astype(np.float64))\n    )\n\n    if m.needed_options == \"F\":\n        bad_options = \"C\"\n    else:\n        bad_options = \"F\"\n    # Shape, dtype and the order need to be correct for a TensorMap cast\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_view_tensor\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_view_tensor(\n            np.zeros((3, 5, 2), dtype=np.float64, order=bad_options)\n        )\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_view_tensor\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_view_tensor(\n            np.zeros((3, 5, 2), dtype=np.float32, order=m.needed_options)\n        )\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_view_tensor\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_view_tensor(\n            np.zeros((3, 5), dtype=np.float64, order=m.needed_options)\n        )\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_view_tensor\\(\\): incompatible function arguments\"\n    ):\n        temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)\n        m.round_trip_view_tensor(\n            temp[:, ::-1, :],\n        )\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_view_tensor\\(\\): incompatible function arguments\"\n    ):\n        temp = np.zeros((3, 5, 2), dtype=np.float64, order=m.needed_options)\n        temp.setflags(write=False)\n        m.round_trip_view_tensor(temp)\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_references_actually_refer(m):\n\n    a = m.reference_tensor()\n    temp = a[indices]\n    a[indices] = 100\n    assert_equal_tensor_ref(m.copy_const_tensor(), modified=100)\n    a[indices] = temp\n    assert_equal_tensor_ref(m.copy_const_tensor())\n\n    a = m.reference_view_of_tensor()\n    a[indices] = 100\n    assert_equal_tensor_ref(m.copy_const_tensor(), modified=100)\n    a[indices] = temp\n    assert_equal_tensor_ref(m.copy_const_tensor())\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_round_trip(m):\n\n    assert_equal_tensor_ref(m.round_trip_tensor(tensor_ref))\n\n    with pytest.raises(TypeError, match=\"^Cannot cast array data from\"):\n        assert_equal_tensor_ref(m.round_trip_tensor2(tensor_ref))\n\n    assert_equal_tensor_ref(m.round_trip_tensor2(np.array(tensor_ref, dtype=np.int32)))\n    assert_equal_tensor_ref(m.round_trip_fixed_tensor(tensor_ref))\n    assert_equal_tensor_ref(m.round_trip_aligned_view_tensor(m.reference_tensor()))\n\n    copy = np.array(tensor_ref, dtype=np.float64, order=m.needed_options)\n    assert_equal_tensor_ref(m.round_trip_view_tensor(copy))\n    assert_equal_tensor_ref(m.round_trip_view_tensor_ref(copy))\n    assert_equal_tensor_ref(m.round_trip_view_tensor_ptr(copy))\n    copy.setflags(write=False)\n    assert_equal_tensor_ref(m.round_trip_const_view_tensor(copy))\n\n    np.testing.assert_array_equal(\n        tensor_ref[:, ::-1, :], m.round_trip_tensor(tensor_ref[:, ::-1, :])\n    )\n\n    assert m.round_trip_rank_0(np.float64(3.5)) == 3.5\n    assert m.round_trip_rank_0(3.5) == 3.5\n\n    with pytest.raises(\n        TypeError,\n        match=r\"^round_trip_rank_0_noconvert\\(\\): incompatible function arguments\",\n    ):\n        m.round_trip_rank_0_noconvert(np.float64(3.5))\n\n    with pytest.raises(\n        TypeError,\n        match=r\"^round_trip_rank_0_noconvert\\(\\): incompatible function arguments\",\n    ):\n        m.round_trip_rank_0_noconvert(3.5)\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_rank_0_view\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_rank_0_view(np.float64(3.5))\n\n    with pytest.raises(\n        TypeError, match=r\"^round_trip_rank_0_view\\(\\): incompatible function arguments\"\n    ):\n        m.round_trip_rank_0_view(3.5)\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_round_trip_references_actually_refer(m):\n\n    # Need to create a copy that matches the type on the C side\n    copy = np.array(tensor_ref, dtype=np.float64, order=m.needed_options)\n    a = m.round_trip_view_tensor(copy)\n    temp = a[indices]\n    a[indices] = 100\n    assert_equal_tensor_ref(copy, modified=100)\n    a[indices] = temp\n    assert_equal_tensor_ref(copy)\n\n\n@pytest.mark.parametrize(\"m\", submodules)\ndef test_doc_string(m, doc):\n    assert (\n        doc(m.copy_tensor) == \"copy_tensor() -> numpy.ndarray[numpy.float64[?, ?, ?]]\"\n    )\n    assert (\n        doc(m.copy_fixed_tensor)\n        == \"copy_fixed_tensor() -> numpy.ndarray[numpy.float64[3, 5, 2]]\"\n    )\n    assert (\n        doc(m.reference_const_tensor)\n        == \"reference_const_tensor() -> numpy.ndarray[numpy.float64[?, ?, ?]]\"\n    )\n\n    order_flag = f\"flags.{m.needed_options.lower()}_contiguous\"\n    assert doc(m.round_trip_view_tensor) == (\n        f\"round_trip_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}])\"\n        + f\" -> numpy.ndarray[numpy.float64[?, ?, ?], flags.writeable, {order_flag}]\"\n    )\n    assert doc(m.round_trip_const_view_tensor) == (\n        f\"round_trip_const_view_tensor(arg0: numpy.ndarray[numpy.float64[?, ?, ?], {order_flag}])\"\n        + \" -> numpy.ndarray[numpy.float64[?, ?, ?]]\"\n    )\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eigen_tensor_avoid_stl_array.cpp",
    "content": "/*\n    tests/eigen_tensor.cpp -- automatic conversion of Eigen Tensor\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\nconstexpr const char *test_eigen_tensor_module_name = \"eigen_tensor_avoid_stl_array\";\n\n#ifndef EIGEN_AVOID_STL_ARRAY\n#    define EIGEN_AVOID_STL_ARRAY\n#endif\n\n#define PYBIND11_TEST_EIGEN_TENSOR_NAMESPACE eigen_tensor_avoid_stl_array\n\n#include \"test_eigen_tensor.inl\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/CMakeLists.txt",
    "content": "possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)\n\nif(\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\")\n  message(STATUS \"Skipping embed test on PyPy\")\n  add_custom_target(cpptest) # Dummy target on PyPy. Embedding is not supported.\n  set(_suppress_unused_variable_warning \"${DOWNLOAD_CATCH}\")\n  return()\nendif()\n\nfind_package(Catch 2.13.9)\n\nif(CATCH_FOUND)\n  message(STATUS \"Building interpreter tests using Catch v${CATCH_VERSION}\")\nelse()\n  message(STATUS \"Catch not detected. Interpreter tests will be skipped. Install Catch headers\"\n                 \" manually or use `cmake -DDOWNLOAD_CATCH=ON` to fetch them automatically.\")\n  return()\nendif()\n\nfind_package(Threads REQUIRED)\n\nadd_executable(test_embed catch.cpp test_interpreter.cpp)\npybind11_enable_warnings(test_embed)\n\ntarget_link_libraries(test_embed PRIVATE pybind11::embed Catch2::Catch2 Threads::Threads)\n\nif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n  file(COPY test_interpreter.py test_trampoline.py DESTINATION \"${CMAKE_CURRENT_BINARY_DIR}\")\nendif()\n\nadd_custom_target(\n  cpptest\n  COMMAND \"$<TARGET_FILE:test_embed>\"\n  DEPENDS test_embed\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n\npybind11_add_module(external_module THIN_LTO external_module.cpp)\nset_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n                                                 \"${CMAKE_CURRENT_BINARY_DIR}\")\nforeach(config ${CMAKE_CONFIGURATION_TYPES})\n  string(TOUPPER ${config} config)\n  set_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config}\n                                                   \"${CMAKE_CURRENT_BINARY_DIR}\")\nendforeach()\nadd_dependencies(cpptest external_module)\n\nadd_dependencies(check cpptest)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/catch.cpp",
    "content": "// The Catch implementation is compiled here. This is a standalone\n// translation unit to avoid recompiling it for every test change.\n\n#include <pybind11/embed.h>\n\n#ifdef _MSC_VER\n// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to\n// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).\n#    pragma warning(disable : 4996)\n#endif\n\n// Catch uses _ internally, which breaks gettext style defines\n#ifdef _\n#    undef _\n#endif\n\n#define CATCH_CONFIG_RUNNER\n#include <catch.hpp>\n\nnamespace py = pybind11;\n\nint main(int argc, char *argv[]) {\n    // Setup for TEST_CASE in test_interpreter.cpp, tagging on a large random number:\n    std::string updated_pythonpath(\"pybind11_test_embed_PYTHONPATH_2099743835476552\");\n    const char *preexisting_pythonpath = getenv(\"PYTHONPATH\");\n    if (preexisting_pythonpath != nullptr) {\n#if defined(_WIN32)\n        updated_pythonpath += ';';\n#else\n        updated_pythonpath += ':';\n#endif\n        updated_pythonpath += preexisting_pythonpath;\n    }\n#if defined(_WIN32)\n    _putenv_s(\"PYTHONPATH\", updated_pythonpath.c_str());\n#else\n    setenv(\"PYTHONPATH\", updated_pythonpath.c_str(), /*replace=*/1);\n#endif\n\n    py::scoped_interpreter guard{};\n\n    auto result = Catch::Session().run(argc, argv);\n\n    return result < 0xff ? result : 0xff;\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/external_module.cpp",
    "content": "#include <pybind11/pybind11.h>\n\nnamespace py = pybind11;\n\n/* Simple test module/test class to check that the referenced internals data of external pybind11\n * modules aren't preserved over a finalize/initialize.\n */\n\nPYBIND11_MODULE(external_module, m) {\n    class A {\n    public:\n        explicit A(int value) : v{value} {};\n        int v;\n    };\n\n    py::class_<A>(m, \"A\").def(py::init<int>()).def_readwrite(\"value\", &A::v);\n\n    m.def(\"internals_at\",\n          []() { return reinterpret_cast<uintptr_t>(&py::detail::get_internals()); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/test_interpreter.cpp",
    "content": "#include <pybind11/embed.h>\n\n#ifdef _MSC_VER\n// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to\n// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).\n#    pragma warning(disable : 4996)\n#endif\n\n#include <catch.hpp>\n#include <cstdlib>\n#include <fstream>\n#include <functional>\n#include <thread>\n#include <utility>\n\nnamespace py = pybind11;\nusing namespace py::literals;\n\nclass Widget {\npublic:\n    explicit Widget(std::string message) : message(std::move(message)) {}\n    virtual ~Widget() = default;\n\n    std::string the_message() const { return message; }\n    virtual int the_answer() const = 0;\n    virtual std::string argv0() const = 0;\n\nprivate:\n    std::string message;\n};\n\nclass PyWidget final : public Widget {\n    using Widget::Widget;\n\n    int the_answer() const override { PYBIND11_OVERRIDE_PURE(int, Widget, the_answer); }\n    std::string argv0() const override { PYBIND11_OVERRIDE_PURE(std::string, Widget, argv0); }\n};\n\nclass test_override_cache_helper {\n\npublic:\n    virtual int func() { return 0; }\n\n    test_override_cache_helper() = default;\n    virtual ~test_override_cache_helper() = default;\n    // Non-copyable\n    test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;\n    test_override_cache_helper(test_override_cache_helper const &Copy) = delete;\n};\n\nclass test_override_cache_helper_trampoline : public test_override_cache_helper {\n    int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }\n};\n\nPYBIND11_EMBEDDED_MODULE(widget_module, m) {\n    py::class_<Widget, PyWidget>(m, \"Widget\")\n        .def(py::init<std::string>())\n        .def_property_readonly(\"the_message\", &Widget::the_message);\n\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n\nPYBIND11_EMBEDDED_MODULE(trampoline_module, m) {\n    py::class_<test_override_cache_helper,\n               test_override_cache_helper_trampoline,\n               std::shared_ptr<test_override_cache_helper>>(m, \"test_override_cache_helper\")\n        .def(py::init_alias<>())\n        .def(\"func\", &test_override_cache_helper::func);\n}\n\nPYBIND11_EMBEDDED_MODULE(throw_exception, ) { throw std::runtime_error(\"C++ Error\"); }\n\nPYBIND11_EMBEDDED_MODULE(throw_error_already_set, ) {\n    auto d = py::dict();\n    d[\"missing\"].cast<py::object>();\n}\n\nTEST_CASE(\"PYTHONPATH is used to update sys.path\") {\n    // The setup for this TEST_CASE is in catch.cpp!\n    auto sys_path = py::str(py::module_::import(\"sys\").attr(\"path\")).cast<std::string>();\n    REQUIRE_THAT(sys_path,\n                 Catch::Matchers::Contains(\"pybind11_test_embed_PYTHONPATH_2099743835476552\"));\n}\n\nTEST_CASE(\"Pass classes and data between modules defined in C++ and Python\") {\n    auto module_ = py::module_::import(\"test_interpreter\");\n    REQUIRE(py::hasattr(module_, \"DerivedWidget\"));\n\n    auto locals = py::dict(\"hello\"_a = \"Hello, World!\", \"x\"_a = 5, **module_.attr(\"__dict__\"));\n    py::exec(R\"(\n        widget = DerivedWidget(\"{} - {}\".format(hello, x))\n        message = widget.the_message\n    )\",\n             py::globals(),\n             locals);\n    REQUIRE(locals[\"message\"].cast<std::string>() == \"Hello, World! - 5\");\n\n    auto py_widget = module_.attr(\"DerivedWidget\")(\"The question\");\n    auto message = py_widget.attr(\"the_message\");\n    REQUIRE(message.cast<std::string>() == \"The question\");\n\n    const auto &cpp_widget = py_widget.cast<const Widget &>();\n    REQUIRE(cpp_widget.the_answer() == 42);\n}\n\nTEST_CASE(\"Override cache\") {\n    auto module_ = py::module_::import(\"test_trampoline\");\n    REQUIRE(py::hasattr(module_, \"func\"));\n    REQUIRE(py::hasattr(module_, \"func2\"));\n\n    auto locals = py::dict(**module_.attr(\"__dict__\"));\n\n    int i = 0;\n    for (; i < 1500; ++i) {\n        std::shared_ptr<test_override_cache_helper> p_obj;\n        std::shared_ptr<test_override_cache_helper> p_obj2;\n\n        py::object loc_inst = locals[\"func\"]();\n        p_obj = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);\n\n        int ret = p_obj->func();\n\n        REQUIRE(ret == 42);\n\n        loc_inst = locals[\"func2\"]();\n\n        p_obj2 = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);\n\n        p_obj2->func();\n    }\n}\n\nTEST_CASE(\"Import error handling\") {\n    REQUIRE_NOTHROW(py::module_::import(\"widget_module\"));\n    REQUIRE_THROWS_WITH(py::module_::import(\"throw_exception\"), \"ImportError: C++ Error\");\n    REQUIRE_THROWS_WITH(py::module_::import(\"throw_error_already_set\"),\n                        Catch::Contains(\"ImportError: initialization failed\"));\n\n    auto locals = py::dict(\"is_keyerror\"_a = false, \"message\"_a = \"not set\");\n    py::exec(R\"(\n        try:\n            import throw_error_already_set\n        except ImportError as e:\n            is_keyerror = type(e.__cause__) == KeyError\n            message = str(e.__cause__)\n    )\",\n             py::globals(),\n             locals);\n    REQUIRE(locals[\"is_keyerror\"].cast<bool>() == true);\n    REQUIRE(locals[\"message\"].cast<std::string>() == \"'missing'\");\n}\n\nTEST_CASE(\"There can be only one interpreter\") {\n    static_assert(std::is_move_constructible<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_move_assignable<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_copy_constructible<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_copy_assignable<py::scoped_interpreter>::value, \"\");\n\n    REQUIRE_THROWS_WITH(py::initialize_interpreter(), \"The interpreter is already running\");\n    REQUIRE_THROWS_WITH(py::scoped_interpreter(), \"The interpreter is already running\");\n\n    py::finalize_interpreter();\n    REQUIRE_NOTHROW(py::scoped_interpreter());\n    {\n        auto pyi1 = py::scoped_interpreter();\n        auto pyi2 = std::move(pyi1);\n    }\n    py::initialize_interpreter();\n}\n\nbool has_pybind11_internals_builtin() {\n    auto builtins = py::handle(PyEval_GetBuiltins());\n    return builtins.contains(PYBIND11_INTERNALS_ID);\n};\n\nbool has_pybind11_internals_static() {\n    auto **&ipp = py::detail::get_internals_pp();\n    return (ipp != nullptr) && (*ipp != nullptr);\n}\n\nTEST_CASE(\"Restart the interpreter\") {\n    // Verify pre-restart state.\n    REQUIRE(py::module_::import(\"widget_module\").attr(\"add\")(1, 2).cast<int>() == 3);\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n    REQUIRE(py::module_::import(\"external_module\").attr(\"A\")(123).attr(\"value\").cast<int>()\n            == 123);\n\n    // local and foreign module internals should point to the same internals:\n    REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())\n            == py::module_::import(\"external_module\").attr(\"internals_at\")().cast<uintptr_t>());\n\n    // Restart the interpreter.\n    py::finalize_interpreter();\n    REQUIRE(Py_IsInitialized() == 0);\n\n    py::initialize_interpreter();\n    REQUIRE(Py_IsInitialized() == 1);\n\n    // Internals are deleted after a restart.\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n    pybind11::detail::get_internals();\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n    REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())\n            == py::module_::import(\"external_module\").attr(\"internals_at\")().cast<uintptr_t>());\n\n    // Make sure that an interpreter with no get_internals() created until finalize still gets the\n    // internals destroyed\n    py::finalize_interpreter();\n    py::initialize_interpreter();\n    bool ran = false;\n    py::module_::import(\"__main__\").attr(\"internals_destroy_test\")\n        = py::capsule(&ran, [](void *ran) {\n              py::detail::get_internals();\n              *static_cast<bool *>(ran) = true;\n          });\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n    REQUIRE_FALSE(ran);\n    py::finalize_interpreter();\n    REQUIRE(ran);\n    py::initialize_interpreter();\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n\n    // C++ modules can be reloaded.\n    auto cpp_module = py::module_::import(\"widget_module\");\n    REQUIRE(cpp_module.attr(\"add\")(1, 2).cast<int>() == 3);\n\n    // C++ type information is reloaded and can be used in python modules.\n    auto py_module = py::module_::import(\"test_interpreter\");\n    auto py_widget = py_module.attr(\"DerivedWidget\")(\"Hello after restart\");\n    REQUIRE(py_widget.attr(\"the_message\").cast<std::string>() == \"Hello after restart\");\n}\n\nTEST_CASE(\"Subinterpreter\") {\n    // Add tags to the modules in the main interpreter and test the basics.\n    py::module_::import(\"__main__\").attr(\"main_tag\") = \"main interpreter\";\n    {\n        auto m = py::module_::import(\"widget_module\");\n        m.attr(\"extension_module_tag\") = \"added to module in main interpreter\";\n\n        REQUIRE(m.attr(\"add\")(1, 2).cast<int>() == 3);\n    }\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n\n    /// Create and switch to a subinterpreter.\n    auto *main_tstate = PyThreadState_Get();\n    auto *sub_tstate = Py_NewInterpreter();\n\n    // Subinterpreters get their own copy of builtins. detail::get_internals() still\n    // works by returning from the static variable, i.e. all interpreters share a single\n    // global pybind11::internals;\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n\n    // Modules tags should be gone.\n    REQUIRE_FALSE(py::hasattr(py::module_::import(\"__main__\"), \"tag\"));\n    {\n        auto m = py::module_::import(\"widget_module\");\n        REQUIRE_FALSE(py::hasattr(m, \"extension_module_tag\"));\n\n        // Function bindings should still work.\n        REQUIRE(m.attr(\"add\")(1, 2).cast<int>() == 3);\n    }\n\n    // Restore main interpreter.\n    Py_EndInterpreter(sub_tstate);\n    PyThreadState_Swap(main_tstate);\n\n    REQUIRE(py::hasattr(py::module_::import(\"__main__\"), \"main_tag\"));\n    REQUIRE(py::hasattr(py::module_::import(\"widget_module\"), \"extension_module_tag\"));\n}\n\nTEST_CASE(\"Execution frame\") {\n    // When the interpreter is embedded, there is no execution frame, but `py::exec`\n    // should still function by using reasonable globals: `__main__.__dict__`.\n    py::exec(\"var = dict(number=42)\");\n    REQUIRE(py::globals()[\"var\"][\"number\"].cast<int>() == 42);\n}\n\nTEST_CASE(\"Threads\") {\n    // Restart interpreter to ensure threads are not initialized\n    py::finalize_interpreter();\n    py::initialize_interpreter();\n    REQUIRE_FALSE(has_pybind11_internals_static());\n\n    constexpr auto num_threads = 10;\n    auto locals = py::dict(\"count\"_a = 0);\n\n    {\n        py::gil_scoped_release gil_release{};\n\n        auto threads = std::vector<std::thread>();\n        for (auto i = 0; i < num_threads; ++i) {\n            threads.emplace_back([&]() {\n                py::gil_scoped_acquire gil{};\n                locals[\"count\"] = locals[\"count\"].cast<int>() + 1;\n            });\n        }\n\n        for (auto &thread : threads) {\n            thread.join();\n        }\n    }\n\n    REQUIRE(locals[\"count\"].cast<int>() == num_threads);\n}\n\n// Scope exit utility https://stackoverflow.com/a/36644501/7255855\nstruct scope_exit {\n    std::function<void()> f_;\n    explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}\n    ~scope_exit() {\n        if (f_) {\n            f_();\n        }\n    }\n};\n\nTEST_CASE(\"Reload module from file\") {\n    // Disable generation of cached bytecode (.pyc files) for this test, otherwise\n    // Python might pick up an old version from the cache instead of the new versions\n    // of the .py files generated below\n    auto sys = py::module_::import(\"sys\");\n    bool dont_write_bytecode = sys.attr(\"dont_write_bytecode\").cast<bool>();\n    sys.attr(\"dont_write_bytecode\") = true;\n    // Reset the value at scope exit\n    scope_exit reset_dont_write_bytecode(\n        [&]() { sys.attr(\"dont_write_bytecode\") = dont_write_bytecode; });\n\n    std::string module_name = \"test_module_reload\";\n    std::string module_file = module_name + \".py\";\n\n    // Create the module .py file\n    std::ofstream test_module(module_file);\n    test_module << \"def test():\\n\";\n    test_module << \"    return 1\\n\";\n    test_module.close();\n    // Delete the file at scope exit\n    scope_exit delete_module_file([&]() { std::remove(module_file.c_str()); });\n\n    // Import the module from file\n    auto module_ = py::module_::import(module_name.c_str());\n    int result = module_.attr(\"test\")().cast<int>();\n    REQUIRE(result == 1);\n\n    // Update the module .py file with a small change\n    test_module.open(module_file);\n    test_module << \"def test():\\n\";\n    test_module << \"    return 2\\n\";\n    test_module.close();\n\n    // Reload the module\n    module_.reload();\n    result = module_.attr(\"test\")().cast<int>();\n    REQUIRE(result == 2);\n}\n\nTEST_CASE(\"sys.argv gets initialized properly\") {\n    py::finalize_interpreter();\n    {\n        py::scoped_interpreter default_scope;\n        auto module = py::module::import(\"test_interpreter\");\n        auto py_widget = module.attr(\"DerivedWidget\")(\"The question\");\n        const auto &cpp_widget = py_widget.cast<const Widget &>();\n        REQUIRE(cpp_widget.argv0().empty());\n    }\n\n    {\n        char *argv[] = {strdup(\"a.out\")};\n        py::scoped_interpreter argv_scope(true, 1, argv);\n        std::free(argv[0]);\n        auto module = py::module::import(\"test_interpreter\");\n        auto py_widget = module.attr(\"DerivedWidget\")(\"The question\");\n        const auto &cpp_widget = py_widget.cast<const Widget &>();\n        REQUIRE(cpp_widget.argv0() == \"a.out\");\n    }\n    py::initialize_interpreter();\n}\n\nTEST_CASE(\"make_iterator can be called before then after finalizing an interpreter\") {\n    // Reproduction of issue #2101 (https://github.com/pybind/pybind11/issues/2101)\n    py::finalize_interpreter();\n\n    std::vector<int> container;\n    {\n        pybind11::scoped_interpreter g;\n        auto iter = pybind11::make_iterator(container.begin(), container.end());\n    }\n\n    REQUIRE_NOTHROW([&]() {\n        pybind11::scoped_interpreter g;\n        auto iter = pybind11::make_iterator(container.begin(), container.end());\n    }());\n\n    py::initialize_interpreter();\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/test_interpreter.py",
    "content": "import sys\n\nfrom widget_module import Widget\n\n\nclass DerivedWidget(Widget):\n    def __init__(self, message):\n        super().__init__(message)\n\n    def the_answer(self):\n        return 42\n\n    def argv0(self):\n        return sys.argv[0]\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_embed/test_trampoline.py",
    "content": "import trampoline_module\n\n\ndef func():\n    class Test(trampoline_module.test_override_cache_helper):\n        def func(self):\n            return 42\n\n    return Test()\n\n\ndef func2():\n    class Test(trampoline_module.test_override_cache_helper):\n        pass\n\n    return Test()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_enum.cpp",
    "content": "/*\n    tests/test_enums.cpp -- enumerations\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(enums, m) {\n    // test_unscoped_enum\n    enum UnscopedEnum { EOne = 1, ETwo, EThree };\n    py::enum_<UnscopedEnum>(m, \"UnscopedEnum\", py::arithmetic(), \"An unscoped enumeration\")\n        .value(\"EOne\", EOne, \"Docstring for EOne\")\n        .value(\"ETwo\", ETwo, \"Docstring for ETwo\")\n        .value(\"EThree\", EThree, \"Docstring for EThree\")\n        .export_values();\n\n    // test_scoped_enum\n    enum class ScopedEnum { Two = 2, Three };\n    py::enum_<ScopedEnum>(m, \"ScopedEnum\", py::arithmetic())\n        .value(\"Two\", ScopedEnum::Two)\n        .value(\"Three\", ScopedEnum::Three);\n\n    m.def(\"test_scoped_enum\", [](ScopedEnum z) {\n        return \"ScopedEnum::\" + std::string(z == ScopedEnum::Two ? \"Two\" : \"Three\");\n    });\n\n    // test_binary_operators\n    enum Flags { Read = 4, Write = 2, Execute = 1 };\n    py::enum_<Flags>(m, \"Flags\", py::arithmetic())\n        .value(\"Read\", Flags::Read)\n        .value(\"Write\", Flags::Write)\n        .value(\"Execute\", Flags::Execute)\n        .export_values();\n\n    // test_implicit_conversion\n    class ClassWithUnscopedEnum {\n    public:\n        enum EMode { EFirstMode = 1, ESecondMode };\n\n        static EMode test_function(EMode mode) { return mode; }\n    };\n    py::class_<ClassWithUnscopedEnum> exenum_class(m, \"ClassWithUnscopedEnum\");\n    exenum_class.def_static(\"test_function\", &ClassWithUnscopedEnum::test_function);\n    py::enum_<ClassWithUnscopedEnum::EMode>(exenum_class, \"EMode\")\n        .value(\"EFirstMode\", ClassWithUnscopedEnum::EFirstMode)\n        .value(\"ESecondMode\", ClassWithUnscopedEnum::ESecondMode)\n        .export_values();\n\n    // test_enum_to_int\n    m.def(\"test_enum_to_int\", [](int) {});\n    m.def(\"test_enum_to_uint\", [](uint32_t) {});\n    m.def(\"test_enum_to_long_long\", [](long long) {});\n\n    // test_duplicate_enum_name\n    enum SimpleEnum { ONE, TWO, THREE };\n\n    m.def(\"register_bad_enum\", [m]() {\n        py::enum_<SimpleEnum>(m, \"SimpleEnum\")\n            .value(\"ONE\", SimpleEnum::ONE) // NOTE: all value function calls are called with the\n                                           // same first parameter value\n            .value(\"ONE\", SimpleEnum::TWO)\n            .value(\"ONE\", SimpleEnum::THREE)\n            .export_values();\n    });\n\n    // test_enum_scalar\n    enum UnscopedUCharEnum : unsigned char {};\n    enum class ScopedShortEnum : short {};\n    enum class ScopedLongEnum : long {};\n    enum UnscopedUInt64Enum : std::uint64_t {};\n    static_assert(\n        py::detail::all_of<\n            std::is_same<py::enum_<UnscopedUCharEnum>::Scalar, unsigned char>,\n            std::is_same<py::enum_<ScopedShortEnum>::Scalar, short>,\n            std::is_same<py::enum_<ScopedLongEnum>::Scalar, long>,\n            std::is_same<py::enum_<UnscopedUInt64Enum>::Scalar, std::uint64_t>>::value,\n        \"Error during the deduction of enum's scalar type with normal integer underlying\");\n\n    // test_enum_scalar_with_char_underlying\n    enum class ScopedCharEnum : char { Zero, Positive };\n    enum class ScopedWCharEnum : wchar_t { Zero, Positive };\n    enum class ScopedChar32Enum : char32_t { Zero, Positive };\n    enum class ScopedChar16Enum : char16_t { Zero, Positive };\n\n    // test the scalar of char type enums according to chapter 'Character types'\n    // from https://en.cppreference.com/w/cpp/language/types\n    static_assert(\n        py::detail::any_of<\n            std::is_same<py::enum_<ScopedCharEnum>::Scalar, signed char>,  // e.g. gcc on x86\n            std::is_same<py::enum_<ScopedCharEnum>::Scalar, unsigned char> // e.g. arm linux\n            >::value,\n        \"char should be cast to either signed char or unsigned char\");\n    static_assert(sizeof(py::enum_<ScopedWCharEnum>::Scalar) == 2\n                      || sizeof(py::enum_<ScopedWCharEnum>::Scalar) == 4,\n                  \"wchar_t should be either 16 bits (Windows) or 32 (everywhere else)\");\n    static_assert(\n        py::detail::all_of<\n            std::is_same<py::enum_<ScopedChar32Enum>::Scalar, std::uint_least32_t>,\n            std::is_same<py::enum_<ScopedChar16Enum>::Scalar, std::uint_least16_t>>::value,\n        \"char32_t, char16_t (and char8_t)'s size, signedness, and alignment is determined\");\n#if defined(PYBIND11_HAS_U8STRING)\n    enum class ScopedChar8Enum : char8_t { Zero, Positive };\n    static_assert(std::is_same<py::enum_<ScopedChar8Enum>::Scalar, unsigned char>::value);\n#endif\n\n    // test_char_underlying_enum\n    py::enum_<ScopedCharEnum>(m, \"ScopedCharEnum\")\n        .value(\"Zero\", ScopedCharEnum::Zero)\n        .value(\"Positive\", ScopedCharEnum::Positive);\n    py::enum_<ScopedWCharEnum>(m, \"ScopedWCharEnum\")\n        .value(\"Zero\", ScopedWCharEnum::Zero)\n        .value(\"Positive\", ScopedWCharEnum::Positive);\n    py::enum_<ScopedChar32Enum>(m, \"ScopedChar32Enum\")\n        .value(\"Zero\", ScopedChar32Enum::Zero)\n        .value(\"Positive\", ScopedChar32Enum::Positive);\n    py::enum_<ScopedChar16Enum>(m, \"ScopedChar16Enum\")\n        .value(\"Zero\", ScopedChar16Enum::Zero)\n        .value(\"Positive\", ScopedChar16Enum::Positive);\n\n    // test_bool_underlying_enum\n    enum class ScopedBoolEnum : bool { FALSE, TRUE };\n\n    // bool is unsigned (std::is_signed returns false) and 1-byte long, so represented with u8\n    static_assert(std::is_same<py::enum_<ScopedBoolEnum>::Scalar, std::uint8_t>::value, \"\");\n\n    py::enum_<ScopedBoolEnum>(m, \"ScopedBoolEnum\")\n        .value(\"FALSE\", ScopedBoolEnum::FALSE)\n        .value(\"TRUE\", ScopedBoolEnum::TRUE);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_enum.py",
    "content": "import pytest\n\nfrom pybind11_tests import enums as m\n\n\ndef test_unscoped_enum():\n    assert str(m.UnscopedEnum.EOne) == \"UnscopedEnum.EOne\"\n    assert str(m.UnscopedEnum.ETwo) == \"UnscopedEnum.ETwo\"\n    assert str(m.EOne) == \"UnscopedEnum.EOne\"\n    assert repr(m.UnscopedEnum.EOne) == \"<UnscopedEnum.EOne: 1>\"\n    assert repr(m.UnscopedEnum.ETwo) == \"<UnscopedEnum.ETwo: 2>\"\n    assert repr(m.EOne) == \"<UnscopedEnum.EOne: 1>\"\n\n    # name property\n    assert m.UnscopedEnum.EOne.name == \"EOne\"\n    assert m.UnscopedEnum.EOne.value == 1\n    assert m.UnscopedEnum.ETwo.name == \"ETwo\"\n    assert m.UnscopedEnum.ETwo.value == 2\n    assert m.EOne is m.UnscopedEnum.EOne\n    # name, value readonly\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.EOne.name = \"\"\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.EOne.value = 10\n    # name, value returns a copy\n    # TODO: Neither the name nor value tests actually check against aliasing.\n    # Use a mutable type that has reference semantics.\n    nonaliased_name = m.UnscopedEnum.EOne.name\n    nonaliased_name = \"bar\"  # noqa: F841\n    assert m.UnscopedEnum.EOne.name == \"EOne\"\n    nonaliased_value = m.UnscopedEnum.EOne.value\n    nonaliased_value = 10  # noqa: F841\n    assert m.UnscopedEnum.EOne.value == 1\n\n    # __members__ property\n    assert m.UnscopedEnum.__members__ == {\n        \"EOne\": m.UnscopedEnum.EOne,\n        \"ETwo\": m.UnscopedEnum.ETwo,\n        \"EThree\": m.UnscopedEnum.EThree,\n    }\n    # __members__ readonly\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.__members__ = {}\n    # __members__ returns a copy\n    nonaliased_members = m.UnscopedEnum.__members__\n    nonaliased_members[\"bar\"] = \"baz\"\n    assert m.UnscopedEnum.__members__ == {\n        \"EOne\": m.UnscopedEnum.EOne,\n        \"ETwo\": m.UnscopedEnum.ETwo,\n        \"EThree\": m.UnscopedEnum.EThree,\n    }\n\n    for docstring_line in \"\"\"An unscoped enumeration\n\nMembers:\n\n  EOne : Docstring for EOne\n\n  ETwo : Docstring for ETwo\n\n  EThree : Docstring for EThree\"\"\".split(\n        \"\\n\"\n    ):\n        assert docstring_line in m.UnscopedEnum.__doc__\n\n    # Unscoped enums will accept ==/!= int comparisons\n    y = m.UnscopedEnum.ETwo\n    assert y == 2\n    assert 2 == y\n    assert y != 3\n    assert 3 != y\n    # Compare with None\n    assert y != None  # noqa: E711\n    assert not (y == None)  # noqa: E711\n    # Compare with an object\n    assert y != object()\n    assert not (y == object())\n    # Compare with string\n    assert y != \"2\"\n    assert \"2\" != y\n    assert not (\"2\" == y)\n    assert not (y == \"2\")\n\n    with pytest.raises(TypeError):\n        y < object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y <= object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y > object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y >= object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y | object()\n\n    with pytest.raises(TypeError):\n        y & object()\n\n    with pytest.raises(TypeError):\n        y ^ object()\n\n    assert int(m.UnscopedEnum.ETwo) == 2\n    assert str(m.UnscopedEnum(2)) == \"UnscopedEnum.ETwo\"\n\n    # order\n    assert m.UnscopedEnum.EOne < m.UnscopedEnum.ETwo\n    assert m.UnscopedEnum.EOne < 2\n    assert m.UnscopedEnum.ETwo > m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.ETwo > 1\n    assert m.UnscopedEnum.ETwo <= 2\n    assert m.UnscopedEnum.ETwo >= 2\n    assert m.UnscopedEnum.EOne <= m.UnscopedEnum.ETwo\n    assert m.UnscopedEnum.EOne <= 2\n    assert m.UnscopedEnum.ETwo >= m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.ETwo >= 1\n    assert not (m.UnscopedEnum.ETwo < m.UnscopedEnum.EOne)\n    assert not (2 < m.UnscopedEnum.EOne)\n\n    # arithmetic\n    assert m.UnscopedEnum.EOne & m.UnscopedEnum.EThree == m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.EOne | m.UnscopedEnum.ETwo == m.UnscopedEnum.EThree\n    assert m.UnscopedEnum.EOne ^ m.UnscopedEnum.EThree == m.UnscopedEnum.ETwo\n\n\ndef test_scoped_enum():\n    assert m.test_scoped_enum(m.ScopedEnum.Three) == \"ScopedEnum::Three\"\n    z = m.ScopedEnum.Two\n    assert m.test_scoped_enum(z) == \"ScopedEnum::Two\"\n\n    # Scoped enums will *NOT* accept ==/!= int comparisons (Will always return False)\n    assert not z == 3\n    assert not 3 == z\n    assert z != 3\n    assert 3 != z\n    # Compare with None\n    assert z != None  # noqa: E711\n    assert not (z == None)  # noqa: E711\n    # Compare with an object\n    assert z != object()\n    assert not (z == object())\n    # Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)\n    with pytest.raises(TypeError):\n        z > 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z < 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z >= 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z <= 3  # noqa: B015\n\n    # order\n    assert m.ScopedEnum.Two < m.ScopedEnum.Three\n    assert m.ScopedEnum.Three > m.ScopedEnum.Two\n    assert m.ScopedEnum.Two <= m.ScopedEnum.Three\n    assert m.ScopedEnum.Two <= m.ScopedEnum.Two\n    assert m.ScopedEnum.Two >= m.ScopedEnum.Two\n    assert m.ScopedEnum.Three >= m.ScopedEnum.Two\n\n\ndef test_implicit_conversion():\n    assert str(m.ClassWithUnscopedEnum.EMode.EFirstMode) == \"EMode.EFirstMode\"\n    assert str(m.ClassWithUnscopedEnum.EFirstMode) == \"EMode.EFirstMode\"\n    assert repr(m.ClassWithUnscopedEnum.EMode.EFirstMode) == \"<EMode.EFirstMode: 1>\"\n    assert repr(m.ClassWithUnscopedEnum.EFirstMode) == \"<EMode.EFirstMode: 1>\"\n\n    f = m.ClassWithUnscopedEnum.test_function\n    first = m.ClassWithUnscopedEnum.EFirstMode\n    second = m.ClassWithUnscopedEnum.ESecondMode\n\n    assert f(first) == 1\n\n    assert f(first) == f(first)\n    assert not f(first) != f(first)\n\n    assert f(first) != f(second)\n    assert not f(first) == f(second)\n\n    assert f(first) == int(f(first))\n    assert not f(first) != int(f(first))\n\n    assert f(first) != int(f(second))\n    assert not f(first) == int(f(second))\n\n    # noinspection PyDictCreation\n    x = {f(first): 1, f(second): 2}\n    x[f(first)] = 3\n    x[f(second)] = 4\n    # Hashing test\n    assert repr(x) == \"{<EMode.EFirstMode: 1>: 3, <EMode.ESecondMode: 2>: 4}\"\n\n\ndef test_binary_operators():\n    assert int(m.Flags.Read) == 4\n    assert int(m.Flags.Write) == 2\n    assert int(m.Flags.Execute) == 1\n    assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7\n    assert int(m.Flags.Read | m.Flags.Write) == 6\n    assert int(m.Flags.Read | m.Flags.Execute) == 5\n    assert int(m.Flags.Write | m.Flags.Execute) == 3\n    assert int(m.Flags.Write | 1) == 3\n    assert ~m.Flags.Write == -3\n\n    state = m.Flags.Read | m.Flags.Write\n    assert (state & m.Flags.Read) != 0\n    assert (state & m.Flags.Write) != 0\n    assert (state & m.Flags.Execute) == 0\n    assert (state & 1) == 0\n\n    state2 = ~state\n    assert state2 == -7\n    assert int(state ^ state2) == -1\n\n\ndef test_enum_to_int():\n    m.test_enum_to_int(m.Flags.Read)\n    m.test_enum_to_int(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_int(m.ScopedCharEnum.Positive)\n    m.test_enum_to_int(m.ScopedBoolEnum.TRUE)\n    m.test_enum_to_uint(m.Flags.Read)\n    m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_uint(m.ScopedCharEnum.Positive)\n    m.test_enum_to_uint(m.ScopedBoolEnum.TRUE)\n    m.test_enum_to_long_long(m.Flags.Read)\n    m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_long_long(m.ScopedCharEnum.Positive)\n    m.test_enum_to_long_long(m.ScopedBoolEnum.TRUE)\n\n\ndef test_duplicate_enum_name():\n    with pytest.raises(ValueError) as excinfo:\n        m.register_bad_enum()\n    assert str(excinfo.value) == 'SimpleEnum: element \"ONE\" already exists!'\n\n\ndef test_char_underlying_enum():  # Issue #1331/PR #1334:\n    assert type(m.ScopedCharEnum.Positive.__int__()) is int\n    assert int(m.ScopedChar16Enum.Zero) == 0\n    assert hash(m.ScopedChar32Enum.Positive) == 1\n    assert type(m.ScopedCharEnum.Positive.__getstate__()) is int\n    assert m.ScopedWCharEnum(1) == m.ScopedWCharEnum.Positive\n    with pytest.raises(TypeError):\n        # Even if the underlying type is char, only an int can be used to construct the enum:\n        m.ScopedCharEnum(\"0\")\n\n\ndef test_bool_underlying_enum():\n    assert type(m.ScopedBoolEnum.TRUE.__int__()) is int\n    assert int(m.ScopedBoolEnum.FALSE) == 0\n    assert hash(m.ScopedBoolEnum.TRUE) == 1\n    assert type(m.ScopedBoolEnum.TRUE.__getstate__()) is int\n    assert m.ScopedBoolEnum(1) == m.ScopedBoolEnum.TRUE\n    # Enum could construct with a bool\n    # (bool is a strict subclass of int, and False will be converted to 0)\n    assert m.ScopedBoolEnum(False) == m.ScopedBoolEnum.FALSE\n\n\ndef test_docstring_signatures():\n    for enum_type in [m.ScopedEnum, m.UnscopedEnum]:\n        for attr in enum_type.__dict__.values():\n            # Issue #2623/PR #2637: Add argument names to enum_ methods\n            assert \"arg0\" not in (attr.__doc__ or \"\")\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eval.cpp",
    "content": "/*\n    tests/test_eval.cpp -- Usage of eval() and eval_file()\n\n    Copyright (c) 2016 Klemens D. Morgenstern\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/eval.h>\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nTEST_SUBMODULE(eval_, m) {\n    // test_evals\n\n    auto global = py::dict(py::module_::import(\"__main__\").attr(\"__dict__\"));\n\n    m.def(\"test_eval_statements\", [global]() {\n        auto local = py::dict();\n        local[\"call_test\"] = py::cpp_function([&]() -> int { return 42; });\n\n        // Regular string literal\n        py::exec(\"message = 'Hello World!'\\n\"\n                 \"x = call_test()\",\n                 global,\n                 local);\n\n        // Multi-line raw string literal\n        py::exec(R\"(\n            if x == 42:\n                print(message)\n            else:\n                raise RuntimeError\n            )\",\n                 global,\n                 local);\n        auto x = local[\"x\"].cast<int>();\n\n        return x == 42;\n    });\n\n    m.def(\"test_eval\", [global]() {\n        auto local = py::dict();\n        local[\"x\"] = py::int_(42);\n        auto x = py::eval(\"x\", global, local);\n        return x.cast<int>() == 42;\n    });\n\n    m.def(\"test_eval_single_statement\", []() {\n        auto local = py::dict();\n        local[\"call_test\"] = py::cpp_function([&]() -> int { return 42; });\n\n        auto result = py::eval<py::eval_single_statement>(\"x = call_test()\", py::dict(), local);\n        auto x = local[\"x\"].cast<int>();\n        return result.is_none() && x == 42;\n    });\n\n    m.def(\"test_eval_file\", [global](py::str filename) {\n        auto local = py::dict();\n        local[\"y\"] = py::int_(43);\n\n        int val_out = 0;\n        local[\"call_test2\"] = py::cpp_function([&](int value) { val_out = value; });\n\n        auto result = py::eval_file(std::move(filename), global, local);\n        return val_out == 43 && result.is_none();\n    });\n\n    m.def(\"test_eval_failure\", []() {\n        try {\n            py::eval(\"nonsense code ...\");\n        } catch (py::error_already_set &) {\n            return true;\n        }\n        return false;\n    });\n\n    m.def(\"test_eval_file_failure\", []() {\n        try {\n            py::eval_file(\"non-existing file\");\n        } catch (std::exception &) {\n            return true;\n        }\n        return false;\n    });\n\n    // test_eval_empty_globals\n    m.def(\"eval_empty_globals\", [](py::object global) {\n        if (global.is_none()) {\n            global = py::dict();\n        }\n        auto int_class = py::eval(\"isinstance(42, int)\", global);\n        return global;\n    });\n\n    // test_eval_closure\n    m.def(\"test_eval_closure\", []() {\n        py::dict global;\n        global[\"closure_value\"] = 42;\n        py::dict local;\n        local[\"closure_value\"] = 0;\n        py::exec(R\"(\n            local_value = closure_value\n\n            def func_global():\n                return closure_value\n\n            def func_local():\n                return local_value\n            )\",\n                 global,\n                 local);\n        return std::make_pair(global, local);\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eval.py",
    "content": "import os\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import eval_ as m\n\n\ndef test_evals(capture):\n    with capture:\n        assert m.test_eval_statements()\n    assert capture == \"Hello World!\"\n\n    assert m.test_eval()\n    assert m.test_eval_single_statement()\n\n    assert m.test_eval_failure()\n\n\n@pytest.mark.xfail(\"env.PYPY\", raises=RuntimeError)\ndef test_eval_file():\n    filename = os.path.join(os.path.dirname(__file__), \"test_eval_call.py\")\n    assert m.test_eval_file(filename)\n\n    assert m.test_eval_file_failure()\n\n\ndef test_eval_empty_globals():\n    assert \"__builtins__\" in m.eval_empty_globals(None)\n\n    g = {}\n    assert \"__builtins__\" in m.eval_empty_globals(g)\n    assert \"__builtins__\" in g\n\n\ndef test_eval_closure():\n    global_, local = m.test_eval_closure()\n\n    assert global_[\"closure_value\"] == 42\n    assert local[\"closure_value\"] == 0\n\n    assert \"local_value\" not in global_\n    assert local[\"local_value\"] == 0\n\n    assert \"func_global\" not in global_\n    assert local[\"func_global\"]() == 42\n\n    assert \"func_local\" not in global_\n    with pytest.raises(NameError):\n        local[\"func_local\"]()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_eval_call.py",
    "content": "# This file is called from 'test_eval.py'\n\nif \"call_test2\" in locals():\n    call_test2(y)  # noqa: F821 undefined name\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_exceptions.cpp",
    "content": "/*\n    tests/test_custom-exceptions.cpp -- exception translation\n\n    Copyright (c) 2016 Pim Schellart <P.Schellart@princeton.edu>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n#include \"test_exceptions.h\"\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <exception>\n#include <stdexcept>\n#include <utility>\n\n// A type that should be raised as an exception in Python\nclass MyException : public std::exception {\npublic:\n    explicit MyException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// A type that should be translated to a standard Python exception\nclass MyException2 : public std::exception {\npublic:\n    explicit MyException2(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// A type that is not derived from std::exception (and is thus unknown)\nclass MyException3 {\npublic:\n    explicit MyException3(const char *m) : message{m} {}\n    virtual const char *what() const noexcept { return message.c_str(); }\n    // Rule of 5 BEGIN: to preempt compiler warnings.\n    MyException3(const MyException3 &) = default;\n    MyException3(MyException3 &&) = default;\n    MyException3 &operator=(const MyException3 &) = default;\n    MyException3 &operator=(MyException3 &&) = default;\n    virtual ~MyException3() = default;\n    // Rule of 5 END.\nprivate:\n    std::string message = \"\";\n};\n\n// A type that should be translated to MyException\n// and delegated to its exception translator\nclass MyException4 : public std::exception {\npublic:\n    explicit MyException4(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// Like the above, but declared via the helper function\nclass MyException5 : public std::logic_error {\npublic:\n    explicit MyException5(const std::string &what) : std::logic_error(what) {}\n};\n\n// Inherits from MyException5\nclass MyException5_1 : public MyException5 {\n    using MyException5::MyException5;\n};\n\n// Exception that will be caught via the module local translator.\nclass MyException6 : public std::exception {\npublic:\n    explicit MyException6(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\nstruct PythonCallInDestructor {\n    explicit PythonCallInDestructor(const py::dict &d) : d(d) {}\n    ~PythonCallInDestructor() { d[\"good\"] = true; }\n\n    py::dict d;\n};\n\nstruct PythonAlreadySetInDestructor {\n    explicit PythonAlreadySetInDestructor(const py::str &s) : s(s) {}\n    ~PythonAlreadySetInDestructor() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            ex.discard_as_unraisable(s);\n        }\n    }\n\n    py::str s;\n};\n\nTEST_SUBMODULE(exceptions, m) {\n    m.def(\"throw_std_exception\",\n          []() { throw std::runtime_error(\"This exception was intentionally thrown.\"); });\n\n    // make a new custom exception and use it as a translation target\n    static py::exception<MyException> ex(m, \"MyException\");\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException &e) {\n            // Set MyException as the active python error\n            ex(e.what());\n        }\n    });\n\n    // register new translator for MyException2\n    // no need to store anything here because this type will\n    // never by visible from Python\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException2 &e) {\n            // Translate this exception to a standard RuntimeError\n            PyErr_SetString(PyExc_RuntimeError, e.what());\n        }\n    });\n\n    // register new translator for MyException4\n    // which will catch it and delegate to the previously registered\n    // translator for MyException by throwing a new exception\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException4 &e) {\n            throw MyException(e.what());\n        }\n    });\n\n    // A simple exception translation:\n    auto ex5 = py::register_exception<MyException5>(m, \"MyException5\");\n    // A slightly more complicated one that declares MyException5_1 as a subclass of MyException5\n    py::register_exception<MyException5_1>(m, \"MyException5_1\", ex5.ptr());\n\n    // py::register_local_exception<LocalSimpleException>(m, \"LocalSimpleException\")\n\n    py::register_local_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException6 &e) {\n            PyErr_SetString(PyExc_RuntimeError, e.what());\n        }\n    });\n\n    m.def(\"throws1\", []() { throw MyException(\"this error should go to a custom type\"); });\n    m.def(\"throws2\",\n          []() { throw MyException2(\"this error should go to a standard Python exception\"); });\n    m.def(\"throws3\", []() { throw MyException3(\"this error cannot be translated\"); });\n    m.def(\"throws4\", []() { throw MyException4(\"this error is rethrown\"); });\n    m.def(\"throws5\",\n          []() { throw MyException5(\"this is a helper-defined translated exception\"); });\n    m.def(\"throws5_1\", []() { throw MyException5_1(\"MyException5 subclass\"); });\n    m.def(\"throws6\", []() { throw MyException6(\"MyException6 only handled in this module\"); });\n    m.def(\"throws_logic_error\", []() {\n        throw std::logic_error(\"this error should fall through to the standard handler\");\n    });\n    m.def(\"throws_overflow_error\", []() { throw std::overflow_error(\"\"); });\n    m.def(\"throws_local_error\", []() { throw LocalException(\"never caught\"); });\n    m.def(\"throws_local_simple_error\", []() { throw LocalSimpleException(\"this mod\"); });\n    m.def(\"exception_matches\", []() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_KeyError)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n    m.def(\"exception_matches_base\", []() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_Exception)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n    m.def(\"modulenotfound_exception_matches_base\", []() {\n        try {\n            // On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError\n            py::module_::import(\"nonexistent\");\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_ImportError)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n\n    m.def(\"throw_already_set\", [](bool err) {\n        if (err) {\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n        }\n        try {\n            throw py::error_already_set();\n        } catch (const std::runtime_error &e) {\n            if ((err && e.what() != std::string(\"ValueError: foo\"))\n                || (!err\n                    && e.what()\n                           != std::string(\"Internal error: pybind11::error_already_set called \"\n                                          \"while Python error indicator not set.\"))) {\n                PyErr_Clear();\n                throw std::runtime_error(\"error message mismatch\");\n            }\n        }\n        PyErr_Clear();\n        if (err) {\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n        }\n        throw py::error_already_set();\n    });\n\n    m.def(\"python_call_in_destructor\", [](const py::dict &d) {\n        bool retval = false;\n        try {\n            PythonCallInDestructor set_dict_in_destructor(d);\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n            throw py::error_already_set();\n        } catch (const py::error_already_set &) {\n            retval = true;\n        }\n        return retval;\n    });\n\n    m.def(\"python_alreadyset_in_destructor\", [](const py::str &s) {\n        PythonAlreadySetInDestructor alreadyset_in_destructor(s);\n        return true;\n    });\n\n    // test_nested_throws\n    m.def(\"try_catch\",\n          [m](const py::object &exc_type, const py::function &f, const py::args &args) {\n              try {\n                  f(*args);\n              } catch (py::error_already_set &ex) {\n                  if (ex.matches(exc_type)) {\n                      py::print(ex.what());\n                  } else {\n                      // Simply `throw;` also works and is better, but using `throw ex;`\n                      // here to cover that situation (as observed in the wild).\n                      throw ex; // Invokes the copy ctor.\n                  }\n              }\n          });\n\n    // Test repr that cannot be displayed\n    m.def(\"simple_bool_passthrough\", [](bool x) { return x; });\n\n    m.def(\"throw_should_be_translated_to_key_error\", []() { throw shared_exception(); });\n\n    m.def(\"raise_from\", []() {\n        PyErr_SetString(PyExc_ValueError, \"inner\");\n        py::raise_from(PyExc_ValueError, \"outer\");\n        throw py::error_already_set();\n    });\n\n    m.def(\"raise_from_already_set\", []() {\n        try {\n            PyErr_SetString(PyExc_ValueError, \"inner\");\n            throw py::error_already_set();\n        } catch (py::error_already_set &e) {\n            py::raise_from(e, PyExc_ValueError, \"outer\");\n            throw py::error_already_set();\n        }\n    });\n\n    m.def(\"throw_nested_exception\", []() {\n        try {\n            throw std::runtime_error(\"Inner Exception\");\n        } catch (const std::runtime_error &) {\n            std::throw_with_nested(std::runtime_error(\"Outer Exception\"));\n        }\n    });\n\n    m.def(\"error_already_set_what\", [](const py::object &exc_type, const py::object &exc_value) {\n        PyErr_SetObject(exc_type.ptr(), exc_value.ptr());\n        std::string what = py::error_already_set().what();\n        bool py_err_set_after_what = (PyErr_Occurred() != nullptr);\n        PyErr_Clear();\n        return py::make_tuple(std::move(what), py_err_set_after_what);\n    });\n\n    m.def(\"test_cross_module_interleaved_error_already_set\", []() {\n        auto cm = py::module_::import(\"cross_module_interleaved_error_already_set\");\n        auto interleaved_error_already_set\n            = reinterpret_cast<void (*)()>(PyLong_AsVoidPtr(cm.attr(\"funcaddr\").ptr()));\n        interleaved_error_already_set();\n    });\n\n    m.def(\"test_error_already_set_double_restore\", [](bool dry_run) {\n        PyErr_SetString(PyExc_ValueError, \"Random error.\");\n        py::error_already_set e;\n        e.restore();\n        PyErr_Clear();\n        if (!dry_run) {\n            e.restore();\n        }\n    });\n\n    // https://github.com/pybind/pybind11/issues/4075\n    m.def(\"test_pypy_oserror_normalization\", []() {\n        try {\n            py::module_::import(\"io\").attr(\"open\")(\"this_filename_must_not_exist\", \"r\");\n        } catch (const py::error_already_set &e) {\n            return py::str(e.what()); // str must be built before e goes out of scope.\n        }\n        return py::str(\"UNEXPECTED\");\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_exceptions.h",
    "content": "#pragma once\n#include \"pybind11_tests.h\"\n\n#include <stdexcept>\n\n// shared exceptions for cross_module_tests\n\nclass PYBIND11_EXPORT_EXCEPTION shared_exception : public pybind11::builtin_exception {\npublic:\n    using builtin_exception::builtin_exception;\n    explicit shared_exception() : shared_exception(\"\") {}\n    void set_error() const override { PyErr_SetString(PyExc_RuntimeError, what()); }\n};\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_exceptions.py",
    "content": "import sys\n\nimport pytest\n\nimport env\nimport pybind11_cross_module_tests as cm\nimport pybind11_tests  # noqa: F401\nfrom pybind11_tests import exceptions as m\n\n\ndef test_std_exception(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_std_exception()\n    assert msg(excinfo.value) == \"This exception was intentionally thrown.\"\n\n\ndef test_error_already_set(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_already_set(False)\n    assert (\n        msg(excinfo.value)\n        == \"Internal error: pybind11::error_already_set called while Python error indicator not set.\"\n    )\n\n    with pytest.raises(ValueError) as excinfo:\n        m.throw_already_set(True)\n    assert msg(excinfo.value) == \"foo\"\n\n\ndef test_raise_from(msg):\n    with pytest.raises(ValueError) as excinfo:\n        m.raise_from()\n    assert msg(excinfo.value) == \"outer\"\n    assert msg(excinfo.value.__cause__) == \"inner\"\n\n\ndef test_raise_from_already_set(msg):\n    with pytest.raises(ValueError) as excinfo:\n        m.raise_from_already_set()\n    assert msg(excinfo.value) == \"outer\"\n    assert msg(excinfo.value.__cause__) == \"inner\"\n\n\ndef test_cross_module_exceptions(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.raise_runtime_error()\n    assert str(excinfo.value) == \"My runtime error\"\n\n    with pytest.raises(ValueError) as excinfo:\n        cm.raise_value_error()\n    assert str(excinfo.value) == \"My value error\"\n\n    with pytest.raises(ValueError) as excinfo:\n        cm.throw_pybind_value_error()\n    assert str(excinfo.value) == \"pybind11 value error\"\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.throw_pybind_type_error()\n    assert str(excinfo.value) == \"pybind11 type error\"\n\n    with pytest.raises(StopIteration) as excinfo:\n        cm.throw_stop_iteration()\n\n    with pytest.raises(cm.LocalSimpleException) as excinfo:\n        cm.throw_local_simple_error()\n    assert msg(excinfo.value) == \"external mod\"\n\n    with pytest.raises(KeyError) as excinfo:\n        cm.throw_local_error()\n    # KeyError is a repr of the key, so it has an extra set of quotes\n    assert str(excinfo.value) == \"'just local'\"\n\n\n# TODO: FIXME\n@pytest.mark.xfail(\n    \"env.MACOS and (env.PYPY or pybind11_tests.compiler_info.startswith('Homebrew Clang'))\",\n    raises=RuntimeError,\n    reason=\"See Issue #2847, PR #2999, PR #4324\",\n)\ndef test_cross_module_exception_translator():\n    with pytest.raises(KeyError):\n        # translator registered in cross_module_tests\n        m.throw_should_be_translated_to_key_error()\n\n\ndef test_python_call_in_catch():\n    d = {}\n    assert m.python_call_in_destructor(d) is True\n    assert d[\"good\"] is True\n\n\ndef ignore_pytest_unraisable_warning(f):\n    unraisable = \"PytestUnraisableExceptionWarning\"\n    if hasattr(pytest, unraisable):  # Python >= 3.8 and pytest >= 6\n        dec = pytest.mark.filterwarnings(f\"ignore::pytest.{unraisable}\")\n        return dec(f)\n    else:\n        return f\n\n\n# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583\n@pytest.mark.xfail(env.PYPY, reason=\"Failure on PyPy 3.8 (7.3.7)\", strict=False)\n@ignore_pytest_unraisable_warning\ndef test_python_alreadyset_in_destructor(monkeypatch, capsys):\n    hooked = False\n    triggered = False\n\n    if hasattr(sys, \"unraisablehook\"):  # Python 3.8+\n        hooked = True\n        # Don't take `sys.unraisablehook`, as that's overwritten by pytest\n        default_hook = sys.__unraisablehook__\n\n        def hook(unraisable_hook_args):\n            exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args\n            if obj == \"already_set demo\":\n                nonlocal triggered\n                triggered = True\n            default_hook(unraisable_hook_args)\n            return\n\n        # Use monkeypatch so pytest can apply and remove the patch as appropriate\n        monkeypatch.setattr(sys, \"unraisablehook\", hook)\n\n    assert m.python_alreadyset_in_destructor(\"already_set demo\") is True\n    if hooked:\n        assert triggered is True\n\n    _, captured_stderr = capsys.readouterr()\n    assert captured_stderr.startswith(\"Exception ignored in: 'already_set demo'\")\n    assert captured_stderr.rstrip().endswith(\"KeyError: 'bar'\")\n\n\ndef test_exception_matches():\n    assert m.exception_matches()\n    assert m.exception_matches_base()\n    assert m.modulenotfound_exception_matches_base()\n\n\ndef test_custom(msg):\n    # Can we catch a MyException?\n    with pytest.raises(m.MyException) as excinfo:\n        m.throws1()\n    assert msg(excinfo.value) == \"this error should go to a custom type\"\n\n    # Can we translate to standard Python exceptions?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws2()\n    assert msg(excinfo.value) == \"this error should go to a standard Python exception\"\n\n    # Can we handle unknown exceptions?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws3()\n    assert msg(excinfo.value) == \"Caught an unknown exception!\"\n\n    # Can we delegate to another handler by rethrowing?\n    with pytest.raises(m.MyException) as excinfo:\n        m.throws4()\n    assert msg(excinfo.value) == \"this error is rethrown\"\n\n    # Can we fall-through to the default handler?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws_logic_error()\n    assert (\n        msg(excinfo.value) == \"this error should fall through to the standard handler\"\n    )\n\n    # OverFlow error translation.\n    with pytest.raises(OverflowError) as excinfo:\n        m.throws_overflow_error()\n\n    # Can we handle a helper-declared exception?\n    with pytest.raises(m.MyException5) as excinfo:\n        m.throws5()\n    assert msg(excinfo.value) == \"this is a helper-defined translated exception\"\n\n    # Exception subclassing:\n    with pytest.raises(m.MyException5) as excinfo:\n        m.throws5_1()\n    assert msg(excinfo.value) == \"MyException5 subclass\"\n    assert isinstance(excinfo.value, m.MyException5_1)\n\n    with pytest.raises(m.MyException5_1) as excinfo:\n        m.throws5_1()\n    assert msg(excinfo.value) == \"MyException5 subclass\"\n\n    with pytest.raises(m.MyException5) as excinfo:\n        try:\n            m.throws5()\n        except m.MyException5_1 as err:\n            raise RuntimeError(\"Exception error: caught child from parent\") from err\n    assert msg(excinfo.value) == \"this is a helper-defined translated exception\"\n\n\ndef test_nested_throws(capture):\n    \"\"\"Tests nested (e.g. C++ -> Python -> C++) exception handling\"\"\"\n\n    def throw_myex():\n        raise m.MyException(\"nested error\")\n\n    def throw_myex5():\n        raise m.MyException5(\"nested error 5\")\n\n    # In the comments below, the exception is caught in the first step, thrown in the last step\n\n    # C++ -> Python\n    with capture:\n        m.try_catch(m.MyException5, throw_myex5)\n    assert str(capture).startswith(\"MyException5: nested error 5\")\n\n    # Python -> C++ -> Python\n    with pytest.raises(m.MyException) as excinfo:\n        m.try_catch(m.MyException5, throw_myex)\n    assert str(excinfo.value) == \"nested error\"\n\n    def pycatch(exctype, f, *args):\n        try:\n            f(*args)\n        except m.MyException as e:\n            print(e)\n\n    # C++ -> Python -> C++ -> Python\n    with capture:\n        m.try_catch(\n            m.MyException5,\n            pycatch,\n            m.MyException,\n            m.try_catch,\n            m.MyException,\n            throw_myex5,\n        )\n    assert str(capture).startswith(\"MyException5: nested error 5\")\n\n    # C++ -> Python -> C++\n    with capture:\n        m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)\n    assert capture == \"this error is rethrown\"\n\n    # Python -> C++ -> Python -> C++\n    with pytest.raises(m.MyException5) as excinfo:\n        m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)\n    assert str(excinfo.value) == \"this is a helper-defined translated exception\"\n\n\ndef test_throw_nested_exception():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_nested_exception()\n    assert str(excinfo.value) == \"Outer Exception\"\n    assert str(excinfo.value.__cause__) == \"Inner Exception\"\n\n\n# This can often happen if you wrap a pybind11 class in a Python wrapper\ndef test_invalid_repr():\n    class MyRepr:\n        def __repr__(self):\n            raise AttributeError(\"Example error\")\n\n    with pytest.raises(TypeError):\n        m.simple_bool_passthrough(MyRepr())\n\n\ndef test_local_translator(msg):\n    \"\"\"Tests that a local translator works and that the local translator from\n    the cross module is not applied\"\"\"\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws6()\n    assert msg(excinfo.value) == \"MyException6 only handled in this module\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws_local_error()\n    assert not isinstance(excinfo.value, KeyError)\n    assert msg(excinfo.value) == \"never caught\"\n\n    with pytest.raises(Exception) as excinfo:\n        m.throws_local_simple_error()\n    assert not isinstance(excinfo.value, cm.LocalSimpleException)\n    assert msg(excinfo.value) == \"this mod\"\n\n\ndef test_error_already_set_message_with_unicode_surrogate():  # Issue #4288\n    assert m.error_already_set_what(RuntimeError, \"\\ud927\") == (\n        \"RuntimeError: \\\\ud927\",\n        False,\n    )\n\n\ndef test_error_already_set_message_with_malformed_utf8():\n    assert m.error_already_set_what(RuntimeError, b\"\\x80\") == (\n        \"RuntimeError: b'\\\\x80'\",\n        False,\n    )\n\n\nclass FlakyException(Exception):\n    def __init__(self, failure_point):\n        if failure_point == \"failure_point_init\":\n            raise ValueError(\"triggered_failure_point_init\")\n        self.failure_point = failure_point\n\n    def __str__(self):\n        if self.failure_point == \"failure_point_str\":\n            raise ValueError(\"triggered_failure_point_str\")\n        return \"FlakyException.__str__\"\n\n\n@pytest.mark.parametrize(\n    \"exc_type, exc_value, expected_what\",\n    (\n        (ValueError, \"plain_str\", \"ValueError: plain_str\"),\n        (ValueError, (\"tuple_elem\",), \"ValueError: tuple_elem\"),\n        (FlakyException, (\"happy\",), \"FlakyException: FlakyException.__str__\"),\n    ),\n)\ndef test_error_already_set_what_with_happy_exceptions(\n    exc_type, exc_value, expected_what\n):\n    what, py_err_set_after_what = m.error_already_set_what(exc_type, exc_value)\n    assert not py_err_set_after_what\n    assert what == expected_what\n\n\n@pytest.mark.skipif(\"env.PYPY\", reason=\"PyErr_NormalizeException Segmentation fault\")\ndef test_flaky_exception_failure_point_init():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.error_already_set_what(FlakyException, (\"failure_point_init\",))\n    lines = str(excinfo.value).splitlines()\n    # PyErr_NormalizeException replaces the original FlakyException with ValueError:\n    assert lines[:3] == [\n        \"pybind11::error_already_set: MISMATCH of original and normalized active exception types:\"\n        \" ORIGINAL FlakyException REPLACED BY ValueError: triggered_failure_point_init\",\n        \"\",\n        \"At:\",\n    ]\n    # Checking the first two lines of the traceback as formatted in error_string():\n    assert \"test_exceptions.py(\" in lines[3]\n    assert lines[3].endswith(\"): __init__\")\n    assert lines[4].endswith(\"): test_flaky_exception_failure_point_init\")\n\n\ndef test_flaky_exception_failure_point_str():\n    what, py_err_set_after_what = m.error_already_set_what(\n        FlakyException, (\"failure_point_str\",)\n    )\n    assert not py_err_set_after_what\n    lines = what.splitlines()\n    if env.PYPY and len(lines) == 3:\n        n = 3  # Traceback is missing.\n    else:\n        n = 5\n    assert (\n        lines[:n]\n        == [\n            \"FlakyException: <MESSAGE UNAVAILABLE DUE TO ANOTHER EXCEPTION>\",\n            \"\",\n            \"MESSAGE UNAVAILABLE DUE TO EXCEPTION: ValueError: triggered_failure_point_str\",\n            \"\",\n            \"At:\",\n        ][:n]\n    )\n\n\ndef test_cross_module_interleaved_error_already_set():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_cross_module_interleaved_error_already_set()\n    assert str(excinfo.value) in (\n        \"2nd error.\",  # Almost all platforms.\n        \"RuntimeError: 2nd error.\",  # Some PyPy builds (seen under macOS).\n    )\n\n\ndef test_error_already_set_double_restore():\n    m.test_error_already_set_double_restore(True)  # dry_run\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_error_already_set_double_restore(False)\n    assert str(excinfo.value) == (\n        \"Internal error: pybind11::detail::error_fetch_and_normalize::restore()\"\n        \" called a second time. ORIGINAL ERROR: ValueError: Random error.\"\n    )\n\n\ndef test_pypy_oserror_normalization():\n    # https://github.com/pybind/pybind11/issues/4075\n    what = m.test_pypy_oserror_normalization()\n    assert \"this_filename_must_not_exist\" in what\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_factory_constructors.cpp",
    "content": "/*\n    tests/test_factory_constructors.cpp -- tests construction from a factory function\n                                           via py::init_factory()\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <cmath>\n#include <new>\n#include <utility>\n\n// Classes for testing python construction via C++ factory function:\n// Not publicly constructible, copyable, or movable:\nclass TestFactory1 {\n    friend class TestFactoryHelper;\n    TestFactory1() : value(\"(empty)\") { print_default_created(this); }\n    explicit TestFactory1(int v) : value(std::to_string(v)) { print_created(this, value); }\n    explicit TestFactory1(std::string v) : value(std::move(v)) { print_created(this, value); }\n\npublic:\n    std::string value;\n    TestFactory1(TestFactory1 &&) = delete;\n    TestFactory1(const TestFactory1 &) = delete;\n    TestFactory1 &operator=(TestFactory1 &&) = delete;\n    TestFactory1 &operator=(const TestFactory1 &) = delete;\n    ~TestFactory1() { print_destroyed(this); }\n};\n// Non-public construction, but moveable:\nclass TestFactory2 {\n    friend class TestFactoryHelper;\n    TestFactory2() : value(\"(empty2)\") { print_default_created(this); }\n    explicit TestFactory2(int v) : value(std::to_string(v)) { print_created(this, value); }\n    explicit TestFactory2(std::string v) : value(std::move(v)) { print_created(this, value); }\n\npublic:\n    TestFactory2(TestFactory2 &&m) noexcept : value{std::move(m.value)} {\n        print_move_created(this);\n    }\n    TestFactory2 &operator=(TestFactory2 &&m) noexcept {\n        value = std::move(m.value);\n        print_move_assigned(this);\n        return *this;\n    }\n    std::string value;\n    ~TestFactory2() { print_destroyed(this); }\n};\n// Mixed direct/factory construction:\nclass TestFactory3 {\nprotected:\n    friend class TestFactoryHelper;\n    TestFactory3() : value(\"(empty3)\") { print_default_created(this); }\n    explicit TestFactory3(int v) : value(std::to_string(v)) { print_created(this, value); }\n\npublic:\n    explicit TestFactory3(std::string v) : value(std::move(v)) { print_created(this, value); }\n    TestFactory3(TestFactory3 &&m) noexcept : value{std::move(m.value)} {\n        print_move_created(this);\n    }\n    TestFactory3 &operator=(TestFactory3 &&m) noexcept {\n        value = std::move(m.value);\n        print_move_assigned(this);\n        return *this;\n    }\n    std::string value;\n    virtual ~TestFactory3() { print_destroyed(this); }\n};\n// Inheritance test\nclass TestFactory4 : public TestFactory3 {\npublic:\n    TestFactory4() : TestFactory3() { print_default_created(this); }\n    explicit TestFactory4(int v) : TestFactory3(v) { print_created(this, v); }\n    ~TestFactory4() override { print_destroyed(this); }\n};\n// Another class for an invalid downcast test\nclass TestFactory5 : public TestFactory3 {\npublic:\n    explicit TestFactory5(int i) : TestFactory3(i) { print_created(this, i); }\n    ~TestFactory5() override { print_destroyed(this); }\n};\n\nclass TestFactory6 {\nprotected:\n    int value;\n    bool alias = false;\n\npublic:\n    explicit TestFactory6(int i) : value{i} { print_created(this, i); }\n    TestFactory6(TestFactory6 &&f) noexcept {\n        print_move_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    TestFactory6(const TestFactory6 &f) {\n        print_copy_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    virtual ~TestFactory6() { print_destroyed(this); }\n    virtual int get() { return value; }\n    bool has_alias() const { return alias; }\n};\nclass PyTF6 : public TestFactory6 {\npublic:\n    // Special constructor that allows the factory to construct a PyTF6 from a TestFactory6 only\n    // when an alias is needed:\n    explicit PyTF6(TestFactory6 &&base) : TestFactory6(std::move(base)) {\n        alias = true;\n        print_created(this, \"move\", value);\n    }\n    explicit PyTF6(int i) : TestFactory6(i) {\n        alias = true;\n        print_created(this, i);\n    }\n    PyTF6(PyTF6 &&f) noexcept : TestFactory6(std::move(f)) { print_move_created(this); }\n    PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); }\n    explicit PyTF6(std::string s) : TestFactory6((int) s.size()) {\n        alias = true;\n        print_created(this, s);\n    }\n    ~PyTF6() override { print_destroyed(this); }\n    int get() override { PYBIND11_OVERRIDE(int, TestFactory6, get, /*no args*/); }\n};\n\nclass TestFactory7 {\nprotected:\n    int value;\n    bool alias = false;\n\npublic:\n    explicit TestFactory7(int i) : value{i} { print_created(this, i); }\n    TestFactory7(TestFactory7 &&f) noexcept {\n        print_move_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    TestFactory7(const TestFactory7 &f) {\n        print_copy_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    virtual ~TestFactory7() { print_destroyed(this); }\n    virtual int get() { return value; }\n    bool has_alias() const { return alias; }\n};\nclass PyTF7 : public TestFactory7 {\npublic:\n    explicit PyTF7(int i) : TestFactory7(i) {\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = true;\n        print_created(this, i);\n    }\n    PyTF7(PyTF7 &&f) noexcept : TestFactory7(std::move(f)) { print_move_created(this); }\n    PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); }\n    ~PyTF7() override { print_destroyed(this); }\n    int get() override { PYBIND11_OVERRIDE(int, TestFactory7, get, /*no args*/); }\n};\n\nclass TestFactoryHelper {\npublic:\n    // Non-movable, non-copyable type:\n    // Return via pointer:\n    static TestFactory1 *construct1() { return new TestFactory1(); }\n    // Holder:\n    static std::unique_ptr<TestFactory1> construct1(int a) {\n        return std::unique_ptr<TestFactory1>(new TestFactory1(a));\n    }\n    // pointer again\n    static TestFactory1 *construct1_string(std::string a) {\n        return new TestFactory1(std::move(a));\n    }\n\n    // Moveable type:\n    // pointer:\n    static TestFactory2 *construct2() { return new TestFactory2(); }\n    // holder:\n    static std::unique_ptr<TestFactory2> construct2(int a) {\n        return std::unique_ptr<TestFactory2>(new TestFactory2(a));\n    }\n    // by value moving:\n    static TestFactory2 construct2(std::string a) { return TestFactory2(std::move(a)); }\n\n    // shared_ptr holder type:\n    // pointer:\n    static TestFactory3 *construct3() { return new TestFactory3(); }\n    // holder:\n    static std::shared_ptr<TestFactory3> construct3(int a) {\n        return std::shared_ptr<TestFactory3>(new TestFactory3(a));\n    }\n};\n\nTEST_SUBMODULE(factory_constructors, m) {\n\n    // Define various trivial types to allow simpler overload resolution:\n    py::module_ m_tag = m.def_submodule(\"tag\");\n#define MAKE_TAG_TYPE(Name)                                                                       \\\n    struct Name##_tag {};                                                                         \\\n    py::class_<Name##_tag>(m_tag, #Name \"_tag\").def(py::init<>());                                \\\n    m_tag.attr(#Name) = py::cast(Name##_tag{})\n    MAKE_TAG_TYPE(pointer);\n    MAKE_TAG_TYPE(unique_ptr);\n    MAKE_TAG_TYPE(move);\n    MAKE_TAG_TYPE(shared_ptr);\n    MAKE_TAG_TYPE(derived);\n    MAKE_TAG_TYPE(TF4);\n    MAKE_TAG_TYPE(TF5);\n    MAKE_TAG_TYPE(null_ptr);\n    MAKE_TAG_TYPE(null_unique_ptr);\n    MAKE_TAG_TYPE(null_shared_ptr);\n    MAKE_TAG_TYPE(base);\n    MAKE_TAG_TYPE(invalid_base);\n    MAKE_TAG_TYPE(alias);\n    MAKE_TAG_TYPE(unaliasable);\n    MAKE_TAG_TYPE(mixed);\n\n    // test_init_factory_basic, test_bad_type\n    py::class_<TestFactory1>(m, \"TestFactory1\")\n        .def(py::init([](unique_ptr_tag, int v) { return TestFactoryHelper::construct1(v); }))\n        .def(py::init(&TestFactoryHelper::construct1_string)) // raw function pointer\n        .def(py::init([](pointer_tag) { return TestFactoryHelper::construct1(); }))\n        .def(py::init(\n            [](py::handle, int v, py::handle) { return TestFactoryHelper::construct1(v); }))\n        .def_readwrite(\"value\", &TestFactory1::value);\n    py::class_<TestFactory2>(m, \"TestFactory2\")\n        .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct2(v); }))\n        .def(py::init([](unique_ptr_tag, std::string v) {\n            return TestFactoryHelper::construct2(std::move(v));\n        }))\n        .def(py::init([](move_tag) { return TestFactoryHelper::construct2(); }))\n        .def_readwrite(\"value\", &TestFactory2::value);\n\n    // Stateful & reused:\n    int c = 1;\n    auto c4a = [c](pointer_tag, TF4_tag, int a) {\n        (void) c;\n        return new TestFactory4(a);\n    };\n\n    // test_init_factory_basic, test_init_factory_casting\n    py::class_<TestFactory3, std::shared_ptr<TestFactory3>> pyTestFactory3(m, \"TestFactory3\");\n    pyTestFactory3\n        .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct3(v); }))\n        .def(py::init([](shared_ptr_tag) { return TestFactoryHelper::construct3(); }));\n    ignoreOldStyleInitWarnings([&pyTestFactory3]() {\n        pyTestFactory3.def(\"__init__\", [](TestFactory3 &self, std::string v) {\n            new (&self) TestFactory3(std::move(v));\n        }); // placement-new ctor\n    });\n    pyTestFactory3\n        // factories returning a derived type:\n        .def(py::init(c4a)) // derived ptr\n        .def(py::init([](pointer_tag, TF5_tag, int a) { return new TestFactory5(a); }))\n        // derived shared ptr:\n        .def(py::init(\n            [](shared_ptr_tag, TF4_tag, int a) { return std::make_shared<TestFactory4>(a); }))\n        .def(py::init(\n            [](shared_ptr_tag, TF5_tag, int a) { return std::make_shared<TestFactory5>(a); }))\n\n        // Returns nullptr:\n        .def(py::init([](null_ptr_tag) { return (TestFactory3 *) nullptr; }))\n        .def(py::init([](null_unique_ptr_tag) { return std::unique_ptr<TestFactory3>(); }))\n        .def(py::init([](null_shared_ptr_tag) { return std::shared_ptr<TestFactory3>(); }))\n\n        .def_readwrite(\"value\", &TestFactory3::value);\n\n    // test_init_factory_casting\n    py::class_<TestFactory4, TestFactory3, std::shared_ptr<TestFactory4>>(m, \"TestFactory4\")\n        .def(py::init(c4a)) // pointer\n        ;\n\n    // Doesn't need to be registered, but registering makes getting ConstructorStats easier:\n    py::class_<TestFactory5, TestFactory3, std::shared_ptr<TestFactory5>>(m, \"TestFactory5\");\n\n    // test_init_factory_alias\n    // Alias testing\n    py::class_<TestFactory6, PyTF6>(m, \"TestFactory6\")\n        .def(py::init([](base_tag, int i) { return TestFactory6(i); }))\n        .def(py::init([](alias_tag, int i) { return PyTF6(i); }))\n        .def(py::init([](alias_tag, std::string s) { return PyTF6(std::move(s)); }))\n        .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF6(i); }))\n        .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory6(i); }))\n        .def(py::init(\n            [](base_tag, alias_tag, pointer_tag, int i) { return (TestFactory6 *) new PyTF6(i); }))\n\n        .def(\"get\", &TestFactory6::get)\n        .def(\"has_alias\", &TestFactory6::has_alias)\n\n        .def_static(\n            \"get_cstats\", &ConstructorStats::get<TestFactory6>, py::return_value_policy::reference)\n        .def_static(\n            \"get_alias_cstats\", &ConstructorStats::get<PyTF6>, py::return_value_policy::reference);\n\n    // test_init_factory_dual\n    // Separate alias constructor testing\n    py::class_<TestFactory7, PyTF7, std::shared_ptr<TestFactory7>>(m, \"TestFactory7\")\n        .def(py::init([](int i) { return TestFactory7(i); }, [](int i) { return PyTF7(i); }))\n        .def(py::init([](pointer_tag, int i) { return new TestFactory7(i); },\n                      [](pointer_tag, int i) { return new PyTF7(i); }))\n        .def(py::init([](mixed_tag, int i) { return new TestFactory7(i); },\n                      [](mixed_tag, int i) { return PyTF7(i); }))\n        .def(py::init([](mixed_tag, const std::string &s) { return TestFactory7((int) s.size()); },\n                      [](mixed_tag, const std::string &s) { return new PyTF7((int) s.size()); }))\n        .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory7(i); },\n                      [](base_tag, pointer_tag, int i) { return (TestFactory7 *) new PyTF7(i); }))\n        .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF7(i); },\n                      [](alias_tag, pointer_tag, int i) { return new PyTF7(10 * i); }))\n        .def(py::init(\n            [](shared_ptr_tag, base_tag, int i) { return std::make_shared<TestFactory7>(i); },\n            [](shared_ptr_tag, base_tag, int i) {\n                auto *p = new PyTF7(i);\n                return std::shared_ptr<TestFactory7>(p);\n            }))\n        .def(py::init([](shared_ptr_tag,\n                         invalid_base_tag,\n                         int i) { return std::make_shared<TestFactory7>(i); },\n                      [](shared_ptr_tag, invalid_base_tag, int i) {\n                          return std::make_shared<TestFactory7>(i);\n                      })) // <-- invalid alias factory\n\n        .def(\"get\", &TestFactory7::get)\n        .def(\"has_alias\", &TestFactory7::has_alias)\n\n        .def_static(\n            \"get_cstats\", &ConstructorStats::get<TestFactory7>, py::return_value_policy::reference)\n        .def_static(\n            \"get_alias_cstats\", &ConstructorStats::get<PyTF7>, py::return_value_policy::reference);\n\n    // test_placement_new_alternative\n    // Class with a custom new operator but *without* a placement new operator (issue #948)\n    class NoPlacementNew {\n    public:\n        explicit NoPlacementNew(int i) : i(i) {}\n        static void *operator new(std::size_t s) {\n            auto *p = ::operator new(s);\n            py::print(\"operator new called, returning\", reinterpret_cast<uintptr_t>(p));\n            return p;\n        }\n        static void operator delete(void *p) {\n            py::print(\"operator delete called on\", reinterpret_cast<uintptr_t>(p));\n            ::operator delete(p);\n        }\n        int i;\n    };\n    // As of 2.2, `py::init<args>` no longer requires placement new\n    py::class_<NoPlacementNew>(m, \"NoPlacementNew\")\n        .def(py::init<int>())\n        .def(py::init([]() { return new NoPlacementNew(100); }))\n        .def_readwrite(\"i\", &NoPlacementNew::i);\n\n    // test_reallocations\n    // Class that has verbose operator_new/operator_delete calls\n    struct NoisyAlloc {\n        NoisyAlloc(const NoisyAlloc &) = default;\n        explicit NoisyAlloc(int i) { py::print(py::str(\"NoisyAlloc(int {})\").format(i)); }\n        explicit NoisyAlloc(double d) { py::print(py::str(\"NoisyAlloc(double {})\").format(d)); }\n        ~NoisyAlloc() { py::print(\"~NoisyAlloc()\"); }\n\n        static void *operator new(size_t s) {\n            py::print(\"noisy new\");\n            return ::operator new(s);\n        }\n        static void *operator new(size_t, void *p) {\n            py::print(\"noisy placement new\");\n            return p;\n        }\n        static void operator delete(void *p, size_t) {\n            py::print(\"noisy delete\");\n            ::operator delete(p);\n        }\n        static void operator delete(void *, void *) { py::print(\"noisy placement delete\"); }\n    };\n\n    py::class_<NoisyAlloc> pyNoisyAlloc(m, \"NoisyAlloc\");\n    // Since these overloads have the same number of arguments, the dispatcher will try each of\n    // them until the arguments convert.  Thus we can get a pre-allocation here when passing a\n    // single non-integer:\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\"__init__\", [](NoisyAlloc *a, int i) {\n            new (a) NoisyAlloc(i);\n        }); // Regular constructor, runs first, requires preallocation\n    });\n\n    pyNoisyAlloc.def(py::init([](double d) { return new NoisyAlloc(d); }));\n\n    // The two-argument version: first the factory pointer overload.\n    pyNoisyAlloc.def(py::init([](int i, int) { return new NoisyAlloc(i); }));\n    // Return-by-value:\n    pyNoisyAlloc.def(py::init([](double d, int) { return NoisyAlloc(d); }));\n    // Old-style placement new init; requires preallocation\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\"__init__\",\n                         [](NoisyAlloc &a, double d, double) { new (&a) NoisyAlloc(d); });\n    });\n    // Requires deallocation of previous overload preallocated value:\n    pyNoisyAlloc.def(py::init([](int i, double) { return new NoisyAlloc(i); }));\n    // Regular again: requires yet another preallocation\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\n            \"__init__\", [](NoisyAlloc &a, int i, const std::string &) { new (&a) NoisyAlloc(i); });\n    });\n\n    // static_assert testing (the following def's should all fail with appropriate compilation\n    // errors):\n#if 0\n    struct BadF1Base {};\n    struct BadF1 : BadF1Base {};\n    struct PyBadF1 : BadF1 {};\n    py::class_<BadF1, PyBadF1, std::shared_ptr<BadF1>> bf1(m, \"BadF1\");\n    // wrapped factory function must return a compatible pointer, holder, or value\n    bf1.def(py::init([]() { return 3; }));\n    // incompatible factory function pointer return type\n    bf1.def(py::init([]() { static int three = 3; return &three; }));\n    // incompatible factory function std::shared_ptr<T> return type: cannot convert shared_ptr<T> to holder\n    // (non-polymorphic base)\n    bf1.def(py::init([]() { return std::shared_ptr<BadF1Base>(new BadF1()); }));\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_factory_constructors.py",
    "content": "import re\n\nimport pytest\n\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import factory_constructors as m\nfrom pybind11_tests.factory_constructors import tag\n\n\ndef test_init_factory_basic():\n    \"\"\"Tests py::init_factory() wrapper around various ways of returning the object\"\"\"\n\n    cstats = [\n        ConstructorStats.get(c)\n        for c in [m.TestFactory1, m.TestFactory2, m.TestFactory3]\n    ]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    x1 = m.TestFactory1(tag.unique_ptr, 3)\n    assert x1.value == \"3\"\n    y1 = m.TestFactory1(tag.pointer)\n    assert y1.value == \"(empty)\"\n    z1 = m.TestFactory1(\"hi!\")\n    assert z1.value == \"hi!\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n\n    x2 = m.TestFactory2(tag.move)\n    assert x2.value == \"(empty2)\"\n    y2 = m.TestFactory2(tag.pointer, 7)\n    assert y2.value == \"7\"\n    z2 = m.TestFactory2(tag.unique_ptr, \"hi again\")\n    assert z2.value == \"hi again\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n\n    x3 = m.TestFactory3(tag.shared_ptr)\n    assert x3.value == \"(empty3)\"\n    y3 = m.TestFactory3(tag.pointer, 42)\n    assert y3.value == \"42\"\n    z3 = m.TestFactory3(\"bye\")\n    assert z3.value == \"bye\"\n\n    for null_ptr_kind in [tag.null_ptr, tag.null_unique_ptr, tag.null_shared_ptr]:\n        with pytest.raises(TypeError) as excinfo:\n            m.TestFactory3(null_ptr_kind)\n        assert (\n            str(excinfo.value) == \"pybind11::init(): factory function returned nullptr\"\n        )\n\n    assert [i.alive() for i in cstats] == [3, 3, 3]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 9\n\n    del x1, y2, y3, z3\n    assert [i.alive() for i in cstats] == [2, 2, 1]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 5\n    del x2, x3, y1, z1, z2\n    assert [i.alive() for i in cstats] == [0, 0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"3\", \"hi!\"],\n        [\"7\", \"hi again\"],\n        [\"42\", \"bye\"],\n    ]\n    assert [i.default_constructions for i in cstats] == [1, 1, 1]\n\n\ndef test_init_factory_signature(msg):\n    with pytest.raises(TypeError) as excinfo:\n        m.TestFactory1(\"invalid\", \"constructor\", \"arguments\")\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)\n            2. m.factory_constructors.TestFactory1(arg0: str)\n            3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)\n            4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle)\n\n        Invoked with: 'invalid', 'constructor', 'arguments'\n    \"\"\"\n    )\n\n    assert (\n        msg(m.TestFactory1.__init__.__doc__)\n        == \"\"\"\n        __init__(*args, **kwargs)\n        Overloaded function.\n\n        1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) -> None\n\n        2. __init__(self: m.factory_constructors.TestFactory1, arg0: str) -> None\n\n        3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None\n\n        4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_init_factory_casting():\n    \"\"\"Tests py::init_factory() wrapper with various upcasting and downcasting returns\"\"\"\n\n    cstats = [\n        ConstructorStats.get(c)\n        for c in [m.TestFactory3, m.TestFactory4, m.TestFactory5]\n    ]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    # Construction from derived references:\n    a = m.TestFactory3(tag.pointer, tag.TF4, 4)\n    assert a.value == \"4\"\n    b = m.TestFactory3(tag.shared_ptr, tag.TF4, 5)\n    assert b.value == \"5\"\n    c = m.TestFactory3(tag.pointer, tag.TF5, 6)\n    assert c.value == \"6\"\n    d = m.TestFactory3(tag.shared_ptr, tag.TF5, 7)\n    assert d.value == \"7\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    # Shared a lambda with TF3:\n    e = m.TestFactory4(tag.pointer, tag.TF4, 8)\n    assert e.value == \"8\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 5\n    assert [i.alive() for i in cstats] == [5, 3, 2]\n\n    del a\n    assert [i.alive() for i in cstats] == [4, 2, 2]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    del b, c, e\n    assert [i.alive() for i in cstats] == [1, 0, 1]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 1\n\n    del d\n    assert [i.alive() for i in cstats] == [0, 0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"4\", \"5\", \"6\", \"7\", \"8\"],\n        [\"4\", \"5\", \"8\"],\n        [\"6\", \"7\"],\n    ]\n\n\ndef test_init_factory_alias():\n    \"\"\"Tests py::init_factory() wrapper with value conversions and alias types\"\"\"\n\n    cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    a = m.TestFactory6(tag.base, 1)\n    assert a.get() == 1\n    assert not a.has_alias()\n    b = m.TestFactory6(tag.alias, \"hi there\")\n    assert b.get() == 8\n    assert b.has_alias()\n    c = m.TestFactory6(tag.alias, 3)\n    assert c.get() == 3\n    assert c.has_alias()\n    d = m.TestFactory6(tag.alias, tag.pointer, 4)\n    assert d.get() == 4\n    assert d.has_alias()\n    e = m.TestFactory6(tag.base, tag.pointer, 5)\n    assert e.get() == 5\n    assert not e.has_alias()\n    f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6)\n    assert f.get() == 6\n    assert f.has_alias()\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n    assert [i.alive() for i in cstats] == [6, 4]\n\n    del a, b, e\n    assert [i.alive() for i in cstats] == [3, 3]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    del f, c, d\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    class MyTest(m.TestFactory6):\n        def __init__(self, *args):\n            m.TestFactory6.__init__(self, *args)\n\n        def get(self):\n            return -5 + m.TestFactory6.get(self)\n\n    # Return Class by value, moved into new alias:\n    z = MyTest(tag.base, 123)\n    assert z.get() == 118\n    assert z.has_alias()\n\n    # Return alias by value, moved into new alias:\n    y = MyTest(tag.alias, \"why hello!\")\n    assert y.get() == 5\n    assert y.has_alias()\n\n    # Return Class by pointer, moved into new alias then original destroyed:\n    x = MyTest(tag.base, tag.pointer, 47)\n    assert x.get() == 42\n    assert x.has_alias()\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    assert [i.alive() for i in cstats] == [3, 3]\n    del x, y, z\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"1\", \"8\", \"3\", \"4\", \"5\", \"6\", \"123\", \"10\", \"47\"],\n        [\"hi there\", \"3\", \"4\", \"6\", \"move\", \"123\", \"why hello!\", \"move\", \"47\"],\n    ]\n\n\ndef test_init_factory_dual():\n    \"\"\"Tests init factory functions with dual main/alias factory functions\"\"\"\n    from pybind11_tests.factory_constructors import TestFactory7\n\n    cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    class PythFactory7(TestFactory7):\n        def get(self):\n            return 100 + TestFactory7.get(self)\n\n    a1 = TestFactory7(1)\n    a2 = PythFactory7(2)\n    assert a1.get() == 1\n    assert a2.get() == 102\n    assert not a1.has_alias()\n    assert a2.has_alias()\n\n    b1 = TestFactory7(tag.pointer, 3)\n    b2 = PythFactory7(tag.pointer, 4)\n    assert b1.get() == 3\n    assert b2.get() == 104\n    assert not b1.has_alias()\n    assert b2.has_alias()\n\n    c1 = TestFactory7(tag.mixed, 5)\n    c2 = PythFactory7(tag.mixed, 6)\n    assert c1.get() == 5\n    assert c2.get() == 106\n    assert not c1.has_alias()\n    assert c2.has_alias()\n\n    d1 = TestFactory7(tag.base, tag.pointer, 7)\n    d2 = PythFactory7(tag.base, tag.pointer, 8)\n    assert d1.get() == 7\n    assert d2.get() == 108\n    assert not d1.has_alias()\n    assert d2.has_alias()\n\n    # Both return an alias; the second multiplies the value by 10:\n    e1 = TestFactory7(tag.alias, tag.pointer, 9)\n    e2 = PythFactory7(tag.alias, tag.pointer, 10)\n    assert e1.get() == 9\n    assert e2.get() == 200\n    assert e1.has_alias()\n    assert e2.has_alias()\n\n    f1 = TestFactory7(tag.shared_ptr, tag.base, 11)\n    f2 = PythFactory7(tag.shared_ptr, tag.base, 12)\n    assert f1.get() == 11\n    assert f2.get() == 112\n    assert not f1.has_alias()\n    assert f2.has_alias()\n\n    g1 = TestFactory7(tag.shared_ptr, tag.invalid_base, 13)\n    assert g1.get() == 13\n    assert not g1.has_alias()\n    with pytest.raises(TypeError) as excinfo:\n        PythFactory7(tag.shared_ptr, tag.invalid_base, 14)\n    assert (\n        str(excinfo.value)\n        == \"pybind11::init(): construction failed: returned holder-wrapped instance is not an \"\n        \"alias instance\"\n    )\n\n    assert [i.alive() for i in cstats] == [13, 7]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 13\n\n    del a1, a2, b1, d1, e1, e2\n    assert [i.alive() for i in cstats] == [7, 4]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 7\n    del b2, c1, c2, d2, f1, f2, g1\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"100\", \"11\", \"12\", \"13\", \"14\"],\n        [\"2\", \"4\", \"6\", \"8\", \"9\", \"100\", \"12\"],\n    ]\n\n\ndef test_no_placement_new(capture):\n    \"\"\"Prior to 2.2, `py::init<...>` relied on the type supporting placement\n    new; this tests a class without placement new support.\"\"\"\n    with capture:\n        a = m.NoPlacementNew(123)\n\n    found = re.search(r\"^operator new called, returning (\\d+)\\n$\", str(capture))\n    assert found\n    assert a.i == 123\n    with capture:\n        del a\n        pytest.gc_collect()\n    assert capture == \"operator delete called on \" + found.group(1)\n\n    with capture:\n        b = m.NoPlacementNew()\n\n    found = re.search(r\"^operator new called, returning (\\d+)\\n$\", str(capture))\n    assert found\n    assert b.i == 100\n    with capture:\n        del b\n        pytest.gc_collect()\n    assert capture == \"operator delete called on \" + found.group(1)\n\n\ndef test_multiple_inheritance():\n    class MITest(m.TestFactory1, m.TestFactory2):\n        def __init__(self):\n            m.TestFactory1.__init__(self, tag.unique_ptr, 33)\n            m.TestFactory2.__init__(self, tag.move)\n\n    a = MITest()\n    assert m.TestFactory1.value.fget(a) == \"33\"\n    assert m.TestFactory2.value.fget(a) == \"(empty2)\"\n\n\ndef create_and_destroy(*args):\n    a = m.NoisyAlloc(*args)\n    print(\"---\")\n    del a\n    pytest.gc_collect()\n\n\ndef strip_comments(s):\n    return re.sub(r\"\\s+#.*\", \"\", s)\n\n\ndef test_reallocation_a(capture, msg):\n    \"\"\"When the constructor is overloaded, previous overloads can require a preallocated value.\n    This test makes sure that such preallocated values only happen when they might be necessary,\n    and that they are deallocated properly.\"\"\"\n\n    pytest.gc_collect()\n\n    with capture:\n        create_and_destroy(1)\n    assert (\n        msg(capture)\n        == \"\"\"\n        noisy new\n        noisy placement new\n        NoisyAlloc(int 1)\n        ---\n        ~NoisyAlloc()\n        noisy delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_b(capture, msg):\n    with capture:\n        create_and_destroy(1.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new               # allocation required to attempt first overload\n        noisy delete            # have to dealloc before considering factory init overload\n        noisy new               # pointer factory calling \"new\", part 1: allocation\n        NoisyAlloc(double 1.5)  # ... part two, invoking constructor\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_c(capture, msg):\n    with capture:\n        create_and_destroy(2, 3)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new          # pointer factory calling \"new\", allocation\n        NoisyAlloc(int 2)  # constructor\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_d(capture, msg):\n    with capture:\n        create_and_destroy(2.5, 3)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        NoisyAlloc(double 2.5)  # construction (local func variable: operator_new not called)\n        noisy new               # return-by-value \"new\" part 1: allocation\n        ~NoisyAlloc()           # moved-away local func variable destruction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_e(capture, msg):\n    with capture:\n        create_and_destroy(3.5, 4.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new               # preallocation needed before invoking placement-new overload\n        noisy placement new     # Placement new\n        NoisyAlloc(double 3.5)  # construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_f(capture, msg):\n    with capture:\n        create_and_destroy(4, 0.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new          # preallocation needed before invoking placement-new overload\n        noisy delete       # deallocation of preallocated storage\n        noisy new          # Factory pointer allocation\n        NoisyAlloc(int 4)  # factory pointer construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_g(capture, msg):\n    with capture:\n        create_and_destroy(5, \"hi\")\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new            # preallocation needed before invoking first placement new\n        noisy delete         # delete before considering new-style constructor\n        noisy new            # preallocation for second placement new\n        noisy placement new  # Placement new in the second placement new overload\n        NoisyAlloc(int 5)    # construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_invalid_self():\n    \"\"\"Tests invocation of the pybind-registered base class with an invalid `self` argument.\"\"\"\n\n    class NotPybindDerived:\n        pass\n\n    # Attempts to initialize with an invalid type passed as `self`:\n    class BrokenTF1(m.TestFactory1):\n        def __init__(self, bad):\n            if bad == 1:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory1.__init__(a, tag.pointer)\n            elif bad == 2:\n                a = NotPybindDerived()\n                m.TestFactory1.__init__(a, tag.pointer)\n\n    # Same as above, but for a class with an alias:\n    class BrokenTF6(m.TestFactory6):\n        def __init__(self, bad):\n            if bad == 0:\n                m.TestFactory6.__init__()\n            elif bad == 1:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory6.__init__(a, tag.base, 1)\n            elif bad == 2:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory6.__init__(a, tag.alias, 1)\n            elif bad == 3:\n                m.TestFactory6.__init__(\n                    NotPybindDerived.__new__(NotPybindDerived), tag.base, 1\n                )\n            elif bad == 4:\n                m.TestFactory6.__init__(\n                    NotPybindDerived.__new__(NotPybindDerived), tag.alias, 1\n                )\n\n    for arg in (1, 2):\n        with pytest.raises(TypeError) as excinfo:\n            BrokenTF1(arg)\n        assert (\n            str(excinfo.value)\n            == \"__init__(self, ...) called with invalid or missing `self` argument\"\n        )\n\n    for arg in (0, 1, 2, 3, 4):\n        with pytest.raises(TypeError) as excinfo:\n            BrokenTF6(arg)\n        assert (\n            str(excinfo.value)\n            == \"__init__(self, ...) called with invalid or missing `self` argument\"\n        )\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_gil_scoped.cpp",
    "content": "/*\n    tests/test_gil_scoped.cpp -- acquire and release gil\n\n    Copyright (c) 2017 Borja Zarco (Google LLC) <bzarco@google.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"pybind11_tests.h\"\n\n#include <string>\n#include <thread>\n\n#define CROSS_MODULE(Function)                                                                    \\\n    auto cm = py::module_::import(\"cross_module_gil_utils\");                                      \\\n    auto target = reinterpret_cast<void (*)()>(PyLong_AsVoidPtr(cm.attr(Function).ptr()));\n\nclass VirtClass {\npublic:\n    virtual ~VirtClass() = default;\n    VirtClass() = default;\n    VirtClass(const VirtClass &) = delete;\n    virtual void virtual_func() {}\n    virtual void pure_virtual_func() = 0;\n};\n\nclass PyVirtClass : public VirtClass {\n    void virtual_func() override { PYBIND11_OVERRIDE(void, VirtClass, virtual_func, ); }\n    void pure_virtual_func() override {\n        PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func, );\n    }\n};\n\nTEST_SUBMODULE(gil_scoped, m) {\n    m.attr(\"defined_THREAD_SANITIZER\") =\n#if defined(THREAD_SANITIZER)\n        true;\n#else\n        false;\n#endif\n\n    m.def(\"intentional_deadlock\",\n          []() { std::thread([]() { py::gil_scoped_acquire gil_acquired; }).join(); });\n\n    py::class_<VirtClass, PyVirtClass>(m, \"VirtClass\")\n        .def(py::init<>())\n        .def(\"virtual_func\", &VirtClass::virtual_func)\n        .def(\"pure_virtual_func\", &VirtClass::pure_virtual_func);\n\n    m.def(\"test_callback_py_obj\", [](py::object &func) { func(); });\n    m.def(\"test_callback_std_func\", [](const std::function<void()> &func) { func(); });\n    m.def(\"test_callback_virtual_func\", [](VirtClass &virt) { virt.virtual_func(); });\n    m.def(\"test_callback_pure_virtual_func\", [](VirtClass &virt) { virt.pure_virtual_func(); });\n    m.def(\"test_cross_module_gil_released\", []() {\n        CROSS_MODULE(\"gil_acquire_funcaddr\")\n        py::gil_scoped_release gil_release;\n        target();\n    });\n    m.def(\"test_cross_module_gil_acquired\", []() {\n        CROSS_MODULE(\"gil_acquire_funcaddr\")\n        py::gil_scoped_acquire gil_acquire;\n        target();\n    });\n    m.def(\"test_cross_module_gil_inner_custom_released\", []() {\n        CROSS_MODULE(\"gil_acquire_inner_custom_funcaddr\")\n        py::gil_scoped_release gil_release;\n        target();\n    });\n    m.def(\"test_cross_module_gil_inner_custom_acquired\", []() {\n        CROSS_MODULE(\"gil_acquire_inner_custom_funcaddr\")\n        py::gil_scoped_acquire gil_acquire;\n        target();\n    });\n    m.def(\"test_cross_module_gil_inner_pybind11_released\", []() {\n        CROSS_MODULE(\"gil_acquire_inner_pybind11_funcaddr\")\n        py::gil_scoped_release gil_release;\n        target();\n    });\n    m.def(\"test_cross_module_gil_inner_pybind11_acquired\", []() {\n        CROSS_MODULE(\"gil_acquire_inner_pybind11_funcaddr\")\n        py::gil_scoped_acquire gil_acquire;\n        target();\n    });\n    m.def(\"test_cross_module_gil_nested_custom_released\", []() {\n        CROSS_MODULE(\"gil_acquire_nested_custom_funcaddr\")\n        py::gil_scoped_release gil_release;\n        target();\n    });\n    m.def(\"test_cross_module_gil_nested_custom_acquired\", []() {\n        CROSS_MODULE(\"gil_acquire_nested_custom_funcaddr\")\n        py::gil_scoped_acquire gil_acquire;\n        target();\n    });\n    m.def(\"test_cross_module_gil_nested_pybind11_released\", []() {\n        CROSS_MODULE(\"gil_acquire_nested_pybind11_funcaddr\")\n        py::gil_scoped_release gil_release;\n        target();\n    });\n    m.def(\"test_cross_module_gil_nested_pybind11_acquired\", []() {\n        CROSS_MODULE(\"gil_acquire_nested_pybind11_funcaddr\")\n        py::gil_scoped_acquire gil_acquire;\n        target();\n    });\n    m.def(\"test_release_acquire\", [](const py::object &obj) {\n        py::gil_scoped_release gil_released;\n        py::gil_scoped_acquire gil_acquired;\n        return py::str(obj);\n    });\n    m.def(\"test_nested_acquire\", [](const py::object &obj) {\n        py::gil_scoped_release gil_released;\n        py::gil_scoped_acquire gil_acquired_outer;\n        py::gil_scoped_acquire gil_acquired_inner;\n        return py::str(obj);\n    });\n    m.def(\"test_multi_acquire_release_cross_module\", [](unsigned bits) {\n        py::set internals_ids;\n        internals_ids.add(PYBIND11_INTERNALS_ID);\n        {\n            py::gil_scoped_release gil_released;\n            auto thread_f = [bits, &internals_ids]() {\n                py::gil_scoped_acquire gil_acquired;\n                auto cm = py::module_::import(\"cross_module_gil_utils\");\n                auto target = reinterpret_cast<std::string (*)(unsigned)>(\n                    PyLong_AsVoidPtr(cm.attr(\"gil_multi_acquire_release_funcaddr\").ptr()));\n                std::string cm_internals_id = target(bits >> 3);\n                internals_ids.add(cm_internals_id);\n            };\n            if ((bits & 0x1u) != 0u) {\n                thread_f();\n            }\n            if ((bits & 0x2u) != 0u) {\n                std::thread non_python_thread(thread_f);\n                non_python_thread.join();\n            }\n            if ((bits & 0x4u) != 0u) {\n                thread_f();\n            }\n        }\n        return internals_ids;\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_gil_scoped.py",
    "content": "import multiprocessing\nimport sys\nimport threading\nimport time\n\nimport pytest\n\nimport env\nfrom pybind11_tests import gil_scoped as m\n\n\nclass ExtendedVirtClass(m.VirtClass):\n    def virtual_func(self):\n        pass\n\n    def pure_virtual_func(self):\n        pass\n\n\ndef test_callback_py_obj():\n    m.test_callback_py_obj(lambda: None)\n\n\ndef test_callback_std_func():\n    m.test_callback_std_func(lambda: None)\n\n\ndef test_callback_virtual_func():\n    extended = ExtendedVirtClass()\n    m.test_callback_virtual_func(extended)\n\n\ndef test_callback_pure_virtual_func():\n    extended = ExtendedVirtClass()\n    m.test_callback_pure_virtual_func(extended)\n\n\ndef test_cross_module_gil_released():\n    \"\"\"Makes sure that the GIL can be acquired by another module from a GIL-released state.\"\"\"\n    m.test_cross_module_gil_released()  # Should not raise a SIGSEGV\n\n\ndef test_cross_module_gil_acquired():\n    \"\"\"Makes sure that the GIL can be acquired by another module from a GIL-acquired state.\"\"\"\n    m.test_cross_module_gil_acquired()  # Should not raise a SIGSEGV\n\n\ndef test_cross_module_gil_inner_custom_released():\n    \"\"\"Makes sure that the GIL can be acquired/released by another module\n    from a GIL-released state using custom locking logic.\"\"\"\n    m.test_cross_module_gil_inner_custom_released()\n\n\ndef test_cross_module_gil_inner_custom_acquired():\n    \"\"\"Makes sure that the GIL can be acquired/acquired by another module\n    from a GIL-acquired state using custom locking logic.\"\"\"\n    m.test_cross_module_gil_inner_custom_acquired()\n\n\ndef test_cross_module_gil_inner_pybind11_released():\n    \"\"\"Makes sure that the GIL can be acquired/released by another module\n    from a GIL-released state using pybind11 locking logic.\"\"\"\n    m.test_cross_module_gil_inner_pybind11_released()\n\n\ndef test_cross_module_gil_inner_pybind11_acquired():\n    \"\"\"Makes sure that the GIL can be acquired/acquired by another module\n    from a GIL-acquired state using pybind11 locking logic.\"\"\"\n    m.test_cross_module_gil_inner_pybind11_acquired()\n\n\ndef test_cross_module_gil_nested_custom_released():\n    \"\"\"Makes sure that the GIL can be nested acquired/released by another module\n    from a GIL-released state using custom locking logic.\"\"\"\n    m.test_cross_module_gil_nested_custom_released()\n\n\ndef test_cross_module_gil_nested_custom_acquired():\n    \"\"\"Makes sure that the GIL can be nested acquired/acquired by another module\n    from a GIL-acquired state using custom locking logic.\"\"\"\n    m.test_cross_module_gil_nested_custom_acquired()\n\n\ndef test_cross_module_gil_nested_pybind11_released():\n    \"\"\"Makes sure that the GIL can be nested acquired/released by another module\n    from a GIL-released state using pybind11 locking logic.\"\"\"\n    m.test_cross_module_gil_nested_pybind11_released()\n\n\ndef test_cross_module_gil_nested_pybind11_acquired():\n    \"\"\"Makes sure that the GIL can be nested acquired/acquired by another module\n    from a GIL-acquired state using pybind11 locking logic.\"\"\"\n    m.test_cross_module_gil_nested_pybind11_acquired()\n\n\ndef test_release_acquire():\n    assert m.test_release_acquire(0xAB) == \"171\"\n\n\ndef test_nested_acquire():\n    assert m.test_nested_acquire(0xAB) == \"171\"\n\n\ndef test_multi_acquire_release_cross_module():\n    for bits in range(16 * 8):\n        internals_ids = m.test_multi_acquire_release_cross_module(bits)\n        assert len(internals_ids) == 2 if bits % 8 else 1\n\n\n# Intentionally putting human review in the loop here, to guard against accidents.\nVARS_BEFORE_ALL_BASIC_TESTS = dict(vars())  # Make a copy of the dict (critical).\nALL_BASIC_TESTS = (\n    test_callback_py_obj,\n    test_callback_std_func,\n    test_callback_virtual_func,\n    test_callback_pure_virtual_func,\n    test_cross_module_gil_released,\n    test_cross_module_gil_acquired,\n    test_cross_module_gil_inner_custom_released,\n    test_cross_module_gil_inner_custom_acquired,\n    test_cross_module_gil_inner_pybind11_released,\n    test_cross_module_gil_inner_pybind11_acquired,\n    test_cross_module_gil_nested_custom_released,\n    test_cross_module_gil_nested_custom_acquired,\n    test_cross_module_gil_nested_pybind11_released,\n    test_cross_module_gil_nested_pybind11_acquired,\n    test_release_acquire,\n    test_nested_acquire,\n    test_multi_acquire_release_cross_module,\n)\n\n\ndef test_all_basic_tests_completeness():\n    num_found = 0\n    for key, value in VARS_BEFORE_ALL_BASIC_TESTS.items():\n        if not key.startswith(\"test_\"):\n            continue\n        assert value in ALL_BASIC_TESTS\n        num_found += 1\n    assert len(ALL_BASIC_TESTS) == num_found\n\n\ndef _intentional_deadlock():\n    m.intentional_deadlock()\n\n\nALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK = ALL_BASIC_TESTS + (_intentional_deadlock,)\n\n\ndef _run_in_process(target, *args, **kwargs):\n    if len(args) == 0:\n        test_fn = target\n    else:\n        test_fn = args[0]\n    # Do not need to wait much, 10s should be more than enough.\n    timeout = 0.1 if test_fn is _intentional_deadlock else 10\n    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)\n    process.daemon = True\n    try:\n        t_start = time.time()\n        process.start()\n        if timeout >= 100:  # For debugging.\n            print(\n                \"\\nprocess.pid STARTED\", process.pid, (sys.argv, target, args, kwargs)\n            )\n            print(f\"COPY-PASTE-THIS: gdb {sys.argv[0]} -p {process.pid}\", flush=True)\n        process.join(timeout=timeout)\n        if timeout >= 100:\n            print(\"\\nprocess.pid JOINED\", process.pid, flush=True)\n        t_delta = time.time() - t_start\n        if process.exitcode == 66 and m.defined_THREAD_SANITIZER:  # Issue #2754\n            # WOULD-BE-NICE-TO-HAVE: Check that the message below is actually in the output.\n            # Maybe this could work:\n            # https://gist.github.com/alexeygrigorev/01ce847f2e721b513b42ea4a6c96905e\n            pytest.skip(\n                \"ThreadSanitizer: starting new threads after multi-threaded fork is not supported.\"\n            )\n        elif test_fn is _intentional_deadlock:\n            assert process.exitcode is None\n            return 0\n        elif process.exitcode is None:\n            assert t_delta > 0.9 * timeout\n            msg = \"DEADLOCK, most likely, exactly what this test is meant to detect.\"\n            if env.PYPY and env.WIN:\n                pytest.skip(msg)\n            raise RuntimeError(msg)\n        return process.exitcode\n    finally:\n        if process.is_alive():\n            process.terminate()\n\n\ndef _run_in_threads(test_fn, num_threads, parallel):\n    threads = []\n    for _ in range(num_threads):\n        thread = threading.Thread(target=test_fn)\n        thread.daemon = True\n        thread.start()\n        if parallel:\n            threads.append(thread)\n        else:\n            thread.join()\n    for thread in threads:\n        thread.join()\n\n\n# TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9\n@pytest.mark.parametrize(\"test_fn\", ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK)\ndef test_run_in_process_one_thread(test_fn):\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert _run_in_process(_run_in_threads, test_fn, num_threads=1, parallel=False) == 0\n\n\n# TODO: FIXME on macOS Python 3.9\n@pytest.mark.parametrize(\"test_fn\", ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK)\ndef test_run_in_process_multiple_threads_parallel(test_fn):\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert _run_in_process(_run_in_threads, test_fn, num_threads=8, parallel=True) == 0\n\n\n# TODO: FIXME on macOS Python 3.9\n@pytest.mark.parametrize(\"test_fn\", ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK)\ndef test_run_in_process_multiple_threads_sequential(test_fn):\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert _run_in_process(_run_in_threads, test_fn, num_threads=8, parallel=False) == 0\n\n\n# TODO: FIXME on macOS Python 3.9\n@pytest.mark.parametrize(\"test_fn\", ALL_BASIC_TESTS_PLUS_INTENTIONAL_DEADLOCK)\ndef test_run_in_process_direct(test_fn):\n    \"\"\"Makes sure there is no GIL deadlock when using processes.\n\n    This test is for completion, but it was never an issue.\n    \"\"\"\n    assert _run_in_process(test_fn) == 0\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_iostream.cpp",
    "content": "/*\n    tests/test_iostream.cpp -- Usage of scoped_output_redirect\n\n    Copyright (c) 2017 Henry F. Schreiner\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/iostream.h>\n\n#include \"pybind11_tests.h\"\n\n#include <atomic>\n#include <iostream>\n#include <mutex>\n#include <string>\n#include <thread>\n\nvoid noisy_function(const std::string &msg, bool flush) {\n\n    std::cout << msg;\n    if (flush) {\n        std::cout << std::flush;\n    }\n}\n\nvoid noisy_funct_dual(const std::string &msg, const std::string &emsg) {\n    std::cout << msg;\n    std::cerr << emsg;\n}\n\n// object to manage C++ thread\n// simply repeatedly write to std::cerr until stopped\n// redirect is called at some point to test the safety of scoped_estream_redirect\nstruct TestThread {\n    TestThread() : stop_{false} {\n        auto thread_f = [this] {\n            static std::mutex cout_mutex;\n            while (!stop_) {\n                {\n                    // #HelpAppreciated: Work on iostream.h thread safety.\n                    // Without this lock, the clang ThreadSanitizer (tsan) reliably reports a\n                    // data race, and this test is predictably flakey on Windows.\n                    // For more background see the discussion under\n                    // https://github.com/pybind/pybind11/pull/2982 and\n                    // https://github.com/pybind/pybind11/pull/2995.\n                    const std::lock_guard<std::mutex> lock(cout_mutex);\n                    std::cout << \"x\" << std::flush;\n                }\n                std::this_thread::sleep_for(std::chrono::microseconds(50));\n            }\n        };\n        t_ = new std::thread(std::move(thread_f));\n    }\n\n    ~TestThread() { delete t_; }\n\n    void stop() { stop_ = true; }\n\n    void join() const {\n        py::gil_scoped_release gil_lock;\n        t_->join();\n    }\n\n    void sleep() {\n        py::gil_scoped_release gil_lock;\n        std::this_thread::sleep_for(std::chrono::milliseconds(50));\n    }\n\n    std::thread *t_{nullptr};\n    std::atomic<bool> stop_;\n};\n\nTEST_SUBMODULE(iostream, m) {\n\n    add_ostream_redirect(m);\n\n    // test_evals\n\n    m.def(\"captured_output_default\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir;\n        std::cout << msg << std::flush;\n    });\n\n    m.def(\"captured_output\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir(std::cout, py::module_::import(\"sys\").attr(\"stdout\"));\n        std::cout << msg << std::flush;\n    });\n\n    m.def(\"guard_output\",\n          &noisy_function,\n          py::call_guard<py::scoped_ostream_redirect>(),\n          py::arg(\"msg\"),\n          py::arg(\"flush\") = true);\n\n    m.def(\"captured_err\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir(std::cerr, py::module_::import(\"sys\").attr(\"stderr\"));\n        std::cerr << msg << std::flush;\n    });\n\n    m.def(\"noisy_function\", &noisy_function, py::arg(\"msg\"), py::arg(\"flush\") = true);\n\n    m.def(\"dual_guard\",\n          &noisy_funct_dual,\n          py::call_guard<py::scoped_ostream_redirect, py::scoped_estream_redirect>(),\n          py::arg(\"msg\"),\n          py::arg(\"emsg\"));\n\n    m.def(\"raw_output\", [](const std::string &msg) { std::cout << msg << std::flush; });\n\n    m.def(\"raw_err\", [](const std::string &msg) { std::cerr << msg << std::flush; });\n\n    m.def(\"captured_dual\", [](const std::string &msg, const std::string &emsg) {\n        py::scoped_ostream_redirect redirout(std::cout, py::module_::import(\"sys\").attr(\"stdout\"));\n        py::scoped_ostream_redirect redirerr(std::cerr, py::module_::import(\"sys\").attr(\"stderr\"));\n        std::cout << msg << std::flush;\n        std::cerr << emsg << std::flush;\n    });\n\n    py::class_<TestThread>(m, \"TestThread\")\n        .def(py::init<>())\n        .def(\"stop\", &TestThread::stop)\n        .def(\"join\", &TestThread::join)\n        .def(\"sleep\", &TestThread::sleep);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_iostream.py",
    "content": "from contextlib import redirect_stderr, redirect_stdout\nfrom io import StringIO\n\nfrom pybind11_tests import iostream as m\n\n\ndef test_captured(capsys):\n    msg = \"I've been redirected to Python, I hope!\"\n    m.captured_output(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n    m.captured_err(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == \"\"\n    assert stderr == msg\n\n\ndef test_captured_large_string(capsys):\n    # Make this bigger than the buffer used on the C++ side: 1024 chars\n    msg = \"I've been redirected to Python, I hope!\"\n    msg = msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_2byte_offset0(capsys):\n    msg = \"\\u07FF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_2byte_offset1(capsys):\n    msg = \"\\u07FF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset0(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset1(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset2(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"12\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset0(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset1(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset2(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"12\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset3(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"123\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_guard_capture(capsys):\n    msg = \"I've been redirected to Python, I hope!\"\n    m.guard_output(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_series_captured(capture):\n    with capture:\n        m.captured_output(\"a\")\n        m.captured_output(\"b\")\n    assert capture == \"ab\"\n\n\ndef test_flush(capfd):\n    msg = \"(not flushed)\"\n    msg2 = \"(flushed)\"\n\n    with m.ostream_redirect():\n        m.noisy_function(msg, flush=False)\n        stdout, stderr = capfd.readouterr()\n        assert stdout == \"\"\n\n        m.noisy_function(msg2, flush=True)\n        stdout, stderr = capfd.readouterr()\n        assert stdout == msg + msg2\n\n        m.noisy_function(msg, flush=False)\n\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n\n\ndef test_not_captured(capfd):\n    msg = \"Something that should not show up in log\"\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.captured_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n\n\ndef test_err(capfd):\n    msg = \"Something that should not show up in log\"\n    stream = StringIO()\n    with redirect_stderr(stream):\n        m.raw_err(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == msg\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stderr(stream):\n        m.captured_err(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n\n\ndef test_multi_captured(capfd):\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.captured_output(\"a\")\n        m.raw_output(\"b\")\n        m.captured_output(\"c\")\n        m.raw_output(\"d\")\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"bd\"\n    assert stream.getvalue() == \"ac\"\n\n\ndef test_dual(capsys):\n    m.captured_dual(\"a\", \"b\")\n    stdout, stderr = capsys.readouterr()\n    assert stdout == \"a\"\n    assert stderr == \"b\"\n\n\ndef test_redirect(capfd):\n    msg = \"Should not be in log!\"\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        with m.ostream_redirect():\n            m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stream.getvalue() == msg\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stream.getvalue() == \"\"\n\n\ndef test_redirect_err(capfd):\n    msg = \"StdOut\"\n    msg2 = \"StdErr\"\n\n    stream = StringIO()\n    with redirect_stderr(stream):\n        with m.ostream_redirect(stdout=False):\n            m.raw_output(msg)\n            m.raw_err(msg2)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n    assert stream.getvalue() == msg2\n\n\ndef test_redirect_both(capfd):\n    msg = \"StdOut\"\n    msg2 = \"StdErr\"\n\n    stream = StringIO()\n    stream2 = StringIO()\n    with redirect_stdout(stream):\n        with redirect_stderr(stream2):\n            with m.ostream_redirect():\n                m.raw_output(msg)\n                m.raw_err(msg2)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n    assert stream2.getvalue() == msg2\n\n\ndef test_threading():\n    with m.ostream_redirect(stdout=True, stderr=False):\n        # start some threads\n        threads = []\n\n        # start some threads\n        for _j in range(20):\n            threads.append(m.TestThread())\n\n        # give the threads some time to fail\n        threads[0].sleep()\n\n        # stop all the threads\n        for t in threads:\n            t.stop()\n\n        for t in threads:\n            t.join()\n\n        # if a thread segfaults, we don't get here\n        assert True\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_kwargs_and_defaults.cpp",
    "content": "/*\n    tests/test_kwargs_and_defaults.cpp -- keyword arguments and default values\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nTEST_SUBMODULE(kwargs_and_defaults, m) {\n    auto kw_func\n        = [](int x, int y) { return \"x=\" + std::to_string(x) + \", y=\" + std::to_string(y); };\n\n    // test_named_arguments\n    m.def(\"kw_func0\", kw_func);\n    m.def(\"kw_func1\", kw_func, py::arg(\"x\"), py::arg(\"y\"));\n    m.def(\"kw_func2\", kw_func, py::arg(\"x\") = 100, py::arg(\"y\") = 200);\n    m.def(\n        \"kw_func3\", [](const char *) {}, py::arg(\"data\") = std::string(\"Hello world!\"));\n\n    /* A fancier default argument */\n    std::vector<int> list{{13, 17}};\n    m.def(\n        \"kw_func4\",\n        [](const std::vector<int> &entries) {\n            std::string ret = \"{\";\n            for (int i : entries) {\n                ret += std::to_string(i) + \" \";\n            }\n            ret.back() = '}';\n            return ret;\n        },\n        py::arg(\"myList\") = list);\n\n    m.def(\"kw_func_udl\", kw_func, \"x\"_a, \"y\"_a = 300);\n    m.def(\"kw_func_udl_z\", kw_func, \"x\"_a, \"y\"_a = 0);\n\n    // test_args_and_kwargs\n    m.def(\"args_function\", [](py::args args) -> py::tuple {\n#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wreturn-std-move\"\n#endif\n        return args;\n#ifdef PYBIND11_DETECTED_CLANG_WITH_MISLEADING_CALL_STD_MOVE_EXPLICITLY_WARNING\n#    pragma clang diagnostic pop\n#endif\n    });\n    m.def(\"args_kwargs_function\", [](const py::args &args, const py::kwargs &kwargs) {\n        return py::make_tuple(args, kwargs);\n    });\n\n    // test_mixed_args_and_kwargs\n    m.def(\"mixed_plus_args\",\n          [](int i, double j, const py::args &args) { return py::make_tuple(i, j, args); });\n    m.def(\"mixed_plus_kwargs\",\n          [](int i, double j, const py::kwargs &kwargs) { return py::make_tuple(i, j, kwargs); });\n    auto mixed_plus_both = [](int i, double j, const py::args &args, const py::kwargs &kwargs) {\n        return py::make_tuple(i, j, args, kwargs);\n    };\n    m.def(\"mixed_plus_args_kwargs\", mixed_plus_both);\n\n    m.def(\"mixed_plus_args_kwargs_defaults\",\n          mixed_plus_both,\n          py::arg(\"i\") = 1,\n          py::arg(\"j\") = 3.14159);\n\n    m.def(\n        \"args_kwonly\",\n        [](int i, double j, const py::args &args, int z) { return py::make_tuple(i, j, args, z); },\n        \"i\"_a,\n        \"j\"_a,\n        \"z\"_a);\n    m.def(\n        \"args_kwonly_kwargs\",\n        [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, args, z, kwargs);\n        },\n        \"i\"_a,\n        \"j\"_a,\n        py::kw_only{},\n        \"z\"_a);\n    m.def(\n        \"args_kwonly_kwargs_defaults\",\n        [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, args, z, kwargs);\n        },\n        \"i\"_a = 1,\n        \"j\"_a = 3.14159,\n        \"z\"_a = 42);\n    m.def(\n        \"args_kwonly_full_monty\",\n        [](int h, int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(h, i, j, args, z, kwargs);\n        },\n        py::arg() = 1,\n        py::arg() = 2,\n        py::pos_only{},\n        \"j\"_a = 3.14159,\n        \"z\"_a = 42);\n\n// test_args_refcount\n// PyPy needs a garbage collection to get the reference count values to match CPython's behaviour\n#ifdef PYPY_VERSION\n#    define GC_IF_NEEDED ConstructorStats::gc()\n#else\n#    define GC_IF_NEEDED\n#endif\n    m.def(\"arg_refcount_h\", [](py::handle h) {\n        GC_IF_NEEDED;\n        return h.ref_count();\n    });\n    m.def(\"arg_refcount_h\", [](py::handle h, py::handle, py::handle) {\n        GC_IF_NEEDED;\n        return h.ref_count();\n    });\n    m.def(\"arg_refcount_o\", [](const py::object &o) {\n        GC_IF_NEEDED;\n        return o.ref_count();\n    });\n    m.def(\"args_refcount\", [](py::args a) {\n        GC_IF_NEEDED;\n        py::tuple t(a.size());\n        for (size_t i = 0; i < a.size(); i++) {\n            // Use raw Python API here to avoid an extra, intermediate incref on the tuple item:\n            t[i] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i)));\n        }\n        return t;\n    });\n    m.def(\"mixed_args_refcount\", [](const py::object &o, py::args a) {\n        GC_IF_NEEDED;\n        py::tuple t(a.size() + 1);\n        t[0] = o.ref_count();\n        for (size_t i = 0; i < a.size(); i++) {\n            // Use raw Python API here to avoid an extra, intermediate incref on the tuple item:\n            t[i + 1] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i)));\n        }\n        return t;\n    });\n\n    // pybind11 won't allow these to be bound: args and kwargs, if present, must be at the end.\n    // Uncomment these to test that the static_assert is indeed working:\n    //    m.def(\"bad_args1\", [](py::args, int) {});\n    //    m.def(\"bad_args2\", [](py::kwargs, int) {});\n    //    m.def(\"bad_args3\", [](py::kwargs, py::args) {});\n    //    m.def(\"bad_args4\", [](py::args, int, py::kwargs) {});\n    //    m.def(\"bad_args5\", [](py::args, py::kwargs, int) {});\n    //    m.def(\"bad_args6\", [](py::args, py::args) {});\n    //    m.def(\"bad_args7\", [](py::kwargs, py::kwargs) {});\n\n    // test_keyword_only_args\n    m.def(\n        \"kw_only_all\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::kw_only(),\n        py::arg(\"i\"),\n        py::arg(\"j\"));\n    m.def(\n        \"kw_only_some\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(),\n        py::kw_only(),\n        py::arg(\"j\"),\n        py::arg(\"k\"));\n    m.def(\n        \"kw_only_with_defaults\",\n        [](int i, int j, int k, int z) { return py::make_tuple(i, j, k, z); },\n        py::arg() = 3,\n        \"j\"_a = 4,\n        py::kw_only(),\n        \"k\"_a = 5,\n        \"z\"_a);\n    m.def(\n        \"kw_only_mixed\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        \"i\"_a,\n        py::kw_only(),\n        \"j\"_a);\n    m.def(\n        \"kw_only_plus_more\",\n        [](int i, int j, int k, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, k, kwargs);\n        },\n        py::arg() /* positional */,\n        py::arg(\"j\") = -1 /* both */,\n        py::kw_only(),\n        py::arg(\"k\") /* kw-only */);\n\n    m.def(\"register_invalid_kw_only\", [](py::module_ m) {\n        m.def(\n            \"bad_kw_only\",\n            [](int i, int j) { return py::make_tuple(i, j); },\n            py::kw_only(),\n            py::arg() /* invalid unnamed argument */,\n            \"j\"_a);\n    });\n\n    // test_positional_only_args\n    m.def(\n        \"pos_only_all\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::arg(\"i\"),\n        py::arg(\"j\"),\n        py::pos_only());\n    m.def(\n        \"pos_only_mix\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::arg(\"i\"),\n        py::pos_only(),\n        py::arg(\"j\"));\n    m.def(\n        \"pos_kw_only_mix\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(\"i\"),\n        py::pos_only(),\n        py::arg(\"j\"),\n        py::kw_only(),\n        py::arg(\"k\"));\n    m.def(\n        \"pos_only_def_mix\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(\"i\"),\n        py::arg(\"j\") = 2,\n        py::pos_only(),\n        py::arg(\"k\") = 3);\n\n    // These should fail to compile:\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n    // argument annotations are required when using kw_only\n    m.def(\n        \"bad_kw_only1\", [](int) {}, py::kw_only());\n    // can't specify both `py::kw_only` and a `py::args` argument\n    m.def(\n        \"bad_kw_only2\", [](int i, py::args) {}, py::kw_only(), \"i\"_a);\n#endif\n\n    // test_function_signatures (along with most of the above)\n    struct KWClass {\n        void foo(int, float) {}\n    };\n    py::class_<KWClass>(m, \"KWClass\")\n        .def(\"foo0\", &KWClass::foo)\n        .def(\"foo1\", &KWClass::foo, \"x\"_a, \"y\"_a);\n\n    // Make sure a class (not an instance) can be used as a default argument.\n    // The return value doesn't matter, only that the module is importable.\n    m.def(\n        \"class_default_argument\",\n        [](py::object a) { return py::repr(std::move(a)); },\n        \"a\"_a = py::module_::import(\"decimal\").attr(\"Decimal\"));\n\n    // Initial implementation of kw_only was broken when used on a method/constructor before any\n    // other arguments\n    // https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n\n    struct first_arg_kw_only {};\n    py::class_<first_arg_kw_only>(m, \"first_arg_kw_only\")\n        .def(py::init([](int) { return first_arg_kw_only(); }),\n             py::kw_only(), // This being before any args was broken\n             py::arg(\"i\") = 0)\n        .def(\n            \"method\",\n            [](first_arg_kw_only &, int, int) {},\n            py::kw_only(), // and likewise here\n            py::arg(\"i\") = 1,\n            py::arg(\"j\") = 2)\n        // Closely related: pos_only marker didn't show up properly when it was before any other\n        // arguments (although that is fairly useless in practice).\n        .def(\n            \"pos_only\",\n            [](first_arg_kw_only &, int, int) {},\n            py::pos_only{},\n            py::arg(\"i\"),\n            py::arg(\"j\"));\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_kwargs_and_defaults.py",
    "content": "import pytest\n\nfrom pybind11_tests import kwargs_and_defaults as m\n\n\ndef test_function_signatures(doc):\n    assert doc(m.kw_func0) == \"kw_func0(arg0: int, arg1: int) -> str\"\n    assert doc(m.kw_func1) == \"kw_func1(x: int, y: int) -> str\"\n    assert doc(m.kw_func2) == \"kw_func2(x: int = 100, y: int = 200) -> str\"\n    assert doc(m.kw_func3) == \"kw_func3(data: str = 'Hello world!') -> None\"\n    assert doc(m.kw_func4) == \"kw_func4(myList: List[int] = [13, 17]) -> str\"\n    assert doc(m.kw_func_udl) == \"kw_func_udl(x: int, y: int = 300) -> str\"\n    assert doc(m.kw_func_udl_z) == \"kw_func_udl_z(x: int, y: int = 0) -> str\"\n    assert doc(m.args_function) == \"args_function(*args) -> tuple\"\n    assert (\n        doc(m.args_kwargs_function) == \"args_kwargs_function(*args, **kwargs) -> tuple\"\n    )\n    assert (\n        doc(m.KWClass.foo0)\n        == \"foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None\"\n    )\n    assert (\n        doc(m.KWClass.foo1)\n        == \"foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None\"\n    )\n\n\ndef test_named_arguments(msg):\n    assert m.kw_func0(5, 10) == \"x=5, y=10\"\n\n    assert m.kw_func1(5, 10) == \"x=5, y=10\"\n    assert m.kw_func1(5, y=10) == \"x=5, y=10\"\n    assert m.kw_func1(y=10, x=5) == \"x=5, y=10\"\n\n    assert m.kw_func2() == \"x=100, y=200\"\n    assert m.kw_func2(5) == \"x=5, y=200\"\n    assert m.kw_func2(x=5) == \"x=5, y=200\"\n    assert m.kw_func2(y=10) == \"x=100, y=10\"\n    assert m.kw_func2(5, 10) == \"x=5, y=10\"\n    assert m.kw_func2(x=5, y=10) == \"x=5, y=10\"\n\n    with pytest.raises(TypeError) as excinfo:\n        # noinspection PyArgumentList\n        m.kw_func2(x=5, y=10, z=12)\n    assert excinfo.match(\n        r\"(?s)^kw_func2\\(\\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))\"\n        + \"{3}$\"\n    )\n\n    assert m.kw_func4() == \"{13 17}\"\n    assert m.kw_func4(myList=[1, 2, 3]) == \"{1 2 3}\"\n\n    assert m.kw_func_udl(x=5, y=10) == \"x=5, y=10\"\n    assert m.kw_func_udl_z(x=5) == \"x=5, y=0\"\n\n\ndef test_arg_and_kwargs():\n    args = \"arg1_value\", \"arg2_value\", 3\n    assert m.args_function(*args) == args\n\n    args = \"a1\", \"a2\"\n    kwargs = dict(arg3=\"a3\", arg4=4)\n    assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)\n\n\ndef test_mixed_args_and_kwargs(msg):\n    mpa = m.mixed_plus_args\n    mpk = m.mixed_plus_kwargs\n    mpak = m.mixed_plus_args_kwargs\n    mpakd = m.mixed_plus_args_kwargs_defaults\n\n    assert mpa(1, 2.5, 4, 99.5, None) == (1, 2.5, (4, 99.5, None))\n    assert mpa(1, 2.5) == (1, 2.5, ())\n    with pytest.raises(TypeError) as excinfo:\n        assert mpa(1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: int, arg1: float, *args) -> tuple\n\n        Invoked with: 1\n    \"\"\"\n    )\n    with pytest.raises(TypeError) as excinfo:\n        assert mpa()\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: int, arg1: float, *args) -> tuple\n\n        Invoked with:\n    \"\"\"\n    )\n\n    assert mpk(-2, 3.5, pi=3.14159, e=2.71828) == (\n        -2,\n        3.5,\n        {\"e\": 2.71828, \"pi\": 3.14159},\n    )\n    assert mpak(7, 7.7, 7.77, 7.777, 7.7777, minusseven=-7) == (\n        7,\n        7.7,\n        (7.77, 7.777, 7.7777),\n        {\"minusseven\": -7},\n    )\n    assert mpakd() == (1, 3.14159, (), {})\n    assert mpakd(3) == (3, 3.14159, (), {})\n    assert mpakd(j=2.71828) == (1, 2.71828, (), {})\n    assert mpakd(k=42) == (1, 3.14159, (), {\"k\": 42})\n    assert mpakd(1, 1, 2, 3, 5, 8, then=13, followedby=21) == (\n        1,\n        1,\n        (2, 3, 5, 8),\n        {\"then\": 13, \"followedby\": 21},\n    )\n    # Arguments specified both positionally and via kwargs should fail:\n    with pytest.raises(TypeError) as excinfo:\n        assert mpakd(1, i=1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:\n            1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple\n\n        Invoked with: 1; kwargs: i=1\n    \"\"\"\n    )\n    with pytest.raises(TypeError) as excinfo:\n        assert mpakd(1, 2, j=1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:\n            1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple\n\n        Invoked with: 1, 2; kwargs: j=1\n    \"\"\"\n    )\n\n    # Arguments after a py::args are automatically keyword-only (pybind 2.9+)\n    assert m.args_kwonly(2, 2.5, z=22) == (2, 2.5, (), 22)\n    assert m.args_kwonly(2, 2.5, \"a\", \"b\", \"c\", z=22) == (2, 2.5, (\"a\", \"b\", \"c\"), 22)\n    assert m.args_kwonly(z=22, i=4, j=16) == (4, 16, (), 22)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.args_kwonly(2, 2.5, 22)  # missing z= keyword\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        args_kwonly(): incompatible function arguments. The following argument types are supported:\n            1. (i: int, j: float, *args, z: int) -> tuple\n\n        Invoked with: 2, 2.5, 22\n    \"\"\"\n    )\n\n    assert m.args_kwonly_kwargs(i=1, k=4, j=10, z=-1, y=9) == (\n        1,\n        10,\n        (),\n        -1,\n        {\"k\": 4, \"y\": 9},\n    )\n    assert m.args_kwonly_kwargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, z=11, y=12) == (\n        1,\n        2,\n        (3, 4, 5, 6, 7, 8, 9, 10),\n        11,\n        {\"y\": 12},\n    )\n    assert (\n        m.args_kwonly_kwargs.__doc__\n        == \"args_kwonly_kwargs(i: int, j: float, *args, z: int, **kwargs) -> tuple\\n\"\n    )\n\n    assert (\n        m.args_kwonly_kwargs_defaults.__doc__\n        == \"args_kwonly_kwargs_defaults(i: int = 1, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\\n\"  # noqa: E501 line too long\n    )\n    assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})\n    assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})\n    assert m.args_kwonly_kwargs_defaults(z=-99) == (1, 3.14159, (), -99, {})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, 8) == (5, 6, (7, 8), 42, {})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8) == (5, 6, (7,), 42, {\"m\": 8})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8, z=9) == (5, 6, (7,), 9, {\"m\": 8})\n\n\ndef test_keyword_only_args(msg):\n    assert m.kw_only_all(i=1, j=2) == (1, 2)\n    assert m.kw_only_all(j=1, i=2) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_all(i=1) == (1,)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_all(1, 2) == (1, 2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.kw_only_some(1, k=3, j=2) == (1, 2, 3)\n\n    assert m.kw_only_with_defaults(z=8) == (3, 4, 5, 8)\n    assert m.kw_only_with_defaults(2, z=8) == (2, 4, 5, 8)\n    assert m.kw_only_with_defaults(2, j=7, k=8, z=9) == (2, 7, 8, 9)\n    assert m.kw_only_with_defaults(2, 7, z=9, k=8) == (2, 7, 8, 9)\n\n    assert m.kw_only_mixed(1, j=2) == (1, 2)\n    assert m.kw_only_mixed(j=2, i=3) == (3, 2)\n    assert m.kw_only_mixed(i=2, j=3) == (2, 3)\n\n    assert m.kw_only_plus_more(4, 5, k=6, extra=7) == (4, 5, 6, {\"extra\": 7})\n    assert m.kw_only_plus_more(3, k=5, j=4, extra=6) == (3, 4, 5, {\"extra\": 6})\n    assert m.kw_only_plus_more(2, k=3, extra=4) == (2, -1, 3, {\"extra\": 4})\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_mixed(i=1) == (1,)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_invalid_kw_only(m)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        arg(): cannot specify an unnamed argument after a kw_only() annotation or args() argument\n    \"\"\"\n    )\n\n    # https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n    x = m.first_arg_kw_only(i=1)\n    x.method()\n    x.method(i=1, j=2)\n    assert (\n        m.first_arg_kw_only.__init__.__doc__\n        == \"__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 0) -> None\\n\"  # noqa: E501 line too long\n    )\n    assert (\n        m.first_arg_kw_only.method.__doc__\n        == \"method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 1, j: int = 2) -> None\\n\"  # noqa: E501 line too long\n    )\n\n\ndef test_positional_only_args(msg):\n    assert m.pos_only_all(1, 2) == (1, 2)\n    assert m.pos_only_all(2, 1) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_all(i=1, j=2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_only_mix(1, 2) == (1, 2)\n    assert m.pos_only_mix(2, j=1) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_mix(i=1, j=2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_kw_only_mix(1, 2, k=3) == (1, 2, 3)\n    assert m.pos_kw_only_mix(1, j=2, k=3) == (1, 2, 3)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_kw_only_mix(i=1, j=2, k=3)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_kw_only_mix(1, 2, 3)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_def_mix()\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_only_def_mix(1) == (1, 2, 3)\n    assert m.pos_only_def_mix(1, 4) == (1, 4, 3)\n    assert m.pos_only_def_mix(1, 4, 7) == (1, 4, 7)\n    assert m.pos_only_def_mix(1, 4, k=7) == (1, 4, 7)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_def_mix(1, j=4)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    # Mix it with args and kwargs:\n    assert (\n        m.args_kwonly_full_monty.__doc__\n        == \"args_kwonly_full_monty(arg0: int = 1, arg1: int = 2, /, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\\n\"  # noqa: E501 line too long\n    )\n    assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8, 9) == (8, 9, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8, 9, 10) == (8, 9, 10.0, (), 42, {})\n    assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (\n        3,\n        4,\n        5.0,\n        (\n            6,\n            7,\n        ),\n        9,\n        {\"m\": 8},\n    )\n    assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (\n        3,\n        4,\n        5.0,\n        (\n            6,\n            7,\n        ),\n        9,\n        {\"m\": 8},\n    )\n    assert m.args_kwonly_full_monty(5, j=7, m=8, z=9) == (5, 2, 7.0, (), 9, {\"m\": 8})\n    assert m.args_kwonly_full_monty(i=5, j=7, m=8, z=9) == (\n        1,\n        2,\n        7.0,\n        (),\n        9,\n        {\"i\": 5, \"m\": 8},\n    )\n\n    # pos_only at the beginning of the argument list was \"broken\" in how it was displayed (though\n    # this is fairly useless in practice).  Related to:\n    # https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n    assert (\n        m.first_arg_kw_only.pos_only.__doc__\n        == \"pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: int, j: int) -> None\\n\"  # noqa: E501 line too long\n    )\n\n\ndef test_signatures():\n    assert \"kw_only_all(*, i: int, j: int) -> tuple\\n\" == m.kw_only_all.__doc__\n    assert \"kw_only_mixed(i: int, *, j: int) -> tuple\\n\" == m.kw_only_mixed.__doc__\n    assert \"pos_only_all(i: int, j: int, /) -> tuple\\n\" == m.pos_only_all.__doc__\n    assert \"pos_only_mix(i: int, /, j: int) -> tuple\\n\" == m.pos_only_mix.__doc__\n    assert (\n        \"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\\n\"\n        == m.pos_kw_only_mix.__doc__\n    )\n\n\ndef test_args_refcount():\n    \"\"\"Issue/PR #1216 - py::args elements get double-inc_ref()ed when combined with regular\n    arguments\"\"\"\n    refcount = m.arg_refcount_h\n\n    myval = 54321\n    expected = refcount(myval)\n    assert m.arg_refcount_h(myval) == expected\n    assert m.arg_refcount_o(myval) == expected + 1\n    assert m.arg_refcount_h(myval) == expected\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_args(1, 2.0, \"a\", myval) == (1, 2.0, (\"a\", myval))\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_kwargs(3, 4.0, a=1, b=myval) == (3, 4.0, {\"a\": 1, \"b\": myval})\n    assert refcount(myval) == expected\n\n    assert m.args_function(-1, myval) == (-1, myval)\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_args_kwargs(5, 6.0, myval, a=myval) == (\n        5,\n        6.0,\n        (myval,),\n        {\"a\": myval},\n    )\n    assert refcount(myval) == expected\n\n    assert m.args_kwargs_function(7, 8, myval, a=1, b=myval) == (\n        (7, 8, myval),\n        {\"a\": 1, \"b\": myval},\n    )\n    assert refcount(myval) == expected\n\n    exp3 = refcount(myval, myval, myval)\n    assert m.args_refcount(myval, myval, myval) == (exp3, exp3, exp3)\n    assert refcount(myval) == expected\n\n    # This function takes the first arg as a `py::object` and the rest as a `py::args`.  Unlike the\n    # previous case, when we have both positional and `py::args` we need to construct a new tuple\n    # for the `py::args`; in the previous case, we could simply inc_ref and pass on Python's input\n    # tuple without having to inc_ref the individual elements, but here we can't, hence the extra\n    # refs.\n    assert m.mixed_args_refcount(myval, myval, myval) == (exp3 + 3, exp3 + 3, exp3 + 3)\n\n    assert m.class_default_argument() == \"<class 'decimal.Decimal'>\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_local_bindings.cpp",
    "content": "/*\n    tests/test_local_bindings.cpp -- tests the py::module_local class feature which makes a class\n                                     binding local to the module in which it is defined.\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n#include <pybind11/stl_bind.h>\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <numeric>\n#include <utility>\n\nTEST_SUBMODULE(local_bindings, m) {\n    // test_load_external\n    m.def(\"load_external1\", [](ExternalType1 &e) { return e.i; });\n    m.def(\"load_external2\", [](ExternalType2 &e) { return e.i; });\n\n    // test_local_bindings\n    // Register a class with py::module_local:\n    bind_local<LocalType, -1>(m, \"LocalType\", py::module_local()).def(\"get3\", [](LocalType &t) {\n        return t.i + 3;\n    });\n\n    m.def(\"local_value\", [](LocalType &l) { return l.i; });\n\n    // test_nonlocal_failure\n    // The main pybind11 test module is loaded first, so this registration will succeed (the second\n    // one, in pybind11_cross_module_tests.cpp, is designed to fail):\n    bind_local<NonLocalType, 0>(m, \"NonLocalType\")\n        .def(py::init<int>())\n        .def(\"get\", [](LocalType &i) { return i.i; });\n\n    // test_duplicate_local\n    // py::module_local declarations should be visible across compilation units that get linked\n    // together; this tries to register a duplicate local.  It depends on a definition in\n    // test_class.cpp and should raise a runtime error from the duplicate definition attempt.  If\n    // test_class isn't available it *also* throws a runtime error (with \"test_class not enabled\"\n    // as value).\n    m.def(\"register_local_external\", [m]() {\n        auto main = py::module_::import(\"pybind11_tests\");\n        if (py::hasattr(main, \"class_\")) {\n            bind_local<LocalExternal, 7>(m, \"LocalExternal\", py::module_local());\n        } else {\n            throw std::runtime_error(\"test_class not enabled\");\n        }\n    });\n\n    // test_stl_bind_local\n    // stl_bind.h binders defaults to py::module_local if the types are local or converting:\n    py::bind_vector<LocalVec>(m, \"LocalVec\");\n    py::bind_map<LocalMap>(m, \"LocalMap\");\n    // and global if the type (or one of the types, for the map) is global:\n    py::bind_vector<NonLocalVec>(m, \"NonLocalVec\");\n    py::bind_map<NonLocalMap>(m, \"NonLocalMap\");\n\n    // test_stl_bind_global\n    // They can, however, be overridden to global using `py::module_local(false)`:\n    bind_local<NonLocal2, 10>(m, \"NonLocal2\");\n    py::bind_vector<LocalVec2>(m, \"LocalVec2\", py::module_local());\n    py::bind_map<NonLocalMap2>(m, \"NonLocalMap2\", py::module_local(false));\n\n    // test_mixed_local_global\n    // We try this both with the global type registered first and vice versa (the order shouldn't\n    // matter).\n    m.def(\"register_mixed_global\", [m]() {\n        bind_local<MixedGlobalLocal, 100>(m, \"MixedGlobalLocal\", py::module_local(false));\n    });\n    m.def(\"register_mixed_local\", [m]() {\n        bind_local<MixedLocalGlobal, 1000>(m, \"MixedLocalGlobal\", py::module_local());\n    });\n    m.def(\"get_mixed_gl\", [](int i) { return MixedGlobalLocal(i); });\n    m.def(\"get_mixed_lg\", [](int i) { return MixedLocalGlobal(i); });\n\n    // test_internal_locals_differ\n    m.def(\"local_cpp_types_addr\",\n          []() { return (uintptr_t) &py::detail::get_local_internals().registered_types_cpp; });\n\n    // test_stl_caster_vs_stl_bind\n    m.def(\"load_vector_via_caster\",\n          [](std::vector<int> v) { return std::accumulate(v.begin(), v.end(), 0); });\n\n    // test_cross_module_calls\n    m.def(\"return_self\", [](LocalVec *v) { return v; });\n    m.def(\"return_copy\", [](const LocalVec &v) { return LocalVec(v); });\n\n    class Cat : public pets::Pet {\n    public:\n        explicit Cat(std::string name) : Pet(std::move(name)) {}\n    };\n    py::class_<pets::Pet>(m, \"Pet\", py::module_local()).def(\"get_name\", &pets::Pet::name);\n    // Binding for local extending class:\n    py::class_<Cat, pets::Pet>(m, \"Cat\").def(py::init<std::string>());\n    m.def(\"pet_name\", [](pets::Pet &p) { return p.name(); });\n\n    py::class_<MixGL>(m, \"MixGL\").def(py::init<int>());\n    m.def(\"get_gl_value\", [](MixGL &o) { return o.i + 10; });\n\n    py::class_<MixGL2>(m, \"MixGL2\").def(py::init<int>());\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_local_bindings.py",
    "content": "import pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import local_bindings as m\n\n\ndef test_load_external():\n    \"\"\"Load a `py::module_local` type that's only registered in an external module\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    assert m.load_external1(cm.ExternalType1(11)) == 11\n    assert m.load_external2(cm.ExternalType2(22)) == 22\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.load_external2(cm.ExternalType1(21)) == 21\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.load_external1(cm.ExternalType2(12)) == 12\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_local_bindings():\n    \"\"\"Tests that duplicate `py::module_local` class bindings work across modules\"\"\"\n\n    # Make sure we can load the second module with the conflicting (but local) definition:\n    import pybind11_cross_module_tests as cm\n\n    i1 = m.LocalType(5)\n    assert i1.get() == 4\n    assert i1.get3() == 8\n\n    i2 = cm.LocalType(10)\n    assert i2.get() == 11\n    assert i2.get2() == 12\n\n    assert not hasattr(i1, \"get2\")\n    assert not hasattr(i2, \"get3\")\n\n    # Loading within the local module\n    assert m.local_value(i1) == 5\n    assert cm.local_value(i2) == 10\n\n    # Cross-module loading works as well (on failure, the type loader looks for\n    # external module-local converters):\n    assert m.local_value(i2) == 10\n    assert cm.local_value(i1) == 5\n\n\ndef test_nonlocal_failure():\n    \"\"\"Tests that attempting to register a non-local type in multiple modules fails\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalType\" is already registered!'\n    )\n\n\ndef test_duplicate_local():\n    \"\"\"Tests expected failure when registering a class twice with py::local in the same module\"\"\"\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_local_external()\n    import pybind11_tests\n\n    assert str(excinfo.value) == (\n        'generic_type: type \"LocalExternal\" is already registered!'\n        if hasattr(pybind11_tests, \"class_\")\n        else \"test_class not enabled\"\n    )\n\n\ndef test_stl_bind_local():\n    import pybind11_cross_module_tests as cm\n\n    v1, v2 = m.LocalVec(), cm.LocalVec()\n    v1.append(m.LocalType(1))\n    v1.append(m.LocalType(2))\n    v2.append(cm.LocalType(1))\n    v2.append(cm.LocalType(2))\n\n    # Cross module value loading:\n    v1.append(cm.LocalType(3))\n    v2.append(m.LocalType(3))\n\n    assert [i.get() for i in v1] == [0, 1, 2]\n    assert [i.get() for i in v2] == [2, 3, 4]\n\n    v3, v4 = m.NonLocalVec(), cm.NonLocalVec2()\n    v3.append(m.NonLocalType(1))\n    v3.append(m.NonLocalType(2))\n    v4.append(m.NonLocal2(3))\n    v4.append(m.NonLocal2(4))\n\n    assert [i.get() for i in v3] == [1, 2]\n    assert [i.get() for i in v4] == [13, 14]\n\n    d1, d2 = m.LocalMap(), cm.LocalMap()\n    d1[\"a\"] = v1[0]\n    d1[\"b\"] = v1[1]\n    d2[\"c\"] = v2[0]\n    d2[\"d\"] = v2[1]\n    assert {i: d1[i].get() for i in d1} == {\"a\": 0, \"b\": 1}\n    assert {i: d2[i].get() for i in d2} == {\"c\": 2, \"d\": 3}\n\n\ndef test_stl_bind_global():\n    import pybind11_cross_module_tests as cm\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_map()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalMap\" is already registered!'\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_vec()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalVec\" is already registered!'\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_map2()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalMap2\" is already registered!'\n    )\n\n\ndef test_mixed_local_global():\n    \"\"\"Local types take precedence over globally registered types: a module with a `module_local`\n    type can be registered even if the type is already registered globally.  With the module,\n    casting will go to the local type; outside the module casting goes to the global type.\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    m.register_mixed_global()\n    m.register_mixed_local()\n\n    a = []\n    a.append(m.MixedGlobalLocal(1))\n    a.append(m.MixedLocalGlobal(2))\n    a.append(m.get_mixed_gl(3))\n    a.append(m.get_mixed_lg(4))\n\n    assert [x.get() for x in a] == [101, 1002, 103, 1004]\n\n    cm.register_mixed_global_local()\n    cm.register_mixed_local_global()\n    a.append(m.MixedGlobalLocal(5))\n    a.append(m.MixedLocalGlobal(6))\n    a.append(cm.MixedGlobalLocal(7))\n    a.append(cm.MixedLocalGlobal(8))\n    a.append(m.get_mixed_gl(9))\n    a.append(m.get_mixed_lg(10))\n    a.append(cm.get_mixed_gl(11))\n    a.append(cm.get_mixed_lg(12))\n\n    assert [x.get() for x in a] == [\n        101,\n        1002,\n        103,\n        1004,\n        105,\n        1006,\n        207,\n        2008,\n        109,\n        1010,\n        211,\n        2012,\n    ]\n\n\ndef test_internal_locals_differ():\n    \"\"\"Makes sure the internal local type map differs across the two modules\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    assert m.local_cpp_types_addr() != cm.local_cpp_types_addr()\n\n\n@pytest.mark.xfail(\"env.PYPY and sys.pypy_version_info < (7, 3, 2)\")\ndef test_stl_caster_vs_stl_bind(msg):\n    \"\"\"One module uses a generic vector caster from `<pybind11/stl.h>` while the other\n    exports `std::vector<int>` via `py:bind_vector` and `py::module_local`\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    v1 = cm.VectorInt([1, 2, 3])\n    assert m.load_vector_via_caster(v1) == 6\n    assert cm.load_vector_via_binding(v1) == 6\n\n    v2 = [1, 2, 3]\n    assert m.load_vector_via_caster(v2) == 6\n    with pytest.raises(TypeError) as excinfo:\n        cm.load_vector_via_binding(v2)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n    load_vector_via_binding(): incompatible function arguments. The following argument types are supported:\n        1. (arg0: pybind11_cross_module_tests.VectorInt) -> int\n\n    Invoked with: [1, 2, 3]\n    \"\"\"\n    )\n\n\ndef test_cross_module_calls():\n    import pybind11_cross_module_tests as cm\n\n    v1 = m.LocalVec()\n    v1.append(m.LocalType(1))\n    v2 = cm.LocalVec()\n    v2.append(cm.LocalType(2))\n\n    # Returning the self pointer should get picked up as returning an existing\n    # instance (even when that instance is of a foreign, non-local type).\n    assert m.return_self(v1) is v1\n    assert cm.return_self(v2) is v2\n    assert m.return_self(v2) is v2\n    assert cm.return_self(v1) is v1\n\n    assert m.LocalVec is not cm.LocalVec\n    # Returning a copy, on the other hand, always goes to the local type,\n    # regardless of where the source type came from.\n    assert type(m.return_copy(v1)) is m.LocalVec\n    assert type(m.return_copy(v2)) is m.LocalVec\n    assert type(cm.return_copy(v1)) is cm.LocalVec\n    assert type(cm.return_copy(v2)) is cm.LocalVec\n\n    # Test the example given in the documentation (which also tests inheritance casting):\n    mycat = m.Cat(\"Fluffy\")\n    mydog = cm.Dog(\"Rover\")\n    assert mycat.get_name() == \"Fluffy\"\n    assert mydog.name() == \"Rover\"\n    assert m.Cat.__base__.__name__ == \"Pet\"\n    assert cm.Dog.__base__.__name__ == \"Pet\"\n    assert m.Cat.__base__ is not cm.Dog.__base__\n    assert m.pet_name(mycat) == \"Fluffy\"\n    assert m.pet_name(mydog) == \"Rover\"\n    assert cm.pet_name(mycat) == \"Fluffy\"\n    assert cm.pet_name(mydog) == \"Rover\"\n\n    assert m.MixGL is not cm.MixGL\n    a = m.MixGL(1)\n    b = cm.MixGL(2)\n    assert m.get_gl_value(a) == 11\n    assert m.get_gl_value(b) == 12\n    assert cm.get_gl_value(a) == 101\n    assert cm.get_gl_value(b) == 102\n\n    c, d = m.MixGL2(3), cm.MixGL2(4)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_gl_value(c)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_gl_value(d)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_methods_and_attributes.cpp",
    "content": "/*\n    tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,\n    __str__, argument and return value conventions\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#if !defined(PYBIND11_OVERLOAD_CAST)\ntemplate <typename... Args>\nusing overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;\n#endif\n\nclass ExampleMandA {\npublic:\n    ExampleMandA() { print_default_created(this); }\n    explicit ExampleMandA(int value) : value(value) { print_created(this, value); }\n    ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }\n    explicit ExampleMandA(std::string &&) {}\n    ExampleMandA(ExampleMandA &&e) noexcept : value(e.value) { print_move_created(this); }\n    ~ExampleMandA() { print_destroyed(this); }\n\n    std::string toString() const { return \"ExampleMandA[value=\" + std::to_string(value) + \"]\"; }\n\n    void operator=(const ExampleMandA &e) {\n        print_copy_assigned(this);\n        value = e.value;\n    }\n    void operator=(ExampleMandA &&e) noexcept {\n        print_move_assigned(this);\n        value = e.value;\n    }\n\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    void add1(ExampleMandA other) { value += other.value; }         // passing by value\n    void add2(ExampleMandA &other) { value += other.value; }        // passing by reference\n    void add3(const ExampleMandA &other) { value += other.value; }  // passing by const reference\n    void add4(ExampleMandA *other) { value += other->value; }       // passing by pointer\n    void add5(const ExampleMandA *other) { value += other->value; } // passing by const pointer\n\n    void add6(int other) { value += other; }        // passing by value\n    void add7(int &other) { value += other; }       // passing by reference\n    void add8(const int &other) { value += other; } // passing by const reference\n    // NOLINTNEXTLINE(readability-non-const-parameter) Deliberately non-const for testing\n    void add9(int *other) { value += *other; }        // passing by pointer\n    void add10(const int *other) { value += *other; } // passing by const pointer\n\n    void consume_str(std::string &&) {}\n\n    ExampleMandA self1() { return *this; }              // return by value\n    ExampleMandA &self2() { return *this; }             // return by reference\n    const ExampleMandA &self3() const { return *this; } // return by const reference\n    ExampleMandA *self4() { return this; }              // return by pointer\n    const ExampleMandA *self5() const { return this; }  // return by const pointer\n\n    int internal1() const { return value; }        // return by value\n    int &internal2() { return value; }             // return by reference\n    const int &internal3() const { return value; } // return by const reference\n    int *internal4() { return &value; }            // return by pointer\n    const int *internal5() { return &value; }      // return by const pointer\n\n    py::str overloaded() { return \"()\"; }\n    py::str overloaded(int) { return \"(int)\"; }\n    py::str overloaded(int, float) { return \"(int, float)\"; }\n    py::str overloaded(float, int) { return \"(float, int)\"; }\n    py::str overloaded(int, int) { return \"(int, int)\"; }\n    py::str overloaded(float, float) { return \"(float, float)\"; }\n    py::str overloaded(int) const { return \"(int) const\"; }\n    py::str overloaded(int, float) const { return \"(int, float) const\"; }\n    py::str overloaded(float, int) const { return \"(float, int) const\"; }\n    py::str overloaded(int, int) const { return \"(int, int) const\"; }\n    py::str overloaded(float, float) const { return \"(float, float) const\"; }\n\n    static py::str overloaded(float) { return \"static float\"; }\n\n    int value = 0;\n};\n\nstruct TestProperties {\n    int value = 1;\n    static int static_value;\n\n    int get() const { return value; }\n    void set(int v) { value = v; }\n\n    static int static_get() { return static_value; }\n    static void static_set(int v) { static_value = v; }\n};\nint TestProperties::static_value = 1;\n\nstruct TestPropertiesOverride : TestProperties {\n    int value = 99;\n    static int static_value;\n};\nint TestPropertiesOverride::static_value = 99;\n\nstruct TestPropRVP {\n    UserType v1{1};\n    UserType v2{1};\n    static UserType sv1;\n    static UserType sv2;\n\n    const UserType &get1() const { return v1; }\n    const UserType &get2() const { return v2; }\n    UserType get_rvalue() const { return v2; }\n    void set1(int v) { v1.set(v); }\n    void set2(int v) { v2.set(v); }\n};\nUserType TestPropRVP::sv1(1);\nUserType TestPropRVP::sv2(1);\n\n// Test None-allowed py::arg argument policy\nclass NoneTester {\npublic:\n    int answer = 42;\n};\nint none1(const NoneTester &obj) { return obj.answer; }\nint none2(NoneTester *obj) { return obj ? obj->answer : -1; }\nint none3(std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }\nint none4(std::shared_ptr<NoneTester> *obj) { return obj && *obj ? (*obj)->answer : -1; }\nint none5(const std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }\n\n// Issue #2778: implicit casting from None to object (not pointer)\nclass NoneCastTester {\npublic:\n    int answer = -1;\n    NoneCastTester() = default;\n    explicit NoneCastTester(int v) : answer(v) {}\n};\n\nstruct StrIssue {\n    int val = -1;\n\n    StrIssue() = default;\n    explicit StrIssue(int i) : val{i} {}\n};\n\n// Issues #854, #910: incompatible function args when member function/pointer is in unregistered\n// base class\nclass UnregisteredBase {\npublic:\n    void do_nothing() const {}\n    void increase_value() {\n        rw_value++;\n        ro_value += 0.25;\n    }\n    void set_int(int v) { rw_value = v; }\n    int get_int() const { return rw_value; }\n    double get_double() const { return ro_value; }\n    int rw_value = 42;\n    double ro_value = 1.25;\n};\nclass RegisteredDerived : public UnregisteredBase {\npublic:\n    using UnregisteredBase::UnregisteredBase;\n    double sum() const { return rw_value + ro_value; }\n};\n\n// Test explicit lvalue ref-qualification\nstruct RefQualified {\n    int value = 0;\n\n    void refQualified(int other) & { value += other; }\n    int constRefQualified(int other) const & { return value + other; }\n};\n\n// Test rvalue ref param\nstruct RValueRefParam {\n    std::size_t func1(std::string &&s) { return s.size(); }\n    std::size_t func2(std::string &&s) const { return s.size(); }\n    std::size_t func3(std::string &&s) & { return s.size(); }\n    std::size_t func4(std::string &&s) const & { return s.size(); }\n};\n\nTEST_SUBMODULE(methods_and_attributes, m) {\n    // test_methods_and_attributes\n    py::class_<ExampleMandA> emna(m, \"ExampleMandA\");\n    emna.def(py::init<>())\n        .def(py::init<int>())\n        .def(py::init<std::string &&>())\n        .def(py::init<const ExampleMandA &>())\n        .def(\"add1\", &ExampleMandA::add1)\n        .def(\"add2\", &ExampleMandA::add2)\n        .def(\"add3\", &ExampleMandA::add3)\n        .def(\"add4\", &ExampleMandA::add4)\n        .def(\"add5\", &ExampleMandA::add5)\n        .def(\"add6\", &ExampleMandA::add6)\n        .def(\"add7\", &ExampleMandA::add7)\n        .def(\"add8\", &ExampleMandA::add8)\n        .def(\"add9\", &ExampleMandA::add9)\n        .def(\"add10\", &ExampleMandA::add10)\n        .def(\"consume_str\", &ExampleMandA::consume_str)\n        .def(\"self1\", &ExampleMandA::self1)\n        .def(\"self2\", &ExampleMandA::self2)\n        .def(\"self3\", &ExampleMandA::self3)\n        .def(\"self4\", &ExampleMandA::self4)\n        .def(\"self5\", &ExampleMandA::self5)\n        .def(\"internal1\", &ExampleMandA::internal1)\n        .def(\"internal2\", &ExampleMandA::internal2)\n        .def(\"internal3\", &ExampleMandA::internal3)\n        .def(\"internal4\", &ExampleMandA::internal4)\n        .def(\"internal5\", &ExampleMandA::internal5)\n#if defined(PYBIND11_OVERLOAD_CAST)\n        .def(\"overloaded\", py::overload_cast<>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<float, int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int, int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<float, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded_float\", py::overload_cast<float, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", py::overload_cast<int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<int, float>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<float, int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<int, int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))\n#else\n        // Use both the traditional static_cast method and the C++11 compatible overload_cast_\n        .def(\"overloaded\", overload_cast_<>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", overload_cast_<int>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", overload_cast_<int,   float>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(float,   int)>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(int,     int)>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))\n        .def(\"overloaded_float\", overload_cast_<float, float>()(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", overload_cast_<int         >()(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\", overload_cast_<int,   float>()(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(float,   int) const>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(int,     int) const>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))\n#endif\n        // test_no_mixed_overloads\n        // Raise error if trying to mix static/non-static overloads on the same name:\n        .def_static(\"add_mixed_overloads1\",\n                    []() {\n                        auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(\n                            py::module_::import(\"pybind11_tests.methods_and_attributes\")\n                                .attr(\"ExampleMandA\"));\n                        emna.def(\"overload_mixed1\",\n                                 static_cast<py::str (ExampleMandA::*)(int, int)>(\n                                     &ExampleMandA::overloaded))\n                            .def_static(\n                                \"overload_mixed1\",\n                                static_cast<py::str (*)(float)>(&ExampleMandA::overloaded));\n                    })\n        .def_static(\"add_mixed_overloads2\",\n                    []() {\n                        auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(\n                            py::module_::import(\"pybind11_tests.methods_and_attributes\")\n                                .attr(\"ExampleMandA\"));\n                        emna.def_static(\"overload_mixed2\",\n                                        static_cast<py::str (*)(float)>(&ExampleMandA::overloaded))\n                            .def(\"overload_mixed2\",\n                                 static_cast<py::str (ExampleMandA::*)(int, int)>(\n                                     &ExampleMandA::overloaded));\n                    })\n        .def(\"__str__\", &ExampleMandA::toString)\n        .def_readwrite(\"value\", &ExampleMandA::value);\n\n    // test_copy_method\n    // Issue #443: can't call copied methods in Python 3\n    emna.attr(\"add2b\") = emna.attr(\"add2\");\n\n    // test_properties, test_static_properties, test_static_cls\n    py::class_<TestProperties>(m, \"TestProperties\")\n        .def(py::init<>())\n        .def_readonly(\"def_readonly\", &TestProperties::value)\n        .def_readwrite(\"def_readwrite\", &TestProperties::value)\n        .def_property(\"def_writeonly\", nullptr, [](TestProperties &s, int v) { s.value = v; })\n        .def_property(\"def_property_writeonly\", nullptr, &TestProperties::set)\n        .def_property_readonly(\"def_property_readonly\", &TestProperties::get)\n        .def_property(\"def_property\", &TestProperties::get, &TestProperties::set)\n        .def_property(\"def_property_impossible\", nullptr, nullptr)\n        .def_readonly_static(\"def_readonly_static\", &TestProperties::static_value)\n        .def_readwrite_static(\"def_readwrite_static\", &TestProperties::static_value)\n        .def_property_static(\"def_writeonly_static\",\n                             nullptr,\n                             [](const py::object &, int v) { TestProperties::static_value = v; })\n        .def_property_readonly_static(\n            \"def_property_readonly_static\",\n            [](const py::object &) { return TestProperties::static_get(); })\n        .def_property_static(\n            \"def_property_writeonly_static\",\n            nullptr,\n            [](const py::object &, int v) { return TestProperties::static_set(v); })\n        .def_property_static(\n            \"def_property_static\",\n            [](const py::object &) { return TestProperties::static_get(); },\n            [](const py::object &, int v) { TestProperties::static_set(v); })\n        .def_property_static(\n            \"static_cls\",\n            [](py::object cls) { return cls; },\n            [](const py::object &cls, const py::function &f) { f(cls); });\n\n    py::class_<TestPropertiesOverride, TestProperties>(m, \"TestPropertiesOverride\")\n        .def(py::init<>())\n        .def_readonly(\"def_readonly\", &TestPropertiesOverride::value)\n        .def_readonly_static(\"def_readonly_static\", &TestPropertiesOverride::static_value);\n\n    auto static_get1 = [](const py::object &) -> const UserType & { return TestPropRVP::sv1; };\n    auto static_get2 = [](const py::object &) -> const UserType & { return TestPropRVP::sv2; };\n    auto static_set1 = [](const py::object &, int v) { TestPropRVP::sv1.set(v); };\n    auto static_set2 = [](const py::object &, int v) { TestPropRVP::sv2.set(v); };\n    auto rvp_copy = py::return_value_policy::copy;\n\n    // test_property_return_value_policies\n    py::class_<TestPropRVP>(m, \"TestPropRVP\")\n        .def(py::init<>())\n        .def_property_readonly(\"ro_ref\", &TestPropRVP::get1)\n        .def_property_readonly(\"ro_copy\", &TestPropRVP::get2, rvp_copy)\n        .def_property_readonly(\"ro_func\", py::cpp_function(&TestPropRVP::get2, rvp_copy))\n        .def_property(\"rw_ref\", &TestPropRVP::get1, &TestPropRVP::set1)\n        .def_property(\"rw_copy\", &TestPropRVP::get2, &TestPropRVP::set2, rvp_copy)\n        .def_property(\n            \"rw_func\", py::cpp_function(&TestPropRVP::get2, rvp_copy), &TestPropRVP::set2)\n        .def_property_readonly_static(\"static_ro_ref\", static_get1)\n        .def_property_readonly_static(\"static_ro_copy\", static_get2, rvp_copy)\n        .def_property_readonly_static(\"static_ro_func\", py::cpp_function(static_get2, rvp_copy))\n        .def_property_static(\"static_rw_ref\", static_get1, static_set1)\n        .def_property_static(\"static_rw_copy\", static_get2, static_set2, rvp_copy)\n        .def_property_static(\n            \"static_rw_func\", py::cpp_function(static_get2, rvp_copy), static_set2)\n        // test_property_rvalue_policy\n        .def_property_readonly(\"rvalue\", &TestPropRVP::get_rvalue)\n        .def_property_readonly_static(\"static_rvalue\",\n                                      [](const py::object &) { return UserType(1); });\n\n    // test_metaclass_override\n    struct MetaclassOverride {};\n    py::class_<MetaclassOverride>(m, \"MetaclassOverride\", py::metaclass((PyObject *) &PyType_Type))\n        .def_property_readonly_static(\"readonly\", [](const py::object &) { return 1; });\n\n    // test_overload_ordering\n    m.def(\"overload_order\", [](const std::string &) { return 1; });\n    m.def(\"overload_order\", [](const std::string &) { return 2; });\n    m.def(\"overload_order\", [](int) { return 3; });\n    m.def(\n        \"overload_order\", [](int) { return 4; }, py::prepend{});\n\n#if !defined(PYPY_VERSION)\n    // test_dynamic_attributes\n    class DynamicClass {\n    public:\n        DynamicClass() { print_default_created(this); }\n        DynamicClass(const DynamicClass &) = delete;\n        ~DynamicClass() { print_destroyed(this); }\n    };\n    py::class_<DynamicClass>(m, \"DynamicClass\", py::dynamic_attr()).def(py::init());\n\n    class CppDerivedDynamicClass : public DynamicClass {};\n    py::class_<CppDerivedDynamicClass, DynamicClass>(m, \"CppDerivedDynamicClass\").def(py::init());\n#endif\n\n    // test_bad_arg_default\n    // Issue/PR #648: bad arg default debugging output\n#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)\n    m.attr(\"detailed_error_messages_enabled\") = true;\n#else\n    m.attr(\"detailed_error_messages_enabled\") = false;\n#endif\n    m.def(\"bad_arg_def_named\", [] {\n        auto m = py::module_::import(\"pybind11_tests\");\n        m.def(\n            \"should_fail\",\n            [](int, UnregisteredType) {},\n            py::arg(),\n            py::arg(\"a\") = UnregisteredType());\n    });\n    m.def(\"bad_arg_def_unnamed\", [] {\n        auto m = py::module_::import(\"pybind11_tests\");\n        m.def(\n            \"should_fail\",\n            [](int, UnregisteredType) {},\n            py::arg(),\n            py::arg() = UnregisteredType());\n    });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_accepts_none\n    py::class_<NoneTester, std::shared_ptr<NoneTester>>(m, \"NoneTester\").def(py::init<>());\n    m.def(\"no_none1\", &none1, py::arg{}.none(false));\n    m.def(\"no_none2\", &none2, py::arg{}.none(false));\n    m.def(\"no_none3\", &none3, py::arg{}.none(false));\n    m.def(\"no_none4\", &none4, py::arg{}.none(false));\n    m.def(\"no_none5\", &none5, py::arg{}.none(false));\n    m.def(\"ok_none1\", &none1);\n    m.def(\"ok_none2\", &none2, py::arg{}.none(true));\n    m.def(\"ok_none3\", &none3);\n    m.def(\"ok_none4\", &none4, py::arg{}.none(true));\n    m.def(\"ok_none5\", &none5);\n\n    m.def(\"no_none_kwarg\", &none2, \"a\"_a.none(false));\n    m.def(\"no_none_kwarg_kw_only\", &none2, py::kw_only(), \"a\"_a.none(false));\n\n    // test_casts_none\n    // Issue #2778: implicit casting from None to object (not pointer)\n    py::class_<NoneCastTester>(m, \"NoneCastTester\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(py::init([](py::none const &) { return NoneCastTester{}; }));\n    py::implicitly_convertible<py::none, NoneCastTester>();\n    m.def(\"ok_obj_or_none\", [](NoneCastTester const &foo) { return foo.answer; });\n\n    // test_str_issue\n    // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid\n    py::class_<StrIssue>(m, \"StrIssue\")\n        .def(py::init<int>())\n        .def(py::init<>())\n        .def(\"__str__\",\n             [](const StrIssue &si) { return \"StrIssue[\" + std::to_string(si.val) + \"]\"; });\n\n    // test_unregistered_base_implementations\n    //\n    // Issues #854/910: incompatible function args when member function/pointer is in unregistered\n    // base class The methods and member pointers below actually resolve to members/pointers in\n    // UnregisteredBase; before this test/fix they would be registered via lambda with a first\n    // argument of an unregistered type, and thus uncallable.\n    py::class_<RegisteredDerived>(m, \"RegisteredDerived\")\n        .def(py::init<>())\n        .def(\"do_nothing\", &RegisteredDerived::do_nothing)\n        .def(\"increase_value\", &RegisteredDerived::increase_value)\n        .def_readwrite(\"rw_value\", &RegisteredDerived::rw_value)\n        .def_readonly(\"ro_value\", &RegisteredDerived::ro_value)\n        // Uncommenting the next line should trigger a static_assert:\n        // .def_readwrite(\"fails\", &UserType::value)\n        // Uncommenting the next line should trigger a static_assert:\n        // .def_readonly(\"fails\", &UserType::value)\n        .def_property(\"rw_value_prop\", &RegisteredDerived::get_int, &RegisteredDerived::set_int)\n        .def_property_readonly(\"ro_value_prop\", &RegisteredDerived::get_double)\n        // This one is in the registered class:\n        .def(\"sum\", &RegisteredDerived::sum);\n\n    using Adapted\n        = decltype(py::method_adaptor<RegisteredDerived>(&RegisteredDerived::do_nothing));\n    static_assert(std::is_same<Adapted, void (RegisteredDerived::*)() const>::value, \"\");\n\n    // test_methods_and_attributes\n    py::class_<RefQualified>(m, \"RefQualified\")\n        .def(py::init<>())\n        .def_readonly(\"value\", &RefQualified::value)\n        .def(\"refQualified\", &RefQualified::refQualified)\n        .def(\"constRefQualified\", &RefQualified::constRefQualified);\n\n    py::class_<RValueRefParam>(m, \"RValueRefParam\")\n        .def(py::init<>())\n        .def(\"func1\", &RValueRefParam::func1)\n        .def(\"func2\", &RValueRefParam::func2)\n        .def(\"func3\", &RValueRefParam::func3)\n        .def(\"func4\", &RValueRefParam::func4);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_methods_and_attributes.py",
    "content": "import sys\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import methods_and_attributes as m\n\nNO_GETTER_MSG = (\n    \"unreadable attribute\" if sys.version_info < (3, 11) else \"object has no getter\"\n)\nNO_SETTER_MSG = (\n    \"can't set attribute\" if sys.version_info < (3, 11) else \"object has no setter\"\n)\nNO_DELETER_MSG = (\n    \"can't delete attribute\" if sys.version_info < (3, 11) else \"object has no deleter\"\n)\n\n\ndef test_methods_and_attributes():\n    instance1 = m.ExampleMandA()\n    instance2 = m.ExampleMandA(32)\n\n    instance1.add1(instance2)\n    instance1.add2(instance2)\n    instance1.add3(instance2)\n    instance1.add4(instance2)\n    instance1.add5(instance2)\n    instance1.add6(32)\n    instance1.add7(32)\n    instance1.add8(32)\n    instance1.add9(32)\n    instance1.add10(32)\n\n    assert str(instance1) == \"ExampleMandA[value=320]\"\n    assert str(instance2) == \"ExampleMandA[value=32]\"\n    assert str(instance1.self1()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self2()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self3()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self4()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self5()) == \"ExampleMandA[value=320]\"\n\n    assert instance1.internal1() == 320\n    assert instance1.internal2() == 320\n    assert instance1.internal3() == 320\n    assert instance1.internal4() == 320\n    assert instance1.internal5() == 320\n\n    assert instance1.overloaded() == \"()\"\n    assert instance1.overloaded(0) == \"(int)\"\n    assert instance1.overloaded(1, 1.0) == \"(int, float)\"\n    assert instance1.overloaded(2.0, 2) == \"(float, int)\"\n    assert instance1.overloaded(3, 3) == \"(int, int)\"\n    assert instance1.overloaded(4.0, 4.0) == \"(float, float)\"\n    assert instance1.overloaded_const(-3) == \"(int) const\"\n    assert instance1.overloaded_const(5, 5.0) == \"(int, float) const\"\n    assert instance1.overloaded_const(6.0, 6) == \"(float, int) const\"\n    assert instance1.overloaded_const(7, 7) == \"(int, int) const\"\n    assert instance1.overloaded_const(8.0, 8.0) == \"(float, float) const\"\n    assert instance1.overloaded_float(1, 1) == \"(float, float)\"\n    assert instance1.overloaded_float(1, 1.0) == \"(float, float)\"\n    assert instance1.overloaded_float(1.0, 1) == \"(float, float)\"\n    assert instance1.overloaded_float(1.0, 1.0) == \"(float, float)\"\n\n    assert instance1.value == 320\n    instance1.value = 100\n    assert str(instance1) == \"ExampleMandA[value=100]\"\n\n    cstats = ConstructorStats.get(m.ExampleMandA)\n    assert cstats.alive() == 2\n    del instance1, instance2\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"32\"]\n    assert cstats.default_constructions == 1\n    assert cstats.copy_constructions == 2\n    assert cstats.move_constructions >= 2\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_copy_method():\n    \"\"\"Issue #443: calling copied methods fails in Python 3\"\"\"\n\n    m.ExampleMandA.add2c = m.ExampleMandA.add2\n    m.ExampleMandA.add2d = m.ExampleMandA.add2b\n    a = m.ExampleMandA(123)\n    assert a.value == 123\n    a.add2(m.ExampleMandA(-100))\n    assert a.value == 23\n    a.add2b(m.ExampleMandA(20))\n    assert a.value == 43\n    a.add2c(m.ExampleMandA(6))\n    assert a.value == 49\n    a.add2d(m.ExampleMandA(-7))\n    assert a.value == 42\n\n\ndef test_properties():\n    instance = m.TestProperties()\n\n    assert instance.def_readonly == 1\n    with pytest.raises(AttributeError):\n        instance.def_readonly = 2\n\n    instance.def_readwrite = 2\n    assert instance.def_readwrite == 2\n\n    assert instance.def_property_readonly == 2\n    with pytest.raises(AttributeError):\n        instance.def_property_readonly = 3\n\n    instance.def_property = 3\n    assert instance.def_property == 3\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_writeonly  # unused var\n    assert NO_GETTER_MSG in str(excinfo.value)\n\n    instance.def_property_writeonly = 4\n    assert instance.def_property_readonly == 4\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_impossible  # noqa: F841 unused var\n    assert NO_GETTER_MSG in str(excinfo.value)\n\n    with pytest.raises(AttributeError) as excinfo:\n        instance.def_property_impossible = 5\n    assert NO_SETTER_MSG in str(excinfo.value)\n\n\ndef test_static_properties():\n    assert m.TestProperties.def_readonly_static == 1\n    with pytest.raises(AttributeError) as excinfo:\n        m.TestProperties.def_readonly_static = 2\n    assert NO_SETTER_MSG in str(excinfo.value)\n\n    m.TestProperties.def_readwrite_static = 2\n    assert m.TestProperties.def_readwrite_static == 2\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = m.TestProperties.def_writeonly_static  # unused var\n    assert NO_GETTER_MSG in str(excinfo.value)\n\n    m.TestProperties.def_writeonly_static = 3\n    assert m.TestProperties.def_readonly_static == 3\n\n    assert m.TestProperties.def_property_readonly_static == 3\n    with pytest.raises(AttributeError) as excinfo:\n        m.TestProperties.def_property_readonly_static = 99\n    assert NO_SETTER_MSG in str(excinfo.value)\n\n    m.TestProperties.def_property_static = 4\n    assert m.TestProperties.def_property_static == 4\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = m.TestProperties.def_property_writeonly_static\n    assert NO_GETTER_MSG in str(excinfo.value)\n\n    m.TestProperties.def_property_writeonly_static = 5\n    assert m.TestProperties.def_property_static == 5\n\n    # Static property read and write via instance\n    instance = m.TestProperties()\n\n    m.TestProperties.def_readwrite_static = 0\n    assert m.TestProperties.def_readwrite_static == 0\n    assert instance.def_readwrite_static == 0\n\n    instance.def_readwrite_static = 2\n    assert m.TestProperties.def_readwrite_static == 2\n    assert instance.def_readwrite_static == 2\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_writeonly_static  # noqa: F841 unused var\n    assert NO_GETTER_MSG in str(excinfo.value)\n\n    instance.def_property_writeonly_static = 4\n    assert instance.def_property_static == 4\n\n    # It should be possible to override properties in derived classes\n    assert m.TestPropertiesOverride().def_readonly == 99\n    assert m.TestPropertiesOverride.def_readonly_static == 99\n\n    # Only static attributes can be deleted\n    del m.TestPropertiesOverride.def_readonly_static\n    assert (\n        hasattr(m.TestPropertiesOverride, \"def_readonly_static\")\n        and m.TestPropertiesOverride.def_readonly_static\n        is m.TestProperties.def_readonly_static\n    )\n    assert \"def_readonly_static\" not in m.TestPropertiesOverride.__dict__\n    properties_override = m.TestPropertiesOverride()\n    with pytest.raises(AttributeError) as excinfo:\n        del properties_override.def_readonly\n    assert NO_DELETER_MSG in str(excinfo.value)\n\n\ndef test_static_cls():\n    \"\"\"Static property getter and setters expect the type object as the their only argument\"\"\"\n\n    instance = m.TestProperties()\n    assert m.TestProperties.static_cls is m.TestProperties\n    assert instance.static_cls is m.TestProperties\n\n    def check_self(self):\n        assert self is m.TestProperties\n\n    m.TestProperties.static_cls = check_self\n    instance.static_cls = check_self\n\n\ndef test_metaclass_override():\n    \"\"\"Overriding pybind11's default metaclass changes the behavior of `static_property`\"\"\"\n\n    assert type(m.ExampleMandA).__name__ == \"pybind11_type\"\n    assert type(m.MetaclassOverride).__name__ == \"type\"\n\n    assert m.MetaclassOverride.readonly == 1\n    assert (\n        type(m.MetaclassOverride.__dict__[\"readonly\"]).__name__\n        == \"pybind11_static_property\"\n    )\n\n    # Regular `type` replaces the property instead of calling `__set__()`\n    m.MetaclassOverride.readonly = 2\n    assert m.MetaclassOverride.readonly == 2\n    assert isinstance(m.MetaclassOverride.__dict__[\"readonly\"], int)\n\n\ndef test_no_mixed_overloads():\n    from pybind11_tests import detailed_error_messages_enabled\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.ExampleMandA.add_mixed_overloads1()\n    assert str(\n        excinfo.value\n    ) == \"overloading a method with both static and instance methods is not supported; \" + (\n        \"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details\"\n        if not detailed_error_messages_enabled\n        else \"error while attempting to bind static method ExampleMandA.overload_mixed1\"\n        \"(arg0: float) -> str\"\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.ExampleMandA.add_mixed_overloads2()\n    assert str(\n        excinfo.value\n    ) == \"overloading a method with both static and instance methods is not supported; \" + (\n        \"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details\"\n        if not detailed_error_messages_enabled\n        else \"error while attempting to bind instance method ExampleMandA.overload_mixed2\"\n        \"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)\"\n        \" -> str\"\n    )\n\n\n@pytest.mark.parametrize(\"access\", [\"ro\", \"rw\", \"static_ro\", \"static_rw\"])\ndef test_property_return_value_policies(access):\n    if not access.startswith(\"static\"):\n        obj = m.TestPropRVP()\n    else:\n        obj = m.TestPropRVP\n\n    ref = getattr(obj, access + \"_ref\")\n    assert ref.value == 1\n    ref.value = 2\n    assert getattr(obj, access + \"_ref\").value == 2\n    ref.value = 1  # restore original value for static properties\n\n    copy = getattr(obj, access + \"_copy\")\n    assert copy.value == 1\n    copy.value = 2\n    assert getattr(obj, access + \"_copy\").value == 1\n\n    copy = getattr(obj, access + \"_func\")\n    assert copy.value == 1\n    copy.value = 2\n    assert getattr(obj, access + \"_func\").value == 1\n\n\ndef test_property_rvalue_policy():\n    \"\"\"When returning an rvalue, the return value policy is automatically changed from\n    `reference(_internal)` to `move`. The following would not work otherwise.\"\"\"\n\n    instance = m.TestPropRVP()\n    o = instance.rvalue\n    assert o.value == 1\n\n    os = m.TestPropRVP.static_rvalue\n    assert os.value == 1\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_dynamic_attributes():\n    instance = m.DynamicClass()\n    assert not hasattr(instance, \"foo\")\n    assert \"foo\" not in dir(instance)\n\n    # Dynamically add attribute\n    instance.foo = 42\n    assert hasattr(instance, \"foo\")\n    assert instance.foo == 42\n    assert \"foo\" in dir(instance)\n\n    # __dict__ should be accessible and replaceable\n    assert \"foo\" in instance.__dict__\n    instance.__dict__ = {\"bar\": True}\n    assert not hasattr(instance, \"foo\")\n    assert hasattr(instance, \"bar\")\n\n    with pytest.raises(TypeError) as excinfo:\n        instance.__dict__ = []\n    assert str(excinfo.value) == \"__dict__ must be set to a dictionary, not a 'list'\"\n\n    cstats = ConstructorStats.get(m.DynamicClass)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n    # Derived classes should work as well\n    class PythonDerivedDynamicClass(m.DynamicClass):\n        pass\n\n    for cls in m.CppDerivedDynamicClass, PythonDerivedDynamicClass:\n        derived = cls()\n        derived.foobar = 100\n        assert derived.foobar == 100\n\n        assert cstats.alive() == 1\n        del derived\n        assert cstats.alive() == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_cyclic_gc():\n    # One object references itself\n    instance = m.DynamicClass()\n    instance.circular_reference = instance\n\n    cstats = ConstructorStats.get(m.DynamicClass)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n    # Two object reference each other\n    i1 = m.DynamicClass()\n    i2 = m.DynamicClass()\n    i1.cycle = i2\n    i2.cycle = i1\n\n    assert cstats.alive() == 2\n    del i1, i2\n    assert cstats.alive() == 0\n\n\ndef test_bad_arg_default(msg):\n    from pybind11_tests import detailed_error_messages_enabled\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.bad_arg_def_named()\n    assert msg(excinfo.value) == (\n        \"arg(): could not convert default argument 'a: UnregisteredType' in function \"\n        \"'should_fail' into a Python object (type not registered yet?)\"\n        if detailed_error_messages_enabled\n        else \"arg(): could not convert default argument into a Python object (type not registered \"\n        \"yet?). #define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more information.\"\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.bad_arg_def_unnamed()\n    assert msg(excinfo.value) == (\n        \"arg(): could not convert default argument 'UnregisteredType' in function \"\n        \"'should_fail' into a Python object (type not registered yet?)\"\n        if detailed_error_messages_enabled\n        else \"arg(): could not convert default argument into a Python object (type not registered \"\n        \"yet?). #define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more information.\"\n    )\n\n\ndef test_accepts_none(msg):\n    a = m.NoneTester()\n    assert m.no_none1(a) == 42\n    assert m.no_none2(a) == 42\n    assert m.no_none3(a) == 42\n    assert m.no_none4(a) == 42\n    assert m.no_none5(a) == 42\n    assert m.ok_none1(a) == 42\n    assert m.ok_none2(a) == 42\n    assert m.ok_none3(a) == 42\n    assert m.ok_none4(a) == 42\n    assert m.ok_none5(a) == 42\n\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none1(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none2(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none3(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none4(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none5(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    # The first one still raises because you can't pass None as a lvalue reference arg:\n    with pytest.raises(TypeError) as excinfo:\n        assert m.ok_none1(None) == -1\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ok_none1(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: m.methods_and_attributes.NoneTester) -> int\n\n        Invoked with: None\n    \"\"\"\n    )\n\n    # The rest take the argument as pointer or holder, and accept None:\n    assert m.ok_none2(None) == -1\n    assert m.ok_none3(None) == -1\n    assert m.ok_none4(None) == -1\n    assert m.ok_none5(None) == -1\n\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg(a=None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg_kw_only(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg_kw_only(a=None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_casts_none():\n    \"\"\"#2778: implicit casting from None to object (not pointer)\"\"\"\n    a = m.NoneCastTester()\n    assert m.ok_obj_or_none(a) == -1\n    a = m.NoneCastTester(4)\n    assert m.ok_obj_or_none(a) == 4\n    a = m.NoneCastTester(None)\n    assert m.ok_obj_or_none(a) == -1\n    assert m.ok_obj_or_none(None) == -1\n\n\ndef test_str_issue(msg):\n    \"\"\"#283: __str__ called on uninitialized instance when constructor arguments invalid\"\"\"\n\n    assert str(m.StrIssue(3)) == \"StrIssue[3]\"\n\n    with pytest.raises(TypeError) as excinfo:\n        str(m.StrIssue(\"no\", \"such\", \"constructor\"))\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.methods_and_attributes.StrIssue(arg0: int)\n            2. m.methods_and_attributes.StrIssue()\n\n        Invoked with: 'no', 'such', 'constructor'\n    \"\"\"\n    )\n\n\ndef test_unregistered_base_implementations():\n    a = m.RegisteredDerived()\n    a.do_nothing()\n    assert a.rw_value == 42\n    assert a.ro_value == 1.25\n    a.rw_value += 5\n    assert a.sum() == 48.25\n    a.increase_value()\n    assert a.rw_value == 48\n    assert a.ro_value == 1.5\n    assert a.sum() == 49.5\n    assert a.rw_value_prop == 48\n    a.rw_value_prop += 1\n    assert a.rw_value_prop == 49\n    a.increase_value()\n    assert a.ro_value_prop == 1.75\n\n\ndef test_ref_qualified():\n    \"\"\"Tests that explicit lvalue ref-qualified methods can be called just like their\n    non ref-qualified counterparts.\"\"\"\n\n    r = m.RefQualified()\n    assert r.value == 0\n    r.refQualified(17)\n    assert r.value == 17\n    assert r.constRefQualified(23) == 40\n\n\ndef test_overload_ordering():\n    \"Check to see if the normal overload order (first defined) and prepend overload order works\"\n    assert m.overload_order(\"string\") == 1\n    assert m.overload_order(0) == 4\n\n    assert \"1. overload_order(arg0: int) -> int\" in m.overload_order.__doc__\n    assert \"2. overload_order(arg0: str) -> int\" in m.overload_order.__doc__\n    assert \"3. overload_order(arg0: str) -> int\" in m.overload_order.__doc__\n    assert \"4. overload_order(arg0: int) -> int\" in m.overload_order.__doc__\n\n    with pytest.raises(TypeError) as err:\n        m.overload_order(1.1)\n\n    assert \"1. (arg0: int) -> int\" in str(err.value)\n    assert \"2. (arg0: str) -> int\" in str(err.value)\n    assert \"3. (arg0: str) -> int\" in str(err.value)\n    assert \"4. (arg0: int) -> int\" in str(err.value)\n\n\ndef test_rvalue_ref_param():\n    r = m.RValueRefParam()\n    assert r.func1(\"123\") == 3\n    assert r.func2(\"1234\") == 4\n    assert r.func3(\"12345\") == 5\n    assert r.func4(\"123456\") == 6\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_modules.cpp",
    "content": "/*\n    tests/test_modules.cpp -- nested modules, importing modules, and\n                            internal references\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(modules, m) {\n    // test_nested_modules\n    // This is intentionally \"py::module\" to verify it still can be used in place of \"py::module_\"\n    py::module m_sub = m.def_submodule(\"subsubmodule\");\n    m_sub.def(\"submodule_func\", []() { return \"submodule_func()\"; });\n\n    // test_reference_internal\n    class A {\n    public:\n        explicit A(int v) : v(v) { print_created(this, v); }\n        ~A() { print_destroyed(this); }\n        A(const A &) { print_copy_created(this); }\n        A &operator=(const A &copy) {\n            print_copy_assigned(this);\n            v = copy.v;\n            return *this;\n        }\n        std::string toString() const { return \"A[\" + std::to_string(v) + \"]\"; }\n\n    private:\n        int v;\n    };\n    py::class_<A>(m_sub, \"A\").def(py::init<int>()).def(\"__repr__\", &A::toString);\n\n    class B {\n    public:\n        B() { print_default_created(this); }\n        ~B() { print_destroyed(this); }\n        B(const B &) { print_copy_created(this); }\n        B &operator=(const B &copy) {\n            print_copy_assigned(this);\n            a1 = copy.a1;\n            a2 = copy.a2;\n            return *this;\n        }\n        A &get_a1() { return a1; }\n        A &get_a2() { return a2; }\n\n        A a1{1};\n        A a2{2};\n    };\n    py::class_<B>(m_sub, \"B\")\n        .def(py::init<>())\n        .def(\"get_a1\",\n             &B::get_a1,\n             \"Return the internal A 1\",\n             py::return_value_policy::reference_internal)\n        .def(\"get_a2\",\n             &B::get_a2,\n             \"Return the internal A 2\",\n             py::return_value_policy::reference_internal)\n        .def_readwrite(\"a1\", &B::a1) // def_readonly uses an internal\n                                     // reference return policy by default\n        .def_readwrite(\"a2\", &B::a2);\n\n    // This is intentionally \"py::module\" to verify it still can be used in place of \"py::module_\"\n    m.attr(\"OD\") = py::module::import(\"collections\").attr(\"OrderedDict\");\n\n    // test_duplicate_registration\n    // Registering two things with the same name\n    m.def(\"duplicate_registration\", []() {\n        class Dupe1 {};\n        class Dupe2 {};\n        class Dupe3 {};\n        class DupeException {};\n\n        // Go ahead and leak, until we have a non-leaking py::module_ constructor\n        auto dm\n            = py::module_::create_extension_module(\"dummy\", nullptr, new py::module_::module_def);\n        auto failures = py::list();\n\n        py::class_<Dupe1>(dm, \"Dupe1\");\n        py::class_<Dupe2>(dm, \"Dupe2\");\n        dm.def(\"dupe1_factory\", []() { return Dupe1(); });\n        py::exception<DupeException>(dm, \"DupeException\");\n\n        try {\n            py::class_<Dupe1>(dm, \"Dupe1\");\n            failures.append(\"Dupe1 class\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            dm.def(\"Dupe1\", []() { return Dupe1(); });\n            failures.append(\"Dupe1 function\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::class_<Dupe3>(dm, \"dupe1_factory\");\n            failures.append(\"dupe1_factory\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::exception<Dupe3>(dm, \"Dupe2\");\n            failures.append(\"Dupe2\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            dm.def(\"DupeException\", []() { return 30; });\n            failures.append(\"DupeException1\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::class_<DupeException>(dm, \"DupeException\");\n            failures.append(\"DupeException2\");\n        } catch (std::runtime_error &) {\n        }\n\n        return failures;\n    });\n\n    m.def(\"def_submodule\", [](py::module_ m, const char *name) { return m.def_submodule(name); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_modules.py",
    "content": "import pytest\n\nimport env\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import modules as m\nfrom pybind11_tests.modules import subsubmodule as ms\n\n\ndef test_nested_modules():\n    import pybind11_tests\n\n    assert pybind11_tests.__name__ == \"pybind11_tests\"\n    assert pybind11_tests.modules.__name__ == \"pybind11_tests.modules\"\n    assert (\n        pybind11_tests.modules.subsubmodule.__name__\n        == \"pybind11_tests.modules.subsubmodule\"\n    )\n    assert m.__name__ == \"pybind11_tests.modules\"\n    assert ms.__name__ == \"pybind11_tests.modules.subsubmodule\"\n\n    assert ms.submodule_func() == \"submodule_func()\"\n\n\ndef test_reference_internal():\n    b = ms.B()\n    assert str(b.get_a1()) == \"A[1]\"\n    assert str(b.a1) == \"A[1]\"\n    assert str(b.get_a2()) == \"A[2]\"\n    assert str(b.a2) == \"A[2]\"\n\n    b.a1 = ms.A(42)\n    b.a2 = ms.A(43)\n    assert str(b.get_a1()) == \"A[42]\"\n    assert str(b.a1) == \"A[42]\"\n    assert str(b.get_a2()) == \"A[43]\"\n    assert str(b.a2) == \"A[43]\"\n\n    astats, bstats = ConstructorStats.get(ms.A), ConstructorStats.get(ms.B)\n    assert astats.alive() == 2\n    assert bstats.alive() == 1\n    del b\n    assert astats.alive() == 0\n    assert bstats.alive() == 0\n    assert astats.values() == [\"1\", \"2\", \"42\", \"43\"]\n    assert bstats.values() == []\n    assert astats.default_constructions == 0\n    assert bstats.default_constructions == 1\n    assert astats.copy_constructions == 0\n    assert bstats.copy_constructions == 0\n    # assert astats.move_constructions >= 0  # Don't invoke any\n    # assert bstats.move_constructions >= 0  # Don't invoke any\n    assert astats.copy_assignments == 2\n    assert bstats.copy_assignments == 0\n    assert astats.move_assignments == 0\n    assert bstats.move_assignments == 0\n\n\ndef test_importing():\n    from collections import OrderedDict\n\n    from pybind11_tests.modules import OD\n\n    assert OD is OrderedDict\n    assert str(OD([(1, \"a\"), (2, \"b\")])) == \"OrderedDict([(1, 'a'), (2, 'b')])\"\n\n\ndef test_pydoc():\n    \"\"\"Pydoc needs to be able to provide help() for everything inside a pybind11 module\"\"\"\n    import pydoc\n\n    import pybind11_tests\n\n    assert pybind11_tests.__name__ == \"pybind11_tests\"\n    assert pybind11_tests.__doc__ == \"pybind11 test module\"\n    assert pydoc.text.docmodule(pybind11_tests)\n\n\ndef test_duplicate_registration():\n    \"\"\"Registering two things with the same name\"\"\"\n\n    assert m.duplicate_registration() == []\n\n\ndef test_builtin_key_type():\n    \"\"\"Test that all the keys in the builtin modules have type str.\n\n    Previous versions of pybind11 would add a unicode key in python 2.\n    \"\"\"\n    if hasattr(__builtins__, \"keys\"):\n        keys = __builtins__.keys()\n    else:  # this is to make pypy happy since builtins is different there.\n        keys = __builtins__.__dict__.keys()\n\n    assert {type(k) for k in keys} == {str}\n\n\n@pytest.mark.xfail(\"env.PYPY\", reason=\"PyModule_GetName()\")\ndef test_def_submodule_failures():\n    sm = m.def_submodule(m, b\"ScratchSubModuleName\")  # Using bytes to show it works.\n    assert sm.__name__ == m.__name__ + \".\" + \"ScratchSubModuleName\"\n    malformed_utf8 = b\"\\x80\"\n    if env.PYPY:\n        # It is not worth the effort finding a trigger for a failure when running with PyPy.\n        pytest.skip(\"Sufficiently exercised on platforms other than PyPy.\")\n    else:\n        # Meant to trigger PyModule_GetName() failure:\n        sm_name_orig = sm.__name__\n        sm.__name__ = malformed_utf8\n        try:\n            with pytest.raises(Exception):\n                # Seen with Python 3.9: SystemError: nameless module\n                # But we do not want to exercise the internals of PyModule_GetName(), which could\n                # change in future versions of Python, but a bad __name__ is very likely to cause\n                # some kind of failure indefinitely.\n                m.def_submodule(sm, b\"SubSubModuleName\")\n        finally:\n            # Clean up to ensure nothing gets upset by a module with an invalid __name__.\n            sm.__name__ = sm_name_orig  # Purely precautionary.\n    # Meant to trigger PyImport_AddModule() failure:\n    with pytest.raises(UnicodeDecodeError):\n        m.def_submodule(sm, malformed_utf8)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_multiple_inheritance.cpp",
    "content": "/*\n    tests/test_multiple_inheritance.cpp -- multiple inheritance,\n    implicit MI casts\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nnamespace {\n\n// Many bases for testing that multiple inheritance from many classes (i.e. requiring extra\n// space for holder constructed flags) works.\ntemplate <int N>\nstruct BaseN {\n    explicit BaseN(int i) : i(i) {}\n    int i;\n};\n\n// test_mi_static_properties\nstruct Vanilla {\n    std::string vanilla() { return \"Vanilla\"; };\n};\nstruct WithStatic1 {\n    static std::string static_func1() { return \"WithStatic1\"; };\n    static int static_value1;\n};\nstruct WithStatic2 {\n    static std::string static_func2() { return \"WithStatic2\"; };\n    static int static_value2;\n};\nstruct VanillaStaticMix1 : Vanilla, WithStatic1, WithStatic2 {\n    static std::string static_func() { return \"VanillaStaticMix1\"; }\n    static int static_value;\n};\nstruct VanillaStaticMix2 : WithStatic1, Vanilla, WithStatic2 {\n    static std::string static_func() { return \"VanillaStaticMix2\"; }\n    static int static_value;\n};\nint WithStatic1::static_value1 = 1;\nint WithStatic2::static_value2 = 2;\nint VanillaStaticMix1::static_value = 12;\nint VanillaStaticMix2::static_value = 12;\n\n// test_multiple_inheritance_virtbase\nstruct Base1a {\n    explicit Base1a(int i) : i(i) {}\n    int foo() const { return i; }\n    int i;\n};\nstruct Base2a {\n    explicit Base2a(int i) : i(i) {}\n    int bar() const { return i; }\n    int i;\n};\nstruct Base12a : Base1a, Base2a {\n    Base12a(int i, int j) : Base1a(i), Base2a(j) {}\n};\n\n// test_mi_unaligned_base\n// test_mi_base_return\nstruct I801B1 {\n    int a = 1;\n    I801B1() = default;\n    I801B1(const I801B1 &) = default;\n    virtual ~I801B1() = default;\n};\nstruct I801B2 {\n    int b = 2;\n    I801B2() = default;\n    I801B2(const I801B2 &) = default;\n    virtual ~I801B2() = default;\n};\nstruct I801C : I801B1, I801B2 {};\nstruct I801D : I801C {}; // Indirect MI\n\n} // namespace\n\nTEST_SUBMODULE(multiple_inheritance, m) {\n    // Please do not interleave `struct` and `class` definitions with bindings code,\n    // but implement `struct`s and `class`es in the anonymous namespace above.\n    // This helps keeping the smart_holder branch in sync with master.\n\n    // test_multiple_inheritance_mix1\n    // test_multiple_inheritance_mix2\n    struct Base1 {\n        explicit Base1(int i) : i(i) {}\n        int foo() const { return i; }\n        int i;\n    };\n    py::class_<Base1> b1(m, \"Base1\");\n    b1.def(py::init<int>()).def(\"foo\", &Base1::foo);\n\n    struct Base2 {\n        explicit Base2(int i) : i(i) {}\n        int bar() const { return i; }\n        int i;\n    };\n    py::class_<Base2> b2(m, \"Base2\");\n    b2.def(py::init<int>()).def(\"bar\", &Base2::bar);\n\n    // test_multiple_inheritance_cpp\n    struct Base12 : Base1, Base2 {\n        Base12(int i, int j) : Base1(i), Base2(j) {}\n    };\n    struct MIType : Base12 {\n        MIType(int i, int j) : Base12(i, j) {}\n    };\n    py::class_<Base12, Base1, Base2>(m, \"Base12\");\n    py::class_<MIType, Base12>(m, \"MIType\").def(py::init<int, int>());\n\n    // test_multiple_inheritance_python_many_bases\n#define PYBIND11_BASEN(N)                                                                         \\\n    py::class_<BaseN<(N)>>(m, \"BaseN\" #N).def(py::init<int>()).def(\"f\" #N, [](BaseN<N> &b) {      \\\n        return b.i + (N);                                                                         \\\n    })\n    PYBIND11_BASEN(1);\n    PYBIND11_BASEN(2);\n    PYBIND11_BASEN(3);\n    PYBIND11_BASEN(4);\n    PYBIND11_BASEN(5);\n    PYBIND11_BASEN(6);\n    PYBIND11_BASEN(7);\n    PYBIND11_BASEN(8);\n    PYBIND11_BASEN(9);\n    PYBIND11_BASEN(10);\n    PYBIND11_BASEN(11);\n    PYBIND11_BASEN(12);\n    PYBIND11_BASEN(13);\n    PYBIND11_BASEN(14);\n    PYBIND11_BASEN(15);\n    PYBIND11_BASEN(16);\n    PYBIND11_BASEN(17);\n\n    // Uncommenting this should result in a compile time failure (MI can only be specified via\n    // template parameters because pybind has to know the types involved; see discussion in #742\n    // for details).\n    //    struct Base12v2 : Base1, Base2 {\n    //        Base12v2(int i, int j) : Base1(i), Base2(j) { }\n    //    };\n    //    py::class_<Base12v2>(m, \"Base12v2\", b1, b2)\n    //        .def(py::init<int, int>());\n\n    // test_multiple_inheritance_virtbase\n    // Test the case where not all base classes are specified, and where pybind11 requires the\n    // py::multiple_inheritance flag to perform proper casting between types.\n    py::class_<Base1a, std::shared_ptr<Base1a>>(m, \"Base1a\")\n        .def(py::init<int>())\n        .def(\"foo\", &Base1a::foo);\n\n    py::class_<Base2a, std::shared_ptr<Base2a>>(m, \"Base2a\")\n        .def(py::init<int>())\n        .def(\"bar\", &Base2a::bar);\n\n    py::class_<Base12a, /* Base1 missing */ Base2a, std::shared_ptr<Base12a>>(\n        m, \"Base12a\", py::multiple_inheritance())\n        .def(py::init<int, int>());\n\n    m.def(\"bar_base2a\", [](Base2a *b) { return b->bar(); });\n    m.def(\"bar_base2a_sharedptr\", [](const std::shared_ptr<Base2a> &b) { return b->bar(); });\n\n    // test_mi_unaligned_base\n    // test_mi_base_return\n    // Issue #801: invalid casting to derived type with MI bases\n    // Unregistered classes:\n    struct I801B3 {\n        int c = 3;\n        virtual ~I801B3() = default;\n    };\n    struct I801E : I801B3, I801D {};\n\n    py::class_<I801B1, std::shared_ptr<I801B1>>(m, \"I801B1\")\n        .def(py::init<>())\n        .def_readonly(\"a\", &I801B1::a);\n    py::class_<I801B2, std::shared_ptr<I801B2>>(m, \"I801B2\")\n        .def(py::init<>())\n        .def_readonly(\"b\", &I801B2::b);\n    py::class_<I801C, I801B1, I801B2, std::shared_ptr<I801C>>(m, \"I801C\").def(py::init<>());\n    py::class_<I801D, I801C, std::shared_ptr<I801D>>(m, \"I801D\").def(py::init<>());\n\n    // Two separate issues here: first, we want to recognize a pointer to a base type as being a\n    // known instance even when the pointer value is unequal (i.e. due to a non-first\n    // multiple-inheritance base class):\n    m.def(\"i801b1_c\", [](I801C *c) { return static_cast<I801B1 *>(c); });\n    m.def(\"i801b2_c\", [](I801C *c) { return static_cast<I801B2 *>(c); });\n    m.def(\"i801b1_d\", [](I801D *d) { return static_cast<I801B1 *>(d); });\n    m.def(\"i801b2_d\", [](I801D *d) { return static_cast<I801B2 *>(d); });\n\n    // Second, when returned a base class pointer to a derived instance, we cannot assume that the\n    // pointer is `reinterpret_cast`able to the derived pointer because, like above, the base class\n    // pointer could be offset.\n    m.def(\"i801c_b1\", []() -> I801B1 * { return new I801C(); });\n    m.def(\"i801c_b2\", []() -> I801B2 * { return new I801C(); });\n    m.def(\"i801d_b1\", []() -> I801B1 * { return new I801D(); });\n    m.def(\"i801d_b2\", []() -> I801B2 * { return new I801D(); });\n\n    // Return a base class pointer to a pybind-registered type when the actual derived type\n    // isn't pybind-registered (and uses multiple-inheritance to offset the pybind base)\n    m.def(\"i801e_c\", []() -> I801C * { return new I801E(); });\n    m.def(\"i801e_b2\", []() -> I801B2 * { return new I801E(); });\n\n    // test_mi_static_properties\n    py::class_<Vanilla>(m, \"Vanilla\").def(py::init<>()).def(\"vanilla\", &Vanilla::vanilla);\n\n    py::class_<WithStatic1>(m, \"WithStatic1\")\n        .def(py::init<>())\n        .def_static(\"static_func1\", &WithStatic1::static_func1)\n        .def_readwrite_static(\"static_value1\", &WithStatic1::static_value1);\n\n    py::class_<WithStatic2>(m, \"WithStatic2\")\n        .def(py::init<>())\n        .def_static(\"static_func2\", &WithStatic2::static_func2)\n        .def_readwrite_static(\"static_value2\", &WithStatic2::static_value2);\n\n    py::class_<VanillaStaticMix1, Vanilla, WithStatic1, WithStatic2>(m, \"VanillaStaticMix1\")\n        .def(py::init<>())\n        .def_static(\"static_func\", &VanillaStaticMix1::static_func)\n        .def_readwrite_static(\"static_value\", &VanillaStaticMix1::static_value);\n\n    py::class_<VanillaStaticMix2, WithStatic1, Vanilla, WithStatic2>(m, \"VanillaStaticMix2\")\n        .def(py::init<>())\n        .def_static(\"static_func\", &VanillaStaticMix2::static_func)\n        .def_readwrite_static(\"static_value\", &VanillaStaticMix2::static_value);\n\n    struct WithDict {};\n    struct VanillaDictMix1 : Vanilla, WithDict {};\n    struct VanillaDictMix2 : WithDict, Vanilla {};\n    py::class_<WithDict>(m, \"WithDict\", py::dynamic_attr()).def(py::init<>());\n    py::class_<VanillaDictMix1, Vanilla, WithDict>(m, \"VanillaDictMix1\").def(py::init<>());\n    py::class_<VanillaDictMix2, WithDict, Vanilla>(m, \"VanillaDictMix2\").def(py::init<>());\n\n    // test_diamond_inheritance\n    // Issue #959: segfault when constructing diamond inheritance instance\n    // All of these have int members so that there will be various unequal pointers involved.\n    struct B {\n        int b;\n        B() = default;\n        B(const B &) = default;\n        virtual ~B() = default;\n    };\n    struct C0 : public virtual B {\n        int c0;\n    };\n    struct C1 : public virtual B {\n        int c1;\n    };\n    struct D : public C0, public C1 {\n        int d;\n    };\n    py::class_<B>(m, \"B\").def(\"b\", [](B *self) { return self; });\n    py::class_<C0, B>(m, \"C0\").def(\"c0\", [](C0 *self) { return self; });\n    py::class_<C1, B>(m, \"C1\").def(\"c1\", [](C1 *self) { return self; });\n    py::class_<D, C0, C1>(m, \"D\").def(py::init<>());\n\n    // test_pr3635_diamond_*\n    // - functions are get_{base}_{var}, return {var}\n    struct MVB {\n        MVB() = default;\n        MVB(const MVB &) = default;\n        virtual ~MVB() = default;\n\n        int b = 1;\n        int get_b_b() const { return b; }\n    };\n    struct MVC : virtual MVB {\n        int c = 2;\n        int get_c_b() const { return b; }\n        int get_c_c() const { return c; }\n    };\n    struct MVD0 : virtual MVC {\n        int d0 = 3;\n        int get_d0_b() const { return b; }\n        int get_d0_c() const { return c; }\n        int get_d0_d0() const { return d0; }\n    };\n    struct MVD1 : virtual MVC {\n        int d1 = 4;\n        int get_d1_b() const { return b; }\n        int get_d1_c() const { return c; }\n        int get_d1_d1() const { return d1; }\n    };\n    struct MVE : virtual MVD0, virtual MVD1 {\n        int e = 5;\n        int get_e_b() const { return b; }\n        int get_e_c() const { return c; }\n        int get_e_d0() const { return d0; }\n        int get_e_d1() const { return d1; }\n        int get_e_e() const { return e; }\n    };\n    struct MVF : virtual MVE {\n        int f = 6;\n        int get_f_b() const { return b; }\n        int get_f_c() const { return c; }\n        int get_f_d0() const { return d0; }\n        int get_f_d1() const { return d1; }\n        int get_f_e() const { return e; }\n        int get_f_f() const { return f; }\n    };\n    py::class_<MVB>(m, \"MVB\")\n        .def(py::init<>())\n        .def(\"get_b_b\", &MVB::get_b_b)\n        .def_readwrite(\"b\", &MVB::b);\n    py::class_<MVC, MVB>(m, \"MVC\")\n        .def(py::init<>())\n        .def(\"get_c_b\", &MVC::get_c_b)\n        .def(\"get_c_c\", &MVC::get_c_c)\n        .def_readwrite(\"c\", &MVC::c);\n    py::class_<MVD0, MVC>(m, \"MVD0\")\n        .def(py::init<>())\n        .def(\"get_d0_b\", &MVD0::get_d0_b)\n        .def(\"get_d0_c\", &MVD0::get_d0_c)\n        .def(\"get_d0_d0\", &MVD0::get_d0_d0)\n        .def_readwrite(\"d0\", &MVD0::d0);\n    py::class_<MVD1, MVC>(m, \"MVD1\")\n        .def(py::init<>())\n        .def(\"get_d1_b\", &MVD1::get_d1_b)\n        .def(\"get_d1_c\", &MVD1::get_d1_c)\n        .def(\"get_d1_d1\", &MVD1::get_d1_d1)\n        .def_readwrite(\"d1\", &MVD1::d1);\n    py::class_<MVE, MVD0, MVD1>(m, \"MVE\")\n        .def(py::init<>())\n        .def(\"get_e_b\", &MVE::get_e_b)\n        .def(\"get_e_c\", &MVE::get_e_c)\n        .def(\"get_e_d0\", &MVE::get_e_d0)\n        .def(\"get_e_d1\", &MVE::get_e_d1)\n        .def(\"get_e_e\", &MVE::get_e_e)\n        .def_readwrite(\"e\", &MVE::e);\n    py::class_<MVF, MVE>(m, \"MVF\")\n        .def(py::init<>())\n        .def(\"get_f_b\", &MVF::get_f_b)\n        .def(\"get_f_c\", &MVF::get_f_c)\n        .def(\"get_f_d0\", &MVF::get_f_d0)\n        .def(\"get_f_d1\", &MVF::get_f_d1)\n        .def(\"get_f_e\", &MVF::get_f_e)\n        .def(\"get_f_f\", &MVF::get_f_f)\n        .def_readwrite(\"f\", &MVF::f);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_multiple_inheritance.py",
    "content": "import pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import multiple_inheritance as m\n\n\ndef test_multiple_inheritance_cpp():\n    mt = m.MIType(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_multiple_inheritance_mix1():\n    class Base1:\n        def __init__(self, i):\n            self.i = i\n\n        def foo(self):\n            return self.i\n\n    class MITypePy(Base1, m.Base2):\n        def __init__(self, i, j):\n            Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    mt = MITypePy(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\ndef test_multiple_inheritance_mix2():\n    class Base2:\n        def __init__(self, i):\n            self.i = i\n\n        def bar(self):\n            return self.i\n\n    class MITypePy(m.Base1, Base2):\n        def __init__(self, i, j):\n            m.Base1.__init__(self, i)\n            Base2.__init__(self, j)\n\n    mt = MITypePy(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_multiple_inheritance_python():\n    class MI1(m.Base1, m.Base2):\n        def __init__(self, i, j):\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class B1:\n        def v(self):\n            return 1\n\n    class MI2(B1, m.Base1, m.Base2):\n        def __init__(self, i, j):\n            B1.__init__(self)\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class MI3(MI2):\n        def __init__(self, i, j):\n            MI2.__init__(self, i, j)\n\n    class MI4(MI3, m.Base2):\n        def __init__(self, i, j):\n            MI3.__init__(self, i, j)\n            # This should be ignored (Base2 is already initialized via MI2):\n            m.Base2.__init__(self, i + 100)\n\n    class MI5(m.Base2, B1, m.Base1):\n        def __init__(self, i, j):\n            B1.__init__(self)\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class MI6(m.Base2, B1):\n        def __init__(self, i):\n            m.Base2.__init__(self, i)\n            B1.__init__(self)\n\n    class B2(B1):\n        def v(self):\n            return 2\n\n    class B3:\n        def v(self):\n            return 3\n\n    class B4(B3, B2):\n        def v(self):\n            return 4\n\n    class MI7(B4, MI6):\n        def __init__(self, i):\n            B4.__init__(self)\n            MI6.__init__(self, i)\n\n    class MI8(MI6, B3):\n        def __init__(self, i):\n            MI6.__init__(self, i)\n            B3.__init__(self)\n\n    class MI8b(B3, MI6):\n        def __init__(self, i):\n            B3.__init__(self)\n            MI6.__init__(self, i)\n\n    mi1 = MI1(1, 2)\n    assert mi1.foo() == 1\n    assert mi1.bar() == 2\n\n    mi2 = MI2(3, 4)\n    assert mi2.v() == 1\n    assert mi2.foo() == 3\n    assert mi2.bar() == 4\n\n    mi3 = MI3(5, 6)\n    assert mi3.v() == 1\n    assert mi3.foo() == 5\n    assert mi3.bar() == 6\n\n    mi4 = MI4(7, 8)\n    assert mi4.v() == 1\n    assert mi4.foo() == 7\n    assert mi4.bar() == 8\n\n    mi5 = MI5(10, 11)\n    assert mi5.v() == 1\n    assert mi5.foo() == 10\n    assert mi5.bar() == 11\n\n    mi6 = MI6(12)\n    assert mi6.v() == 1\n    assert mi6.bar() == 12\n\n    mi7 = MI7(13)\n    assert mi7.v() == 4\n    assert mi7.bar() == 13\n\n    mi8 = MI8(14)\n    assert mi8.v() == 1\n    assert mi8.bar() == 14\n\n    mi8b = MI8b(15)\n    assert mi8b.v() == 3\n    assert mi8b.bar() == 15\n\n\ndef test_multiple_inheritance_python_many_bases():\n    class MIMany14(m.BaseN1, m.BaseN2, m.BaseN3, m.BaseN4):\n        def __init__(self):\n            m.BaseN1.__init__(self, 1)\n            m.BaseN2.__init__(self, 2)\n            m.BaseN3.__init__(self, 3)\n            m.BaseN4.__init__(self, 4)\n\n    class MIMany58(m.BaseN5, m.BaseN6, m.BaseN7, m.BaseN8):\n        def __init__(self):\n            m.BaseN5.__init__(self, 5)\n            m.BaseN6.__init__(self, 6)\n            m.BaseN7.__init__(self, 7)\n            m.BaseN8.__init__(self, 8)\n\n    class MIMany916(\n        m.BaseN9,\n        m.BaseN10,\n        m.BaseN11,\n        m.BaseN12,\n        m.BaseN13,\n        m.BaseN14,\n        m.BaseN15,\n        m.BaseN16,\n    ):\n        def __init__(self):\n            m.BaseN9.__init__(self, 9)\n            m.BaseN10.__init__(self, 10)\n            m.BaseN11.__init__(self, 11)\n            m.BaseN12.__init__(self, 12)\n            m.BaseN13.__init__(self, 13)\n            m.BaseN14.__init__(self, 14)\n            m.BaseN15.__init__(self, 15)\n            m.BaseN16.__init__(self, 16)\n\n    class MIMany19(MIMany14, MIMany58, m.BaseN9):\n        def __init__(self):\n            MIMany14.__init__(self)\n            MIMany58.__init__(self)\n            m.BaseN9.__init__(self, 9)\n\n    class MIMany117(MIMany14, MIMany58, MIMany916, m.BaseN17):\n        def __init__(self):\n            MIMany14.__init__(self)\n            MIMany58.__init__(self)\n            MIMany916.__init__(self)\n            m.BaseN17.__init__(self, 17)\n\n    # Inherits from 4 registered C++ classes: can fit in one pointer on any modern arch:\n    a = MIMany14()\n    for i in range(1, 4):\n        assert getattr(a, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 8: requires 1/2 pointers worth of holder flags on 32/64-bit arch:\n    b = MIMany916()\n    for i in range(9, 16):\n        assert getattr(b, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 9: requires >= 2 pointers worth of holder flags\n    c = MIMany19()\n    for i in range(1, 9):\n        assert getattr(c, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 17: requires >= 3 pointers worth of holder flags\n    d = MIMany117()\n    for i in range(1, 17):\n        assert getattr(d, \"f\" + str(i))() == 2 * i\n\n\ndef test_multiple_inheritance_virtbase():\n    class MITypePy(m.Base12a):\n        def __init__(self, i, j):\n            m.Base12a.__init__(self, i, j)\n\n    mt = MITypePy(3, 4)\n    assert mt.bar() == 4\n    assert m.bar_base2a(mt) == 4\n    assert m.bar_base2a_sharedptr(mt) == 4\n\n\ndef test_mi_static_properties():\n    \"\"\"Mixing bases with and without static properties should be possible\n    and the result should be independent of base definition order\"\"\"\n\n    for d in (m.VanillaStaticMix1(), m.VanillaStaticMix2()):\n        assert d.vanilla() == \"Vanilla\"\n        assert d.static_func1() == \"WithStatic1\"\n        assert d.static_func2() == \"WithStatic2\"\n        assert d.static_func() == d.__class__.__name__\n\n        m.WithStatic1.static_value1 = 1\n        m.WithStatic2.static_value2 = 2\n        assert d.static_value1 == 1\n        assert d.static_value2 == 2\n        assert d.static_value == 12\n\n        d.static_value1 = 0\n        assert d.static_value1 == 0\n        d.static_value2 = 0\n        assert d.static_value2 == 0\n        d.static_value = 0\n        assert d.static_value == 0\n\n\n# Requires PyPy 6+\ndef test_mi_dynamic_attributes():\n    \"\"\"Mixing bases with and without dynamic attribute support\"\"\"\n\n    for d in (m.VanillaDictMix1(), m.VanillaDictMix2()):\n        d.dynamic = 1\n        assert d.dynamic == 1\n\n\ndef test_mi_unaligned_base():\n    \"\"\"Returning an offset (non-first MI) base class pointer should recognize the instance\"\"\"\n\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    c = m.I801C()\n    d = m.I801D()\n    # + 4 below because we have the two instances, and each instance has offset base I801B2\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n    b1c = m.i801b1_c(c)\n    assert b1c is c\n    b2c = m.i801b2_c(c)\n    assert b2c is c\n    b1d = m.i801b1_d(d)\n    assert b1d is d\n    b2d = m.i801b2_d(d)\n    assert b2d is d\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4  # no extra instances\n    del c, b1c, b2c\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    del d, b1d, b2d\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n\ndef test_mi_base_return():\n    \"\"\"Tests returning an offset (non-first MI) base class pointer to a derived instance\"\"\"\n\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    c1 = m.i801c_b1()\n    assert type(c1) is m.I801C\n    assert c1.a == 1\n    assert c1.b == 2\n\n    d1 = m.i801d_b1()\n    assert type(d1) is m.I801D\n    assert d1.a == 1\n    assert d1.b == 2\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    c2 = m.i801c_b2()\n    assert type(c2) is m.I801C\n    assert c2.a == 1\n    assert c2.b == 2\n\n    d2 = m.i801d_b2()\n    assert type(d2) is m.I801D\n    assert d2.a == 1\n    assert d2.b == 2\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 8\n\n    del c2\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n    del c1, d1, d2\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    # Returning an unregistered derived type with a registered base; we won't\n    # pick up the derived type, obviously, but should still work (as an object\n    # of whatever type was returned).\n    e1 = m.i801e_c()\n    assert type(e1) is m.I801C\n    assert e1.a == 1\n    assert e1.b == 2\n\n    e2 = m.i801e_b2()\n    assert type(e2) is m.I801B2\n    assert e2.b == 2\n\n\ndef test_diamond_inheritance():\n    \"\"\"Tests that diamond inheritance works as expected (issue #959)\"\"\"\n\n    # Issue #959: this shouldn't segfault:\n    d = m.D()\n\n    # Make sure all the various distinct pointers are all recognized as registered instances:\n    assert d is d.c0()\n    assert d is d.c1()\n    assert d is d.b()\n    assert d is d.c0().b()\n    assert d is d.c1().b()\n    assert d is d.c0().c1().b().c0().b()\n\n\ndef test_pr3635_diamond_b():\n    o = m.MVB()\n    assert o.b == 1\n\n    assert o.get_b_b() == 1\n\n\ndef test_pr3635_diamond_c():\n    o = m.MVC()\n    assert o.b == 1\n    assert o.c == 2\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n\n    assert o.get_c_c() == 2\n\n\ndef test_pr3635_diamond_d0():\n    o = m.MVD0()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n\n    assert o.get_d0_d0() == 3\n\n\ndef test_pr3635_diamond_d1():\n    o = m.MVD1()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d1 == 4\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d1_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d1_c() == 2\n\n    assert o.get_d1_d1() == 4\n\n\ndef test_pr3635_diamond_e():\n    o = m.MVE()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n    assert o.get_d1_b() == 1\n    assert o.get_e_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n    assert o.get_d1_c() == 2\n    assert o.get_e_c() == 2\n\n    assert o.get_d0_d0() == 3\n    assert o.get_e_d0() == 3\n\n    assert o.get_d1_d1() == 4\n    assert o.get_e_d1() == 4\n\n    assert o.get_e_e() == 5\n\n\ndef test_pr3635_diamond_f():\n    o = m.MVF()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n    assert o.f == 6\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n    assert o.get_d1_b() == 1\n    assert o.get_e_b() == 1\n    assert o.get_f_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n    assert o.get_d1_c() == 2\n    assert o.get_e_c() == 2\n    assert o.get_f_c() == 2\n\n    assert o.get_d0_d0() == 3\n    assert o.get_e_d0() == 3\n    assert o.get_f_d0() == 3\n\n    assert o.get_d1_d1() == 4\n    assert o.get_e_d1() == 4\n    assert o.get_f_d1() == 4\n\n    assert o.get_e_e() == 5\n    assert o.get_f_e() == 5\n\n    assert o.get_f_f() == 6\n\n\ndef test_python_inherit_from_mi():\n    \"\"\"Tests extending a Python class from a single inheritor of a MI class\"\"\"\n\n    class PyMVF(m.MVF):\n        g = 7\n\n        def get_g_g(self):\n            return self.g\n\n    o = PyMVF()\n\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n    assert o.f == 6\n    assert o.g == 7\n\n    assert o.get_g_g() == 7\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_array.cpp",
    "content": "/*\n    tests/test_numpy_array.cpp -- test core array functionality\n\n    Copyright (c) 2016 Ivan Smirnov <i.s.smirnov@gmail.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\n#include <cstdint>\n#include <utility>\n\n// Size / dtype checks.\nstruct DtypeCheck {\n    py::dtype numpy{};\n    py::dtype pybind11{};\n};\n\ntemplate <typename T>\nDtypeCheck get_dtype_check(const char *name) {\n    py::module_ np = py::module_::import(\"numpy\");\n    DtypeCheck check{};\n    check.numpy = np.attr(\"dtype\")(np.attr(name));\n    check.pybind11 = py::dtype::of<T>();\n    return check;\n}\n\nstd::vector<DtypeCheck> get_concrete_dtype_checks() {\n    return {// Normalization\n            get_dtype_check<std::int8_t>(\"int8\"),\n            get_dtype_check<std::uint8_t>(\"uint8\"),\n            get_dtype_check<std::int16_t>(\"int16\"),\n            get_dtype_check<std::uint16_t>(\"uint16\"),\n            get_dtype_check<std::int32_t>(\"int32\"),\n            get_dtype_check<std::uint32_t>(\"uint32\"),\n            get_dtype_check<std::int64_t>(\"int64\"),\n            get_dtype_check<std::uint64_t>(\"uint64\")};\n}\n\nstruct DtypeSizeCheck {\n    std::string name{};\n    int size_cpp{};\n    int size_numpy{};\n    // For debugging.\n    py::dtype dtype{};\n};\n\ntemplate <typename T>\nDtypeSizeCheck get_dtype_size_check() {\n    DtypeSizeCheck check{};\n    check.name = py::type_id<T>();\n    check.size_cpp = sizeof(T);\n    check.dtype = py::dtype::of<T>();\n    check.size_numpy = check.dtype.attr(\"itemsize\").template cast<int>();\n    return check;\n}\n\nstd::vector<DtypeSizeCheck> get_platform_dtype_size_checks() {\n    return {\n        get_dtype_size_check<short>(),\n        get_dtype_size_check<unsigned short>(),\n        get_dtype_size_check<int>(),\n        get_dtype_size_check<unsigned int>(),\n        get_dtype_size_check<long>(),\n        get_dtype_size_check<unsigned long>(),\n        get_dtype_size_check<long long>(),\n        get_dtype_size_check<unsigned long long>(),\n    };\n}\n\n// Arrays.\nusing arr = py::array;\nusing arr_t = py::array_t<uint16_t, 0>;\nstatic_assert(std::is_same<arr_t::value_type, uint16_t>::value, \"\");\n\ntemplate <typename... Ix>\narr data(const arr &a, Ix... index) {\n    return arr(a.nbytes() - a.offset_at(index...), (const uint8_t *) a.data(index...));\n}\n\ntemplate <typename... Ix>\narr data_t(const arr_t &a, Ix... index) {\n    return arr(a.size() - a.index_at(index...), a.data(index...));\n}\n\ntemplate <typename... Ix>\narr &mutate_data(arr &a, Ix... index) {\n    auto *ptr = (uint8_t *) a.mutable_data(index...);\n    for (py::ssize_t i = 0; i < a.nbytes() - a.offset_at(index...); i++) {\n        ptr[i] = (uint8_t) (ptr[i] * 2);\n    }\n    return a;\n}\n\ntemplate <typename... Ix>\narr_t &mutate_data_t(arr_t &a, Ix... index) {\n    auto ptr = a.mutable_data(index...);\n    for (py::ssize_t i = 0; i < a.size() - a.index_at(index...); i++) {\n        ptr[i]++;\n    }\n    return a;\n}\n\ntemplate <typename... Ix>\npy::ssize_t index_at(const arr &a, Ix... idx) {\n    return a.index_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t index_at_t(const arr_t &a, Ix... idx) {\n    return a.index_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t offset_at(const arr &a, Ix... idx) {\n    return a.offset_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t offset_at_t(const arr_t &a, Ix... idx) {\n    return a.offset_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t at_t(const arr_t &a, Ix... idx) {\n    return a.at(idx...);\n}\ntemplate <typename... Ix>\narr_t &mutate_at_t(arr_t &a, Ix... idx) {\n    a.mutable_at(idx...)++;\n    return a;\n}\n\n#define def_index_fn(name, type)                                                                  \\\n    sm.def(#name, [](type a) { return name(a); });                                                \\\n    sm.def(#name, [](type a, int i) { return name(a, i); });                                      \\\n    sm.def(#name, [](type a, int i, int j) { return name(a, i, j); });                            \\\n    sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); });\n\ntemplate <typename T, typename T2>\npy::handle auxiliaries(T &&r, T2 &&r2) {\n    if (r.ndim() != 2) {\n        throw std::domain_error(\"error: ndim != 2\");\n    }\n    py::list l;\n    l.append(*r.data(0, 0));\n    l.append(*r2.mutable_data(0, 0));\n    l.append(r.data(0, 1) == r2.mutable_data(0, 1));\n    l.append(r.ndim());\n    l.append(r.itemsize());\n    l.append(r.shape(0));\n    l.append(r.shape(1));\n    l.append(r.size());\n    l.append(r.nbytes());\n    return l.release();\n}\n\n// note: declaration at local scope would create a dangling reference!\nstatic int data_i = 42;\n\nTEST_SUBMODULE(numpy_array, sm) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (const py::error_already_set &) {\n        return;\n    }\n\n    // test_dtypes\n    py::class_<DtypeCheck>(sm, \"DtypeCheck\")\n        .def_readonly(\"numpy\", &DtypeCheck::numpy)\n        .def_readonly(\"pybind11\", &DtypeCheck::pybind11)\n        .def(\"__repr__\", [](const DtypeCheck &self) {\n            return py::str(\"<DtypeCheck numpy={} pybind11={}>\").format(self.numpy, self.pybind11);\n        });\n    sm.def(\"get_concrete_dtype_checks\", &get_concrete_dtype_checks);\n\n    py::class_<DtypeSizeCheck>(sm, \"DtypeSizeCheck\")\n        .def_readonly(\"name\", &DtypeSizeCheck::name)\n        .def_readonly(\"size_cpp\", &DtypeSizeCheck::size_cpp)\n        .def_readonly(\"size_numpy\", &DtypeSizeCheck::size_numpy)\n        .def(\"__repr__\", [](const DtypeSizeCheck &self) {\n            return py::str(\"<DtypeSizeCheck name='{}' size_cpp={} size_numpy={} dtype={}>\")\n                .format(self.name, self.size_cpp, self.size_numpy, self.dtype);\n        });\n    sm.def(\"get_platform_dtype_size_checks\", &get_platform_dtype_size_checks);\n\n    // test_array_attributes\n    sm.def(\"ndim\", [](const arr &a) { return a.ndim(); });\n    sm.def(\"shape\", [](const arr &a) { return arr(a.ndim(), a.shape()); });\n    sm.def(\"shape\", [](const arr &a, py::ssize_t dim) { return a.shape(dim); });\n    sm.def(\"strides\", [](const arr &a) { return arr(a.ndim(), a.strides()); });\n    sm.def(\"strides\", [](const arr &a, py::ssize_t dim) { return a.strides(dim); });\n    sm.def(\"writeable\", [](const arr &a) { return a.writeable(); });\n    sm.def(\"size\", [](const arr &a) { return a.size(); });\n    sm.def(\"itemsize\", [](const arr &a) { return a.itemsize(); });\n    sm.def(\"nbytes\", [](const arr &a) { return a.nbytes(); });\n    sm.def(\"owndata\", [](const arr &a) { return a.owndata(); });\n\n    // test_index_offset\n    def_index_fn(index_at, const arr &);\n    def_index_fn(index_at_t, const arr_t &);\n    def_index_fn(offset_at, const arr &);\n    def_index_fn(offset_at_t, const arr_t &);\n    // test_data\n    def_index_fn(data, const arr &);\n    def_index_fn(data_t, const arr_t &);\n    // test_mutate_data, test_mutate_readonly\n    def_index_fn(mutate_data, arr &);\n    def_index_fn(mutate_data_t, arr_t &);\n    def_index_fn(at_t, const arr_t &);\n    def_index_fn(mutate_at_t, arr_t &);\n\n    // test_make_c_f_array\n    sm.def(\"make_f_array\", [] { return py::array_t<float>({2, 2}, {4, 8}); });\n    sm.def(\"make_c_array\", [] { return py::array_t<float>({2, 2}, {8, 4}); });\n\n    // test_empty_shaped_array\n    sm.def(\"make_empty_shaped_array\", [] { return py::array(py::dtype(\"f\"), {}, {}); });\n    // test numpy scalars (empty shape, ndim==0)\n    sm.def(\"scalar_int\", []() { return py::array(py::dtype(\"i\"), {}, {}, &data_i); });\n\n    // test_wrap\n    sm.def(\"wrap\", [](const py::array &a) {\n        return py::array(a.dtype(),\n                         {a.shape(), a.shape() + a.ndim()},\n                         {a.strides(), a.strides() + a.ndim()},\n                         a.data(),\n                         a);\n    });\n\n    // test_numpy_view\n    struct ArrayClass {\n        int data[2] = {1, 2};\n        ArrayClass() { py::print(\"ArrayClass()\"); }\n        ~ArrayClass() { py::print(\"~ArrayClass()\"); }\n    };\n    py::class_<ArrayClass>(sm, \"ArrayClass\")\n        .def(py::init<>())\n        .def(\"numpy_view\", [](py::object &obj) {\n            py::print(\"ArrayClass::numpy_view()\");\n            auto &a = obj.cast<ArrayClass &>();\n            return py::array_t<int>({2}, {4}, a.data, obj);\n        });\n\n    // test_cast_numpy_int64_to_uint64\n    sm.def(\"function_taking_uint64\", [](uint64_t) {});\n\n    // test_isinstance\n    sm.def(\"isinstance_untyped\", [](py::object yes, py::object no) {\n        return py::isinstance<py::array>(std::move(yes))\n               && !py::isinstance<py::array>(std::move(no));\n    });\n    sm.def(\"isinstance_typed\", [](const py::object &o) {\n        return py::isinstance<py::array_t<double>>(o) && !py::isinstance<py::array_t<int>>(o);\n    });\n\n    // test_constructors\n    sm.def(\"default_constructors\", []() {\n        return py::dict(\"array\"_a = py::array(),\n                        \"array_t<int32>\"_a = py::array_t<std::int32_t>(),\n                        \"array_t<double>\"_a = py::array_t<double>());\n    });\n    sm.def(\"converting_constructors\", [](const py::object &o) {\n        return py::dict(\"array\"_a = py::array(o),\n                        \"array_t<int32>\"_a = py::array_t<std::int32_t>(o),\n                        \"array_t<double>\"_a = py::array_t<double>(o));\n    });\n\n    // test_overload_resolution\n    sm.def(\"overloaded\", [](const py::array_t<double> &) { return \"double\"; });\n    sm.def(\"overloaded\", [](const py::array_t<float> &) { return \"float\"; });\n    sm.def(\"overloaded\", [](const py::array_t<int> &) { return \"int\"; });\n    sm.def(\"overloaded\", [](const py::array_t<unsigned short> &) { return \"unsigned short\"; });\n    sm.def(\"overloaded\", [](const py::array_t<long long> &) { return \"long long\"; });\n    sm.def(\"overloaded\",\n           [](const py::array_t<std::complex<double>> &) { return \"double complex\"; });\n    sm.def(\"overloaded\", [](const py::array_t<std::complex<float>> &) { return \"float complex\"; });\n\n    sm.def(\"overloaded2\",\n           [](const py::array_t<std::complex<double>> &) { return \"double complex\"; });\n    sm.def(\"overloaded2\", [](const py::array_t<double> &) { return \"double\"; });\n    sm.def(\"overloaded2\",\n           [](const py::array_t<std::complex<float>> &) { return \"float complex\"; });\n    sm.def(\"overloaded2\", [](const py::array_t<float> &) { return \"float\"; });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // Only accept the exact types:\n    sm.def(\n        \"overloaded3\", [](const py::array_t<int> &) { return \"int\"; }, py::arg{}.noconvert());\n    sm.def(\n        \"overloaded3\",\n        [](const py::array_t<double> &) { return \"double\"; },\n        py::arg{}.noconvert());\n\n    // Make sure we don't do unsafe coercion (e.g. float to int) when not using forcecast, but\n    // rather that float gets converted via the safe (conversion to double) overload:\n    sm.def(\"overloaded4\", [](const py::array_t<long long, 0> &) { return \"long long\"; });\n    sm.def(\"overloaded4\", [](const py::array_t<double, 0> &) { return \"double\"; });\n\n    // But we do allow conversion to int if forcecast is enabled (but only if no overload matches\n    // without conversion)\n    sm.def(\"overloaded5\", [](const py::array_t<unsigned int> &) { return \"unsigned int\"; });\n    sm.def(\"overloaded5\", [](const py::array_t<double> &) { return \"double\"; });\n\n    // test_greedy_string_overload\n    // Issue 685: ndarray shouldn't go to std::string overload\n    sm.def(\"issue685\", [](const std::string &) { return \"string\"; });\n    sm.def(\"issue685\", [](const py::array &) { return \"array\"; });\n    sm.def(\"issue685\", [](const py::object &) { return \"other\"; });\n\n    // test_array_unchecked_fixed_dims\n    sm.def(\n        \"proxy_add2\",\n        [](py::array_t<double> a, double v) {\n            auto r = a.mutable_unchecked<2>();\n            for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                    r(i, j) += v;\n                }\n            }\n        },\n        py::arg{}.noconvert(),\n        py::arg());\n\n    sm.def(\"proxy_init3\", [](double start) {\n        py::array_t<double, py::array::c_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked<3>();\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t k = 0; k < r.shape(2); k++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_init3F\", [](double start) {\n        py::array_t<double, py::array::f_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked<3>();\n        for (py::ssize_t k = 0; k < r.shape(2); k++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_squared_L2_norm\", [](const py::array_t<double> &a) {\n        auto r = a.unchecked<1>();\n        double sumsq = 0;\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            sumsq += r[i] * r(i); // Either notation works for a 1D array\n        }\n        return sumsq;\n    });\n\n    sm.def(\"proxy_auxiliaries2\", [](py::array_t<double> a) {\n        auto r = a.unchecked<2>();\n        auto r2 = a.mutable_unchecked<2>();\n        return auxiliaries(r, r2);\n    });\n\n    sm.def(\"proxy_auxiliaries1_const_ref\", [](py::array_t<double> a) {\n        const auto &r = a.unchecked<1>();\n        const auto &r2 = a.mutable_unchecked<1>();\n        return r(0) == r2(0) && r[0] == r2[0];\n    });\n\n    sm.def(\"proxy_auxiliaries2_const_ref\", [](py::array_t<double> a) {\n        const auto &r = a.unchecked<2>();\n        const auto &r2 = a.mutable_unchecked<2>();\n        return r(0, 0) == r2(0, 0);\n    });\n\n    // test_array_unchecked_dyn_dims\n    // Same as the above, but without a compile-time dimensions specification:\n    sm.def(\n        \"proxy_add2_dyn\",\n        [](py::array_t<double> a, double v) {\n            auto r = a.mutable_unchecked();\n            if (r.ndim() != 2) {\n                throw std::domain_error(\"error: ndim != 2\");\n            }\n            for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                    r(i, j) += v;\n                }\n            }\n        },\n        py::arg{}.noconvert(),\n        py::arg());\n    sm.def(\"proxy_init3_dyn\", [](double start) {\n        py::array_t<double, py::array::c_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked();\n        if (r.ndim() != 3) {\n            throw std::domain_error(\"error: ndim != 3\");\n        }\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t k = 0; k < r.shape(2); k++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_auxiliaries2_dyn\", [](py::array_t<double> a) {\n        return auxiliaries(a.unchecked(), a.mutable_unchecked());\n    });\n\n    sm.def(\"array_auxiliaries2\", [](py::array_t<double> a) { return auxiliaries(a, a); });\n\n    // test_array_failures\n    // Issue #785: Uninformative \"Unknown internal error\" exception when constructing array from\n    // empty object:\n    sm.def(\"array_fail_test\", []() { return py::array(py::object()); });\n    sm.def(\"array_t_fail_test\", []() { return py::array_t<double>(py::object()); });\n    // Make sure the error from numpy is being passed through:\n    sm.def(\"array_fail_test_negative_size\", []() {\n        int c = 0;\n        return py::array(-1, &c);\n    });\n\n    // test_initializer_list\n    // Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous\n    sm.def(\"array_initializer_list1\", []() { return py::array_t<float>(1); });\n    // { 1 } also works for the above, but clang warns about it\n    sm.def(\"array_initializer_list2\", []() { return py::array_t<float>({1, 2}); });\n    sm.def(\"array_initializer_list3\", []() { return py::array_t<float>({1, 2, 3}); });\n    sm.def(\"array_initializer_list4\", []() { return py::array_t<float>({1, 2, 3, 4}); });\n\n    // test_array_resize\n    // reshape array to 2D without changing size\n    sm.def(\"array_reshape2\", [](py::array_t<double> a) {\n        const auto dim_sz = (py::ssize_t) std::sqrt(a.size());\n        if (dim_sz * dim_sz != a.size()) {\n            throw std::domain_error(\n                \"array_reshape2: input array total size is not a squared integer\");\n        }\n        a.resize({dim_sz, dim_sz});\n    });\n\n    // resize to 3D array with each dimension = N\n    sm.def(\"array_resize3\", [](py::array_t<double> a, size_t N, bool refcheck) {\n        a.resize({N, N, N}, refcheck);\n    });\n\n    // test_array_create_and_resize\n    // return 2D array with Nrows = Ncols = N\n    sm.def(\"create_and_resize\", [](size_t N) {\n        py::array_t<double> a;\n        a.resize({N, N});\n        std::fill(a.mutable_data(), a.mutable_data() + a.size(), 42.);\n        return a;\n    });\n\n    sm.def(\"array_view\",\n           [](py::array_t<uint8_t> a, const std::string &dtype) { return a.view(dtype); });\n\n    sm.def(\"reshape_initializer_list\", [](py::array_t<int> a, size_t N, size_t M, size_t O) {\n        return a.reshape({N, M, O});\n    });\n    sm.def(\"reshape_tuple\", [](py::array_t<int> a, const std::vector<int> &new_shape) {\n        return a.reshape(new_shape);\n    });\n\n    sm.def(\"index_using_ellipsis\",\n           [](const py::array &a) { return a[py::make_tuple(0, py::ellipsis(), 0)]; });\n\n    // test_argument_conversions\n    sm.def(\n        \"accept_double\", [](const py::array_t<double, 0> &) {}, py::arg(\"a\"));\n    sm.def(\n        \"accept_double_forcecast\",\n        [](const py::array_t<double, py::array::forcecast> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_c_style\",\n        [](const py::array_t<double, py::array::c_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_c_style_forcecast\",\n        [](const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_f_style\",\n        [](const py::array_t<double, py::array::f_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_f_style_forcecast\",\n        [](const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_noconvert\", [](const py::array_t<double, 0> &) {}, \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_c_style_noconvert\",\n        [](const py::array_t<double, py::array::c_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_c_style_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_f_style_noconvert\",\n        [](const py::array_t<double, py::array::f_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_f_style_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},\n        \"a\"_a.noconvert());\n\n    // Check that types returns correct npy format descriptor\n    sm.def(\"test_fmt_desc_float\", [](const py::array_t<float> &) {});\n    sm.def(\"test_fmt_desc_double\", [](const py::array_t<double> &) {});\n    sm.def(\"test_fmt_desc_const_float\", [](const py::array_t<const float> &) {});\n    sm.def(\"test_fmt_desc_const_double\", [](const py::array_t<const double> &) {});\n\n    sm.def(\"round_trip_float\", [](double d) { return d; });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_array.py",
    "content": "import pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import numpy_array as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_dtypes():\n    # See issue #1328.\n    # - Platform-dependent sizes.\n    for size_check in m.get_platform_dtype_size_checks():\n        print(size_check)\n        assert size_check.size_cpp == size_check.size_numpy, size_check\n    # - Concrete sizes.\n    for check in m.get_concrete_dtype_checks():\n        print(check)\n        assert check.numpy == check.pybind11, check\n        if check.numpy.num != check.pybind11.num:\n            print(\n                f\"NOTE: typenum mismatch for {check}: {check.numpy.num} != {check.pybind11.num}\"\n            )\n\n\n@pytest.fixture(scope=\"function\")\ndef arr():\n    return np.array([[1, 2, 3], [4, 5, 6]], \"=u2\")\n\n\ndef test_array_attributes():\n    a = np.array(0, \"f8\")\n    assert m.ndim(a) == 0\n    assert all(m.shape(a) == [])\n    assert all(m.strides(a) == [])\n    with pytest.raises(IndexError) as excinfo:\n        m.shape(a, 0)\n    assert str(excinfo.value) == \"invalid axis: 0 (ndim = 0)\"\n    with pytest.raises(IndexError) as excinfo:\n        m.strides(a, 0)\n    assert str(excinfo.value) == \"invalid axis: 0 (ndim = 0)\"\n    assert m.writeable(a)\n    assert m.size(a) == 1\n    assert m.itemsize(a) == 8\n    assert m.nbytes(a) == 8\n    assert m.owndata(a)\n\n    a = np.array([[1, 2, 3], [4, 5, 6]], \"u2\").view()\n    a.flags.writeable = False\n    assert m.ndim(a) == 2\n    assert all(m.shape(a) == [2, 3])\n    assert m.shape(a, 0) == 2\n    assert m.shape(a, 1) == 3\n    assert all(m.strides(a) == [6, 2])\n    assert m.strides(a, 0) == 6\n    assert m.strides(a, 1) == 2\n    with pytest.raises(IndexError) as excinfo:\n        m.shape(a, 2)\n    assert str(excinfo.value) == \"invalid axis: 2 (ndim = 2)\"\n    with pytest.raises(IndexError) as excinfo:\n        m.strides(a, 2)\n    assert str(excinfo.value) == \"invalid axis: 2 (ndim = 2)\"\n    assert not m.writeable(a)\n    assert m.size(a) == 6\n    assert m.itemsize(a) == 2\n    assert m.nbytes(a) == 12\n    assert not m.owndata(a)\n\n\n@pytest.mark.parametrize(\n    \"args, ret\", [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)]\n)\ndef test_index_offset(arr, args, ret):\n    assert m.index_at(arr, *args) == ret\n    assert m.index_at_t(arr, *args) == ret\n    assert m.offset_at(arr, *args) == ret * arr.dtype.itemsize\n    assert m.offset_at_t(arr, *args) == ret * arr.dtype.itemsize\n\n\ndef test_dim_check_fail(arr):\n    for func in (\n        m.index_at,\n        m.index_at_t,\n        m.offset_at,\n        m.offset_at_t,\n        m.data,\n        m.data_t,\n        m.mutate_data,\n        m.mutate_data_t,\n    ):\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 1, 2, 3)\n        assert str(excinfo.value) == \"too many indices for an array: 3 (ndim = 2)\"\n\n\n@pytest.mark.parametrize(\n    \"args, ret\",\n    [\n        ([], [1, 2, 3, 4, 5, 6]),\n        ([1], [4, 5, 6]),\n        ([0, 1], [2, 3, 4, 5, 6]),\n        ([1, 2], [6]),\n    ],\n)\ndef test_data(arr, args, ret):\n    from sys import byteorder\n\n    assert all(m.data_t(arr, *args) == ret)\n    assert all(m.data(arr, *args)[(0 if byteorder == \"little\" else 1) :: 2] == ret)\n    assert all(m.data(arr, *args)[(1 if byteorder == \"little\" else 0) :: 2] == 0)\n\n\n@pytest.mark.parametrize(\"dim\", [0, 1, 3])\ndef test_at_fail(arr, dim):\n    for func in m.at_t, m.mutate_at_t:\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, *([0] * dim))\n        assert str(excinfo.value) == f\"index dimension mismatch: {dim} (ndim = 2)\"\n\n\ndef test_at(arr):\n    assert m.at_t(arr, 0, 2) == 3\n    assert m.at_t(arr, 1, 0) == 4\n\n    assert all(m.mutate_at_t(arr, 0, 2).ravel() == [1, 2, 4, 4, 5, 6])\n    assert all(m.mutate_at_t(arr, 1, 0).ravel() == [1, 2, 4, 5, 5, 6])\n\n\ndef test_mutate_readonly(arr):\n    arr.flags.writeable = False\n    for func, args in (\n        (m.mutate_data, ()),\n        (m.mutate_data_t, ()),\n        (m.mutate_at_t, (0, 0)),\n    ):\n        with pytest.raises(ValueError) as excinfo:\n            func(arr, *args)\n        assert str(excinfo.value) == \"array is not writeable\"\n\n\ndef test_mutate_data(arr):\n    assert all(m.mutate_data(arr).ravel() == [2, 4, 6, 8, 10, 12])\n    assert all(m.mutate_data(arr).ravel() == [4, 8, 12, 16, 20, 24])\n    assert all(m.mutate_data(arr, 1).ravel() == [4, 8, 12, 32, 40, 48])\n    assert all(m.mutate_data(arr, 0, 1).ravel() == [4, 16, 24, 64, 80, 96])\n    assert all(m.mutate_data(arr, 1, 2).ravel() == [4, 16, 24, 64, 80, 192])\n\n    assert all(m.mutate_data_t(arr).ravel() == [5, 17, 25, 65, 81, 193])\n    assert all(m.mutate_data_t(arr).ravel() == [6, 18, 26, 66, 82, 194])\n    assert all(m.mutate_data_t(arr, 1).ravel() == [6, 18, 26, 67, 83, 195])\n    assert all(m.mutate_data_t(arr, 0, 1).ravel() == [6, 19, 27, 68, 84, 196])\n    assert all(m.mutate_data_t(arr, 1, 2).ravel() == [6, 19, 27, 68, 84, 197])\n\n\ndef test_bounds_check(arr):\n    for func in (\n        m.index_at,\n        m.index_at_t,\n        m.data,\n        m.data_t,\n        m.mutate_data,\n        m.mutate_data_t,\n        m.at_t,\n        m.mutate_at_t,\n    ):\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 2, 0)\n        assert str(excinfo.value) == \"index 2 is out of bounds for axis 0 with size 2\"\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 0, 4)\n        assert str(excinfo.value) == \"index 4 is out of bounds for axis 1 with size 3\"\n\n\ndef test_make_c_f_array():\n    assert m.make_c_array().flags.c_contiguous\n    assert not m.make_c_array().flags.f_contiguous\n    assert m.make_f_array().flags.f_contiguous\n    assert not m.make_f_array().flags.c_contiguous\n\n\ndef test_make_empty_shaped_array():\n    m.make_empty_shaped_array()\n\n    # empty shape means numpy scalar, PEP 3118\n    assert m.scalar_int().ndim == 0\n    assert m.scalar_int().shape == ()\n    assert m.scalar_int() == 42\n\n\ndef test_wrap():\n    def assert_references(a, b, base=None):\n        if base is None:\n            base = a\n        assert a is not b\n        assert a.__array_interface__[\"data\"][0] == b.__array_interface__[\"data\"][0]\n        assert a.shape == b.shape\n        assert a.strides == b.strides\n        assert a.flags.c_contiguous == b.flags.c_contiguous\n        assert a.flags.f_contiguous == b.flags.f_contiguous\n        assert a.flags.writeable == b.flags.writeable\n        assert a.flags.aligned == b.flags.aligned\n        # 1.13 supported Python 3.6\n        if tuple(int(x) for x in np.__version__.split(\".\")[:2]) >= (1, 14):\n            assert a.flags.writebackifcopy == b.flags.writebackifcopy\n        else:\n            assert a.flags.updateifcopy == b.flags.updateifcopy\n        assert np.all(a == b)\n        assert not b.flags.owndata\n        assert b.base is base\n        if a.flags.writeable and a.ndim == 2:\n            a[0, 0] = 1234\n            assert b[0, 0] == 1234\n\n    a1 = np.array([1, 2], dtype=np.int16)\n    assert a1.flags.owndata and a1.base is None\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order=\"F\")\n    assert a1.flags.owndata and a1.base is None\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order=\"C\")\n    a1.flags.writeable = False\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.random.random((4, 4, 4))\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1t = a1.transpose()\n    a2 = m.wrap(a1t)\n    assert_references(a1t, a2, a1)\n\n    a1d = a1.diagonal()\n    a2 = m.wrap(a1d)\n    assert_references(a1d, a2, a1)\n\n    a1m = a1[::-1, ::-1, ::-1]\n    a2 = m.wrap(a1m)\n    assert_references(a1m, a2, a1)\n\n\ndef test_numpy_view(capture):\n    with capture:\n        ac = m.ArrayClass()\n        ac_view_1 = ac.numpy_view()\n        ac_view_2 = ac.numpy_view()\n        assert np.all(ac_view_1 == np.array([1, 2], dtype=np.int32))\n        del ac\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        ArrayClass()\n        ArrayClass::numpy_view()\n        ArrayClass::numpy_view()\n    \"\"\"\n    )\n    ac_view_1[0] = 4\n    ac_view_1[1] = 3\n    assert ac_view_2[0] == 4\n    assert ac_view_2[1] == 3\n    with capture:\n        del ac_view_1\n        del ac_view_2\n        pytest.gc_collect()\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        ~ArrayClass()\n    \"\"\"\n    )\n\n\ndef test_cast_numpy_int64_to_uint64():\n    m.function_taking_uint64(123)\n    m.function_taking_uint64(np.uint64(123))\n\n\ndef test_isinstance():\n    assert m.isinstance_untyped(np.array([1, 2, 3]), \"not an array\")\n    assert m.isinstance_typed(np.array([1.0, 2.0, 3.0]))\n\n\ndef test_constructors():\n    defaults = m.default_constructors()\n    for a in defaults.values():\n        assert a.size == 0\n    assert defaults[\"array\"].dtype == np.array([]).dtype\n    assert defaults[\"array_t<int32>\"].dtype == np.int32\n    assert defaults[\"array_t<double>\"].dtype == np.float64\n\n    results = m.converting_constructors([1, 2, 3])\n    for a in results.values():\n        np.testing.assert_array_equal(a, [1, 2, 3])\n    assert results[\"array\"].dtype == np.int_\n    assert results[\"array_t<int32>\"].dtype == np.int32\n    assert results[\"array_t<double>\"].dtype == np.float64\n\n\ndef test_overload_resolution(msg):\n    # Exact overload matches:\n    assert m.overloaded(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded(np.array([1], dtype=\"float32\")) == \"float\"\n    assert m.overloaded(np.array([1], dtype=\"ushort\")) == \"unsigned short\"\n    assert m.overloaded(np.array([1], dtype=\"intc\")) == \"int\"\n    assert m.overloaded(np.array([1], dtype=\"longlong\")) == \"long long\"\n    assert m.overloaded(np.array([1], dtype=\"complex\")) == \"double complex\"\n    assert m.overloaded(np.array([1], dtype=\"csingle\")) == \"float complex\"\n\n    # No exact match, should call first convertible version:\n    assert m.overloaded(np.array([1], dtype=\"uint8\")) == \"double\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded(\"not an array\")\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        overloaded(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float64]) -> str\n            2. (arg0: numpy.ndarray[numpy.float32]) -> str\n            3. (arg0: numpy.ndarray[numpy.int32]) -> str\n            4. (arg0: numpy.ndarray[numpy.uint16]) -> str\n            5. (arg0: numpy.ndarray[numpy.int64]) -> str\n            6. (arg0: numpy.ndarray[numpy.complex128]) -> str\n            7. (arg0: numpy.ndarray[numpy.complex64]) -> str\n\n        Invoked with: 'not an array'\n    \"\"\"\n    )\n\n    assert m.overloaded2(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded2(np.array([1], dtype=\"float32\")) == \"float\"\n    assert m.overloaded2(np.array([1], dtype=\"complex64\")) == \"float complex\"\n    assert m.overloaded2(np.array([1], dtype=\"complex128\")) == \"double complex\"\n    assert m.overloaded2(np.array([1], dtype=\"float32\")) == \"float\"\n\n    assert m.overloaded3(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded3(np.array([1], dtype=\"intc\")) == \"int\"\n    expected_exc = \"\"\"\n        overloaded3(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.int32]) -> str\n            2. (arg0: numpy.ndarray[numpy.float64]) -> str\n\n        Invoked with: \"\"\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"uintc\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1], dtype=\"uint32\"))\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"float32\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1.0], dtype=\"float32\"))\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"complex\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1.0 + 0.0j]))\n\n    # Exact matches:\n    assert m.overloaded4(np.array([1], dtype=\"double\")) == \"double\"\n    assert m.overloaded4(np.array([1], dtype=\"longlong\")) == \"long long\"\n    # Non-exact matches requiring conversion.  Since float to integer isn't a\n    # save conversion, it should go to the double overload, but short can go to\n    # either (and so should end up on the first-registered, the long long).\n    assert m.overloaded4(np.array([1], dtype=\"float32\")) == \"double\"\n    assert m.overloaded4(np.array([1], dtype=\"short\")) == \"long long\"\n\n    assert m.overloaded5(np.array([1], dtype=\"double\")) == \"double\"\n    assert m.overloaded5(np.array([1], dtype=\"uintc\")) == \"unsigned int\"\n    assert m.overloaded5(np.array([1], dtype=\"float32\")) == \"unsigned int\"\n\n\ndef test_greedy_string_overload():\n    \"\"\"Tests fix for #685 - ndarray shouldn't go to std::string overload\"\"\"\n\n    assert m.issue685(\"abc\") == \"string\"\n    assert m.issue685(np.array([97, 98, 99], dtype=\"b\")) == \"array\"\n    assert m.issue685(123) == \"other\"\n\n\ndef test_array_unchecked_fixed_dims(msg):\n    z1 = np.array([[1, 2], [3, 4]], dtype=\"float64\")\n    m.proxy_add2(z1, 10)\n    assert np.all(z1 == [[11, 12], [13, 14]])\n\n    with pytest.raises(ValueError) as excinfo:\n        m.proxy_add2(np.array([1.0, 2, 3]), 5.0)\n    assert (\n        msg(excinfo.value) == \"array has incorrect number of dimensions: 1; expected 2\"\n    )\n\n    expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype=\"int\")\n    assert np.all(m.proxy_init3(3.0) == expect_c)\n    expect_f = np.transpose(expect_c)\n    assert np.all(m.proxy_init3F(3.0) == expect_f)\n\n    assert m.proxy_squared_L2_norm(np.array(range(6))) == 55\n    assert m.proxy_squared_L2_norm(np.array(range(6), dtype=\"float64\")) == 55\n\n    assert m.proxy_auxiliaries2(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]\n    assert m.proxy_auxiliaries2(z1) == m.array_auxiliaries2(z1)\n\n    assert m.proxy_auxiliaries1_const_ref(z1[0, :])\n    assert m.proxy_auxiliaries2_const_ref(z1)\n\n\ndef test_array_unchecked_dyn_dims():\n    z1 = np.array([[1, 2], [3, 4]], dtype=\"float64\")\n    m.proxy_add2_dyn(z1, 10)\n    assert np.all(z1 == [[11, 12], [13, 14]])\n\n    expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype=\"int\")\n    assert np.all(m.proxy_init3_dyn(3.0) == expect_c)\n\n    assert m.proxy_auxiliaries2_dyn(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]\n    assert m.proxy_auxiliaries2_dyn(z1) == m.array_auxiliaries2(z1)\n\n\ndef test_array_failure():\n    with pytest.raises(ValueError) as excinfo:\n        m.array_fail_test()\n    assert str(excinfo.value) == \"cannot create a pybind11::array from a nullptr\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.array_t_fail_test()\n    assert str(excinfo.value) == \"cannot create a pybind11::array_t from a nullptr\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.array_fail_test_negative_size()\n    assert str(excinfo.value) == \"negative dimensions are not allowed\"\n\n\ndef test_initializer_list():\n    assert m.array_initializer_list1().shape == (1,)\n    assert m.array_initializer_list2().shape == (1, 2)\n    assert m.array_initializer_list3().shape == (1, 2, 3)\n    assert m.array_initializer_list4().shape == (1, 2, 3, 4)\n\n\ndef test_array_resize():\n    a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=\"float64\")\n    m.array_reshape2(a)\n    assert a.size == 9\n    assert np.all(a == [[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n\n    # total size change should succced with refcheck off\n    m.array_resize3(a, 4, False)\n    assert a.size == 64\n    # ... and fail with refcheck on\n    try:\n        m.array_resize3(a, 3, True)\n    except ValueError as e:\n        assert str(e).startswith(\"cannot resize an array\")\n    # transposed array doesn't own data\n    b = a.transpose()\n    try:\n        m.array_resize3(b, 3, False)\n    except ValueError as e:\n        assert str(e).startswith(\"cannot resize this array: it does not own its data\")\n    # ... but reshape should be fine\n    m.array_reshape2(b)\n    assert b.shape == (8, 8)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_array_create_and_resize():\n    a = m.create_and_resize(2)\n    assert a.size == 4\n    assert np.all(a == 42.0)\n\n\ndef test_array_view():\n    a = np.ones(100 * 4).astype(\"uint8\")\n    a_float_view = m.array_view(a, \"float32\")\n    assert a_float_view.shape == (100 * 1,)  # 1 / 4 bytes = 8 / 32\n\n    a_int16_view = m.array_view(a, \"int16\")  # 1 / 2 bytes = 16 / 32\n    assert a_int16_view.shape == (100 * 2,)\n\n\ndef test_array_view_invalid():\n    a = np.ones(100 * 4).astype(\"uint8\")\n    with pytest.raises(TypeError):\n        m.array_view(a, \"deadly_dtype\")\n\n\ndef test_reshape_initializer_list():\n    a = np.arange(2 * 7 * 3) + 1\n    x = m.reshape_initializer_list(a, 2, 7, 3)\n    assert x.shape == (2, 7, 3)\n    assert list(x[1][4]) == [34, 35, 36]\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_initializer_list(a, 1, 7, 3)\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape (1,7,3)\"\n\n\ndef test_reshape_tuple():\n    a = np.arange(3 * 7 * 2) + 1\n    x = m.reshape_tuple(a, (3, 7, 2))\n    assert x.shape == (3, 7, 2)\n    assert list(x[1][4]) == [23, 24]\n    y = m.reshape_tuple(x, (x.size,))\n    assert y.shape == (42,)\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_tuple(a, (3, 7, 1))\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape (3,7,1)\"\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_tuple(a, ())\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape ()\"\n\n\ndef test_index_using_ellipsis():\n    a = m.index_using_ellipsis(np.zeros((5, 6, 7)))\n    assert a.shape == (6,)\n\n\n@pytest.mark.parametrize(\n    \"test_func\",\n    [\n        m.test_fmt_desc_float,\n        m.test_fmt_desc_double,\n        m.test_fmt_desc_const_float,\n        m.test_fmt_desc_const_double,\n    ],\n)\ndef test_format_descriptors_for_floating_point_types(test_func):\n    assert \"numpy.ndarray[numpy.float\" in test_func.__doc__\n\n\n@pytest.mark.parametrize(\"forcecast\", [False, True])\n@pytest.mark.parametrize(\"contiguity\", [None, \"C\", \"F\"])\n@pytest.mark.parametrize(\"noconvert\", [False, True])\n@pytest.mark.filterwarnings(\n    \"ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning\"\n)\ndef test_argument_conversions(forcecast, contiguity, noconvert):\n    function_name = \"accept_double\"\n    if contiguity == \"C\":\n        function_name += \"_c_style\"\n    elif contiguity == \"F\":\n        function_name += \"_f_style\"\n    if forcecast:\n        function_name += \"_forcecast\"\n    if noconvert:\n        function_name += \"_noconvert\"\n    function = getattr(m, function_name)\n\n    for dtype in [np.dtype(\"float32\"), np.dtype(\"float64\"), np.dtype(\"complex128\")]:\n        for order in [\"C\", \"F\"]:\n            for shape in [(2, 2), (1, 3, 1, 1), (1, 1, 1), (0,)]:\n                if not noconvert:\n                    # If noconvert is not passed, only complex128 needs to be truncated and\n                    # \"cannot be safely obtained\". So without `forcecast`, the argument shouldn't\n                    # be accepted.\n                    should_raise = dtype.name == \"complex128\" and not forcecast\n                else:\n                    # If noconvert is passed, only float64 and the matching order is accepted.\n                    # If at most one dimension has a size greater than 1, the array is also\n                    # trivially contiguous.\n                    trivially_contiguous = sum(1 for d in shape if d > 1) <= 1\n                    should_raise = dtype.name != \"float64\" or (\n                        contiguity is not None\n                        and contiguity != order\n                        and not trivially_contiguous\n                    )\n\n                array = np.zeros(shape, dtype=dtype, order=order)\n                if not should_raise:\n                    function(array)\n                else:\n                    with pytest.raises(\n                        TypeError, match=\"incompatible function arguments\"\n                    ):\n                        function(array)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_dtype_refcount_leak():\n    from sys import getrefcount\n\n    dtype = np.dtype(np.float_)\n    a = np.array([1], dtype=dtype)\n    before = getrefcount(dtype)\n    m.ndim(a)\n    after = getrefcount(dtype)\n    assert after == before\n\n\ndef test_round_trip_float():\n    arr = np.zeros((), np.float64)\n    arr[()] = 37.2\n    assert m.round_trip_float(arr) == 37.2\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_dtypes.cpp",
    "content": "/*\n  tests/test_numpy_dtypes.cpp -- Structured and compound NumPy dtypes\n\n  Copyright (c) 2016 Ivan Smirnov\n\n  All rights reserved. Use of this source code is governed by a\n  BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n\n#include \"pybind11_tests.h\"\n\n#ifdef __GNUC__\n#    define PYBIND11_PACKED(cls) cls __attribute__((__packed__))\n#else\n#    define PYBIND11_PACKED(cls) __pragma(pack(push, 1)) cls __pragma(pack(pop))\n#endif\n\nnamespace py = pybind11;\n\nstruct SimpleStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    long double ldbl_;\n};\n\nstd::ostream &operator<<(std::ostream &os, const SimpleStruct &v) {\n    return os << \"s:\" << v.bool_ << \",\" << v.uint_ << \",\" << v.float_ << \",\" << v.ldbl_;\n}\n\nstruct SimpleStructReordered {\n    bool bool_;\n    float float_;\n    uint32_t uint_;\n    long double ldbl_;\n};\n\nPYBIND11_PACKED(struct PackedStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    long double ldbl_;\n});\n\nstd::ostream &operator<<(std::ostream &os, const PackedStruct &v) {\n    return os << \"p:\" << v.bool_ << \",\" << v.uint_ << \",\" << v.float_ << \",\" << v.ldbl_;\n}\n\nPYBIND11_PACKED(struct NestedStruct {\n    SimpleStruct a;\n    PackedStruct b;\n});\n\nstd::ostream &operator<<(std::ostream &os, const NestedStruct &v) {\n    return os << \"n:a=\" << v.a << \";b=\" << v.b;\n}\n\nstruct PartialStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    uint64_t dummy2;\n    long double ldbl_;\n};\n\nstruct PartialNestedStruct {\n    uint64_t dummy1;\n    PartialStruct a;\n    uint64_t dummy2;\n};\n\nstruct UnboundStruct {};\n\nstruct StringStruct {\n    char a[3];\n    std::array<char, 3> b;\n};\n\nstruct ComplexStruct {\n    std::complex<float> cflt;\n    std::complex<double> cdbl;\n};\n\nstd::ostream &operator<<(std::ostream &os, const ComplexStruct &v) {\n    return os << \"c:\" << v.cflt << \",\" << v.cdbl;\n}\n\nstruct ArrayStruct {\n    char a[3][4];\n    int32_t b[2];\n    std::array<uint8_t, 3> c;\n    std::array<float, 2> d[4];\n};\n\nPYBIND11_PACKED(struct StructWithUglyNames {\n    int8_t __x__;\n    uint64_t __y__;\n});\n\nenum class E1 : int64_t { A = -1, B = 1 };\nenum E2 : uint8_t { X = 1, Y = 2 };\n\nPYBIND11_PACKED(struct EnumStruct {\n    E1 e1;\n    E2 e2;\n});\n\nstd::ostream &operator<<(std::ostream &os, const StringStruct &v) {\n    os << \"a='\";\n    for (size_t i = 0; i < 3 && (v.a[i] != 0); i++) {\n        os << v.a[i];\n    }\n    os << \"',b='\";\n    for (size_t i = 0; i < 3 && (v.b[i] != 0); i++) {\n        os << v.b[i];\n    }\n    return os << \"'\";\n}\n\nstd::ostream &operator<<(std::ostream &os, const ArrayStruct &v) {\n    os << \"a={\";\n    for (int i = 0; i < 3; i++) {\n        if (i > 0) {\n            os << ',';\n        }\n        os << '{';\n        for (int j = 0; j < 3; j++) {\n            os << v.a[i][j] << ',';\n        }\n        os << v.a[i][3] << '}';\n    }\n    os << \"},b={\" << v.b[0] << ',' << v.b[1];\n    os << \"},c={\" << int(v.c[0]) << ',' << int(v.c[1]) << ',' << int(v.c[2]);\n    os << \"},d={\";\n    for (int i = 0; i < 4; i++) {\n        if (i > 0) {\n            os << ',';\n        }\n        os << '{' << v.d[i][0] << ',' << v.d[i][1] << '}';\n    }\n    return os << '}';\n}\n\nstd::ostream &operator<<(std::ostream &os, const EnumStruct &v) {\n    return os << \"e1=\" << (v.e1 == E1::A ? \"A\" : \"B\") << \",e2=\" << (v.e2 == E2::X ? \"X\" : \"Y\");\n}\n\ntemplate <typename T>\npy::array mkarray_via_buffer(size_t n) {\n    return py::array(py::buffer_info(\n        nullptr, sizeof(T), py::format_descriptor<T>::format(), 1, {n}, {sizeof(T)}));\n}\n\n#define SET_TEST_VALS(s, i)                                                                       \\\n    do {                                                                                          \\\n        (s).bool_ = (i) % 2 != 0;                                                                 \\\n        (s).uint_ = (uint32_t) (i);                                                               \\\n        (s).float_ = (float) (i) *1.5f;                                                           \\\n        (s).ldbl_ = (long double) (i) * -2.5L;                                                    \\\n    } while (0)\n\ntemplate <typename S>\npy::array_t<S, 0> create_recarray(size_t n) {\n    auto arr = mkarray_via_buffer<S>(n);\n    auto req = arr.request();\n    auto *ptr = static_cast<S *>(req.ptr);\n    for (size_t i = 0; i < n; i++) {\n        SET_TEST_VALS(ptr[i], i);\n    }\n    return arr;\n}\n\ntemplate <typename S>\npy::list print_recarray(py::array_t<S, 0> arr) {\n    const auto req = arr.request();\n    auto *const ptr = static_cast<S *>(req.ptr);\n    auto l = py::list();\n    for (py::ssize_t i = 0; i < req.size; i++) {\n        std::stringstream ss;\n        ss << ptr[i];\n        l.append(py::str(ss.str()));\n    }\n    return l;\n}\n\npy::array_t<int32_t, 0> test_array_ctors(int i) {\n    using arr_t = py::array_t<int32_t, 0>;\n\n    std::vector<int32_t> data{1, 2, 3, 4, 5, 6};\n    std::vector<py::ssize_t> shape{3, 2};\n    std::vector<py::ssize_t> strides{8, 4};\n\n    auto *ptr = data.data();\n    auto *vptr = (void *) ptr;\n    auto dtype = py::dtype(\"int32\");\n\n    py::buffer_info buf_ndim1(vptr, 4, \"i\", 6);\n    py::buffer_info buf_ndim1_null(nullptr, 4, \"i\", 6);\n    py::buffer_info buf_ndim2(vptr, 4, \"i\", 2, shape, strides);\n    py::buffer_info buf_ndim2_null(nullptr, 4, \"i\", 2, shape, strides);\n\n    auto fill = [](py::array arr) {\n        auto req = arr.request();\n        for (int i = 0; i < 6; i++) {\n            ((int32_t *) req.ptr)[i] = i + 1;\n        }\n        return arr;\n    };\n\n    switch (i) {\n        // shape: (3, 2)\n        case 10:\n            return arr_t(shape, strides, ptr);\n        case 11:\n            return py::array(shape, strides, ptr);\n        case 12:\n            return py::array(dtype, shape, strides, vptr);\n        case 13:\n            return arr_t(shape, ptr);\n        case 14:\n            return py::array(shape, ptr);\n        case 15:\n            return py::array(dtype, shape, vptr);\n        case 16:\n            return arr_t(buf_ndim2);\n        case 17:\n            return py::array(buf_ndim2);\n        // shape: (3, 2) - post-fill\n        case 20:\n            return fill(arr_t(shape, strides));\n        case 21:\n            return py::array(shape, strides, ptr); // can't have nullptr due to templated ctor\n        case 22:\n            return fill(py::array(dtype, shape, strides));\n        case 23:\n            return fill(arr_t(shape));\n        case 24:\n            return py::array(shape, ptr); // can't have nullptr due to templated ctor\n        case 25:\n            return fill(py::array(dtype, shape));\n        case 26:\n            return fill(arr_t(buf_ndim2_null));\n        case 27:\n            return fill(py::array(buf_ndim2_null));\n        // shape: (6, )\n        case 30:\n            return arr_t(6, ptr);\n        case 31:\n            return py::array(6, ptr);\n        case 32:\n            return py::array(dtype, 6, vptr);\n        case 33:\n            return arr_t(buf_ndim1);\n        case 34:\n            return py::array(buf_ndim1);\n        // shape: (6, )\n        case 40:\n            return fill(arr_t(6));\n        case 41:\n            return py::array(6, ptr); // can't have nullptr due to templated ctor\n        case 42:\n            return fill(py::array(dtype, 6));\n        case 43:\n            return fill(arr_t(buf_ndim1_null));\n        case 44:\n            return fill(py::array(buf_ndim1_null));\n    }\n    return arr_t();\n}\n\npy::list test_dtype_ctors() {\n    py::list list;\n    list.append(py::dtype(\"int32\"));\n    list.append(py::dtype(std::string(\"float64\")));\n    list.append(py::dtype::from_args(py::str(\"bool\")));\n    py::list names, offsets, formats;\n    py::dict dict;\n    names.append(py::str(\"a\"));\n    names.append(py::str(\"b\"));\n    dict[\"names\"] = names;\n    offsets.append(py::int_(1));\n    offsets.append(py::int_(10));\n    dict[\"offsets\"] = offsets;\n    formats.append(py::dtype(\"int32\"));\n    formats.append(py::dtype(\"float64\"));\n    dict[\"formats\"] = formats;\n    dict[\"itemsize\"] = py::int_(20);\n    list.append(py::dtype::from_args(dict));\n    list.append(py::dtype(names, formats, offsets, 20));\n    list.append(py::dtype(py::buffer_info((void *) nullptr, sizeof(unsigned int), \"I\", 1)));\n    list.append(py::dtype(py::buffer_info((void *) nullptr, 0, \"T{i:a:f:b:}\", 1)));\n    list.append(py::dtype(py::detail::npy_api::NPY_DOUBLE_));\n    return list;\n}\n\nstruct A {};\nstruct B {};\n\nTEST_SUBMODULE(numpy_dtypes, m) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (const py::error_already_set &) {\n        return;\n    }\n\n    // typeinfo may be registered before the dtype descriptor for scalar casts to work...\n    py::class_<SimpleStruct>(m, \"SimpleStruct\")\n        // Explicit construct to ensure zero-valued initialization.\n        .def(py::init([]() { return SimpleStruct(); }))\n        .def_readwrite(\"bool_\", &SimpleStruct::bool_)\n        .def_readwrite(\"uint_\", &SimpleStruct::uint_)\n        .def_readwrite(\"float_\", &SimpleStruct::float_)\n        .def_readwrite(\"ldbl_\", &SimpleStruct::ldbl_)\n        .def(\"astuple\",\n             [](const SimpleStruct &self) {\n                 return py::make_tuple(self.bool_, self.uint_, self.float_, self.ldbl_);\n             })\n        .def_static(\"fromtuple\", [](const py::tuple &tup) {\n            if (py::len(tup) != 4) {\n                throw py::cast_error(\"Invalid size\");\n            }\n            return SimpleStruct{tup[0].cast<bool>(),\n                                tup[1].cast<uint32_t>(),\n                                tup[2].cast<float>(),\n                                tup[3].cast<long double>()};\n        });\n\n    PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(SimpleStructReordered, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(PackedStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(NestedStruct, a, b);\n    PYBIND11_NUMPY_DTYPE(PartialStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(PartialNestedStruct, a);\n    PYBIND11_NUMPY_DTYPE(StringStruct, a, b);\n    PYBIND11_NUMPY_DTYPE(ArrayStruct, a, b, c, d);\n    PYBIND11_NUMPY_DTYPE(EnumStruct, e1, e2);\n    PYBIND11_NUMPY_DTYPE(ComplexStruct, cflt, cdbl);\n\n    // ... or after\n    py::class_<PackedStruct>(m, \"PackedStruct\");\n\n    PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, \"x\", __y__, \"y\");\n\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n    // If enabled, this should produce a static_assert failure telling the user that the struct\n    // is not a POD type\n    struct NotPOD {\n        std::string v;\n        NotPOD() : v(\"hi\"){};\n    };\n    PYBIND11_NUMPY_DTYPE(NotPOD, v);\n#endif\n\n    // Check that dtypes can be registered programmatically, both from\n    // initializer lists of field descriptors and from other containers.\n    py::detail::npy_format_descriptor<A>::register_dtype({});\n    py::detail::npy_format_descriptor<B>::register_dtype(\n        std::vector<py::detail::field_descriptor>{});\n\n    // test_recarray, test_scalar_conversion\n    m.def(\"create_rec_simple\", &create_recarray<SimpleStruct>);\n    m.def(\"create_rec_packed\", &create_recarray<PackedStruct>);\n    m.def(\"create_rec_nested\", [](size_t n) { // test_signature\n        py::array_t<NestedStruct, 0> arr = mkarray_via_buffer<NestedStruct>(n);\n        auto req = arr.request();\n        auto *ptr = static_cast<NestedStruct *>(req.ptr);\n        for (size_t i = 0; i < n; i++) {\n            SET_TEST_VALS(ptr[i].a, i);\n            SET_TEST_VALS(ptr[i].b, i + 1);\n        }\n        return arr;\n    });\n    m.def(\"create_rec_partial\", &create_recarray<PartialStruct>);\n    m.def(\"create_rec_partial_nested\", [](size_t n) {\n        py::array_t<PartialNestedStruct, 0> arr = mkarray_via_buffer<PartialNestedStruct>(n);\n        auto req = arr.request();\n        auto *ptr = static_cast<PartialNestedStruct *>(req.ptr);\n        for (size_t i = 0; i < n; i++) {\n            SET_TEST_VALS(ptr[i].a, i);\n        }\n        return arr;\n    });\n    m.def(\"print_rec_simple\", &print_recarray<SimpleStruct>);\n    m.def(\"print_rec_packed\", &print_recarray<PackedStruct>);\n    m.def(\"print_rec_nested\", &print_recarray<NestedStruct>);\n\n    // test_format_descriptors\n    m.def(\"get_format_unbound\", []() { return py::format_descriptor<UnboundStruct>::format(); });\n    m.def(\"print_format_descriptors\", []() {\n        py::list l;\n        for (const auto &fmt : {py::format_descriptor<SimpleStruct>::format(),\n                                py::format_descriptor<PackedStruct>::format(),\n                                py::format_descriptor<NestedStruct>::format(),\n                                py::format_descriptor<PartialStruct>::format(),\n                                py::format_descriptor<PartialNestedStruct>::format(),\n                                py::format_descriptor<StringStruct>::format(),\n                                py::format_descriptor<ArrayStruct>::format(),\n                                py::format_descriptor<EnumStruct>::format(),\n                                py::format_descriptor<ComplexStruct>::format()}) {\n            l.append(py::cast(fmt));\n        }\n        return l;\n    });\n\n    // test_dtype\n    std::vector<const char *> dtype_names{\n        \"byte\",    \"short\",   \"intc\",        \"int_\",  \"longlong\",   \"ubyte\",       \"ushort\",\n        \"uintc\",   \"uint\",    \"ulonglong\",   \"half\",  \"single\",     \"double\",      \"longdouble\",\n        \"csingle\", \"cdouble\", \"clongdouble\", \"bool_\", \"datetime64\", \"timedelta64\", \"object_\"};\n\n    m.def(\"print_dtypes\", []() {\n        py::list l;\n        for (const py::handle &d : {py::dtype::of<SimpleStruct>(),\n                                    py::dtype::of<PackedStruct>(),\n                                    py::dtype::of<NestedStruct>(),\n                                    py::dtype::of<PartialStruct>(),\n                                    py::dtype::of<PartialNestedStruct>(),\n                                    py::dtype::of<StringStruct>(),\n                                    py::dtype::of<ArrayStruct>(),\n                                    py::dtype::of<EnumStruct>(),\n                                    py::dtype::of<StructWithUglyNames>(),\n                                    py::dtype::of<ComplexStruct>()}) {\n            l.append(py::str(d));\n        }\n        return l;\n    });\n    m.def(\"test_dtype_ctors\", &test_dtype_ctors);\n    m.def(\"test_dtype_kind\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).kind());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_char_\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).char_());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_num\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).num());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_byteorder\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).byteorder());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_alignment\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).alignment());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_flags\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).flags());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_methods\", []() {\n        py::list list;\n        auto dt1 = py::dtype::of<int32_t>();\n        auto dt2 = py::dtype::of<SimpleStruct>();\n        list.append(dt1);\n        list.append(dt2);\n        list.append(py::bool_(dt1.has_fields()));\n        list.append(py::bool_(dt2.has_fields()));\n        list.append(py::int_(dt1.itemsize()));\n        list.append(py::int_(dt2.itemsize()));\n        return list;\n    });\n    struct TrailingPaddingStruct {\n        int32_t a;\n        char b;\n    };\n    PYBIND11_NUMPY_DTYPE(TrailingPaddingStruct, a, b);\n    m.def(\"trailing_padding_dtype\", []() { return py::dtype::of<TrailingPaddingStruct>(); });\n\n    // test_string_array\n    m.def(\"create_string_array\", [](bool non_empty) {\n        py::array_t<StringStruct, 0> arr = mkarray_via_buffer<StringStruct>(non_empty ? 4 : 0);\n        if (non_empty) {\n            auto req = arr.request();\n            auto *ptr = static_cast<StringStruct *>(req.ptr);\n            for (py::ssize_t i = 0; i < req.size * req.itemsize; i++) {\n                static_cast<char *>(req.ptr)[i] = 0;\n            }\n            ptr[1].a[0] = 'a';\n            ptr[1].b[0] = 'a';\n            ptr[2].a[0] = 'a';\n            ptr[2].b[0] = 'a';\n            ptr[3].a[0] = 'a';\n            ptr[3].b[0] = 'a';\n\n            ptr[2].a[1] = 'b';\n            ptr[2].b[1] = 'b';\n            ptr[3].a[1] = 'b';\n            ptr[3].b[1] = 'b';\n\n            ptr[3].a[2] = 'c';\n            ptr[3].b[2] = 'c';\n        }\n        return arr;\n    });\n    m.def(\"print_string_array\", &print_recarray<StringStruct>);\n\n    // test_array_array\n    m.def(\"create_array_array\", [](size_t n) {\n        py::array_t<ArrayStruct, 0> arr = mkarray_via_buffer<ArrayStruct>(n);\n        auto *ptr = (ArrayStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            for (size_t j = 0; j < 3; j++) {\n                for (size_t k = 0; k < 4; k++) {\n                    ptr[i].a[j][k] = char('A' + (i * 100 + j * 10 + k) % 26);\n                }\n            }\n            for (size_t j = 0; j < 2; j++) {\n                ptr[i].b[j] = int32_t(i * 1000 + j);\n            }\n            for (size_t j = 0; j < 3; j++) {\n                ptr[i].c[j] = uint8_t(i * 10 + j);\n            }\n            for (size_t j = 0; j < 4; j++) {\n                for (size_t k = 0; k < 2; k++) {\n                    ptr[i].d[j][k] = float(i) * 100.0f + float(j) * 10.0f + float(k);\n                }\n            }\n        }\n        return arr;\n    });\n    m.def(\"print_array_array\", &print_recarray<ArrayStruct>);\n\n    // test_enum_array\n    m.def(\"create_enum_array\", [](size_t n) {\n        py::array_t<EnumStruct, 0> arr = mkarray_via_buffer<EnumStruct>(n);\n        auto *ptr = (EnumStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            ptr[i].e1 = static_cast<E1>(-1 + ((int) i % 2) * 2);\n            ptr[i].e2 = static_cast<E2>(1 + (i % 2));\n        }\n        return arr;\n    });\n    m.def(\"print_enum_array\", &print_recarray<EnumStruct>);\n\n    // test_complex_array\n    m.def(\"create_complex_array\", [](size_t n) {\n        py::array_t<ComplexStruct, 0> arr = mkarray_via_buffer<ComplexStruct>(n);\n        auto *ptr = (ComplexStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            ptr[i].cflt.real(float(i));\n            ptr[i].cflt.imag(float(i) + 0.25f);\n            ptr[i].cdbl.real(double(i) + 0.5);\n            ptr[i].cdbl.imag(double(i) + 0.75);\n        }\n        return arr;\n    });\n    m.def(\"print_complex_array\", &print_recarray<ComplexStruct>);\n\n    // test_array_constructors\n    m.def(\"test_array_ctors\", &test_array_ctors);\n\n    // test_compare_buffer_info\n    struct CompareStruct {\n        bool x;\n        uint32_t y;\n        float z;\n    };\n    PYBIND11_NUMPY_DTYPE(CompareStruct, x, y, z);\n    m.def(\"compare_buffer_info\", []() {\n        py::list list;\n        list.append(py::bool_(py::detail::compare_buffer_info<float>::compare(\n            py::buffer_info(nullptr, sizeof(float), \"f\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<unsigned>::compare(\n            py::buffer_info(nullptr, sizeof(int), \"I\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<long>::compare(\n            py::buffer_info(nullptr, sizeof(long), \"l\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<long>::compare(\n            py::buffer_info(nullptr, sizeof(long), sizeof(long) == sizeof(int) ? \"i\" : \"q\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<CompareStruct>::compare(\n            py::buffer_info(nullptr, sizeof(CompareStruct), \"T{?:x:3xI:y:f:z:}\", 1))));\n        return list;\n    });\n    m.def(\"buffer_to_dtype\", [](py::buffer &buf) { return py::dtype(buf.request()); });\n\n    // test_scalar_conversion\n    auto f_simple = [](SimpleStruct s) { return s.uint_ * 10; };\n    m.def(\"f_simple\", f_simple);\n    m.def(\"f_packed\", [](PackedStruct s) { return s.uint_ * 10; });\n    m.def(\"f_nested\", [](NestedStruct s) { return s.a.uint_ * 10; });\n\n    // test_vectorize\n    m.def(\"f_simple_vectorized\", py::vectorize(f_simple));\n    auto f_simple_pass_thru = [](SimpleStruct s) { return s; };\n    m.def(\"f_simple_pass_thru_vectorized\", py::vectorize(f_simple_pass_thru));\n\n    // test_register_dtype\n    m.def(\"register_dtype\",\n          []() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });\n\n    // test_str_leak\n    m.def(\"dtype_wrapper\", [](const py::object &d) { return py::dtype::from_args(d); });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_dtypes.py",
    "content": "import re\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import numpy_dtypes as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\n@pytest.fixture(scope=\"module\")\ndef simple_dtype():\n    ld = np.dtype(\"longdouble\")\n    return np.dtype(\n        {\n            \"names\": [\"bool_\", \"uint_\", \"float_\", \"ldbl_\"],\n            \"formats\": [\"?\", \"u4\", \"f4\", f\"f{ld.itemsize}\"],\n            \"offsets\": [0, 4, 8, (16 if ld.alignment > 4 else 12)],\n        }\n    )\n\n\n@pytest.fixture(scope=\"module\")\ndef packed_dtype():\n    return np.dtype([(\"bool_\", \"?\"), (\"uint_\", \"u4\"), (\"float_\", \"f4\"), (\"ldbl_\", \"g\")])\n\n\ndef dt_fmt():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n    return (\n        \"{{'names':['bool_','uint_','float_','ldbl_'],\"\n        \"'formats':['?','\" + e + \"u4','\" + e + \"f4','\" + e + \"f{}'],\"\n        \"'offsets':[0,4,8,{}],'itemsize':{}}}\"\n    )\n\n\ndef simple_dtype_fmt():\n    ld = np.dtype(\"longdouble\")\n    simple_ld_off = 12 + 4 * (ld.alignment > 4)\n    return dt_fmt().format(ld.itemsize, simple_ld_off, simple_ld_off + ld.itemsize)\n\n\ndef packed_dtype_fmt():\n    from sys import byteorder\n\n    return \"[('bool_','?'),('uint_','{e}u4'),('float_','{e}f4'),('ldbl_','{e}f{}')]\".format(\n        np.dtype(\"longdouble\").itemsize, e=\"<\" if byteorder == \"little\" else \">\"\n    )\n\n\ndef partial_ld_offset():\n    return (\n        12\n        + 4 * (np.dtype(\"uint64\").alignment > 4)\n        + 8\n        + 8 * (np.dtype(\"longdouble\").alignment > 8)\n    )\n\n\ndef partial_dtype_fmt():\n    ld = np.dtype(\"longdouble\")\n    partial_ld_off = partial_ld_offset()\n    partial_size = partial_ld_off + ld.itemsize\n    partial_end_padding = partial_size % np.dtype(\"uint64\").alignment\n    return dt_fmt().format(\n        ld.itemsize, partial_ld_off, partial_size + partial_end_padding\n    )\n\n\ndef partial_nested_fmt():\n    ld = np.dtype(\"longdouble\")\n    partial_nested_off = 8 + 8 * (ld.alignment > 8)\n    partial_ld_off = partial_ld_offset()\n    partial_size = partial_ld_off + ld.itemsize\n    partial_end_padding = partial_size % np.dtype(\"uint64\").alignment\n    partial_nested_size = partial_nested_off * 2 + partial_size + partial_end_padding\n    return \"{{'names':['a'],'formats':[{}],'offsets':[{}],'itemsize':{}}}\".format(\n        partial_dtype_fmt(), partial_nested_off, partial_nested_size\n    )\n\n\ndef assert_equal(actual, expected_data, expected_dtype):\n    np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype))\n\n\ndef test_format_descriptors():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.get_format_unbound()\n    assert re.match(\n        \"^NumPy type info missing for .*UnboundStruct.*$\", str(excinfo.value)\n    )\n\n    ld = np.dtype(\"longdouble\")\n    ldbl_fmt = (\"4x\" if ld.alignment > 4 else \"\") + ld.char\n    ss_fmt = \"^T{?:bool_:3xI:uint_:f:float_:\" + ldbl_fmt + \":ldbl_:}\"\n    dbl = np.dtype(\"double\")\n    end_padding = ld.itemsize % np.dtype(\"uint64\").alignment\n    partial_fmt = (\n        \"^T{?:bool_:3xI:uint_:f:float_:\"\n        + str(4 * (dbl.alignment > 4) + dbl.itemsize + 8 * (ld.alignment > 8))\n        + \"xg:ldbl_:\"\n        + (str(end_padding) + \"x}\" if end_padding > 0 else \"}\")\n    )\n    nested_extra = str(max(8, ld.alignment))\n    assert m.print_format_descriptors() == [\n        ss_fmt,\n        \"^T{?:bool_:I:uint_:f:float_:g:ldbl_:}\",\n        \"^T{\" + ss_fmt + \":a:^T{?:bool_:I:uint_:f:float_:g:ldbl_:}:b:}\",\n        partial_fmt,\n        \"^T{\" + nested_extra + \"x\" + partial_fmt + \":a:\" + nested_extra + \"x}\",\n        \"^T{3s:a:3s:b:}\",\n        \"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}\",\n        \"^T{q:e1:B:e2:}\",\n        \"^T{Zf:cflt:Zd:cdbl:}\",\n    ]\n\n\ndef test_dtype(simple_dtype):\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    assert [x.replace(\" \", \"\") for x in m.print_dtypes()] == [\n        simple_dtype_fmt(),\n        packed_dtype_fmt(),\n        f\"[('a',{simple_dtype_fmt()}),('b',{packed_dtype_fmt()})]\",\n        partial_dtype_fmt(),\n        partial_nested_fmt(),\n        \"[('a','S3'),('b','S3')]\",\n        (\n            \"{{'names':['a','b','c','d'],\"\n            + \"'formats':[('S4',(3,)),('\"\n            + e\n            + \"i4',(2,)),('u1',(3,)),('\"\n            + e\n            + \"f4',(4,2))],\"\n            + \"'offsets':[0,12,20,24],'itemsize':56}}\"\n        ).format(e=e),\n        \"[('e1','\" + e + \"i8'),('e2','u1')]\",\n        \"[('x','i1'),('y','\" + e + \"u8')]\",\n        \"[('cflt','\" + e + \"c8'),('cdbl','\" + e + \"c16')]\",\n    ]\n\n    d1 = np.dtype(\n        {\n            \"names\": [\"a\", \"b\"],\n            \"formats\": [\"int32\", \"float64\"],\n            \"offsets\": [1, 10],\n            \"itemsize\": 20,\n        }\n    )\n    d2 = np.dtype([(\"a\", \"i4\"), (\"b\", \"f4\")])\n    assert m.test_dtype_ctors() == [\n        np.dtype(\"int32\"),\n        np.dtype(\"float64\"),\n        np.dtype(\"bool\"),\n        d1,\n        d1,\n        np.dtype(\"uint32\"),\n        d2,\n        np.dtype(\"d\"),\n    ]\n\n    assert m.test_dtype_methods() == [\n        np.dtype(\"int32\"),\n        simple_dtype,\n        False,\n        True,\n        np.dtype(\"int32\").itemsize,\n        simple_dtype.itemsize,\n    ]\n\n    assert m.trailing_padding_dtype() == m.buffer_to_dtype(\n        np.zeros(1, m.trailing_padding_dtype())\n    )\n\n    expected_chars = \"bhilqBHILQefdgFDG?MmO\"\n    assert m.test_dtype_kind() == list(\"iiiiiuuuuuffffcccbMmO\")\n    assert m.test_dtype_char_() == list(expected_chars)\n    assert m.test_dtype_num() == [np.dtype(ch).num for ch in expected_chars]\n    assert m.test_dtype_byteorder() == [np.dtype(ch).byteorder for ch in expected_chars]\n    assert m.test_dtype_alignment() == [np.dtype(ch).alignment for ch in expected_chars]\n    assert m.test_dtype_flags() == [chr(np.dtype(ch).flags) for ch in expected_chars]\n\n\ndef test_recarray(simple_dtype, packed_dtype):\n    elements = [(False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)]\n\n    for func, dtype in [\n        (m.create_rec_simple, simple_dtype),\n        (m.create_rec_packed, packed_dtype),\n    ]:\n        arr = func(0)\n        assert arr.dtype == dtype\n        assert_equal(arr, [], simple_dtype)\n        assert_equal(arr, [], packed_dtype)\n\n        arr = func(3)\n        assert arr.dtype == dtype\n        assert_equal(arr, elements, simple_dtype)\n        assert_equal(arr, elements, packed_dtype)\n\n        # Show what recarray's look like in NumPy.\n        assert type(arr[0]) == np.void\n        assert type(arr[0].item()) == tuple\n\n        if dtype == simple_dtype:\n            assert m.print_rec_simple(arr) == [\n                \"s:0,0,0,-0\",\n                \"s:1,1,1.5,-2.5\",\n                \"s:0,2,3,-5\",\n            ]\n        else:\n            assert m.print_rec_packed(arr) == [\n                \"p:0,0,0,-0\",\n                \"p:1,1,1.5,-2.5\",\n                \"p:0,2,3,-5\",\n            ]\n\n    nested_dtype = np.dtype([(\"a\", simple_dtype), (\"b\", packed_dtype)])\n\n    arr = m.create_rec_nested(0)\n    assert arr.dtype == nested_dtype\n    assert_equal(arr, [], nested_dtype)\n\n    arr = m.create_rec_nested(3)\n    assert arr.dtype == nested_dtype\n    assert_equal(\n        arr,\n        [\n            ((False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5)),\n            ((True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)),\n            ((False, 2, 3.0, -5.0), (True, 3, 4.5, -7.5)),\n        ],\n        nested_dtype,\n    )\n    assert m.print_rec_nested(arr) == [\n        \"n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5\",\n        \"n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5\",\n        \"n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5\",\n    ]\n\n    arr = m.create_rec_partial(3)\n    assert str(arr.dtype).replace(\" \", \"\") == partial_dtype_fmt()\n    partial_dtype = arr.dtype\n    assert \"\" not in arr.dtype.fields\n    assert partial_dtype.itemsize > simple_dtype.itemsize\n    assert_equal(arr, elements, simple_dtype)\n    assert_equal(arr, elements, packed_dtype)\n\n    arr = m.create_rec_partial_nested(3)\n    assert str(arr.dtype).replace(\" \", \"\") == partial_nested_fmt()\n    assert \"\" not in arr.dtype.fields\n    assert \"\" not in arr.dtype.fields[\"a\"][0].fields\n    assert arr.dtype.itemsize > partial_dtype.itemsize\n    np.testing.assert_equal(arr[\"a\"], m.create_rec_partial(3))\n\n\ndef test_array_constructors():\n    data = np.arange(1, 7, dtype=\"int32\")\n    for i in range(8):\n        np.testing.assert_array_equal(m.test_array_ctors(10 + i), data.reshape((3, 2)))\n        np.testing.assert_array_equal(m.test_array_ctors(20 + i), data.reshape((3, 2)))\n    for i in range(5):\n        np.testing.assert_array_equal(m.test_array_ctors(30 + i), data)\n        np.testing.assert_array_equal(m.test_array_ctors(40 + i), data)\n\n\ndef test_string_array():\n    arr = m.create_string_array(True)\n    assert str(arr.dtype) == \"[('a', 'S3'), ('b', 'S3')]\"\n    assert m.print_string_array(arr) == [\n        \"a='',b=''\",\n        \"a='a',b='a'\",\n        \"a='ab',b='ab'\",\n        \"a='abc',b='abc'\",\n    ]\n    dtype = arr.dtype\n    assert arr[\"a\"].tolist() == [b\"\", b\"a\", b\"ab\", b\"abc\"]\n    assert arr[\"b\"].tolist() == [b\"\", b\"a\", b\"ab\", b\"abc\"]\n    arr = m.create_string_array(False)\n    assert dtype == arr.dtype\n\n\ndef test_array_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_array_array(3)\n    assert str(arr.dtype).replace(\" \", \"\") == (\n        \"{{'names':['a','b','c','d'],\"\n        + \"'formats':[('S4',(3,)),('\"\n        + e\n        + \"i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],\"\n        + \"'offsets':[0,12,20,24],'itemsize':56}}\"\n    ).format(e=e)\n    assert m.print_array_array(arr) == [\n        \"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},\"\n        + \"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}\",\n        \"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},\"\n        + \"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}\",\n        \"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},\"\n        + \"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}\",\n    ]\n    assert arr[\"a\"].tolist() == [\n        [b\"ABCD\", b\"KLMN\", b\"UVWX\"],\n        [b\"WXYZ\", b\"GHIJ\", b\"QRST\"],\n        [b\"STUV\", b\"CDEF\", b\"MNOP\"],\n    ]\n    assert arr[\"b\"].tolist() == [[0, 1], [1000, 1001], [2000, 2001]]\n    assert m.create_array_array(0).dtype == arr.dtype\n\n\ndef test_enum_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_enum_array(3)\n    dtype = arr.dtype\n    assert dtype == np.dtype([(\"e1\", e + \"i8\"), (\"e2\", \"u1\")])\n    assert m.print_enum_array(arr) == [\"e1=A,e2=X\", \"e1=B,e2=Y\", \"e1=A,e2=X\"]\n    assert arr[\"e1\"].tolist() == [-1, 1, -1]\n    assert arr[\"e2\"].tolist() == [1, 2, 1]\n    assert m.create_enum_array(0).dtype == dtype\n\n\ndef test_complex_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_complex_array(3)\n    dtype = arr.dtype\n    assert dtype == np.dtype([(\"cflt\", e + \"c8\"), (\"cdbl\", e + \"c16\")])\n    assert m.print_complex_array(arr) == [\n        \"c:(0,0.25),(0.5,0.75)\",\n        \"c:(1,1.25),(1.5,1.75)\",\n        \"c:(2,2.25),(2.5,2.75)\",\n    ]\n    assert arr[\"cflt\"].tolist() == [0.0 + 0.25j, 1.0 + 1.25j, 2.0 + 2.25j]\n    assert arr[\"cdbl\"].tolist() == [0.5 + 0.75j, 1.5 + 1.75j, 2.5 + 2.75j]\n    assert m.create_complex_array(0).dtype == dtype\n\n\ndef test_signature(doc):\n    assert (\n        doc(m.create_rec_nested)\n        == \"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]\"\n    )\n\n\ndef test_scalar_conversion():\n    n = 3\n    arrays = [\n        m.create_rec_simple(n),\n        m.create_rec_packed(n),\n        m.create_rec_nested(n),\n        m.create_enum_array(n),\n    ]\n    funcs = [m.f_simple, m.f_packed, m.f_nested]\n\n    for i, func in enumerate(funcs):\n        for j, arr in enumerate(arrays):\n            if i == j and i < 2:\n                assert [func(arr[k]) for k in range(n)] == [k * 10 for k in range(n)]\n            else:\n                with pytest.raises(TypeError) as excinfo:\n                    func(arr[0])\n                assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_vectorize():\n    n = 3\n    array = m.create_rec_simple(n)\n    values = m.f_simple_vectorized(array)\n    np.testing.assert_array_equal(values, [0, 10, 20])\n    array_2 = m.f_simple_pass_thru_vectorized(array)\n    np.testing.assert_array_equal(array, array_2)\n\n\ndef test_cls_and_dtype_conversion(simple_dtype):\n    s = m.SimpleStruct()\n    assert s.astuple() == (False, 0, 0.0, 0.0)\n    assert m.SimpleStruct.fromtuple(s.astuple()).astuple() == s.astuple()\n\n    s.uint_ = 2\n    assert m.f_simple(s) == 20\n\n    # Try as recarray of shape==(1,).\n    s_recarray = np.array([(False, 2, 0.0, 0.0)], dtype=simple_dtype)\n    # Show that this will work for vectorized case.\n    np.testing.assert_array_equal(m.f_simple_vectorized(s_recarray), [20])\n\n    # Show as a scalar that inherits from np.generic.\n    s_scalar = s_recarray[0]\n    assert isinstance(s_scalar, np.void)\n    assert m.f_simple(s_scalar) == 20\n\n    # Show that an *array* scalar (np.ndarray.shape == ()) does not convert.\n    # More specifically, conversion to SimpleStruct is not implicit.\n    s_recarray_scalar = s_recarray.reshape(())\n    assert isinstance(s_recarray_scalar, np.ndarray)\n    assert s_recarray_scalar.dtype == simple_dtype\n    with pytest.raises(TypeError) as excinfo:\n        m.f_simple(s_recarray_scalar)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    # Explicitly convert to m.SimpleStruct.\n    assert m.f_simple(m.SimpleStruct.fromtuple(s_recarray_scalar.item())) == 20\n\n    # Show that an array of dtype=object does *not* convert.\n    s_array_object = np.array([s])\n    assert s_array_object.dtype == object\n    with pytest.raises(TypeError) as excinfo:\n        m.f_simple_vectorized(s_array_object)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    # Explicitly convert to `np.array(..., dtype=simple_dtype)`\n    s_array = np.array([s.astuple()], dtype=simple_dtype)\n    np.testing.assert_array_equal(m.f_simple_vectorized(s_array), [20])\n\n\ndef test_register_dtype():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_dtype()\n    assert \"dtype is already registered\" in str(excinfo.value)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_str_leak():\n    from sys import getrefcount\n\n    fmt = \"f4\"\n    pytest.gc_collect()\n    start = getrefcount(fmt)\n    d = m.dtype_wrapper(fmt)\n    assert d is np.dtype(\"f4\")\n    del d\n    pytest.gc_collect()\n    assert getrefcount(fmt) == start\n\n\ndef test_compare_buffer_info():\n    assert all(m.compare_buffer_info())\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_vectorize.cpp",
    "content": "/*\n    tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array\n    arguments\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\ndouble my_func(int x, float y, double z) {\n    py::print(\"my_func(x:int={}, y:float={:.0f}, z:float={:.0f})\"_s.format(x, y, z));\n    return (float) x * y * z;\n}\n\nTEST_SUBMODULE(numpy_vectorize, m) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (const py::error_already_set &) {\n        return;\n    }\n\n    // test_vectorize, test_docs, test_array_collapse\n    // Vectorize all arguments of a function (though non-vector arguments are also allowed)\n    m.def(\"vectorized_func\", py::vectorize(my_func));\n\n    // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the\n    // vectorization)\n    m.def(\"vectorized_func2\", [](py::array_t<int> x, py::array_t<float> y, float z) {\n        return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(std::move(x),\n                                                                               std::move(y));\n    });\n\n    // Vectorize a complex-valued function\n    m.def(\"vectorized_func3\",\n          py::vectorize([](std::complex<double> c) { return c * std::complex<double>(2.f); }));\n\n    // test_type_selection\n    // NumPy function which only accepts specific data types\n    // A lot of these no lints could be replaced with const refs, and probably should at some\n    // point.\n    m.def(\"selective_func\",\n          [](const py::array_t<int, py::array::c_style> &) { return \"Int branch taken.\"; });\n    m.def(\"selective_func\",\n          [](const py::array_t<float, py::array::c_style> &) { return \"Float branch taken.\"; });\n    m.def(\"selective_func\", [](const py::array_t<std::complex<float>, py::array::c_style> &) {\n        return \"Complex float branch taken.\";\n    });\n\n    // test_passthrough_arguments\n    // Passthrough test: references and non-pod types should be automatically passed through (in\n    // the function definition below, only `b`, `d`, and `g` are vectorized):\n    struct NonPODClass {\n        explicit NonPODClass(int v) : value{v} {}\n        int value;\n    };\n    py::class_<NonPODClass>(m, \"NonPODClass\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &NonPODClass::value);\n    m.def(\"vec_passthrough\",\n          py::vectorize([](const double *a,\n                           double b,\n                           // Changing this broke things\n                           // NOLINTNEXTLINE(performance-unnecessary-value-param)\n                           py::array_t<double> c,\n                           const int &d,\n                           int &e,\n                           NonPODClass f,\n                           const double g) { return *a + b + c.at(0) + d + e + f.value + g; }));\n\n    // test_method_vectorization\n    struct VectorizeTestClass {\n        explicit VectorizeTestClass(int v) : value{v} {};\n        float method(int x, float y) const { return y + (float) (x + value); }\n        int value = 0;\n    };\n    py::class_<VectorizeTestClass> vtc(m, \"VectorizeTestClass\");\n    vtc.def(py::init<int>()).def_readwrite(\"value\", &VectorizeTestClass::value);\n\n    // Automatic vectorizing of methods\n    vtc.def(\"method\", py::vectorize(&VectorizeTestClass::method));\n\n    // test_trivial_broadcasting\n    // Internal optimization test for whether the input is trivially broadcastable:\n    py::enum_<py::detail::broadcast_trivial>(m, \"trivial\")\n        .value(\"f_trivial\", py::detail::broadcast_trivial::f_trivial)\n        .value(\"c_trivial\", py::detail::broadcast_trivial::c_trivial)\n        .value(\"non_trivial\", py::detail::broadcast_trivial::non_trivial);\n    m.def(\"vectorized_is_trivial\",\n          [](const py::array_t<int, py::array::forcecast> &arg1,\n             const py::array_t<float, py::array::forcecast> &arg2,\n             const py::array_t<double, py::array::forcecast> &arg3) {\n              py::ssize_t ndim = 0;\n              std::vector<py::ssize_t> shape;\n              std::array<py::buffer_info, 3> buffers{\n                  {arg1.request(), arg2.request(), arg3.request()}};\n              return py::detail::broadcast(buffers, ndim, shape);\n          });\n\n    m.def(\"add_to\", py::vectorize([](NonPODClass &x, int a) { x.value += a; }));\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_numpy_vectorize.py",
    "content": "import pytest\n\nfrom pybind11_tests import numpy_vectorize as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_vectorize(capture):\n    assert np.isclose(m.vectorized_func3(np.array(3 + 7j)), [6 + 14j])\n\n    for f in [m.vectorized_func, m.vectorized_func2]:\n        with capture:\n            assert np.isclose(f(1, 2, 3), 6)\n        assert capture == \"my_func(x:int=1, y:float=2, z:float=3)\"\n        with capture:\n            assert np.isclose(f(np.array(1), np.array(2), 3), 6)\n        assert capture == \"my_func(x:int=1, y:float=2, z:float=3)\"\n        with capture:\n            assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=3)\n            my_func(x:int=3, y:float=4, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a = np.array([[1, 2], [3, 4]], order=\"F\")\n            b = np.array([[10, 20], [30, 40]], order=\"F\")\n            c = 3\n            result = f(a, b, c)\n            assert np.allclose(result, a * b * c)\n            assert result.flags.f_contiguous\n        # All inputs are F order and full or singletons, so we the result is in col-major order:\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=10, z:float=3)\n            my_func(x:int=3, y:float=30, z:float=3)\n            my_func(x:int=2, y:float=20, z:float=3)\n            my_func(x:int=4, y:float=40, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 3, 5], [7, 9, 11]]),\n                np.array([[2, 4, 6], [8, 10, 12]]),\n                3,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=3)\n            my_func(x:int=3, y:float=4, z:float=3)\n            my_func(x:int=5, y:float=6, z:float=3)\n            my_func(x:int=7, y:float=8, z:float=3)\n            my_func(x:int=9, y:float=10, z:float=3)\n            my_func(x:int=11, y:float=12, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=3, z:float=2)\n            my_func(x:int=3, y:float=4, z:float=2)\n            my_func(x:int=4, y:float=2, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=4, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 2, 3], [4, 5, 6]], order=\"F\"),\n                np.array([[2], [3]]),\n                2,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]])[::, ::2], np.array([[2], [3]]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 2, 3], [4, 5, 6]], order=\"F\")[::, ::2],\n                np.array([[2], [3]]),\n                2,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n\n\ndef test_type_selection():\n    assert m.selective_func(np.array([1], dtype=np.int32)) == \"Int branch taken.\"\n    assert m.selective_func(np.array([1.0], dtype=np.float32)) == \"Float branch taken.\"\n    assert (\n        m.selective_func(np.array([1.0j], dtype=np.complex64))\n        == \"Complex float branch taken.\"\n    )\n\n\ndef test_docs(doc):\n    assert (\n        doc(m.vectorized_func)\n        == \"\"\"\n        vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_trivial_broadcasting():\n    trivial, vectorized_is_trivial = m.trivial, m.vectorized_is_trivial\n\n    assert vectorized_is_trivial(1, 2, 3) == trivial.c_trivial\n    assert vectorized_is_trivial(np.array(1), np.array(2), 3) == trivial.c_trivial\n    assert (\n        vectorized_is_trivial(np.array([1, 3]), np.array([2, 4]), 3)\n        == trivial.c_trivial\n    )\n    assert trivial.c_trivial == vectorized_is_trivial(\n        np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3\n    )\n    assert (\n        vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2)\n        == trivial.non_trivial\n    )\n    assert (\n        vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2)\n        == trivial.non_trivial\n    )\n    z1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=\"int32\")\n    z2 = np.array(z1, dtype=\"float32\")\n    z3 = np.array(z1, dtype=\"float64\")\n    assert vectorized_is_trivial(z1, z2, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(1, z2, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(z1, 1, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(z1, z2, 1) == trivial.c_trivial\n    assert vectorized_is_trivial(z1[::2, ::2], 1, 1) == trivial.non_trivial\n    assert vectorized_is_trivial(1, 1, z1[::2, ::2]) == trivial.c_trivial\n    assert vectorized_is_trivial(1, 1, z3[::2, ::2]) == trivial.non_trivial\n    assert vectorized_is_trivial(z1, 1, z3[1::4, 1::4]) == trivial.c_trivial\n\n    y1 = np.array(z1, order=\"F\")\n    y2 = np.array(y1)\n    y3 = np.array(y1)\n    assert vectorized_is_trivial(y1, y2, y3) == trivial.f_trivial\n    assert vectorized_is_trivial(y1, 1, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(1, y2, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(1, 1, y3) == trivial.f_trivial\n    assert vectorized_is_trivial(y1, z2, 1) == trivial.non_trivial\n    assert vectorized_is_trivial(z1[1::4, 1::4], y2, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(y1[1::4, 1::4], z2, 1) == trivial.c_trivial\n\n    assert m.vectorized_func(z1, z2, z3).flags.c_contiguous\n    assert m.vectorized_func(y1, y2, y3).flags.f_contiguous\n    assert m.vectorized_func(z1, 1, 1).flags.c_contiguous\n    assert m.vectorized_func(1, y2, 1).flags.f_contiguous\n    assert m.vectorized_func(z1[1::4, 1::4], y2, 1).flags.f_contiguous\n    assert m.vectorized_func(y1[1::4, 1::4], z2, 1).flags.c_contiguous\n\n\ndef test_passthrough_arguments(doc):\n    assert doc(m.vec_passthrough) == (\n        \"vec_passthrough(\"\n        + \", \".join(\n            [\n                \"arg0: float\",\n                \"arg1: numpy.ndarray[numpy.float64]\",\n                \"arg2: numpy.ndarray[numpy.float64]\",\n                \"arg3: numpy.ndarray[numpy.int32]\",\n                \"arg4: int\",\n                \"arg5: m.numpy_vectorize.NonPODClass\",\n                \"arg6: numpy.ndarray[numpy.float64]\",\n            ]\n        )\n        + \") -> object\"\n    )\n\n    b = np.array([[10, 20, 30]], dtype=\"float64\")\n    c = np.array([100, 200])  # NOT a vectorized argument\n    d = np.array([[1000], [2000], [3000]], dtype=\"int\")\n    g = np.array([[1000000, 2000000, 3000000]], dtype=\"int\")  # requires casting\n    assert np.all(\n        m.vec_passthrough(1, b, c, d, 10000, m.NonPODClass(100000), g)\n        == np.array(\n            [\n                [1111111, 2111121, 3111131],\n                [1112111, 2112121, 3112131],\n                [1113111, 2113121, 3113131],\n            ]\n        )\n    )\n\n\ndef test_method_vectorization():\n    o = m.VectorizeTestClass(3)\n    x = np.array([1, 2], dtype=\"int\")\n    y = np.array([[10], [20]], dtype=\"float32\")\n    assert np.all(o.method(x, y) == [[14, 15], [24, 25]])\n\n\ndef test_array_collapse():\n    assert not isinstance(m.vectorized_func(1, 2, 3), np.ndarray)\n    assert not isinstance(m.vectorized_func(np.array(1), 2, 3), np.ndarray)\n    z = m.vectorized_func([1], 2, 3)\n    assert isinstance(z, np.ndarray)\n    assert z.shape == (1,)\n    z = m.vectorized_func(1, [[[2]]], 3)\n    assert isinstance(z, np.ndarray)\n    assert z.shape == (1, 1, 1)\n\n\ndef test_vectorized_noreturn():\n    x = m.NonPODClass(0)\n    assert x.value == 0\n    m.add_to(x, [1, 2, 3, 4])\n    assert x.value == 10\n    m.add_to(x, 1)\n    assert x.value == 11\n    m.add_to(x, [[1, 1], [2, 3]])\n    assert x.value == 18\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_opaque_types.cpp",
    "content": "/*\n    tests/test_opaque_types.cpp -- opaque types, passing void pointers\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\n#include <vector>\n\n// IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures\n//\n// This also deliberately doesn't use the below StringList type alias to test\n// that MAKE_OPAQUE can handle a type containing a `,`.  (The `std::allocator`\n// bit is just the default `std::vector` allocator).\nPYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);\n\nusing StringList = std::vector<std::string, std::allocator<std::string>>;\n\nTEST_SUBMODULE(opaque_types, m) {\n    // test_string_list\n    py::class_<StringList>(m, \"StringList\")\n        .def(py::init<>())\n        .def(\"pop_back\", &StringList::pop_back)\n        /* There are multiple versions of push_back(), etc. Select the right ones. */\n        .def(\"push_back\", (void(StringList::*)(const std::string &)) & StringList::push_back)\n        .def(\"back\", (std::string & (StringList::*) ()) & StringList::back)\n        .def(\"__len__\", [](const StringList &v) { return v.size(); })\n        .def(\n            \"__iter__\",\n            [](StringList &v) { return py::make_iterator(v.begin(), v.end()); },\n            py::keep_alive<0, 1>());\n\n    class ClassWithSTLVecProperty {\n    public:\n        StringList stringList;\n    };\n    py::class_<ClassWithSTLVecProperty>(m, \"ClassWithSTLVecProperty\")\n        .def(py::init<>())\n        .def_readwrite(\"stringList\", &ClassWithSTLVecProperty::stringList);\n\n    m.def(\"print_opaque_list\", [](const StringList &l) {\n        std::string ret = \"Opaque list: [\";\n        bool first = true;\n        for (const auto &entry : l) {\n            if (!first) {\n                ret += \", \";\n            }\n            ret += entry;\n            first = false;\n        }\n        return ret + \"]\";\n    });\n\n    // test_pointers\n    m.def(\"return_void_ptr\", []() { return (void *) 0x1234; });\n    m.def(\"get_void_ptr_value\", [](void *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });\n    m.def(\"return_null_str\", []() { return (char *) nullptr; });\n    m.def(\"get_null_str_value\", [](char *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });\n\n    m.def(\"return_unique_ptr\", []() -> std::unique_ptr<StringList> {\n        auto *result = new StringList();\n        result->push_back(\"some value\");\n        return std::unique_ptr<StringList>(result);\n    });\n\n    // test unions\n    py::class_<IntFloat>(m, \"IntFloat\")\n        .def(py::init<>())\n        .def_readwrite(\"i\", &IntFloat::i)\n        .def_readwrite(\"f\", &IntFloat::f);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_opaque_types.py",
    "content": "import pytest\n\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import opaque_types as m\n\n\ndef test_string_list():\n    lst = m.StringList()\n    lst.push_back(\"Element 1\")\n    lst.push_back(\"Element 2\")\n    assert m.print_opaque_list(lst) == \"Opaque list: [Element 1, Element 2]\"\n    assert lst.back() == \"Element 2\"\n\n    for i, k in enumerate(lst, start=1):\n        assert k == f\"Element {i}\"\n    lst.pop_back()\n    assert m.print_opaque_list(lst) == \"Opaque list: [Element 1]\"\n\n    cvp = m.ClassWithSTLVecProperty()\n    assert m.print_opaque_list(cvp.stringList) == \"Opaque list: []\"\n\n    cvp.stringList = lst\n    cvp.stringList.push_back(\"Element 3\")\n    assert m.print_opaque_list(cvp.stringList) == \"Opaque list: [Element 1, Element 3]\"\n\n\ndef test_pointers(msg):\n    living_before = ConstructorStats.get(UserType).alive()\n    assert m.get_void_ptr_value(m.return_void_ptr()) == 0x1234\n    assert m.get_void_ptr_value(UserType())  # Should also work for other C++ types\n    assert ConstructorStats.get(UserType).alive() == living_before\n\n    with pytest.raises(TypeError) as excinfo:\n        m.get_void_ptr_value([1, 2, 3])  # This should not work\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        get_void_ptr_value(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: capsule) -> int\n\n        Invoked with: [1, 2, 3]\n    \"\"\"\n    )\n\n    assert m.return_null_str() is None\n    assert m.get_null_str_value(m.return_null_str()) is not None\n\n    ptr = m.return_unique_ptr()\n    assert \"StringList\" in repr(ptr)\n    assert m.print_opaque_list(ptr) == \"Opaque list: [some value]\"\n\n\ndef test_unions():\n    int_float_union = m.IntFloat()\n    int_float_union.i = 42\n    assert int_float_union.i == 42\n    int_float_union.f = 3.0\n    assert int_float_union.f == 3.0\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_operator_overloading.cpp",
    "content": "/*\n    tests/test_operator_overloading.cpp -- operator overloading\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/operators.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <functional>\n\nclass Vector2 {\npublic:\n    Vector2(float x, float y) : x(x), y(y) { print_created(this, toString()); }\n    Vector2(const Vector2 &v) : x(v.x), y(v.y) { print_copy_created(this); }\n    Vector2(Vector2 &&v) noexcept : x(v.x), y(v.y) {\n        print_move_created(this);\n        v.x = v.y = 0;\n    }\n    Vector2 &operator=(const Vector2 &v) {\n        x = v.x;\n        y = v.y;\n        print_copy_assigned(this);\n        return *this;\n    }\n    Vector2 &operator=(Vector2 &&v) noexcept {\n        x = v.x;\n        y = v.y;\n        v.x = v.y = 0;\n        print_move_assigned(this);\n        return *this;\n    }\n    ~Vector2() { print_destroyed(this); }\n\n    std::string toString() const {\n        return \"[\" + std::to_string(x) + \", \" + std::to_string(y) + \"]\";\n    }\n\n    Vector2 operator-() const { return Vector2(-x, -y); }\n    Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); }\n    Vector2 operator-(const Vector2 &v) const { return Vector2(x - v.x, y - v.y); }\n    Vector2 operator-(float value) const { return Vector2(x - value, y - value); }\n    Vector2 operator+(float value) const { return Vector2(x + value, y + value); }\n    Vector2 operator*(float value) const { return Vector2(x * value, y * value); }\n    Vector2 operator/(float value) const { return Vector2(x / value, y / value); }\n    Vector2 operator*(const Vector2 &v) const { return Vector2(x * v.x, y * v.y); }\n    Vector2 operator/(const Vector2 &v) const { return Vector2(x / v.x, y / v.y); }\n    Vector2 &operator+=(const Vector2 &v) {\n        x += v.x;\n        y += v.y;\n        return *this;\n    }\n    Vector2 &operator-=(const Vector2 &v) {\n        x -= v.x;\n        y -= v.y;\n        return *this;\n    }\n    Vector2 &operator*=(float v) {\n        x *= v;\n        y *= v;\n        return *this;\n    }\n    Vector2 &operator/=(float v) {\n        x /= v;\n        y /= v;\n        return *this;\n    }\n    Vector2 &operator*=(const Vector2 &v) {\n        x *= v.x;\n        y *= v.y;\n        return *this;\n    }\n    Vector2 &operator/=(const Vector2 &v) {\n        x /= v.x;\n        y /= v.y;\n        return *this;\n    }\n\n    friend Vector2 operator+(float f, const Vector2 &v) { return Vector2(f + v.x, f + v.y); }\n    friend Vector2 operator-(float f, const Vector2 &v) { return Vector2(f - v.x, f - v.y); }\n    friend Vector2 operator*(float f, const Vector2 &v) { return Vector2(f * v.x, f * v.y); }\n    friend Vector2 operator/(float f, const Vector2 &v) { return Vector2(f / v.x, f / v.y); }\n\n    bool operator==(const Vector2 &v) const { return x == v.x && y == v.y; }\n    bool operator!=(const Vector2 &v) const { return x != v.x || y != v.y; }\n\nprivate:\n    float x, y;\n};\n\nclass C1 {};\nclass C2 {};\n\nint operator+(const C1 &, const C1 &) { return 11; }\nint operator+(const C2 &, const C2 &) { return 22; }\nint operator+(const C2 &, const C1 &) { return 21; }\nint operator+(const C1 &, const C2 &) { return 12; }\n\nstruct HashMe {\n    std::string member;\n};\n\nbool operator==(const HashMe &lhs, const HashMe &rhs) { return lhs.member == rhs.member; }\n\n// Note: Specializing explicit within `namespace std { ... }` is done due to a\n// bug in GCC<7. If you are supporting compilers later than this, consider\n// specializing `using template<> struct std::hash<...>` in the global\n// namespace instead, per this recommendation:\n// https://en.cppreference.com/w/cpp/language/extending_std#Adding_template_specializations\nnamespace std {\ntemplate <>\nstruct hash<Vector2> {\n    // Not a good hash function, but easy to test\n    size_t operator()(const Vector2 &) { return 4; }\n};\n\n// HashMe has a hash function in C++ but no `__hash__` for Python.\ntemplate <>\nstruct hash<HashMe> {\n    std::size_t operator()(const HashMe &selector) const {\n        return std::hash<std::string>()(selector.member);\n    }\n};\n} // namespace std\n\n// Not a good abs function, but easy to test.\nstd::string abs(const Vector2 &) { return \"abs(Vector2)\"; }\n\n// MSVC & Intel warns about unknown pragmas, and warnings are errors.\n#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n// clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to\n// `-Wall`, which is used here for overloading (e.g. `py::self += py::self `).\n// Here, we suppress the warning using `#pragma diagnostic`.\n// Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46\n// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).\n#    if defined(__APPLE__) && defined(__clang__)\n#        if (__clang_major__ >= 10)\n#            pragma GCC diagnostic ignored \"-Wself-assign-overloaded\"\n#        endif\n#    elif defined(__clang__)\n#        if (__clang_major__ >= 7)\n#            pragma GCC diagnostic ignored \"-Wself-assign-overloaded\"\n#        endif\n#    endif\n#endif\n\nTEST_SUBMODULE(operators, m) {\n\n    // test_operator_overloading\n    py::class_<Vector2>(m, \"Vector2\")\n        .def(py::init<float, float>())\n        .def(py::self + py::self)\n        .def(py::self + float())\n        .def(py::self - py::self)\n        .def(py::self - float())\n        .def(py::self * float())\n        .def(py::self / float())\n        .def(py::self * py::self)\n        .def(py::self / py::self)\n        .def(py::self += py::self)\n        .def(py::self -= py::self)\n        .def(py::self *= float())\n        .def(py::self /= float())\n        .def(py::self *= py::self)\n        .def(py::self /= py::self)\n        .def(float() + py::self)\n        .def(float() - py::self)\n        .def(float() * py::self)\n        .def(float() / py::self)\n        .def(-py::self)\n        .def(\"__str__\", &Vector2::toString)\n        .def(\"__repr__\", &Vector2::toString)\n        .def(py::self == py::self)\n        .def(py::self != py::self)\n        .def(py::hash(py::self))\n        // N.B. See warning about usage of `py::detail::abs(py::self)` in\n        // `operators.h`.\n        .def(\"__abs__\", [](const Vector2 &v) { return abs(v); });\n\n    m.attr(\"Vector\") = m.attr(\"Vector2\");\n\n    // test_operators_notimplemented\n    // #393: need to return NotSupported to ensure correct arithmetic operator behavior\n    py::class_<C1>(m, \"C1\").def(py::init<>()).def(py::self + py::self);\n\n    py::class_<C2>(m, \"C2\")\n        .def(py::init<>())\n        .def(py::self + py::self)\n        .def(\"__add__\", [](const C2 &c2, const C1 &c1) { return c2 + c1; })\n        .def(\"__radd__\", [](const C2 &c2, const C1 &c1) { return c1 + c2; });\n\n    // test_nested\n    // #328: first member in a class can't be used in operators\n    struct NestABase {\n        int value = -2;\n    };\n    py::class_<NestABase>(m, \"NestABase\")\n        .def(py::init<>())\n        .def_readwrite(\"value\", &NestABase::value);\n\n    struct NestA : NestABase {\n        int value = 3;\n        NestA &operator+=(int i) {\n            value += i;\n            return *this;\n        }\n    };\n    py::class_<NestA>(m, \"NestA\")\n        .def(py::init<>())\n        .def(py::self += int())\n        .def(\n            \"as_base\",\n            [](NestA &a) -> NestABase & { return (NestABase &) a; },\n            py::return_value_policy::reference_internal);\n    m.def(\"get_NestA\", [](const NestA &a) { return a.value; });\n\n    struct NestB {\n        NestA a;\n        int value = 4;\n        NestB &operator-=(int i) {\n            value -= i;\n            return *this;\n        }\n    };\n    py::class_<NestB>(m, \"NestB\")\n        .def(py::init<>())\n        .def(py::self -= int())\n        .def_readwrite(\"a\", &NestB::a);\n    m.def(\"get_NestB\", [](const NestB &b) { return b.value; });\n\n    struct NestC {\n        NestB b;\n        int value = 5;\n        NestC &operator*=(int i) {\n            value *= i;\n            return *this;\n        }\n    };\n    py::class_<NestC>(m, \"NestC\")\n        .def(py::init<>())\n        .def(py::self *= int())\n        .def_readwrite(\"b\", &NestC::b);\n    m.def(\"get_NestC\", [](const NestC &c) { return c.value; });\n\n    // test_overriding_eq_reset_hash\n    // #2191 Overriding __eq__ should set __hash__ to None\n    struct Comparable {\n        int value;\n        bool operator==(const Comparable &rhs) const { return value == rhs.value; }\n    };\n\n    struct Hashable : Comparable {\n        explicit Hashable(int value) : Comparable{value} {};\n        size_t hash() const { return static_cast<size_t>(value); }\n    };\n\n    struct Hashable2 : Hashable {\n        using Hashable::Hashable;\n    };\n\n    py::class_<Comparable>(m, \"Comparable\").def(py::init<int>()).def(py::self == py::self);\n\n    py::class_<Hashable>(m, \"Hashable\")\n        .def(py::init<int>())\n        .def(py::self == py::self)\n        .def(\"__hash__\", &Hashable::hash);\n\n    // define __hash__ before __eq__\n    py::class_<Hashable2>(m, \"Hashable2\")\n        .def(\"__hash__\", &Hashable::hash)\n        .def(py::init<int>())\n        .def(py::self == py::self);\n\n    // define __eq__ but not __hash__\n    py::class_<HashMe>(m, \"HashMe\").def(py::self == py::self);\n\n    m.def(\"get_unhashable_HashMe_set\", []() { return std::unordered_set<HashMe>{{\"one\"}}; });\n}\n#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_operator_overloading.py",
    "content": "import pytest\n\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import operators as m\n\n\ndef test_operator_overloading():\n    v1 = m.Vector2(1, 2)\n    v2 = m.Vector(3, -1)\n    v3 = m.Vector2(1, 2)  # Same value as v1, but different instance.\n    assert v1 is not v3\n\n    assert str(v1) == \"[1.000000, 2.000000]\"\n    assert str(v2) == \"[3.000000, -1.000000]\"\n\n    assert str(-v2) == \"[-3.000000, 1.000000]\"\n\n    assert str(v1 + v2) == \"[4.000000, 1.000000]\"\n    assert str(v1 - v2) == \"[-2.000000, 3.000000]\"\n    assert str(v1 - 8) == \"[-7.000000, -6.000000]\"\n    assert str(v1 + 8) == \"[9.000000, 10.000000]\"\n    assert str(v1 * 8) == \"[8.000000, 16.000000]\"\n    assert str(v1 / 8) == \"[0.125000, 0.250000]\"\n    assert str(8 - v1) == \"[7.000000, 6.000000]\"\n    assert str(8 + v1) == \"[9.000000, 10.000000]\"\n    assert str(8 * v1) == \"[8.000000, 16.000000]\"\n    assert str(8 / v1) == \"[8.000000, 4.000000]\"\n    assert str(v1 * v2) == \"[3.000000, -2.000000]\"\n    assert str(v2 / v1) == \"[3.000000, -0.500000]\"\n\n    assert v1 == v3\n    assert v1 != v2\n    assert hash(v1) == 4\n    # TODO(eric.cousineau): Make this work.\n    # assert abs(v1) == \"abs(Vector2)\"\n\n    v1 += 2 * v2\n    assert str(v1) == \"[7.000000, 0.000000]\"\n    v1 -= v2\n    assert str(v1) == \"[4.000000, 1.000000]\"\n    v1 *= 2\n    assert str(v1) == \"[8.000000, 2.000000]\"\n    v1 /= 16\n    assert str(v1) == \"[0.500000, 0.125000]\"\n    v1 *= v2\n    assert str(v1) == \"[1.500000, -0.125000]\"\n    v2 /= v1\n    assert str(v2) == \"[2.000000, 8.000000]\"\n\n    cstats = ConstructorStats.get(m.Vector2)\n    assert cstats.alive() == 3\n    del v1\n    assert cstats.alive() == 2\n    del v2\n    assert cstats.alive() == 1\n    del v3\n    assert cstats.alive() == 0\n    assert cstats.values() == [\n        \"[1.000000, 2.000000]\",\n        \"[3.000000, -1.000000]\",\n        \"[1.000000, 2.000000]\",\n        \"[-3.000000, 1.000000]\",\n        \"[4.000000, 1.000000]\",\n        \"[-2.000000, 3.000000]\",\n        \"[-7.000000, -6.000000]\",\n        \"[9.000000, 10.000000]\",\n        \"[8.000000, 16.000000]\",\n        \"[0.125000, 0.250000]\",\n        \"[7.000000, 6.000000]\",\n        \"[9.000000, 10.000000]\",\n        \"[8.000000, 16.000000]\",\n        \"[8.000000, 4.000000]\",\n        \"[3.000000, -2.000000]\",\n        \"[3.000000, -0.500000]\",\n        \"[6.000000, -2.000000]\",\n    ]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 10\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_operators_notimplemented():\n    \"\"\"#393: need to return NotSupported to ensure correct arithmetic operator behavior\"\"\"\n\n    c1, c2 = m.C1(), m.C2()\n    assert c1 + c1 == 11\n    assert c2 + c2 == 22\n    assert c2 + c1 == 21\n    assert c1 + c2 == 12\n\n\ndef test_nested():\n    \"\"\"#328: first member in a class can't be used in operators\"\"\"\n\n    a = m.NestA()\n    b = m.NestB()\n    c = m.NestC()\n\n    a += 10\n    assert m.get_NestA(a) == 13\n    b.a += 100\n    assert m.get_NestA(b.a) == 103\n    c.b.a += 1000\n    assert m.get_NestA(c.b.a) == 1003\n    b -= 1\n    assert m.get_NestB(b) == 3\n    c.b -= 3\n    assert m.get_NestB(c.b) == 1\n    c *= 7\n    assert m.get_NestC(c) == 35\n\n    abase = a.as_base()\n    assert abase.value == -2\n    a.as_base().value += 44\n    assert abase.value == 42\n    assert c.b.a.as_base().value == -2\n    c.b.a.as_base().value += 44\n    assert c.b.a.as_base().value == 42\n\n    del c\n    pytest.gc_collect()\n    del a  # Shouldn't delete while abase is still alive\n    pytest.gc_collect()\n\n    assert abase.value == 42\n    del abase, b\n    pytest.gc_collect()\n\n\ndef test_overriding_eq_reset_hash():\n\n    assert m.Comparable(15) is not m.Comparable(15)\n    assert m.Comparable(15) == m.Comparable(15)\n\n    with pytest.raises(TypeError) as excinfo:\n        hash(m.Comparable(15))\n    assert str(excinfo.value).startswith(\"unhashable type:\")\n\n    for hashable in (m.Hashable, m.Hashable2):\n        assert hashable(15) is not hashable(15)\n        assert hashable(15) == hashable(15)\n\n        assert hash(hashable(15)) == 15\n        assert hash(hashable(15)) == hash(hashable(15))\n\n\ndef test_return_set_of_unhashable():\n    with pytest.raises(TypeError) as excinfo:\n        m.get_unhashable_HashMe_set()\n    assert str(excinfo.value.__cause__).startswith(\"unhashable type:\")\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_pickling.cpp",
    "content": "/*\n    tests/test_pickling.cpp -- pickle support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n    Copyright (c) 2021 The Pybind Development Team.\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n#include <memory>\n#include <stdexcept>\n#include <utility>\n\nnamespace exercise_trampoline {\n\nstruct SimpleBase {\n    int num = 0;\n    virtual ~SimpleBase() = default;\n\n    // For compatibility with old clang versions:\n    SimpleBase() = default;\n    SimpleBase(const SimpleBase &) = default;\n};\n\nstruct SimpleBaseTrampoline : SimpleBase {};\n\nstruct SimpleCppDerived : SimpleBase {};\n\nvoid wrap(py::module m) {\n    py::class_<SimpleBase, SimpleBaseTrampoline>(m, \"SimpleBase\")\n        .def(py::init<>())\n        .def_readwrite(\"num\", &SimpleBase::num)\n        .def(py::pickle(\n            [](const py::object &self) {\n                py::dict d;\n                if (py::hasattr(self, \"__dict__\")) {\n                    d = self.attr(\"__dict__\");\n                }\n                return py::make_tuple(self.attr(\"num\"), d);\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 2) {\n                    throw std::runtime_error(\"Invalid state!\");\n                }\n                auto cpp_state = std::unique_ptr<SimpleBase>(new SimpleBaseTrampoline);\n                cpp_state->num = t[0].cast<int>();\n                auto py_state = t[1].cast<py::dict>();\n                return std::make_pair(std::move(cpp_state), py_state);\n            }));\n\n    m.def(\"make_SimpleCppDerivedAsBase\",\n          []() { return std::unique_ptr<SimpleBase>(new SimpleCppDerived); });\n    m.def(\"check_dynamic_cast_SimpleCppDerived\", [](const SimpleBase *base_ptr) {\n        return dynamic_cast<const SimpleCppDerived *>(base_ptr) != nullptr;\n    });\n}\n\n} // namespace exercise_trampoline\n\nTEST_SUBMODULE(pickling, m) {\n    m.def(\"simple_callable\", []() { return 20220426; });\n\n    // test_roundtrip\n    class Pickleable {\n    public:\n        explicit Pickleable(const std::string &value) : m_value(value) {}\n        const std::string &value() const { return m_value; }\n\n        void setExtra1(int extra1) { m_extra1 = extra1; }\n        void setExtra2(int extra2) { m_extra2 = extra2; }\n        int extra1() const { return m_extra1; }\n        int extra2() const { return m_extra2; }\n\n    private:\n        std::string m_value;\n        int m_extra1 = 0;\n        int m_extra2 = 0;\n    };\n\n    class PickleableNew : public Pickleable {\n    public:\n        using Pickleable::Pickleable;\n    };\n\n    py::class_<Pickleable> pyPickleable(m, \"Pickleable\");\n    pyPickleable.def(py::init<std::string>())\n        .def(\"value\", &Pickleable::value)\n        .def(\"extra1\", &Pickleable::extra1)\n        .def(\"extra2\", &Pickleable::extra2)\n        .def(\"setExtra1\", &Pickleable::setExtra1)\n        .def(\"setExtra2\", &Pickleable::setExtra2)\n        // For details on the methods below, refer to\n        // http://docs.python.org/3/library/pickle.html#pickling-class-instances\n        .def(\"__getstate__\", [](const Pickleable &p) {\n            /* Return a tuple that fully encodes the state of the object */\n            return py::make_tuple(p.value(), p.extra1(), p.extra2());\n        });\n    ignoreOldStyleInitWarnings([&pyPickleable]() {\n        pyPickleable.def(\"__setstate__\", [](Pickleable &p, const py::tuple &t) {\n            if (t.size() != 3) {\n                throw std::runtime_error(\"Invalid state!\");\n            }\n            /* Invoke the constructor (need to use in-place version) */\n            new (&p) Pickleable(t[0].cast<std::string>());\n\n            /* Assign any additional state */\n            p.setExtra1(t[1].cast<int>());\n            p.setExtra2(t[2].cast<int>());\n        });\n    });\n\n    py::class_<PickleableNew, Pickleable>(m, \"PickleableNew\")\n        .def(py::init<std::string>())\n        .def(py::pickle(\n            [](const PickleableNew &p) {\n                return py::make_tuple(p.value(), p.extra1(), p.extra2());\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 3) {\n                    throw std::runtime_error(\"Invalid state!\");\n                }\n                auto p = PickleableNew(t[0].cast<std::string>());\n\n                p.setExtra1(t[1].cast<int>());\n                p.setExtra2(t[2].cast<int>());\n                return p;\n            }));\n\n#if !defined(PYPY_VERSION)\n    // test_roundtrip_with_dict\n    class PickleableWithDict {\n    public:\n        explicit PickleableWithDict(const std::string &value) : value(value) {}\n\n        std::string value;\n        int extra;\n    };\n\n    class PickleableWithDictNew : public PickleableWithDict {\n    public:\n        using PickleableWithDict::PickleableWithDict;\n    };\n\n    py::class_<PickleableWithDict> pyPickleableWithDict(\n        m, \"PickleableWithDict\", py::dynamic_attr());\n    pyPickleableWithDict.def(py::init<std::string>())\n        .def_readwrite(\"value\", &PickleableWithDict::value)\n        .def_readwrite(\"extra\", &PickleableWithDict::extra)\n        .def(\"__getstate__\", [](const py::object &self) {\n            /* Also include __dict__ in state */\n            return py::make_tuple(self.attr(\"value\"), self.attr(\"extra\"), self.attr(\"__dict__\"));\n        });\n    ignoreOldStyleInitWarnings([&pyPickleableWithDict]() {\n        pyPickleableWithDict.def(\"__setstate__\", [](const py::object &self, const py::tuple &t) {\n            if (t.size() != 3) {\n                throw std::runtime_error(\"Invalid state!\");\n            }\n            /* Cast and construct */\n            auto &p = self.cast<PickleableWithDict &>();\n            new (&p) PickleableWithDict(t[0].cast<std::string>());\n\n            /* Assign C++ state */\n            p.extra = t[1].cast<int>();\n\n            /* Assign Python state */\n            self.attr(\"__dict__\") = t[2];\n        });\n    });\n\n    py::class_<PickleableWithDictNew, PickleableWithDict>(m, \"PickleableWithDictNew\")\n        .def(py::init<std::string>())\n        .def(py::pickle(\n            [](const py::object &self) {\n                return py::make_tuple(\n                    self.attr(\"value\"), self.attr(\"extra\"), self.attr(\"__dict__\"));\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 3) {\n                    throw std::runtime_error(\"Invalid state!\");\n                }\n\n                auto cpp_state = PickleableWithDictNew(t[0].cast<std::string>());\n                cpp_state.extra = t[1].cast<int>();\n\n                auto py_state = t[2].cast<py::dict>();\n                return std::make_pair(cpp_state, py_state);\n            }));\n#endif\n\n    exercise_trampoline::wrap(m);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_pickling.py",
    "content": "import pickle\nimport re\n\nimport pytest\n\nimport env\nfrom pybind11_tests import pickling as m\n\n\ndef test_pickle_simple_callable():\n    assert m.simple_callable() == 20220426\n    if env.PYPY:\n        serialized = pickle.dumps(m.simple_callable)\n        deserialized = pickle.loads(serialized)\n        assert deserialized() == 20220426\n    else:\n        # To document broken behavior: currently it fails universally with\n        # all C Python versions.\n        with pytest.raises(TypeError) as excinfo:\n            pickle.dumps(m.simple_callable)\n        assert re.search(\"can.*t pickle .*PyCapsule.* object\", str(excinfo.value))\n\n\n@pytest.mark.parametrize(\"cls_name\", [\"Pickleable\", \"PickleableNew\"])\ndef test_roundtrip(cls_name):\n    cls = getattr(m, cls_name)\n    p = cls(\"test_value\")\n    p.setExtra1(15)\n    p.setExtra2(48)\n\n    data = pickle.dumps(p, 2)  # Must use pickle protocol >= 2\n    p2 = pickle.loads(data)\n    assert p2.value() == p.value()\n    assert p2.extra1() == p.extra1()\n    assert p2.extra2() == p.extra2()\n\n\n@pytest.mark.xfail(\"env.PYPY\")\n@pytest.mark.parametrize(\"cls_name\", [\"PickleableWithDict\", \"PickleableWithDictNew\"])\ndef test_roundtrip_with_dict(cls_name):\n    cls = getattr(m, cls_name)\n    p = cls(\"test_value\")\n    p.extra = 15\n    p.dynamic = \"Attribute\"\n\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert p2.value == p.value\n    assert p2.extra == p.extra\n    assert p2.dynamic == p.dynamic\n\n\ndef test_enum_pickle():\n    from pybind11_tests import enums as e\n\n    data = pickle.dumps(e.EOne, 2)\n    assert e.EOne == pickle.loads(data)\n\n\n#\n# exercise_trampoline\n#\nclass SimplePyDerived(m.SimpleBase):\n    pass\n\n\ndef test_roundtrip_simple_py_derived():\n    p = SimplePyDerived()\n    p.num = 202\n    p.stored_in_dict = 303\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert isinstance(p2, SimplePyDerived)\n    assert p2.num == 202\n    assert p2.stored_in_dict == 303\n\n\ndef test_roundtrip_simple_cpp_derived():\n    p = m.make_SimpleCppDerivedAsBase()\n    assert m.check_dynamic_cast_SimpleCppDerived(p)\n    p.num = 404\n    if not env.PYPY:\n        # To ensure that this unit test is not accidentally invalidated.\n        with pytest.raises(AttributeError):\n            # Mimics the `setstate` C++ implementation.\n            setattr(p, \"__dict__\", {})  # noqa: B010\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert isinstance(p2, m.SimpleBase)\n    assert p2.num == 404\n    # Issue #3062: pickleable base C++ classes can incur object slicing\n    #              if derived typeid is not registered with pybind11\n    assert not m.check_dynamic_cast_SimpleCppDerived(p2)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_pytypes.cpp",
    "content": "/*\n    tests/test_pytypes.cpp -- Python type casters\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nnamespace external {\nnamespace detail {\nbool check(PyObject *o) { return PyFloat_Check(o) != 0; }\n\nPyObject *conv(PyObject *o) {\n    PyObject *ret = nullptr;\n    if (PyLong_Check(o)) {\n        double v = PyLong_AsDouble(o);\n        if (!(v == -1.0 && PyErr_Occurred())) {\n            ret = PyFloat_FromDouble(v);\n        }\n    } else {\n        PyErr_SetString(PyExc_TypeError, \"Unexpected type\");\n    }\n    return ret;\n}\n\nPyObject *default_constructed() { return PyFloat_FromDouble(0.0); }\n} // namespace detail\nclass float_ : public py::object {\n    PYBIND11_OBJECT_CVT(float_, py::object, external::detail::check, external::detail::conv)\n\n    float_() : py::object(external::detail::default_constructed(), stolen_t{}) {}\n\n    double get_value() const { return PyFloat_AsDouble(this->ptr()); }\n};\n} // namespace external\n\nnamespace implicit_conversion_from_0_to_handle {\n// Uncomment to trigger compiler error. Note: Before PR #4008 this used to compile successfully.\n// void expected_to_trigger_compiler_error() { py::handle(0); }\n} // namespace implicit_conversion_from_0_to_handle\n\n// Used to validate systematically that PR #4008 does/did NOT change the behavior.\nvoid pure_compile_tests_for_handle_from_PyObject_pointers() {\n    {\n        PyObject *ptr = Py_None;\n        py::handle{ptr};\n    }\n    {\n        PyObject *const ptr = Py_None;\n        py::handle{ptr};\n    }\n    // Uncomment to trigger compiler errors.\n    // PyObject const *               ptr = Py_None; py::handle{ptr};\n    // PyObject const *const          ptr = Py_None; py::handle{ptr};\n    // PyObject volatile *            ptr = Py_None; py::handle{ptr};\n    // PyObject volatile *const       ptr = Py_None; py::handle{ptr};\n    // PyObject const volatile *      ptr = Py_None; py::handle{ptr};\n    // PyObject const volatile *const ptr = Py_None; py::handle{ptr};\n}\n\nnamespace handle_from_move_only_type_with_operator_PyObject {\n\n// Reduced from\n// https://github.com/pytorch/pytorch/blob/279634f384662b7c3a9f8bf7ccc3a6afd2f05657/torch/csrc/utils/object_ptr.h\nstruct operator_ncnst {\n    operator_ncnst() = default;\n    operator_ncnst(operator_ncnst &&) = default;\n    operator PyObject *() /* */ { return Py_None; } // NOLINT(google-explicit-constructor)\n};\n\nstruct operator_const {\n    operator_const() = default;\n    operator_const(operator_const &&) = default;\n    operator PyObject *() const { return Py_None; } // NOLINT(google-explicit-constructor)\n};\n\nbool from_ncnst() {\n    operator_ncnst obj;\n    auto h = py::handle(obj);  // Critical part of test: does this compile?\n    return h.ptr() == Py_None; // Just something.\n}\n\nbool from_const() {\n    operator_const obj;\n    auto h = py::handle(obj);  // Critical part of test: does this compile?\n    return h.ptr() == Py_None; // Just something.\n}\n\nvoid m_defs(py::module_ &m) {\n    m.def(\"handle_from_move_only_type_with_operator_PyObject_ncnst\", from_ncnst);\n    m.def(\"handle_from_move_only_type_with_operator_PyObject_const\", from_const);\n}\n\n} // namespace handle_from_move_only_type_with_operator_PyObject\n\nTEST_SUBMODULE(pytypes, m) {\n    handle_from_move_only_type_with_operator_PyObject::m_defs(m);\n\n    // test_bool\n    m.def(\"get_bool\", [] { return py::bool_(false); });\n    // test_int\n    m.def(\"get_int\", [] { return py::int_(0); });\n    // test_iterator\n    m.def(\"get_iterator\", [] { return py::iterator(); });\n    // test_iterable\n    m.def(\"get_iterable\", [] { return py::iterable(); });\n    m.def(\"get_frozenset_from_iterable\",\n          [](const py::iterable &iter) { return py::frozenset(iter); });\n    m.def(\"get_list_from_iterable\", [](const py::iterable &iter) { return py::list(iter); });\n    m.def(\"get_set_from_iterable\", [](const py::iterable &iter) { return py::set(iter); });\n    m.def(\"get_tuple_from_iterable\", [](const py::iterable &iter) { return py::tuple(iter); });\n    // test_float\n    m.def(\"get_float\", [] { return py::float_(0.0f); });\n    // test_list\n    m.def(\"list_no_args\", []() { return py::list{}; });\n    m.def(\"list_ssize_t\", []() { return py::list{(py::ssize_t) 0}; });\n    m.def(\"list_size_t\", []() { return py::list{(py::size_t) 0}; });\n    m.def(\"list_insert_ssize_t\", [](py::list *l) { return l->insert((py::ssize_t) 1, 83); });\n    m.def(\"list_insert_size_t\", [](py::list *l) { return l->insert((py::size_t) 3, 57); });\n    m.def(\"get_list\", []() {\n        py::list list;\n        list.append(\"value\");\n        py::print(\"Entry at position 0:\", list[0]);\n        list[0] = py::str(\"overwritten\");\n        list.insert(0, \"inserted-0\");\n        list.insert(2, \"inserted-2\");\n        return list;\n    });\n    m.def(\"print_list\", [](const py::list &list) {\n        int index = 0;\n        for (auto item : list) {\n            py::print(\"list item {}: {}\"_s.format(index++, item));\n        }\n    });\n    // test_none\n    m.def(\"get_none\", [] { return py::none(); });\n    m.def(\"print_none\", [](const py::none &none) { py::print(\"none: {}\"_s.format(none)); });\n\n    // test_set, test_frozenset\n    m.def(\"get_set\", []() {\n        py::set set;\n        set.add(py::str(\"key1\"));\n        set.add(\"key2\");\n        set.add(std::string(\"key3\"));\n        return set;\n    });\n    m.def(\"get_frozenset\", []() {\n        py::set set;\n        set.add(py::str(\"key1\"));\n        set.add(\"key2\");\n        set.add(std::string(\"key3\"));\n        return py::frozenset(set);\n    });\n    m.def(\"print_anyset\", [](const py::anyset &set) {\n        for (auto item : set) {\n            py::print(\"key:\", item);\n        }\n    });\n    m.def(\"anyset_size\", [](const py::anyset &set) { return set.size(); });\n    m.def(\"anyset_empty\", [](const py::anyset &set) { return set.empty(); });\n    m.def(\"anyset_contains\",\n          [](const py::anyset &set, const py::object &key) { return set.contains(key); });\n    m.def(\"anyset_contains\",\n          [](const py::anyset &set, const char *key) { return set.contains(key); });\n    m.def(\"set_add\", [](py::set &set, const py::object &key) { set.add(key); });\n    m.def(\"set_clear\", [](py::set &set) { set.clear(); });\n\n    // test_dict\n    m.def(\"get_dict\", []() { return py::dict(\"key\"_a = \"value\"); });\n    m.def(\"print_dict\", [](const py::dict &dict) {\n        for (auto item : dict) {\n            py::print(\"key: {}, value={}\"_s.format(item.first, item.second));\n        }\n    });\n    m.def(\"dict_keyword_constructor\", []() {\n        auto d1 = py::dict(\"x\"_a = 1, \"y\"_a = 2);\n        auto d2 = py::dict(\"z\"_a = 3, **d1);\n        return d2;\n    });\n    m.def(\"dict_contains\",\n          [](const py::dict &dict, const py::object &val) { return dict.contains(val); });\n    m.def(\"dict_contains\",\n          [](const py::dict &dict, const char *val) { return dict.contains(val); });\n\n    // test_tuple\n    m.def(\"tuple_no_args\", []() { return py::tuple{}; });\n    m.def(\"tuple_ssize_t\", []() { return py::tuple{(py::ssize_t) 0}; });\n    m.def(\"tuple_size_t\", []() { return py::tuple{(py::size_t) 0}; });\n    m.def(\"get_tuple\", []() { return py::make_tuple(42, py::none(), \"spam\"); });\n\n    // test_simple_namespace\n    m.def(\"get_simple_namespace\", []() {\n        auto ns = py::module_::import(\"types\").attr(\"SimpleNamespace\")(\n            \"attr\"_a = 42, \"x\"_a = \"foo\", \"wrong\"_a = 1);\n        py::delattr(ns, \"wrong\");\n        py::setattr(ns, \"right\", py::int_(2));\n        return ns;\n    });\n\n    // test_str\n    m.def(\"str_from_char_ssize_t\", []() { return py::str{\"red\", (py::ssize_t) 3}; });\n    m.def(\"str_from_char_size_t\", []() { return py::str{\"blue\", (py::size_t) 4}; });\n    m.def(\"str_from_string\", []() { return py::str(std::string(\"baz\")); });\n    m.def(\"str_from_std_string_input\", [](const std::string &stri) { return py::str(stri); });\n    m.def(\"str_from_cstr_input\", [](const char *c_str) { return py::str(c_str); });\n    m.def(\"str_from_bytes\", []() { return py::str(py::bytes(\"boo\", 3)); });\n    m.def(\"str_from_bytes_input\",\n          [](const py::bytes &encoded_str) { return py::str(encoded_str); });\n\n    m.def(\"str_from_object\", [](const py::object &obj) { return py::str(obj); });\n    m.def(\"repr_from_object\", [](const py::object &obj) { return py::repr(obj); });\n    m.def(\"str_from_handle\", [](py::handle h) { return py::str(h); });\n    m.def(\"str_from_string_from_str\",\n          [](const py::str &obj) { return py::str(static_cast<std::string>(obj)); });\n\n    m.def(\"str_format\", []() {\n        auto s1 = \"{} + {} = {}\"_s.format(1, 2, 3);\n        auto s2 = \"{a} + {b} = {c}\"_s.format(\"a\"_a = 1, \"b\"_a = 2, \"c\"_a = 3);\n        return py::make_tuple(s1, s2);\n    });\n\n    // test_bytes\n    m.def(\"bytes_from_char_ssize_t\", []() { return py::bytes{\"green\", (py::ssize_t) 5}; });\n    m.def(\"bytes_from_char_size_t\", []() { return py::bytes{\"purple\", (py::size_t) 6}; });\n    m.def(\"bytes_from_string\", []() { return py::bytes(std::string(\"foo\")); });\n    m.def(\"bytes_from_str\", []() { return py::bytes(py::str(\"bar\", 3)); });\n\n    // test bytearray\n    m.def(\"bytearray_from_char_ssize_t\", []() { return py::bytearray{\"$%\", (py::ssize_t) 2}; });\n    m.def(\"bytearray_from_char_size_t\", []() { return py::bytearray{\"@$!\", (py::size_t) 3}; });\n    m.def(\"bytearray_from_string\", []() { return py::bytearray(std::string(\"foo\")); });\n    m.def(\"bytearray_size\", []() { return py::bytearray(\"foo\").size(); });\n\n    // test_capsule\n    m.def(\"return_capsule_with_destructor\", []() {\n        py::print(\"creating capsule\");\n        return py::capsule([]() { py::print(\"destructing capsule\"); });\n    });\n\n    m.def(\"return_renamed_capsule_with_destructor\", []() {\n        py::print(\"creating capsule\");\n        auto cap = py::capsule([]() { py::print(\"destructing capsule\"); });\n        static const char *capsule_name = \"test_name1\";\n        py::print(\"renaming capsule\");\n        cap.set_name(capsule_name);\n        return cap;\n    });\n\n    m.def(\"return_capsule_with_destructor_2\", []() {\n        py::print(\"creating capsule\");\n        return py::capsule((void *) 1234, [](void *ptr) {\n            py::print(\"destructing capsule: {}\"_s.format((size_t) ptr));\n        });\n    });\n\n    m.def(\"return_renamed_capsule_with_destructor_2\", []() {\n        py::print(\"creating capsule\");\n        auto cap = py::capsule((void *) 1234, [](void *ptr) {\n            py::print(\"destructing capsule: {}\"_s.format((size_t) ptr));\n        });\n        static const char *capsule_name = \"test_name2\";\n        py::print(\"renaming capsule\");\n        cap.set_name(capsule_name);\n        return cap;\n    });\n\n    m.def(\"return_capsule_with_name_and_destructor\", []() {\n        auto capsule = py::capsule((void *) 12345, \"pointer type description\", [](PyObject *ptr) {\n            if (ptr) {\n                const auto *name = PyCapsule_GetName(ptr);\n                py::print(\"destructing capsule ({}, '{}')\"_s.format(\n                    (size_t) PyCapsule_GetPointer(ptr, name), name));\n            }\n        });\n\n        capsule.set_pointer((void *) 1234);\n\n        // Using get_pointer<T>()\n        void *contents1 = static_cast<void *>(capsule);\n        void *contents2 = capsule.get_pointer();\n        void *contents3 = capsule.get_pointer<void>();\n\n        auto result1 = reinterpret_cast<size_t>(contents1);\n        auto result2 = reinterpret_cast<size_t>(contents2);\n        auto result3 = reinterpret_cast<size_t>(contents3);\n\n        py::print(\n            \"created capsule ({}, '{}')\"_s.format(result1 & result2 & result3, capsule.name()));\n        return capsule;\n    });\n\n    m.def(\"return_capsule_with_explicit_nullptr_dtor\", []() {\n        py::print(\"creating capsule with explicit nullptr dtor\");\n        return py::capsule(reinterpret_cast<void *>(1234),\n                           static_cast<void (*)(void *)>(nullptr)); // PR #4221\n    });\n\n    // test_accessors\n    m.def(\"accessor_api\", [](const py::object &o) {\n        auto d = py::dict();\n\n        d[\"basic_attr\"] = o.attr(\"basic_attr\");\n\n        auto l = py::list();\n        for (auto item : o.attr(\"begin_end\")) {\n            l.append(item);\n        }\n        d[\"begin_end\"] = l;\n\n        d[\"operator[object]\"] = o.attr(\"d\")[\"operator[object]\"_s];\n        d[\"operator[char *]\"] = o.attr(\"d\")[\"operator[char *]\"];\n\n        d[\"attr(object)\"] = o.attr(\"sub\").attr(\"attr_obj\");\n        d[\"attr(char *)\"] = o.attr(\"sub\").attr(\"attr_char\");\n        try {\n            o.attr(\"sub\").attr(\"missing\").ptr();\n        } catch (const py::error_already_set &) {\n            d[\"missing_attr_ptr\"] = \"raised\"_s;\n        }\n        try {\n            o.attr(\"missing\").attr(\"doesn't matter\");\n        } catch (const py::error_already_set &) {\n            d[\"missing_attr_chain\"] = \"raised\"_s;\n        }\n\n        d[\"is_none\"] = o.attr(\"basic_attr\").is_none();\n\n        d[\"operator()\"] = o.attr(\"func\")(1);\n        d[\"operator*\"] = o.attr(\"func\")(*o.attr(\"begin_end\"));\n\n        // Test implicit conversion\n        py::list implicit_list = o.attr(\"begin_end\");\n        d[\"implicit_list\"] = implicit_list;\n        py::dict implicit_dict = o.attr(\"__dict__\");\n        d[\"implicit_dict\"] = implicit_dict;\n\n        return d;\n    });\n\n    m.def(\"tuple_accessor\", [](const py::tuple &existing_t) {\n        try {\n            existing_t[0] = 1;\n        } catch (const py::error_already_set &) {\n            // --> Python system error\n            // Only new tuples (refcount == 1) are mutable\n            auto new_t = py::tuple(3);\n            for (size_t i = 0; i < new_t.size(); ++i) {\n                new_t[i] = i;\n            }\n            return new_t;\n        }\n        return py::tuple();\n    });\n\n    m.def(\"accessor_assignment\", []() {\n        auto l = py::list(1);\n        l[0] = 0;\n\n        auto d = py::dict();\n        d[\"get\"] = l[0];\n        auto var = l[0];\n        d[\"deferred_get\"] = var;\n        l[0] = 1;\n        d[\"set\"] = l[0];\n        var = 99; // this assignment should not overwrite l[0]\n        d[\"deferred_set\"] = l[0];\n        d[\"var\"] = var;\n\n        return d;\n    });\n\n    m.def(\"accessor_moves\", []() { // See PR #3970\n        py::list return_list;\n#ifdef PYBIND11_HANDLE_REF_DEBUG\n        py::int_ py_int_0(0);\n        py::int_ py_int_42(42);\n        py::str py_str_count(\"count\");\n\n        auto tup = py::make_tuple(0);\n\n        py::sequence seq(tup);\n\n        py::list lst;\n        lst.append(0);\n\n#    define PYBIND11_LOCAL_DEF(...)                                                               \\\n        {                                                                                         \\\n            std::size_t inc_refs = py::handle::inc_ref_counter();                                 \\\n            __VA_ARGS__;                                                                          \\\n            inc_refs = py::handle::inc_ref_counter() - inc_refs;                                  \\\n            return_list.append(inc_refs);                                                         \\\n        }\n\n        PYBIND11_LOCAL_DEF(tup[py_int_0])    // l-value (to have a control)\n        PYBIND11_LOCAL_DEF(tup[py::int_(0)]) // r-value\n\n        PYBIND11_LOCAL_DEF(tup.attr(py_str_count))     // l-value\n        PYBIND11_LOCAL_DEF(tup.attr(py::str(\"count\"))) // r-value\n\n        PYBIND11_LOCAL_DEF(seq[py_int_0])    // l-value\n        PYBIND11_LOCAL_DEF(seq[py::int_(0)]) // r-value\n\n        PYBIND11_LOCAL_DEF(seq.attr(py_str_count))     // l-value\n        PYBIND11_LOCAL_DEF(seq.attr(py::str(\"count\"))) // r-value\n\n        PYBIND11_LOCAL_DEF(lst[py_int_0])    // l-value\n        PYBIND11_LOCAL_DEF(lst[py::int_(0)]) // r-value\n\n        PYBIND11_LOCAL_DEF(lst.attr(py_str_count))     // l-value\n        PYBIND11_LOCAL_DEF(lst.attr(py::str(\"count\"))) // r-value\n\n        auto lst_acc = lst[py::int_(0)];\n        lst_acc = py::int_(42);                    // Detaches lst_acc from lst.\n        PYBIND11_LOCAL_DEF(lst_acc = py_int_42)    // l-value\n        PYBIND11_LOCAL_DEF(lst_acc = py::int_(42)) // r-value\n#    undef PYBIND11_LOCAL_DEF\n#endif\n        return return_list;\n    });\n\n    // test_constructors\n    m.def(\"default_constructors\", []() {\n        return py::dict(\"bytes\"_a = py::bytes(),\n                        \"bytearray\"_a = py::bytearray(),\n                        \"str\"_a = py::str(),\n                        \"bool\"_a = py::bool_(),\n                        \"int\"_a = py::int_(),\n                        \"float\"_a = py::float_(),\n                        \"tuple\"_a = py::tuple(),\n                        \"list\"_a = py::list(),\n                        \"dict\"_a = py::dict(),\n                        \"set\"_a = py::set());\n    });\n\n    m.def(\"converting_constructors\", [](const py::dict &d) {\n        return py::dict(\"bytes\"_a = py::bytes(d[\"bytes\"]),\n                        \"bytearray\"_a = py::bytearray(d[\"bytearray\"]),\n                        \"str\"_a = py::str(d[\"str\"]),\n                        \"bool\"_a = py::bool_(d[\"bool\"]),\n                        \"int\"_a = py::int_(d[\"int\"]),\n                        \"float\"_a = py::float_(d[\"float\"]),\n                        \"tuple\"_a = py::tuple(d[\"tuple\"]),\n                        \"list\"_a = py::list(d[\"list\"]),\n                        \"dict\"_a = py::dict(d[\"dict\"]),\n                        \"set\"_a = py::set(d[\"set\"]),\n                        \"frozenset\"_a = py::frozenset(d[\"frozenset\"]),\n                        \"memoryview\"_a = py::memoryview(d[\"memoryview\"]));\n    });\n\n    m.def(\"cast_functions\", [](const py::dict &d) {\n        // When converting between Python types, obj.cast<T>() should be the same as T(obj)\n        return py::dict(\"bytes\"_a = d[\"bytes\"].cast<py::bytes>(),\n                        \"bytearray\"_a = d[\"bytearray\"].cast<py::bytearray>(),\n                        \"str\"_a = d[\"str\"].cast<py::str>(),\n                        \"bool\"_a = d[\"bool\"].cast<py::bool_>(),\n                        \"int\"_a = d[\"int\"].cast<py::int_>(),\n                        \"float\"_a = d[\"float\"].cast<py::float_>(),\n                        \"tuple\"_a = d[\"tuple\"].cast<py::tuple>(),\n                        \"list\"_a = d[\"list\"].cast<py::list>(),\n                        \"dict\"_a = d[\"dict\"].cast<py::dict>(),\n                        \"set\"_a = d[\"set\"].cast<py::set>(),\n                        \"frozenset\"_a = d[\"frozenset\"].cast<py::frozenset>(),\n                        \"memoryview\"_a = d[\"memoryview\"].cast<py::memoryview>());\n    });\n\n    m.def(\"convert_to_pybind11_str\", [](const py::object &o) { return py::str(o); });\n\n    m.def(\"nonconverting_constructor\",\n          [](const std::string &type, py::object value, bool move) -> py::object {\n              if (type == \"bytes\") {\n                  return move ? py::bytes(std::move(value)) : py::bytes(value);\n              }\n              if (type == \"none\") {\n                  return move ? py::none(std::move(value)) : py::none(value);\n              }\n              if (type == \"ellipsis\") {\n                  return move ? py::ellipsis(std::move(value)) : py::ellipsis(value);\n              }\n              if (type == \"type\") {\n                  return move ? py::type(std::move(value)) : py::type(value);\n              }\n              throw std::runtime_error(\"Invalid type\");\n          });\n\n    m.def(\"get_implicit_casting\", []() {\n        py::dict d;\n        d[\"char*_i1\"] = \"abc\";\n        const char *c2 = \"abc\";\n        d[\"char*_i2\"] = c2;\n        d[\"char*_e\"] = py::cast(c2);\n        d[\"char*_p\"] = py::str(c2);\n\n        d[\"int_i1\"] = 42;\n        int i = 42;\n        d[\"int_i2\"] = i;\n        i++;\n        d[\"int_e\"] = py::cast(i);\n        i++;\n        d[\"int_p\"] = py::int_(i);\n\n        d[\"str_i1\"] = std::string(\"str\");\n        std::string s2(\"str1\");\n        d[\"str_i2\"] = s2;\n        s2[3] = '2';\n        d[\"str_e\"] = py::cast(s2);\n        s2[3] = '3';\n        d[\"str_p\"] = py::str(s2);\n\n        py::list l(2);\n        l[0] = 3;\n        l[1] = py::cast(6);\n        l.append(9);\n        l.append(py::cast(12));\n        l.append(py::int_(15));\n\n        return py::dict(\"d\"_a = d, \"l\"_a = l);\n    });\n\n    // test_print\n    m.def(\"print_function\", []() {\n        py::print(\"Hello, World!\");\n        py::print(1, 2.0, \"three\", true, std::string(\"-- multiple args\"));\n        auto args = py::make_tuple(\"and\", \"a\", \"custom\", \"separator\");\n        py::print(\"*args\", *args, \"sep\"_a = \"-\");\n        py::print(\"no new line here\", \"end\"_a = \" -- \");\n        py::print(\"next print\");\n\n        auto py_stderr = py::module_::import(\"sys\").attr(\"stderr\");\n        py::print(\"this goes to stderr\", \"file\"_a = py_stderr);\n\n        py::print(\"flush\", \"flush\"_a = true);\n\n        py::print(\n            \"{a} + {b} = {c}\"_s.format(\"a\"_a = \"py::print\", \"b\"_a = \"str.format\", \"c\"_a = \"this\"));\n    });\n\n    m.def(\"print_failure\", []() { py::print(42, UnregisteredType()); });\n\n    m.def(\"hash_function\", [](py::object obj) { return py::hash(std::move(obj)); });\n\n    m.def(\"obj_contains\",\n          [](py::object &obj, const py::object &key) { return obj.contains(key); });\n\n    m.def(\"test_number_protocol\", [](const py::object &a, const py::object &b) {\n        py::list l;\n        l.append(a.equal(b));\n        l.append(a.not_equal(b));\n        l.append(a < b);\n        l.append(a <= b);\n        l.append(a > b);\n        l.append(a >= b);\n        l.append(a + b);\n        l.append(a - b);\n        l.append(a * b);\n        l.append(a / b);\n        l.append(a | b);\n        l.append(a & b);\n        l.append(a ^ b);\n        l.append(a >> b);\n        l.append(a << b);\n        return l;\n    });\n\n    m.def(\"test_list_slicing\", [](const py::list &a) { return a[py::slice(0, -1, 2)]; });\n\n    // See #2361\n    m.def(\"issue2361_str_implicit_copy_none\", []() {\n        py::str is_this_none = py::none();\n        return is_this_none;\n    });\n    m.def(\"issue2361_dict_implicit_copy_none\", []() {\n        py::dict is_this_none = py::none();\n        return is_this_none;\n    });\n\n    m.def(\"test_memoryview_object\", [](const py::buffer &b) { return py::memoryview(b); });\n\n    m.def(\"test_memoryview_buffer_info\",\n          [](const py::buffer &b) { return py::memoryview(b.request()); });\n\n    m.def(\"test_memoryview_from_buffer\", [](bool is_unsigned) {\n        static const int16_t si16[] = {3, 1, 4, 1, 5};\n        static const uint16_t ui16[] = {2, 7, 1, 8};\n        if (is_unsigned) {\n            return py::memoryview::from_buffer(ui16, {4}, {sizeof(uint16_t)});\n        }\n        return py::memoryview::from_buffer(si16, {5}, {sizeof(int16_t)});\n    });\n\n    m.def(\"test_memoryview_from_buffer_nativeformat\", []() {\n        static const char *format = \"@i\";\n        static const int32_t arr[] = {4, 7, 5};\n        return py::memoryview::from_buffer(arr, sizeof(int32_t), format, {3}, {sizeof(int32_t)});\n    });\n\n    m.def(\"test_memoryview_from_buffer_empty_shape\", []() {\n        static const char *buf = \"\";\n        return py::memoryview::from_buffer(buf, 1, \"B\", {}, {});\n    });\n\n    m.def(\"test_memoryview_from_buffer_invalid_strides\", []() {\n        static const char *buf = \"\\x02\\x03\\x04\";\n        return py::memoryview::from_buffer(buf, 1, \"B\", {3}, {});\n    });\n\n    m.def(\"test_memoryview_from_buffer_nullptr\", []() {\n        return py::memoryview::from_buffer(static_cast<void *>(nullptr), 1, \"B\", {}, {});\n    });\n\n    m.def(\"test_memoryview_from_memory\", []() {\n        const char *buf = \"\\xff\\xe1\\xab\\x37\";\n        return py::memoryview::from_memory(buf, static_cast<py::ssize_t>(strlen(buf)));\n    });\n\n    // test_builtin_functions\n    m.def(\"get_len\", [](py::handle h) { return py::len(h); });\n\n#ifdef PYBIND11_STR_LEGACY_PERMISSIVE\n    m.attr(\"PYBIND11_STR_LEGACY_PERMISSIVE\") = true;\n#endif\n\n    m.def(\"isinstance_pybind11_bytes\",\n          [](py::object o) { return py::isinstance<py::bytes>(std::move(o)); });\n    m.def(\"isinstance_pybind11_str\",\n          [](py::object o) { return py::isinstance<py::str>(std::move(o)); });\n\n    m.def(\"pass_to_pybind11_bytes\", [](py::bytes b) { return py::len(std::move(b)); });\n    m.def(\"pass_to_pybind11_str\", [](py::str s) { return py::len(std::move(s)); });\n    m.def(\"pass_to_std_string\", [](const std::string &s) { return s.size(); });\n\n    // test_weakref\n    m.def(\"weakref_from_handle\", [](py::handle h) { return py::weakref(h); });\n    m.def(\"weakref_from_handle_and_function\",\n          [](py::handle h, py::function f) { return py::weakref(h, std::move(f)); });\n    m.def(\"weakref_from_object\", [](const py::object &o) { return py::weakref(o); });\n    m.def(\"weakref_from_object_and_function\",\n          [](py::object o, py::function f) { return py::weakref(std::move(o), std::move(f)); });\n\n// See PR #3263 for background (https://github.com/pybind/pybind11/pull/3263):\n// pytypes.h could be changed to enforce the \"most correct\" user code below, by removing\n// `const` from iterator `reference` using type aliases, but that will break existing\n// user code.\n#if (defined(__APPLE__) && defined(__clang__)) || defined(PYPY_VERSION)\n// This is \"most correct\" and enforced on these platforms.\n#    define PYBIND11_AUTO_IT auto it\n#else\n// This works on many platforms and is (unfortunately) reflective of existing user code.\n// NOLINTNEXTLINE(bugprone-macro-parentheses)\n#    define PYBIND11_AUTO_IT auto &it\n#endif\n\n    m.def(\"tuple_iterator\", []() {\n        auto tup = py::make_tuple(5, 7);\n        int tup_sum = 0;\n        for (PYBIND11_AUTO_IT : tup) {\n            tup_sum += it.cast<int>();\n        }\n        return tup_sum;\n    });\n\n    m.def(\"dict_iterator\", []() {\n        py::dict dct;\n        dct[py::int_(3)] = 5;\n        dct[py::int_(7)] = 11;\n        int kv_sum = 0;\n        for (PYBIND11_AUTO_IT : dct) {\n            kv_sum += it.first.cast<int>() * 100 + it.second.cast<int>();\n        }\n        return kv_sum;\n    });\n\n    m.def(\"passed_iterator\", [](const py::iterator &py_it) {\n        int elem_sum = 0;\n        for (PYBIND11_AUTO_IT : py_it) {\n            elem_sum += it.cast<int>();\n        }\n        return elem_sum;\n    });\n\n#undef PYBIND11_AUTO_IT\n\n    // Tests below this line are for pybind11 IMPLEMENTATION DETAILS:\n\n    m.def(\"sequence_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::sequence_item::get(o, (py::ssize_t) 1);\n    });\n    m.def(\"sequence_item_set_ssize_t\", [](const py::object &o) {\n        auto s = py::str{\"peppa\", 5};\n        py::detail::accessor_policies::sequence_item::set(o, (py::ssize_t) 1, s);\n    });\n    m.def(\"sequence_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::sequence_item::get(o, (py::size_t) 2);\n    });\n    m.def(\"sequence_item_set_size_t\", [](const py::object &o) {\n        auto s = py::str{\"george\", 6};\n        py::detail::accessor_policies::sequence_item::set(o, (py::size_t) 2, s);\n    });\n    m.def(\"list_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::list_item::get(o, (py::ssize_t) 3);\n    });\n    m.def(\"list_item_set_ssize_t\", [](const py::object &o) {\n        auto s = py::str{\"rebecca\", 7};\n        py::detail::accessor_policies::list_item::set(o, (py::ssize_t) 3, s);\n    });\n    m.def(\"list_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::list_item::get(o, (py::size_t) 4);\n    });\n    m.def(\"list_item_set_size_t\", [](const py::object &o) {\n        auto s = py::str{\"richard\", 7};\n        py::detail::accessor_policies::list_item::set(o, (py::size_t) 4, s);\n    });\n    m.def(\"tuple_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::tuple_item::get(o, (py::ssize_t) 5);\n    });\n    m.def(\"tuple_item_set_ssize_t\", []() {\n        auto s0 = py::str{\"emely\", 5};\n        auto s1 = py::str{\"edmond\", 6};\n        auto o = py::tuple{2};\n        py::detail::accessor_policies::tuple_item::set(o, (py::ssize_t) 0, s0);\n        py::detail::accessor_policies::tuple_item::set(o, (py::ssize_t) 1, s1);\n        return o;\n    });\n    m.def(\"tuple_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::tuple_item::get(o, (py::size_t) 6);\n    });\n    m.def(\"tuple_item_set_size_t\", []() {\n        auto s0 = py::str{\"candy\", 5};\n        auto s1 = py::str{\"cat\", 3};\n        auto o = py::tuple{2};\n        py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 1, s1);\n        py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 0, s0);\n        return o;\n    });\n\n    m.def(\"square_float_\", [](const external::float_ &x) -> double {\n        double v = x.get_value();\n        return v * v;\n    });\n\n    m.def(\"tuple_rvalue_getter\", [](const py::tuple &tup) {\n        // tests accessing tuple object with rvalue int\n        for (size_t i = 0; i < tup.size(); i++) {\n            auto o = py::handle(tup[py::int_(i)]);\n            if (!o) {\n                throw py::value_error(\"tuple is malformed\");\n            }\n        }\n        return tup;\n    });\n    m.def(\"list_rvalue_getter\", [](const py::list &l) {\n        // tests accessing list with rvalue int\n        for (size_t i = 0; i < l.size(); i++) {\n            auto o = py::handle(l[py::int_(i)]);\n            if (!o) {\n                throw py::value_error(\"list is malformed\");\n            }\n        }\n        return l;\n    });\n    m.def(\"populate_dict_rvalue\", [](int population) {\n        auto d = py::dict();\n        for (int i = 0; i < population; i++) {\n            d[py::int_(i)] = py::int_(i);\n        }\n        return d;\n    });\n    m.def(\"populate_obj_str_attrs\", [](py::object &o, int population) {\n        for (int i = 0; i < population; i++) {\n            o.attr(py::str(py::int_(i))) = py::str(py::int_(i));\n        }\n        return o;\n    });\n\n    // testing immutable object augmented assignment: #issue 3812\n    m.def(\"inplace_append\", [](py::object &a, const py::object &b) {\n        a += b;\n        return a;\n    });\n    m.def(\"inplace_subtract\", [](py::object &a, const py::object &b) {\n        a -= b;\n        return a;\n    });\n    m.def(\"inplace_multiply\", [](py::object &a, const py::object &b) {\n        a *= b;\n        return a;\n    });\n    m.def(\"inplace_divide\", [](py::object &a, const py::object &b) {\n        a /= b;\n        return a;\n    });\n    m.def(\"inplace_or\", [](py::object &a, const py::object &b) {\n        a |= b;\n        return a;\n    });\n    m.def(\"inplace_and\", [](py::object &a, const py::object &b) {\n        a &= b;\n        return a;\n    });\n    m.def(\"inplace_lshift\", [](py::object &a, const py::object &b) {\n        a <<= b;\n        return a;\n    });\n    m.def(\"inplace_rshift\", [](py::object &a, const py::object &b) {\n        a >>= b;\n        return a;\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_pytypes.py",
    "content": "import contextlib\nimport sys\nimport types\n\nimport pytest\n\nimport env\nfrom pybind11_tests import detailed_error_messages_enabled\nfrom pybind11_tests import pytypes as m\n\n\ndef test_handle_from_move_only_type_with_operator_PyObject():  # noqa: N802\n    assert m.handle_from_move_only_type_with_operator_PyObject_ncnst()\n    assert m.handle_from_move_only_type_with_operator_PyObject_const()\n\n\ndef test_bool(doc):\n    assert doc(m.get_bool) == \"get_bool() -> bool\"\n\n\ndef test_int(doc):\n    assert doc(m.get_int) == \"get_int() -> int\"\n\n\ndef test_iterator(doc):\n    assert doc(m.get_iterator) == \"get_iterator() -> Iterator\"\n\n\n@pytest.mark.parametrize(\n    \"pytype, from_iter_func\",\n    [\n        (frozenset, m.get_frozenset_from_iterable),\n        (list, m.get_list_from_iterable),\n        (set, m.get_set_from_iterable),\n        (tuple, m.get_tuple_from_iterable),\n    ],\n)\ndef test_from_iterable(pytype, from_iter_func):\n    my_iter = iter(range(10))\n    s = from_iter_func(my_iter)\n    assert type(s) == pytype\n    assert s == pytype(range(10))\n\n\ndef test_iterable(doc):\n    assert doc(m.get_iterable) == \"get_iterable() -> Iterable\"\n\n\ndef test_float(doc):\n    assert doc(m.get_float) == \"get_float() -> float\"\n\n\ndef test_list(capture, doc):\n    assert m.list_no_args() == []\n    assert m.list_ssize_t() == []\n    assert m.list_size_t() == []\n    lins = [1, 2]\n    m.list_insert_ssize_t(lins)\n    assert lins == [1, 83, 2]\n    m.list_insert_size_t(lins)\n    assert lins == [1, 83, 2, 57]\n\n    with capture:\n        lst = m.get_list()\n        assert lst == [\"inserted-0\", \"overwritten\", \"inserted-2\"]\n\n        lst.append(\"value2\")\n        m.print_list(lst)\n    assert (\n        capture.unordered\n        == \"\"\"\n        Entry at position 0: value\n        list item 0: inserted-0\n        list item 1: overwritten\n        list item 2: inserted-2\n        list item 3: value2\n    \"\"\"\n    )\n\n    assert doc(m.get_list) == \"get_list() -> list\"\n    assert doc(m.print_list) == \"print_list(arg0: list) -> None\"\n\n\ndef test_none(capture, doc):\n    assert doc(m.get_none) == \"get_none() -> None\"\n    assert doc(m.print_none) == \"print_none(arg0: None) -> None\"\n\n\ndef test_set(capture, doc):\n    s = m.get_set()\n    assert isinstance(s, set)\n    assert s == {\"key1\", \"key2\", \"key3\"}\n\n    s.add(\"key4\")\n    with capture:\n        m.print_anyset(s)\n    assert (\n        capture.unordered\n        == \"\"\"\n        key: key1\n        key: key2\n        key: key3\n        key: key4\n    \"\"\"\n    )\n\n    m.set_add(s, \"key5\")\n    assert m.anyset_size(s) == 5\n\n    m.set_clear(s)\n    assert m.anyset_empty(s)\n\n    assert not m.anyset_contains(set(), 42)\n    assert m.anyset_contains({42}, 42)\n    assert m.anyset_contains({\"foo\"}, \"foo\")\n\n    assert doc(m.get_set) == \"get_set() -> set\"\n    assert doc(m.print_anyset) == \"print_anyset(arg0: anyset) -> None\"\n\n\ndef test_frozenset(capture, doc):\n    s = m.get_frozenset()\n    assert isinstance(s, frozenset)\n    assert s == frozenset({\"key1\", \"key2\", \"key3\"})\n\n    with capture:\n        m.print_anyset(s)\n    assert (\n        capture.unordered\n        == \"\"\"\n        key: key1\n        key: key2\n        key: key3\n    \"\"\"\n    )\n    assert m.anyset_size(s) == 3\n    assert not m.anyset_empty(s)\n\n    assert not m.anyset_contains(frozenset(), 42)\n    assert m.anyset_contains(frozenset({42}), 42)\n    assert m.anyset_contains(frozenset({\"foo\"}), \"foo\")\n\n    assert doc(m.get_frozenset) == \"get_frozenset() -> frozenset\"\n\n\ndef test_dict(capture, doc):\n    d = m.get_dict()\n    assert d == {\"key\": \"value\"}\n\n    with capture:\n        d[\"key2\"] = \"value2\"\n        m.print_dict(d)\n    assert (\n        capture.unordered\n        == \"\"\"\n        key: key, value=value\n        key: key2, value=value2\n    \"\"\"\n    )\n\n    assert not m.dict_contains({}, 42)\n    assert m.dict_contains({42: None}, 42)\n    assert m.dict_contains({\"foo\": None}, \"foo\")\n\n    assert doc(m.get_dict) == \"get_dict() -> dict\"\n    assert doc(m.print_dict) == \"print_dict(arg0: dict) -> None\"\n\n    assert m.dict_keyword_constructor() == {\"x\": 1, \"y\": 2, \"z\": 3}\n\n\nclass CustomContains:\n    d = {\"key\": None}\n\n    def __contains__(self, m):\n        return m in self.d\n\n\n@pytest.mark.parametrize(\n    \"arg,func\",\n    [\n        (set(), m.anyset_contains),\n        (dict(), m.dict_contains),\n        (CustomContains(), m.obj_contains),\n    ],\n)\n@pytest.mark.xfail(\"env.PYPY and sys.pypy_version_info < (7, 3, 10)\", strict=False)\ndef test_unhashable_exceptions(arg, func):\n    class Unhashable:\n        __hash__ = None\n\n    with pytest.raises(TypeError) as exc_info:\n        func(arg, Unhashable())\n    assert \"unhashable type:\" in str(exc_info.value)\n\n\ndef test_tuple():\n    assert m.tuple_no_args() == ()\n    assert m.tuple_ssize_t() == ()\n    assert m.tuple_size_t() == ()\n    assert m.get_tuple() == (42, None, \"spam\")\n\n\ndef test_simple_namespace():\n    ns = m.get_simple_namespace()\n    assert ns.attr == 42\n    assert ns.x == \"foo\"\n    assert ns.right == 2\n    assert not hasattr(ns, \"wrong\")\n\n\ndef test_str(doc):\n    assert m.str_from_char_ssize_t().encode().decode() == \"red\"\n    assert m.str_from_char_size_t().encode().decode() == \"blue\"\n    assert m.str_from_string().encode().decode() == \"baz\"\n    assert m.str_from_bytes().encode().decode() == \"boo\"\n\n    assert doc(m.str_from_bytes) == \"str_from_bytes() -> str\"\n\n    class A:\n        def __str__(self):\n            return \"this is a str\"\n\n        def __repr__(self):\n            return \"this is a repr\"\n\n    assert m.str_from_object(A()) == \"this is a str\"\n    assert m.repr_from_object(A()) == \"this is a repr\"\n    assert m.str_from_handle(A()) == \"this is a str\"\n\n    s1, s2 = m.str_format()\n    assert s1 == \"1 + 2 = 3\"\n    assert s1 == s2\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.str_from_object(malformed_utf8) is malformed_utf8\n    else:\n        assert m.str_from_object(malformed_utf8) == \"b'\\\\x80'\"\n    assert m.str_from_handle(malformed_utf8) == \"b'\\\\x80'\"\n\n    assert m.str_from_string_from_str(\"this is a str\") == \"this is a str\"\n    ucs_surrogates_str = \"\\udcc3\"\n    with pytest.raises(UnicodeEncodeError):\n        m.str_from_string_from_str(ucs_surrogates_str)\n\n\n@pytest.mark.parametrize(\n    \"func\",\n    [\n        m.str_from_bytes_input,\n        m.str_from_cstr_input,\n        m.str_from_std_string_input,\n    ],\n)\ndef test_surrogate_pairs_unicode_error(func):\n    input_str = \"\\ud83d\\ude4f\".encode(\"utf-8\", \"surrogatepass\")\n    with pytest.raises(UnicodeDecodeError):\n        func(input_str)\n\n\ndef test_bytes(doc):\n    assert m.bytes_from_char_ssize_t().decode() == \"green\"\n    assert m.bytes_from_char_size_t().decode() == \"purple\"\n    assert m.bytes_from_string().decode() == \"foo\"\n    assert m.bytes_from_str().decode() == \"bar\"\n\n    assert doc(m.bytes_from_str) == \"bytes_from_str() -> bytes\"\n\n\ndef test_bytearray(doc):\n    assert m.bytearray_from_char_ssize_t().decode() == \"$%\"\n    assert m.bytearray_from_char_size_t().decode() == \"@$!\"\n    assert m.bytearray_from_string().decode() == \"foo\"\n    assert m.bytearray_size() == len(\"foo\")\n\n\ndef test_capsule(capture):\n    pytest.gc_collect()\n    with capture:\n        a = m.return_capsule_with_destructor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        destructing capsule\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_renamed_capsule_with_destructor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        renaming capsule\n        destructing capsule\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_capsule_with_destructor_2()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        destructing capsule: 1234\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_renamed_capsule_with_destructor_2()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        renaming capsule\n        destructing capsule: 1234\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_capsule_with_name_and_destructor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        created capsule (1234, 'pointer type description')\n        destructing capsule (1234, 'pointer type description')\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_capsule_with_explicit_nullptr_dtor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule with explicit nullptr dtor\n    \"\"\"\n    )\n\n\ndef test_accessors():\n    class SubTestObject:\n        attr_obj = 1\n        attr_char = 2\n\n    class TestObject:\n        basic_attr = 1\n        begin_end = [1, 2, 3]\n        d = {\"operator[object]\": 1, \"operator[char *]\": 2}\n        sub = SubTestObject()\n\n        def func(self, x, *args):\n            return self.basic_attr + x + sum(args)\n\n    d = m.accessor_api(TestObject())\n    assert d[\"basic_attr\"] == 1\n    assert d[\"begin_end\"] == [1, 2, 3]\n    assert d[\"operator[object]\"] == 1\n    assert d[\"operator[char *]\"] == 2\n    assert d[\"attr(object)\"] == 1\n    assert d[\"attr(char *)\"] == 2\n    assert d[\"missing_attr_ptr\"] == \"raised\"\n    assert d[\"missing_attr_chain\"] == \"raised\"\n    assert d[\"is_none\"] is False\n    assert d[\"operator()\"] == 2\n    assert d[\"operator*\"] == 7\n    assert d[\"implicit_list\"] == [1, 2, 3]\n    assert all(x in TestObject.__dict__ for x in d[\"implicit_dict\"])\n\n    assert m.tuple_accessor(tuple()) == (0, 1, 2)\n\n    d = m.accessor_assignment()\n    assert d[\"get\"] == 0\n    assert d[\"deferred_get\"] == 0\n    assert d[\"set\"] == 1\n    assert d[\"deferred_set\"] == 1\n    assert d[\"var\"] == 99\n\n\ndef test_accessor_moves():\n    inc_refs = m.accessor_moves()\n    if inc_refs:\n        assert inc_refs == [1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0]\n    else:\n        pytest.skip(\"Not defined: PYBIND11_HANDLE_REF_DEBUG\")\n\n\ndef test_constructors():\n    \"\"\"C++ default and converting constructors are equivalent to type calls in Python\"\"\"\n    types = [bytes, bytearray, str, bool, int, float, tuple, list, dict, set]\n    expected = {t.__name__: t() for t in types}\n    assert m.default_constructors() == expected\n\n    data = {\n        bytes: b\"41\",  # Currently no supported or working conversions.\n        bytearray: bytearray(b\"41\"),\n        str: 42,\n        bool: \"Not empty\",\n        int: \"42\",\n        float: \"+1e3\",\n        tuple: range(3),\n        list: range(3),\n        dict: [(\"two\", 2), (\"one\", 1), (\"three\", 3)],\n        set: [4, 4, 5, 6, 6, 6],\n        frozenset: [4, 4, 5, 6, 6, 6],\n        memoryview: b\"abc\",\n    }\n    inputs = {k.__name__: v for k, v in data.items()}\n    expected = {k.__name__: k(v) for k, v in data.items()}\n\n    assert m.converting_constructors(inputs) == expected\n    assert m.cast_functions(inputs) == expected\n\n    # Converting constructors and cast functions should just reference rather\n    # than copy when no conversion is needed:\n    noconv1 = m.converting_constructors(expected)\n    for k in noconv1:\n        assert noconv1[k] is expected[k]\n\n    noconv2 = m.cast_functions(expected)\n    for k in noconv2:\n        assert noconv2[k] is expected[k]\n\n\ndef test_non_converting_constructors():\n    non_converting_test_cases = [\n        (\"bytes\", range(10)),\n        (\"none\", 42),\n        (\"ellipsis\", 42),\n        (\"type\", 42),\n    ]\n    for t, v in non_converting_test_cases:\n        for move in [True, False]:\n            with pytest.raises(TypeError) as excinfo:\n                m.nonconverting_constructor(t, v, move)\n            expected_error = (\n                f\"Object of type '{type(v).__name__}' is not an instance of '{t}'\"\n            )\n            assert str(excinfo.value) == expected_error\n\n\ndef test_pybind11_str_raw_str():\n    # specifically to exercise pybind11::str::raw_str\n    cvt = m.convert_to_pybind11_str\n    assert cvt(\"Str\") == \"Str\"\n    assert cvt(b\"Bytes\") == \"b'Bytes'\"\n    assert cvt(None) == \"None\"\n    assert cvt(False) == \"False\"\n    assert cvt(True) == \"True\"\n    assert cvt(42) == \"42\"\n    assert cvt(2**65) == \"36893488147419103232\"\n    assert cvt(-1.50) == \"-1.5\"\n    assert cvt(()) == \"()\"\n    assert cvt((18,)) == \"(18,)\"\n    assert cvt([]) == \"[]\"\n    assert cvt([28]) == \"[28]\"\n    assert cvt({}) == \"{}\"\n    assert cvt({3: 4}) == \"{3: 4}\"\n    assert cvt(set()) == \"set()\"\n    assert cvt({3, 3}) == \"{3}\"\n\n    valid_orig = \"Ǳ\"\n    valid_utf8 = valid_orig.encode(\"utf-8\")\n    valid_cvt = cvt(valid_utf8)\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert valid_cvt is valid_utf8\n    else:\n        assert type(valid_cvt) is str\n        assert valid_cvt == \"b'\\\\xc7\\\\xb1'\"\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert cvt(malformed_utf8) is malformed_utf8\n    else:\n        malformed_cvt = cvt(malformed_utf8)\n        assert type(malformed_cvt) is str\n        assert malformed_cvt == \"b'\\\\x80'\"\n\n\ndef test_implicit_casting():\n    \"\"\"Tests implicit casting when assigning or appending to dicts and lists.\"\"\"\n    z = m.get_implicit_casting()\n    assert z[\"d\"] == {\n        \"char*_i1\": \"abc\",\n        \"char*_i2\": \"abc\",\n        \"char*_e\": \"abc\",\n        \"char*_p\": \"abc\",\n        \"str_i1\": \"str\",\n        \"str_i2\": \"str1\",\n        \"str_e\": \"str2\",\n        \"str_p\": \"str3\",\n        \"int_i1\": 42,\n        \"int_i2\": 42,\n        \"int_e\": 43,\n        \"int_p\": 44,\n    }\n    assert z[\"l\"] == [3, 6, 9, 12, 15]\n\n\ndef test_print(capture):\n    with capture:\n        m.print_function()\n    assert (\n        capture\n        == \"\"\"\n        Hello, World!\n        1 2.0 three True -- multiple args\n        *args-and-a-custom-separator\n        no new line here -- next print\n        flush\n        py::print + str.format = this\n    \"\"\"\n    )\n    assert capture.stderr == \"this goes to stderr\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.print_failure()\n    assert str(excinfo.value) == \"Unable to convert call argument \" + (\n        \"'1' of type 'UnregisteredType' to Python object\"\n        if detailed_error_messages_enabled\n        else \"to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)\"\n    )\n\n\ndef test_hash():\n    class Hashable:\n        def __init__(self, value):\n            self.value = value\n\n        def __hash__(self):\n            return self.value\n\n    class Unhashable:\n        __hash__ = None\n\n    assert m.hash_function(Hashable(42)) == 42\n    with pytest.raises(TypeError):\n        m.hash_function(Unhashable())\n\n\ndef test_number_protocol():\n    for a, b in [(1, 1), (3, 5)]:\n        li = [\n            a == b,\n            a != b,\n            a < b,\n            a <= b,\n            a > b,\n            a >= b,\n            a + b,\n            a - b,\n            a * b,\n            a / b,\n            a | b,\n            a & b,\n            a ^ b,\n            a >> b,\n            a << b,\n        ]\n        assert m.test_number_protocol(a, b) == li\n\n\ndef test_list_slicing():\n    li = list(range(100))\n    assert li[::2] == m.test_list_slicing(li)\n\n\ndef test_issue2361():\n    # See issue #2361\n    assert m.issue2361_str_implicit_copy_none() == \"None\"\n    with pytest.raises(TypeError) as excinfo:\n        assert m.issue2361_dict_implicit_copy_none()\n    assert \"NoneType\" in str(excinfo.value)\n    assert \"iterable\" in str(excinfo.value)\n\n\n@pytest.mark.parametrize(\n    \"method, args, fmt, expected_view\",\n    [\n        (m.test_memoryview_object, (b\"red\",), \"B\", b\"red\"),\n        (m.test_memoryview_buffer_info, (b\"green\",), \"B\", b\"green\"),\n        (m.test_memoryview_from_buffer, (False,), \"h\", [3, 1, 4, 1, 5]),\n        (m.test_memoryview_from_buffer, (True,), \"H\", [2, 7, 1, 8]),\n        (m.test_memoryview_from_buffer_nativeformat, (), \"@i\", [4, 7, 5]),\n    ],\n)\ndef test_memoryview(method, args, fmt, expected_view):\n    view = method(*args)\n    assert isinstance(view, memoryview)\n    assert view.format == fmt\n    assert list(view) == list(expected_view)\n\n\n@pytest.mark.xfail(\"env.PYPY\", reason=\"getrefcount is not available\")\n@pytest.mark.parametrize(\n    \"method\",\n    [\n        m.test_memoryview_object,\n        m.test_memoryview_buffer_info,\n    ],\n)\ndef test_memoryview_refcount(method):\n    buf = b\"\\x0a\\x0b\\x0c\\x0d\"\n    ref_before = sys.getrefcount(buf)\n    view = method(buf)\n    ref_after = sys.getrefcount(buf)\n    assert ref_before < ref_after\n    assert list(view) == list(buf)\n\n\ndef test_memoryview_from_buffer_empty_shape():\n    view = m.test_memoryview_from_buffer_empty_shape()\n    assert isinstance(view, memoryview)\n    assert view.format == \"B\"\n    assert bytes(view) == b\"\"\n\n\ndef test_test_memoryview_from_buffer_invalid_strides():\n    with pytest.raises(RuntimeError):\n        m.test_memoryview_from_buffer_invalid_strides()\n\n\ndef test_test_memoryview_from_buffer_nullptr():\n    with pytest.raises(ValueError):\n        m.test_memoryview_from_buffer_nullptr()\n\n\ndef test_memoryview_from_memory():\n    view = m.test_memoryview_from_memory()\n    assert isinstance(view, memoryview)\n    assert view.format == \"B\"\n    assert bytes(view) == b\"\\xff\\xe1\\xab\\x37\"\n\n\ndef test_builtin_functions():\n    assert m.get_len([i for i in range(42)]) == 42\n    with pytest.raises(TypeError) as exc_info:\n        m.get_len(i for i in range(42))\n    assert str(exc_info.value) in [\n        \"object of type 'generator' has no len()\",\n        \"'generator' has no length\",\n    ]  # PyPy\n\n\ndef test_isinstance_string_types():\n    assert m.isinstance_pybind11_bytes(b\"\")\n    assert not m.isinstance_pybind11_bytes(\"\")\n\n    assert m.isinstance_pybind11_str(\"\")\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.isinstance_pybind11_str(b\"\")\n    else:\n        assert not m.isinstance_pybind11_str(b\"\")\n\n\ndef test_pass_bytes_or_unicode_to_string_types():\n    assert m.pass_to_pybind11_bytes(b\"Bytes\") == 5\n    with pytest.raises(TypeError):\n        m.pass_to_pybind11_bytes(\"Str\")\n\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.pass_to_pybind11_str(b\"Bytes\") == 5\n    else:\n        with pytest.raises(TypeError):\n            m.pass_to_pybind11_str(b\"Bytes\")\n    assert m.pass_to_pybind11_str(\"Str\") == 3\n\n    assert m.pass_to_std_string(b\"Bytes\") == 5\n    assert m.pass_to_std_string(\"Str\") == 3\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.pass_to_pybind11_str(malformed_utf8) == 1\n    else:\n        with pytest.raises(TypeError):\n            m.pass_to_pybind11_str(malformed_utf8)\n\n\n@pytest.mark.parametrize(\n    \"create_weakref, create_weakref_with_callback\",\n    [\n        (m.weakref_from_handle, m.weakref_from_handle_and_function),\n        (m.weakref_from_object, m.weakref_from_object_and_function),\n    ],\n)\ndef test_weakref(create_weakref, create_weakref_with_callback):\n    from weakref import getweakrefcount\n\n    # Apparently, you cannot weakly reference an object()\n    class WeaklyReferenced:\n        pass\n\n    callback_called = False\n\n    def callback(wr):\n        nonlocal callback_called\n        callback_called = True\n\n    obj = WeaklyReferenced()\n    assert getweakrefcount(obj) == 0\n    wr = create_weakref(obj)\n    assert getweakrefcount(obj) == 1\n\n    obj = WeaklyReferenced()\n    assert getweakrefcount(obj) == 0\n    wr = create_weakref_with_callback(obj, callback)  # noqa: F841\n    assert getweakrefcount(obj) == 1\n    assert not callback_called\n    del obj\n    pytest.gc_collect()\n    assert callback_called\n\n\n@pytest.mark.parametrize(\n    \"create_weakref, has_callback\",\n    [\n        (m.weakref_from_handle, False),\n        (m.weakref_from_object, False),\n        (m.weakref_from_handle_and_function, True),\n        (m.weakref_from_object_and_function, True),\n    ],\n)\ndef test_weakref_err(create_weakref, has_callback):\n    class C:\n        __slots__ = []\n\n    def callback(_):\n        pass\n\n    ob = C()\n    # Should raise TypeError on CPython\n    with pytest.raises(TypeError) if not env.PYPY else contextlib.nullcontext():\n        if has_callback:\n            _ = create_weakref(ob, callback)\n        else:\n            _ = create_weakref(ob)\n\n\ndef test_cpp_iterators():\n    assert m.tuple_iterator() == 12\n    assert m.dict_iterator() == 305 + 711\n    assert m.passed_iterator(iter((-7, 3))) == -4\n\n\ndef test_implementation_details():\n    lst = [39, 43, 92, 49, 22, 29, 93, 98, 26, 57, 8]\n    tup = tuple(lst)\n    assert m.sequence_item_get_ssize_t(lst) == 43\n    assert m.sequence_item_set_ssize_t(lst) is None\n    assert lst[1] == \"peppa\"\n    assert m.sequence_item_get_size_t(lst) == 92\n    assert m.sequence_item_set_size_t(lst) is None\n    assert lst[2] == \"george\"\n    assert m.list_item_get_ssize_t(lst) == 49\n    assert m.list_item_set_ssize_t(lst) is None\n    assert lst[3] == \"rebecca\"\n    assert m.list_item_get_size_t(lst) == 22\n    assert m.list_item_set_size_t(lst) is None\n    assert lst[4] == \"richard\"\n    assert m.tuple_item_get_ssize_t(tup) == 29\n    assert m.tuple_item_set_ssize_t() == (\"emely\", \"edmond\")\n    assert m.tuple_item_get_size_t(tup) == 93\n    assert m.tuple_item_set_size_t() == (\"candy\", \"cat\")\n\n\ndef test_external_float_():\n    r1 = m.square_float_(2.0)\n    assert r1 == 4.0\n\n\ndef test_tuple_rvalue_getter():\n    pop = 1000\n    tup = tuple(range(pop))\n    m.tuple_rvalue_getter(tup)\n\n\ndef test_list_rvalue_getter():\n    pop = 1000\n    my_list = list(range(pop))\n    m.list_rvalue_getter(my_list)\n\n\ndef test_populate_dict_rvalue():\n    pop = 1000\n    my_dict = {i: i for i in range(pop)}\n    assert m.populate_dict_rvalue(pop) == my_dict\n\n\ndef test_populate_obj_str_attrs():\n    pop = 1000\n    o = types.SimpleNamespace(**{str(i): i for i in range(pop)})\n    new_o = m.populate_obj_str_attrs(o, pop)\n    new_attrs = {k: v for k, v in new_o.__dict__.items() if not k.startswith(\"_\")}\n    assert all(isinstance(v, str) for v in new_attrs.values())\n    assert len(new_attrs) == pop\n\n\n@pytest.mark.parametrize(\n    \"a,b\", [(\"foo\", \"bar\"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))]\n)\ndef test_inplace_append(a, b):\n    expected = a + b\n    assert m.inplace_append(a, b) == expected\n\n\n@pytest.mark.parametrize(\"a,b\", [(3, 2), (3.0, 2.0), (set(range(3)), set(range(2)))])\ndef test_inplace_subtract(a, b):\n    expected = a - b\n    assert m.inplace_subtract(a, b) == expected\n\n\n@pytest.mark.parametrize(\"a,b\", [(3, 2), (3.0, 2.0), ([1], 3)])\ndef test_inplace_multiply(a, b):\n    expected = a * b\n    assert m.inplace_multiply(a, b) == expected\n\n\n@pytest.mark.parametrize(\"a,b\", [(6, 3), (6.0, 3.0)])\ndef test_inplace_divide(a, b):\n    expected = a / b\n    assert m.inplace_divide(a, b) == expected\n\n\n@pytest.mark.parametrize(\n    \"a,b\",\n    [\n        (False, True),\n        (\n            set(),\n            {\n                1,\n            },\n        ),\n    ],\n)\ndef test_inplace_or(a, b):\n    expected = a | b\n    assert m.inplace_or(a, b) == expected\n\n\n@pytest.mark.parametrize(\n    \"a,b\",\n    [\n        (True, False),\n        (\n            {1, 2, 3},\n            {\n                1,\n            },\n        ),\n    ],\n)\ndef test_inplace_and(a, b):\n    expected = a & b\n    assert m.inplace_and(a, b) == expected\n\n\n@pytest.mark.parametrize(\"a,b\", [(8, 1), (-3, 2)])\ndef test_inplace_lshift(a, b):\n    expected = a << b\n    assert m.inplace_lshift(a, b) == expected\n\n\n@pytest.mark.parametrize(\"a,b\", [(8, 1), (-2, 2)])\ndef test_inplace_rshift(a, b):\n    expected = a >> b\n    assert m.inplace_rshift(a, b) == expected\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_sequences_and_iterators.cpp",
    "content": "/*\n    tests/test_sequences_and_iterators.cpp -- supporting Pythons' sequence protocol, iterators,\n    etc.\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/operators.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <algorithm>\n#include <utility>\n#include <vector>\n\n#ifdef PYBIND11_HAS_OPTIONAL\n#    include <optional>\n#endif // PYBIND11_HAS_OPTIONAL\n\ntemplate <typename T>\nclass NonZeroIterator {\n    const T *ptr_;\n\npublic:\n    explicit NonZeroIterator(const T *ptr) : ptr_(ptr) {}\n    const T &operator*() const { return *ptr_; }\n    NonZeroIterator &operator++() {\n        ++ptr_;\n        return *this;\n    }\n};\n\nclass NonZeroSentinel {};\n\ntemplate <typename A, typename B>\nbool operator==(const NonZeroIterator<std::pair<A, B>> &it, const NonZeroSentinel &) {\n    return !(*it).first || !(*it).second;\n}\n\n/* Iterator where dereferencing returns prvalues instead of references. */\ntemplate <typename T>\nclass NonRefIterator {\n    const T *ptr_;\n\npublic:\n    explicit NonRefIterator(const T *ptr) : ptr_(ptr) {}\n    T operator*() const { return T(*ptr_); }\n    NonRefIterator &operator++() {\n        ++ptr_;\n        return *this;\n    }\n    bool operator==(const NonRefIterator &other) const { return ptr_ == other.ptr_; }\n};\n\nclass NonCopyableInt {\npublic:\n    explicit NonCopyableInt(int value) : value_(value) {}\n    NonCopyableInt(const NonCopyableInt &) = delete;\n    NonCopyableInt(NonCopyableInt &&other) noexcept : value_(other.value_) {\n        other.value_ = -1; // detect when an unwanted move occurs\n    }\n    NonCopyableInt &operator=(const NonCopyableInt &) = delete;\n    NonCopyableInt &operator=(NonCopyableInt &&other) noexcept {\n        value_ = other.value_;\n        other.value_ = -1; // detect when an unwanted move occurs\n        return *this;\n    }\n    int get() const { return value_; }\n    void set(int value) { value_ = value; }\n    ~NonCopyableInt() = default;\n\nprivate:\n    int value_;\n};\nusing NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;\nPYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);\nPYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);\n\ntemplate <typename PythonType>\npy::list test_random_access_iterator(PythonType x) {\n    if (x.size() < 5) {\n        throw py::value_error(\"Please provide at least 5 elements for testing.\");\n    }\n\n    auto checks = py::list();\n    auto assert_equal = [&checks](py::handle a, py::handle b) {\n        auto result = PyObject_RichCompareBool(a.ptr(), b.ptr(), Py_EQ);\n        if (result == -1) {\n            throw py::error_already_set();\n        }\n        checks.append(result != 0);\n    };\n\n    auto it = x.begin();\n    assert_equal(x[0], *it);\n    assert_equal(x[0], it[0]);\n    assert_equal(x[1], it[1]);\n\n    assert_equal(x[1], *(++it));\n    assert_equal(x[1], *(it++));\n    assert_equal(x[2], *it);\n    assert_equal(x[3], *(it += 1));\n    assert_equal(x[2], *(--it));\n    assert_equal(x[2], *(it--));\n    assert_equal(x[1], *it);\n    assert_equal(x[0], *(it -= 1));\n\n    assert_equal(it->attr(\"real\"), x[0].attr(\"real\"));\n    assert_equal((it + 1)->attr(\"real\"), x[1].attr(\"real\"));\n\n    assert_equal(x[1], *(it + 1));\n    assert_equal(x[1], *(1 + it));\n    it += 3;\n    assert_equal(x[1], *(it - 2));\n\n    checks.append(static_cast<std::size_t>(x.end() - x.begin()) == x.size());\n    checks.append((x.begin() + static_cast<std::ptrdiff_t>(x.size())) == x.end());\n    checks.append(x.begin() < x.end());\n\n    return checks;\n}\n\nTEST_SUBMODULE(sequences_and_iterators, m) {\n    // test_sliceable\n    class Sliceable {\n    public:\n        explicit Sliceable(int n) : size(n) {}\n        int start, stop, step;\n        int size;\n    };\n    py::class_<Sliceable>(m, \"Sliceable\")\n        .def(py::init<int>())\n        .def(\"__getitem__\", [](const Sliceable &s, const py::slice &slice) {\n            py::ssize_t start = 0, stop = 0, step = 0, slicelength = 0;\n            if (!slice.compute(s.size, &start, &stop, &step, &slicelength)) {\n                throw py::error_already_set();\n            }\n            int istart = static_cast<int>(start);\n            int istop = static_cast<int>(stop);\n            int istep = static_cast<int>(step);\n            return std::make_tuple(istart, istop, istep);\n        });\n\n    m.def(\"make_forward_slice_size_t\", []() { return py::slice(0, -1, 1); });\n    m.def(\"make_reversed_slice_object\",\n          []() { return py::slice(py::none(), py::none(), py::int_(-1)); });\n#ifdef PYBIND11_HAS_OPTIONAL\n    m.attr(\"has_optional\") = true;\n    m.def(\"make_reversed_slice_size_t_optional_verbose\",\n          []() { return py::slice(std::nullopt, std::nullopt, -1); });\n    // Warning: The following spelling may still compile if optional<> is not present and give\n    // wrong answers. Please use with caution.\n    m.def(\"make_reversed_slice_size_t_optional\", []() { return py::slice({}, {}, -1); });\n#else\n    m.attr(\"has_optional\") = false;\n#endif\n\n    // test_sequence\n    class Sequence {\n    public:\n        explicit Sequence(size_t size) : m_size(size) {\n            print_created(this, \"of size\", m_size);\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[size];\n            memset(m_data, 0, sizeof(float) * size);\n        }\n        explicit Sequence(const std::vector<float> &value) : m_size(value.size()) {\n            print_created(this, \"of size\", m_size, \"from std::vector\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[m_size];\n            memcpy(m_data, &value[0], sizeof(float) * m_size);\n        }\n        Sequence(const Sequence &s) : m_size(s.m_size) {\n            print_copy_created(this);\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[m_size];\n            memcpy(m_data, s.m_data, sizeof(float) * m_size);\n        }\n        Sequence(Sequence &&s) noexcept : m_size(s.m_size), m_data(s.m_data) {\n            print_move_created(this);\n            s.m_size = 0;\n            s.m_data = nullptr;\n        }\n\n        ~Sequence() {\n            print_destroyed(this);\n            delete[] m_data;\n        }\n\n        Sequence &operator=(const Sequence &s) {\n            if (&s != this) {\n                delete[] m_data;\n                m_size = s.m_size;\n                m_data = new float[m_size];\n                memcpy(m_data, s.m_data, sizeof(float) * m_size);\n            }\n            print_copy_assigned(this);\n            return *this;\n        }\n\n        Sequence &operator=(Sequence &&s) noexcept {\n            if (&s != this) {\n                delete[] m_data;\n                m_size = s.m_size;\n                m_data = s.m_data;\n                s.m_size = 0;\n                s.m_data = nullptr;\n            }\n            print_move_assigned(this);\n            return *this;\n        }\n\n        bool operator==(const Sequence &s) const {\n            if (m_size != s.size()) {\n                return false;\n            }\n            for (size_t i = 0; i < m_size; ++i) {\n                if (m_data[i] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        bool operator!=(const Sequence &s) const { return !operator==(s); }\n\n        float operator[](size_t index) const { return m_data[index]; }\n        float &operator[](size_t index) { return m_data[index]; }\n\n        bool contains(float v) const {\n            for (size_t i = 0; i < m_size; ++i) {\n                if (v == m_data[i]) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        Sequence reversed() const {\n            Sequence result(m_size);\n            for (size_t i = 0; i < m_size; ++i) {\n                result[m_size - i - 1] = m_data[i];\n            }\n            return result;\n        }\n\n        size_t size() const { return m_size; }\n\n        const float *begin() const { return m_data; }\n        const float *end() const { return m_data + m_size; }\n\n    private:\n        size_t m_size;\n        float *m_data;\n    };\n    py::class_<Sequence>(m, \"Sequence\")\n        .def(py::init<size_t>())\n        .def(py::init<const std::vector<float> &>())\n        /// Bare bones interface\n        .def(\"__getitem__\",\n             [](const Sequence &s, size_t i) {\n                 if (i >= s.size()) {\n                     throw py::index_error();\n                 }\n                 return s[i];\n             })\n        .def(\"__setitem__\",\n             [](Sequence &s, size_t i, float v) {\n                 if (i >= s.size()) {\n                     throw py::index_error();\n                 }\n                 s[i] = v;\n             })\n        .def(\"__len__\", &Sequence::size)\n        /// Optional sequence protocol operations\n        .def(\n            \"__iter__\",\n            [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); },\n            py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */)\n        .def(\"__contains__\", [](const Sequence &s, float v) { return s.contains(v); })\n        .def(\"__reversed__\", [](const Sequence &s) -> Sequence { return s.reversed(); })\n        /// Slicing protocol (optional)\n        .def(\"__getitem__\",\n             [](const Sequence &s, const py::slice &slice) -> Sequence * {\n                 size_t start = 0, stop = 0, step = 0, slicelength = 0;\n                 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) {\n                     throw py::error_already_set();\n                 }\n                 auto *seq = new Sequence(slicelength);\n                 for (size_t i = 0; i < slicelength; ++i) {\n                     (*seq)[i] = s[start];\n                     start += step;\n                 }\n                 return seq;\n             })\n        .def(\"__setitem__\",\n             [](Sequence &s, const py::slice &slice, const Sequence &value) {\n                 size_t start = 0, stop = 0, step = 0, slicelength = 0;\n                 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) {\n                     throw py::error_already_set();\n                 }\n                 if (slicelength != value.size()) {\n                     throw std::runtime_error(\n                         \"Left and right hand size of slice assignment have different sizes!\");\n                 }\n                 for (size_t i = 0; i < slicelength; ++i) {\n                     s[start] = value[i];\n                     start += step;\n                 }\n             })\n        /// Comparisons\n        .def(py::self == py::self)\n        .def(py::self != py::self)\n        // Could also define py::self + py::self for concatenation, etc.\n        ;\n\n    // test_map_iterator\n    // Interface of a map-like object that isn't (directly) an unordered_map, but provides some\n    // basic map-like functionality.\n    class StringMap {\n    public:\n        StringMap() = default;\n        explicit StringMap(std::unordered_map<std::string, std::string> init)\n            : map(std::move(init)) {}\n\n        void set(const std::string &key, std::string val) { map[key] = std::move(val); }\n        std::string get(const std::string &key) const { return map.at(key); }\n        size_t size() const { return map.size(); }\n\n    private:\n        std::unordered_map<std::string, std::string> map;\n\n    public:\n        decltype(map.cbegin()) begin() const { return map.cbegin(); }\n        decltype(map.cend()) end() const { return map.cend(); }\n    };\n    py::class_<StringMap>(m, \"StringMap\")\n        .def(py::init<>())\n        .def(py::init<std::unordered_map<std::string, std::string>>())\n        .def(\"__getitem__\",\n             [](const StringMap &map, const std::string &key) {\n                 try {\n                     return map.get(key);\n                 } catch (const std::out_of_range &) {\n                     throw py::key_error(\"key '\" + key + \"' does not exist\");\n                 }\n             })\n        .def(\"__setitem__\", &StringMap::set)\n        .def(\"__len__\", &StringMap::size)\n        .def(\n            \"__iter__\",\n            [](const StringMap &map) { return py::make_key_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"items\",\n            [](const StringMap &map) { return py::make_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"values\",\n            [](const StringMap &map) { return py::make_value_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>());\n\n    // test_generalized_iterators\n    class IntPairs {\n    public:\n        explicit IntPairs(std::vector<std::pair<int, int>> data) : data_(std::move(data)) {}\n        const std::pair<int, int> *begin() const { return data_.data(); }\n        // .end() only required for py::make_iterator(self) overload\n        const std::pair<int, int> *end() const { return data_.data() + data_.size(); }\n\n    private:\n        std::vector<std::pair<int, int>> data_;\n    };\n    py::class_<IntPairs>(m, \"IntPairs\")\n        .def(py::init<std::vector<std::pair<int, int>>>())\n        .def(\n            \"nonzero\",\n            [](const IntPairs &s) {\n                return py::make_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                         NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonzero_keys\",\n            [](const IntPairs &s) {\n                return py::make_key_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                             NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonzero_values\",\n            [](const IntPairs &s) {\n                return py::make_value_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                               NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n\n        // test iterator that returns values instead of references\n        .def(\n            \"nonref\",\n            [](const IntPairs &s) {\n                return py::make_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                         NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonref_keys\",\n            [](const IntPairs &s) {\n                return py::make_key_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                             NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonref_values\",\n            [](const IntPairs &s) {\n                return py::make_value_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                               NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n\n        // test single-argument make_iterator\n        .def(\n            \"simple_iterator\",\n            [](IntPairs &self) { return py::make_iterator(self); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"simple_keys\",\n            [](IntPairs &self) { return py::make_key_iterator(self); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"simple_values\",\n            [](IntPairs &self) { return py::make_value_iterator(self); },\n            py::keep_alive<0, 1>())\n\n        // Test iterator with an Extra (doesn't do anything useful, so not used\n        // at runtime, but tests need to be able to compile with the correct\n        // overload. See PR #3293.\n        .def(\n            \"_make_iterator_extras\",\n            [](IntPairs &self) { return py::make_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"_make_key_extras\",\n            [](IntPairs &self) { return py::make_key_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"_make_value_extras\",\n            [](IntPairs &self) { return py::make_value_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>());\n\n    // test_iterator_referencing\n    py::class_<NonCopyableInt>(m, \"NonCopyableInt\")\n        .def(py::init<int>())\n        .def(\"set\", &NonCopyableInt::set)\n        .def(\"__int__\", &NonCopyableInt::get);\n    py::class_<std::vector<NonCopyableInt>>(m, \"VectorNonCopyableInt\")\n        .def(py::init<>())\n        .def(\"append\",\n             [](std::vector<NonCopyableInt> &vec, int value) { vec.emplace_back(value); })\n        .def(\"__iter__\", [](std::vector<NonCopyableInt> &vec) {\n            return py::make_iterator(vec.begin(), vec.end());\n        });\n    py::class_<std::vector<NonCopyableIntPair>>(m, \"VectorNonCopyableIntPair\")\n        .def(py::init<>())\n        .def(\"append\",\n             [](std::vector<NonCopyableIntPair> &vec, const std::pair<int, int> &value) {\n                 vec.emplace_back(NonCopyableInt(value.first), NonCopyableInt(value.second));\n             })\n        .def(\"keys\",\n             [](std::vector<NonCopyableIntPair> &vec) {\n                 return py::make_key_iterator(vec.begin(), vec.end());\n             })\n        .def(\"values\", [](std::vector<NonCopyableIntPair> &vec) {\n            return py::make_value_iterator(vec.begin(), vec.end());\n        });\n\n#if 0\n    // Obsolete: special data structure for exposing custom iterator types to python\n    // kept here for illustrative purposes because there might be some use cases which\n    // are not covered by the much simpler py::make_iterator\n\n    struct PySequenceIterator {\n        PySequenceIterator(const Sequence &seq, py::object ref) : seq(seq), ref(ref) { }\n\n        float next() {\n            if (index == seq.size())\n                throw py::stop_iteration();\n            return seq[index++];\n        }\n\n        const Sequence &seq;\n        py::object ref; // keep a reference\n        size_t index = 0;\n    };\n\n    py::class_<PySequenceIterator>(seq, \"Iterator\")\n        .def(\"__iter__\", [](PySequenceIterator &it) -> PySequenceIterator& { return it; })\n        .def(\"__next__\", &PySequenceIterator::next);\n\n    On the actual Sequence object, the iterator would be constructed as follows:\n    .def(\"__iter__\", [](py::object s) { return PySequenceIterator(s.cast<const Sequence &>(), s); })\n#endif\n\n    // test_python_iterator_in_cpp\n    m.def(\"object_to_list\", [](const py::object &o) {\n        auto l = py::list();\n        for (auto item : o) {\n            l.append(item);\n        }\n        return l;\n    });\n\n    m.def(\"iterator_to_list\", [](py::iterator it) {\n        auto l = py::list();\n        while (it != py::iterator::sentinel()) {\n            l.append(*it);\n            ++it;\n        }\n        return l;\n    });\n\n    // test_sequence_length: check that Python sequences can be converted to py::sequence.\n    m.def(\"sequence_length\", [](const py::sequence &seq) { return seq.size(); });\n\n    // Make sure that py::iterator works with std algorithms\n    m.def(\"count_none\", [](const py::object &o) {\n        return std::count_if(o.begin(), o.end(), [](py::handle h) { return h.is_none(); });\n    });\n\n    m.def(\"find_none\", [](const py::object &o) {\n        auto it = std::find_if(o.begin(), o.end(), [](py::handle h) { return h.is_none(); });\n        return it->is_none();\n    });\n\n    m.def(\"count_nonzeros\", [](const py::dict &d) {\n        return std::count_if(d.begin(), d.end(), [](std::pair<py::handle, py::handle> p) {\n            return p.second.cast<int>() != 0;\n        });\n    });\n\n    m.def(\"tuple_iterator\", &test_random_access_iterator<py::tuple>);\n    m.def(\"list_iterator\", &test_random_access_iterator<py::list>);\n    m.def(\"sequence_iterator\", &test_random_access_iterator<py::sequence>);\n\n    // test_iterator_passthrough\n    // #181: iterator passthrough did not compile\n    m.def(\"iterator_passthrough\", [](py::iterator s) -> py::iterator {\n        return py::make_iterator(std::begin(s), std::end(s));\n    });\n\n    // test_iterator_rvp\n    // #388: Can't make iterators via make_iterator() with different r/v policies\n    static std::vector<int> list = {1, 2, 3};\n    m.def(\"make_iterator_1\",\n          []() { return py::make_iterator<py::return_value_policy::copy>(list); });\n    m.def(\"make_iterator_2\",\n          []() { return py::make_iterator<py::return_value_policy::automatic>(list); });\n\n    // test_iterator on c arrays\n    // #4100: ensure lvalue required as increment operand\n    class CArrayHolder {\n    public:\n        CArrayHolder(double x, double y, double z) {\n            values[0] = x;\n            values[1] = y;\n            values[2] = z;\n        };\n        double values[3];\n    };\n\n    py::class_<CArrayHolder>(m, \"CArrayHolder\")\n        .def(py::init<double, double, double>())\n        .def(\n            \"__iter__\",\n            [](const CArrayHolder &v) { return py::make_iterator(v.values, v.values + 3); },\n            py::keep_alive<0, 1>());\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_sequences_and_iterators.py",
    "content": "import pytest\nfrom pytest import approx\n\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import sequences_and_iterators as m\n\n\ndef test_slice_constructors():\n    assert m.make_forward_slice_size_t() == slice(0, -1, 1)\n    assert m.make_reversed_slice_object() == slice(None, None, -1)\n\n\n@pytest.mark.skipif(not m.has_optional, reason=\"no <optional>\")\ndef test_slice_constructors_explicit_optional():\n    assert m.make_reversed_slice_size_t_optional() == slice(None, None, -1)\n    assert m.make_reversed_slice_size_t_optional_verbose() == slice(None, None, -1)\n\n\ndef test_generalized_iterators():\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero()) == [(1, 2), (3, 4)]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero()) == [(1, 2)]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero()) == []\n\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_keys()) == [1, 3]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_keys()) == [1]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_keys()) == []\n\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_values()) == [2, 4]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_values()) == [2]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_values()) == []\n\n    # __next__ must continue to raise StopIteration\n    it = m.IntPairs([(0, 0)]).nonzero()\n    for _ in range(3):\n        with pytest.raises(StopIteration):\n            next(it)\n\n    it = m.IntPairs([(0, 0)]).nonzero_keys()\n    for _ in range(3):\n        with pytest.raises(StopIteration):\n            next(it)\n\n\ndef test_nonref_iterators():\n    pairs = m.IntPairs([(1, 2), (3, 4), (0, 5)])\n    assert list(pairs.nonref()) == [(1, 2), (3, 4), (0, 5)]\n    assert list(pairs.nonref_keys()) == [1, 3, 0]\n    assert list(pairs.nonref_values()) == [2, 4, 5]\n\n\ndef test_generalized_iterators_simple():\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_iterator()) == [\n        (1, 2),\n        (3, 4),\n        (0, 5),\n    ]\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_keys()) == [1, 3, 0]\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_values()) == [2, 4, 5]\n\n\ndef test_iterator_referencing():\n    \"\"\"Test that iterators reference rather than copy their referents.\"\"\"\n    vec = m.VectorNonCopyableInt()\n    vec.append(3)\n    vec.append(5)\n    assert [int(x) for x in vec] == [3, 5]\n    # Increment everything to make sure the referents can be mutated\n    for x in vec:\n        x.set(int(x) + 1)\n    assert [int(x) for x in vec] == [4, 6]\n\n    vec = m.VectorNonCopyableIntPair()\n    vec.append([3, 4])\n    vec.append([5, 7])\n    assert [int(x) for x in vec.keys()] == [3, 5]\n    assert [int(x) for x in vec.values()] == [4, 7]\n    for x in vec.keys():\n        x.set(int(x) + 1)\n    for x in vec.values():\n        x.set(int(x) + 10)\n    assert [int(x) for x in vec.keys()] == [4, 6]\n    assert [int(x) for x in vec.values()] == [14, 17]\n\n\ndef test_sliceable():\n    sliceable = m.Sliceable(100)\n    assert sliceable[::] == (0, 100, 1)\n    assert sliceable[10::] == (10, 100, 1)\n    assert sliceable[:10:] == (0, 10, 1)\n    assert sliceable[::10] == (0, 100, 10)\n    assert sliceable[-10::] == (90, 100, 1)\n    assert sliceable[:-10:] == (0, 90, 1)\n    assert sliceable[::-10] == (99, -1, -10)\n    assert sliceable[50:60:1] == (50, 60, 1)\n    assert sliceable[50:60:-1] == (50, 60, -1)\n\n\ndef test_sequence():\n    cstats = ConstructorStats.get(m.Sequence)\n\n    s = m.Sequence(5)\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    assert \"Sequence\" in repr(s)\n    assert len(s) == 5\n    assert s[0] == 0 and s[3] == 0\n    assert 12.34 not in s\n    s[0], s[3] = 12.34, 56.78\n    assert 12.34 in s\n    assert s[0] == approx(12.34, rel=1e-05)\n    assert s[3] == approx(56.78, rel=1e-05)\n\n    rev = reversed(s)\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    rev2 = s[::-1]\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    it = iter(m.Sequence(0))\n    for _ in range(3):  # __next__ must continue to raise StopIteration\n        with pytest.raises(StopIteration):\n            next(it)\n    assert cstats.values() == [\"of size\", \"0\"]\n\n    expected = [0, 56.78, 0, 0, 12.34]\n    assert rev == approx(expected, rel=1e-05)\n    assert rev2 == approx(expected, rel=1e-05)\n    assert rev == rev2\n\n    rev[0::2] = m.Sequence([2.0, 2.0, 2.0])\n    assert cstats.values() == [\"of size\", \"3\", \"from std::vector\"]\n\n    assert rev == approx([2, 56.78, 2, 0, 2], rel=1e-05)\n\n    assert cstats.alive() == 4\n    del it\n    assert cstats.alive() == 3\n    del s\n    assert cstats.alive() == 2\n    del rev\n    assert cstats.alive() == 1\n    del rev2\n    assert cstats.alive() == 0\n\n    assert cstats.values() == []\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 1\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_sequence_length():\n    \"\"\"#2076: Exception raised by len(arg) should be propagated\"\"\"\n\n    class BadLen(RuntimeError):\n        pass\n\n    class SequenceLike:\n        def __getitem__(self, i):\n            return None\n\n        def __len__(self):\n            raise BadLen()\n\n    with pytest.raises(BadLen):\n        m.sequence_length(SequenceLike())\n\n    assert m.sequence_length([1, 2, 3]) == 3\n    assert m.sequence_length(\"hello\") == 5\n\n\ndef test_map_iterator():\n    sm = m.StringMap({\"hi\": \"bye\", \"black\": \"white\"})\n    assert sm[\"hi\"] == \"bye\"\n    assert len(sm) == 2\n    assert sm[\"black\"] == \"white\"\n\n    with pytest.raises(KeyError):\n        assert sm[\"orange\"]\n    sm[\"orange\"] = \"banana\"\n    assert sm[\"orange\"] == \"banana\"\n\n    expected = {\"hi\": \"bye\", \"black\": \"white\", \"orange\": \"banana\"}\n    for k in sm:\n        assert sm[k] == expected[k]\n    for k, v in sm.items():\n        assert v == expected[k]\n    assert list(sm.values()) == [expected[k] for k in sm]\n\n    it = iter(m.StringMap({}))\n    for _ in range(3):  # __next__ must continue to raise StopIteration\n        with pytest.raises(StopIteration):\n            next(it)\n\n\ndef test_python_iterator_in_cpp():\n    t = (1, 2, 3)\n    assert m.object_to_list(t) == [1, 2, 3]\n    assert m.object_to_list(iter(t)) == [1, 2, 3]\n    assert m.iterator_to_list(iter(t)) == [1, 2, 3]\n\n    with pytest.raises(TypeError) as excinfo:\n        m.object_to_list(1)\n    assert \"object is not iterable\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.iterator_to_list(1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    def bad_next_call():\n        raise RuntimeError(\"py::iterator::advance() should propagate errors\")\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.iterator_to_list(iter(bad_next_call, None))\n    assert str(excinfo.value) == \"py::iterator::advance() should propagate errors\"\n\n    lst = [1, None, 0, None]\n    assert m.count_none(lst) == 2\n    assert m.find_none(lst) is True\n    assert m.count_nonzeros({\"a\": 0, \"b\": 1, \"c\": 2}) == 2\n\n    r = range(5)\n    assert all(m.tuple_iterator(tuple(r)))\n    assert all(m.list_iterator(list(r)))\n    assert all(m.sequence_iterator(r))\n\n\ndef test_iterator_passthrough():\n    \"\"\"#181: iterator passthrough did not compile\"\"\"\n    from pybind11_tests.sequences_and_iterators import iterator_passthrough\n\n    values = [3, 5, 7, 9, 11, 13, 15]\n    assert list(iterator_passthrough(iter(values))) == values\n\n\ndef test_iterator_rvp():\n    \"\"\"#388: Can't make iterators via make_iterator() with different r/v policies\"\"\"\n    import pybind11_tests.sequences_and_iterators as m\n\n    assert list(m.make_iterator_1()) == [1, 2, 3]\n    assert list(m.make_iterator_2()) == [1, 2, 3]\n    assert not isinstance(m.make_iterator_1(), type(m.make_iterator_2()))\n\n\ndef test_carray_iterator():\n    \"\"\"#4100: Check for proper iterator overload with C-Arrays\"\"\"\n    args_gt = list(float(i) for i in range(3))\n    arr_h = m.CArrayHolder(*args_gt)\n    args = list(arr_h)\n    assert args_gt == args\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_smart_ptr.cpp",
    "content": "/*\n    tests/test_smart_ptr.cpp -- binding classes with custom reference counting,\n    implicit conversions between types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"object.h\"\n#include \"pybind11_tests.h\"\n\nnamespace {\n\n// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the\n// holder size to trigger the non-simple-layout internal instance layout for single inheritance\n// with large holder type:\ntemplate <typename T>\nclass huge_unique_ptr {\n    std::unique_ptr<T> ptr;\n    uint64_t padding[10];\n\npublic:\n    explicit huge_unique_ptr(T *p) : ptr(p) {}\n    T *get() { return ptr.get(); }\n};\n\n// Simple custom holder that works like unique_ptr\ntemplate <typename T>\nclass custom_unique_ptr {\n    std::unique_ptr<T> impl;\n\npublic:\n    explicit custom_unique_ptr(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T *release_ptr() { return impl.release(); }\n};\n\n// Simple custom holder that works like shared_ptr and has operator& overload\n// To obtain address of an instance of this holder pybind should use std::addressof\n// Attempt to get address via operator& may leads to segmentation fault\ntemplate <typename T>\nclass shared_ptr_with_addressof_operator {\n    std::shared_ptr<T> impl;\n\npublic:\n    shared_ptr_with_addressof_operator() = default;\n    explicit shared_ptr_with_addressof_operator(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T **operator&() { throw std::logic_error(\"Call of overloaded operator& is not expected\"); }\n};\n\n// Simple custom holder that works like unique_ptr and has operator& overload\n// To obtain address of an instance of this holder pybind should use std::addressof\n// Attempt to get address via operator& may leads to segmentation fault\ntemplate <typename T>\nclass unique_ptr_with_addressof_operator {\n    std::unique_ptr<T> impl;\n\npublic:\n    unique_ptr_with_addressof_operator() = default;\n    explicit unique_ptr_with_addressof_operator(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T *release_ptr() { return impl.release(); }\n    T **operator&() { throw std::logic_error(\"Call of overloaded operator& is not expected\"); }\n};\n\n// Custom object with builtin reference counting (see 'object.h' for the implementation)\nclass MyObject1 : public Object {\npublic:\n    explicit MyObject1(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const override { return \"MyObject1[\" + std::to_string(value) + \"]\"; }\n\nprotected:\n    ~MyObject1() override { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// Object managed by a std::shared_ptr<>\nclass MyObject2 {\npublic:\n    MyObject2(const MyObject2 &) = default;\n    explicit MyObject2(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const { return \"MyObject2[\" + std::to_string(value) + \"]\"; }\n    virtual ~MyObject2() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>\nclass MyObject3 : public std::enable_shared_from_this<MyObject3> {\npublic:\n    MyObject3(const MyObject3 &) = default;\n    explicit MyObject3(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const { return \"MyObject3[\" + std::to_string(value) + \"]\"; }\n    virtual ~MyObject3() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// test_unique_nodelete\n// Object with a private destructor\nclass MyObject4;\nstd::unordered_set<MyObject4 *> myobject4_instances;\nclass MyObject4 {\npublic:\n    explicit MyObject4(int value) : value{value} {\n        print_created(this);\n        myobject4_instances.insert(this);\n    }\n    int value;\n\n    static void cleanupAllInstances() {\n        auto tmp = std::move(myobject4_instances);\n        myobject4_instances.clear();\n        for (auto *o : tmp) {\n            delete o;\n        }\n    }\n\nprivate:\n    ~MyObject4() {\n        myobject4_instances.erase(this);\n        print_destroyed(this);\n    }\n};\n\n// test_unique_deleter\n// Object with std::unique_ptr<T, D> where D is not matching the base class\n// Object with a protected destructor\nclass MyObject4a;\nstd::unordered_set<MyObject4a *> myobject4a_instances;\nclass MyObject4a {\npublic:\n    explicit MyObject4a(int i) : value{i} {\n        print_created(this);\n        myobject4a_instances.insert(this);\n    };\n    int value;\n\n    static void cleanupAllInstances() {\n        auto tmp = std::move(myobject4a_instances);\n        myobject4a_instances.clear();\n        for (auto *o : tmp) {\n            delete o;\n        }\n    }\n\nprotected:\n    virtual ~MyObject4a() {\n        myobject4a_instances.erase(this);\n        print_destroyed(this);\n    }\n};\n\n// Object derived but with public destructor and no Deleter in default holder\nclass MyObject4b : public MyObject4a {\npublic:\n    explicit MyObject4b(int i) : MyObject4a(i) { print_created(this); }\n    ~MyObject4b() override { print_destroyed(this); }\n};\n\n// test_large_holder\nclass MyObject5 { // managed by huge_unique_ptr\npublic:\n    explicit MyObject5(int value) : value{value} { print_created(this); }\n    ~MyObject5() { print_destroyed(this); }\n    int value;\n};\n\n// test_shared_ptr_and_references\nstruct SharedPtrRef {\n    struct A {\n        A() { print_created(this); }\n        A(const A &) { print_copy_created(this); }\n        A(A &&) noexcept { print_move_created(this); }\n        ~A() { print_destroyed(this); }\n    };\n\n    A value = {};\n    std::shared_ptr<A> shared = std::make_shared<A>();\n};\n\n// test_shared_ptr_from_this_and_references\nstruct SharedFromThisRef {\n    struct B : std::enable_shared_from_this<B> {\n        B() { print_created(this); }\n        // NOLINTNEXTLINE(bugprone-copy-constructor-init)\n        B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); }\n        B(B &&) noexcept : std::enable_shared_from_this<B>() { print_move_created(this); }\n        ~B() { print_destroyed(this); }\n    };\n\n    B value = {};\n    std::shared_ptr<B> shared = std::make_shared<B>();\n};\n\n// Issue #865: shared_from_this doesn't work with virtual inheritance\nstruct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {\n    SharedFromThisVBase() = default;\n    SharedFromThisVBase(const SharedFromThisVBase &) = default;\n    virtual ~SharedFromThisVBase() = default;\n};\nstruct SharedFromThisVirt : virtual SharedFromThisVBase {};\n\n// test_move_only_holder\nstruct C {\n    C() { print_created(this); }\n    ~C() { print_destroyed(this); }\n};\n\n// test_holder_with_addressof_operator\nstruct TypeForHolderWithAddressOf {\n    TypeForHolderWithAddressOf() { print_created(this); }\n    TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); }\n    TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {\n        print_move_created(this);\n    }\n    ~TypeForHolderWithAddressOf() { print_destroyed(this); }\n    std::string toString() const {\n        return \"TypeForHolderWithAddressOf[\" + std::to_string(value) + \"]\";\n    }\n    int value = 42;\n};\n\n// test_move_only_holder_with_addressof_operator\nstruct TypeForMoveOnlyHolderWithAddressOf {\n    explicit TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); }\n    ~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); }\n    std::string toString() const {\n        return \"MoveOnlyHolderWithAddressOf[\" + std::to_string(value) + \"]\";\n    }\n    int value;\n};\n\n// test_smart_ptr_from_default\nstruct HeldByDefaultHolder {};\n\n// test_shared_ptr_gc\n// #187: issue involving std::shared_ptr<> return value policy & garbage collection\nstruct ElementBase {\n    virtual ~ElementBase() = default; /* Force creation of virtual table */\n    ElementBase() = default;\n    ElementBase(const ElementBase &) = delete;\n};\n\nstruct ElementA : ElementBase {\n    explicit ElementA(int v) : v(v) {}\n    int value() const { return v; }\n    int v;\n};\n\nstruct ElementList {\n    void add(const std::shared_ptr<ElementBase> &e) { l.push_back(e); }\n    std::vector<std::shared_ptr<ElementBase>> l;\n};\n\n} // namespace\n\n// ref<T> is a wrapper for 'Object' which uses intrusive reference counting\n// It is always possible to construct a ref<T> from an Object* pointer without\n// possible inconsistencies, hence the 'true' argument at the end.\n// Make pybind11 aware of the non-standard getter member function\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <typename T>\nstruct holder_helper<ref<T>> {\n    static const T *get(const ref<T> &p) { return p.get_ptr(); }\n};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n\n// Make pybind aware of the ref-counted wrapper type (s):\nPYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);\n// The following is not required anymore for std::shared_ptr, but it should compile without error:\nPYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);\n\nTEST_SUBMODULE(smart_ptr, m) {\n    // Please do not interleave `struct` and `class` definitions with bindings code,\n    // but implement `struct`s and `class`es in the anonymous namespace above.\n    // This helps keeping the smart_holder branch in sync with master.\n\n    // test_smart_ptr\n\n    // Object implementation in `object.h`\n    py::class_<Object, ref<Object>> obj(m, \"Object\");\n    obj.def(\"getRefCount\", &Object::getRefCount);\n\n    py::class_<MyObject1, ref<MyObject1>>(m, \"MyObject1\", obj).def(py::init<int>());\n    py::implicitly_convertible<py::int_, MyObject1>();\n\n    m.def(\"make_object_1\", []() -> Object * { return new MyObject1(1); });\n    m.def(\"make_object_2\", []() -> ref<Object> { return ref<Object>(new MyObject1(2)); });\n    m.def(\"make_myobject1_1\", []() -> MyObject1 * { return new MyObject1(4); });\n    m.def(\"make_myobject1_2\", []() -> ref<MyObject1> { return ref<MyObject1>(new MyObject1(5)); });\n    m.def(\"print_object_1\", [](const Object *obj) { py::print(obj->toString()); });\n    m.def(\"print_object_2\", [](ref<Object> obj) { py::print(obj->toString()); });\n    m.def(\"print_object_3\", [](const ref<Object> &obj) { py::print(obj->toString()); });\n    m.def(\"print_object_4\", [](const ref<Object> *obj) { py::print((*obj)->toString()); });\n    m.def(\"print_myobject1_1\", [](const MyObject1 *obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_2\", [](ref<MyObject1> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_3\", [](const ref<MyObject1> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_4\", [](const ref<MyObject1> *obj) { py::print((*obj)->toString()); });\n\n    // Expose constructor stats for the ref type\n    m.def(\"cstats_ref\", &ConstructorStats::get<ref_tag>);\n\n    py::class_<MyObject2, std::shared_ptr<MyObject2>>(m, \"MyObject2\").def(py::init<int>());\n    m.def(\"make_myobject2_1\", []() { return new MyObject2(6); });\n    m.def(\"make_myobject2_2\", []() { return std::make_shared<MyObject2>(7); });\n    m.def(\"print_myobject2_1\", [](const MyObject2 *obj) { py::print(obj->toString()); });\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"print_myobject2_2\", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject2_3\",\n          [](const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject2_4\",\n          [](const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });\n\n    py::class_<MyObject3, std::shared_ptr<MyObject3>>(m, \"MyObject3\").def(py::init<int>());\n    m.def(\"make_myobject3_1\", []() { return new MyObject3(8); });\n    m.def(\"make_myobject3_2\", []() { return std::make_shared<MyObject3>(9); });\n    m.def(\"print_myobject3_1\", [](const MyObject3 *obj) { py::print(obj->toString()); });\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"print_myobject3_2\", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject3_3\",\n          [](const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject3_4\",\n          [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });\n\n    // test_smart_ptr_refcounting\n    m.def(\"test_object1_refcounting\", []() {\n        auto o = ref<MyObject1>(new MyObject1(0));\n        bool good = o->getRefCount() == 1;\n        py::object o2 = py::cast(o, py::return_value_policy::reference);\n        // always request (partial) ownership for objects with intrusive\n        // reference counting even when using the 'reference' RVP\n        good &= o->getRefCount() == 2;\n        return good;\n    });\n\n    // test_unique_nodelete\n    py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m, \"MyObject4\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject4::value)\n        .def_static(\"cleanup_all_instances\", &MyObject4::cleanupAllInstances);\n\n    // test_unique_deleter\n    py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m, \"MyObject4a\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject4a::value)\n        .def_static(\"cleanup_all_instances\", &MyObject4a::cleanupAllInstances);\n\n    py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(m, \"MyObject4b\")\n        .def(py::init<int>());\n\n    // test_large_holder\n    py::class_<MyObject5, huge_unique_ptr<MyObject5>>(m, \"MyObject5\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject5::value);\n\n    // test_shared_ptr_and_references\n    using A = SharedPtrRef::A;\n    py::class_<A, std::shared_ptr<A>>(m, \"A\");\n    py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(m, \"SharedPtrRef\")\n        .def(py::init<>())\n        .def_readonly(\"ref\", &SharedPtrRef::value)\n        .def_property_readonly(\n            \"copy\", [](const SharedPtrRef &s) { return s.value; }, py::return_value_policy::copy)\n        .def_readonly(\"holder_ref\", &SharedPtrRef::shared)\n        .def_property_readonly(\n            \"holder_copy\",\n            [](const SharedPtrRef &s) { return s.shared; },\n            py::return_value_policy::copy)\n        .def(\"set_ref\", [](SharedPtrRef &, const A &) { return true; })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"set_holder\", [](SharedPtrRef &, std::shared_ptr<A>) { return true; });\n\n    // test_shared_ptr_from_this_and_references\n    using B = SharedFromThisRef::B;\n    py::class_<B, std::shared_ptr<B>>(m, \"B\");\n    py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(m, \"SharedFromThisRef\")\n        .def(py::init<>())\n        .def_readonly(\"bad_wp\", &SharedFromThisRef::value)\n        .def_property_readonly(\"ref\",\n                               [](const SharedFromThisRef &s) -> const B & { return *s.shared; })\n        .def_property_readonly(\n            \"copy\",\n            [](const SharedFromThisRef &s) { return s.value; },\n            py::return_value_policy::copy)\n        .def_readonly(\"holder_ref\", &SharedFromThisRef::shared)\n        .def_property_readonly(\n            \"holder_copy\",\n            [](const SharedFromThisRef &s) { return s.shared; },\n            py::return_value_policy::copy)\n        .def(\"set_ref\", [](SharedFromThisRef &, const B &) { return true; })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"set_holder\", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });\n\n    // Issue #865: shared_from_this doesn't work with virtual inheritance\n    static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());\n    py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m, \"SharedFromThisVirt\")\n        .def_static(\"get\", []() { return sft.get(); });\n\n    // test_move_only_holder\n    py::class_<C, custom_unique_ptr<C>>(m, \"TypeWithMoveOnlyHolder\")\n        .def_static(\"make\", []() { return custom_unique_ptr<C>(new C); })\n        .def_static(\"make_as_object\", []() { return py::cast(custom_unique_ptr<C>(new C)); });\n\n    // test_holder_with_addressof_operator\n    using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;\n    py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(m, \"TypeForHolderWithAddressOf\")\n        .def_static(\"make\", []() { return HolderWithAddressOf(new TypeForHolderWithAddressOf); })\n        .def(\"get\", [](const HolderWithAddressOf &self) { return self.get(); })\n        .def(\"print_object_1\",\n             [](const TypeForHolderWithAddressOf *obj) { py::print(obj->toString()); })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"print_object_2\", [](HolderWithAddressOf obj) { py::print(obj.get()->toString()); })\n        .def(\"print_object_3\",\n             [](const HolderWithAddressOf &obj) { py::print(obj.get()->toString()); })\n        .def(\"print_object_4\",\n             [](const HolderWithAddressOf *obj) { py::print((*obj).get()->toString()); });\n\n    // test_move_only_holder_with_addressof_operator\n    using MoveOnlyHolderWithAddressOf\n        = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;\n    py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(\n        m, \"TypeForMoveOnlyHolderWithAddressOf\")\n        .def_static(\"make\",\n                    []() {\n                        return MoveOnlyHolderWithAddressOf(\n                            new TypeForMoveOnlyHolderWithAddressOf(0));\n                    })\n        .def_readwrite(\"value\", &TypeForMoveOnlyHolderWithAddressOf::value)\n        .def(\"print_object\",\n             [](const TypeForMoveOnlyHolderWithAddressOf *obj) { py::print(obj->toString()); });\n\n    // test_smart_ptr_from_default\n    py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(m, \"HeldByDefaultHolder\")\n        .def(py::init<>())\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def_static(\"load_shared_ptr\", [](std::shared_ptr<HeldByDefaultHolder>) {});\n\n    // test_shared_ptr_gc\n    // #187: issue involving std::shared_ptr<> return value policy & garbage collection\n    py::class_<ElementBase, std::shared_ptr<ElementBase>>(m, \"ElementBase\");\n\n    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m, \"ElementA\")\n        .def(py::init<int>())\n        .def(\"value\", &ElementA::value);\n\n    py::class_<ElementList, std::shared_ptr<ElementList>>(m, \"ElementList\")\n        .def(py::init<>())\n        .def(\"add\", &ElementList::add)\n        .def(\"get\", [](ElementList &el) {\n            py::list list;\n            for (auto &e : el.l) {\n                list.append(py::cast(e));\n            }\n            return list;\n        });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_smart_ptr.py",
    "content": "import pytest\n\nm = pytest.importorskip(\"pybind11_tests.smart_ptr\")\nfrom pybind11_tests import ConstructorStats  # noqa: E402\n\n\ndef test_smart_ptr(capture):\n    # Object1\n    for i, o in enumerate(\n        [m.make_object_1(), m.make_object_2(), m.MyObject1(3)], start=1\n    ):\n        assert o.getRefCount() == 1\n        with capture:\n            m.print_object_1(o)\n            m.print_object_2(o)\n            m.print_object_3(o)\n            m.print_object_4(o)\n        assert capture == f\"MyObject1[{i}]\\n\" * 4\n\n    for i, o in enumerate(\n        [m.make_myobject1_1(), m.make_myobject1_2(), m.MyObject1(6), 7], start=4\n    ):\n        print(o)\n        with capture:\n            if not isinstance(o, int):\n                m.print_object_1(o)\n                m.print_object_2(o)\n                m.print_object_3(o)\n                m.print_object_4(o)\n            m.print_myobject1_1(o)\n            m.print_myobject1_2(o)\n            m.print_myobject1_3(o)\n            m.print_myobject1_4(o)\n\n        times = 4 if isinstance(o, int) else 8\n        assert capture == f\"MyObject1[{i}]\\n\" * times\n\n    cstats = ConstructorStats.get(m.MyObject1)\n    assert cstats.alive() == 0\n    expected_values = [f\"MyObject1[{i}]\" for i in range(1, 7)] + [\"MyObject1[7]\"] * 4\n    assert cstats.values() == expected_values\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object2\n    for i, o in zip(\n        [8, 6, 7], [m.MyObject2(8), m.make_myobject2_1(), m.make_myobject2_2()]\n    ):\n        print(o)\n        with capture:\n            m.print_myobject2_1(o)\n            m.print_myobject2_2(o)\n            m.print_myobject2_3(o)\n            m.print_myobject2_4(o)\n        assert capture == f\"MyObject2[{i}]\\n\" * 4\n\n    cstats = ConstructorStats.get(m.MyObject2)\n    assert cstats.alive() == 1\n    o = None\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"MyObject2[8]\", \"MyObject2[6]\", \"MyObject2[7]\"]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object3\n    for i, o in zip(\n        [9, 8, 9], [m.MyObject3(9), m.make_myobject3_1(), m.make_myobject3_2()]\n    ):\n        print(o)\n        with capture:\n            m.print_myobject3_1(o)\n            m.print_myobject3_2(o)\n            m.print_myobject3_3(o)\n            m.print_myobject3_4(o)\n        assert capture == f\"MyObject3[{i}]\\n\" * 4\n\n    cstats = ConstructorStats.get(m.MyObject3)\n    assert cstats.alive() == 1\n    o = None\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"MyObject3[9]\", \"MyObject3[8]\", \"MyObject3[9]\"]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object\n    cstats = ConstructorStats.get(m.Object)\n    assert cstats.alive() == 0\n    assert cstats.values() == []\n    assert cstats.default_constructions == 10\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # ref<>\n    cstats = m.cstats_ref()\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"from pointer\"] * 10\n    assert cstats.default_constructions == 30\n    assert cstats.copy_constructions == 12\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 30\n    assert cstats.move_assignments == 0\n\n\ndef test_smart_ptr_refcounting():\n    assert m.test_object1_refcounting()\n\n\ndef test_unique_nodelete():\n    o = m.MyObject4(23)\n    assert o.value == 23\n    cstats = ConstructorStats.get(m.MyObject4)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 1\n    m.MyObject4.cleanup_all_instances()\n    assert cstats.alive() == 0\n\n\ndef test_unique_nodelete4a():\n    o = m.MyObject4a(23)\n    assert o.value == 23\n    cstats = ConstructorStats.get(m.MyObject4a)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 1\n    m.MyObject4a.cleanup_all_instances()\n    assert cstats.alive() == 0\n\n\ndef test_unique_deleter():\n    m.MyObject4a(0)\n    o = m.MyObject4b(23)\n    assert o.value == 23\n    cstats4a = ConstructorStats.get(m.MyObject4a)\n    assert cstats4a.alive() == 2\n    cstats4b = ConstructorStats.get(m.MyObject4b)\n    assert cstats4b.alive() == 1\n    del o\n    assert cstats4a.alive() == 1  # Should now only be one leftover\n    assert cstats4b.alive() == 0  # Should be deleted\n    m.MyObject4a.cleanup_all_instances()\n    assert cstats4a.alive() == 0\n    assert cstats4b.alive() == 0\n\n\ndef test_large_holder():\n    o = m.MyObject5(5)\n    assert o.value == 5\n    cstats = ConstructorStats.get(m.MyObject5)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 0\n\n\ndef test_shared_ptr_and_references():\n    s = m.SharedPtrRef()\n    stats = ConstructorStats.get(m.A)\n    assert stats.alive() == 2\n\n    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false)\n    assert stats.alive() == 2\n    assert s.set_ref(ref)\n    with pytest.raises(RuntimeError) as excinfo:\n        assert s.set_holder(ref)\n    assert \"Unable to cast from non-held to held instance\" in str(excinfo.value)\n\n    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true)\n    assert stats.alive() == 3\n    assert s.set_ref(copy)\n    assert s.set_holder(copy)\n\n    holder_ref = s.holder_ref  # init_holder_helper(holder_ptr=true, owned=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_ref)\n    assert s.set_holder(holder_ref)\n\n    holder_copy = s.holder_copy  # init_holder_helper(holder_ptr=true, owned=true)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_copy)\n    assert s.set_holder(holder_copy)\n\n    del ref, copy, holder_ref, holder_copy, s\n    assert stats.alive() == 0\n\n\ndef test_shared_ptr_from_this_and_references():\n    s = m.SharedFromThisRef()\n    stats = ConstructorStats.get(m.B)\n    assert stats.alive() == 2\n\n    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)\n    assert stats.alive() == 2\n    assert s.set_ref(ref)\n    assert s.set_holder(\n        ref\n    )  # std::enable_shared_from_this can create a holder from a reference\n\n    bad_wp = s.bad_wp  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)\n    assert stats.alive() == 2\n    assert s.set_ref(bad_wp)\n    with pytest.raises(RuntimeError) as excinfo:\n        assert s.set_holder(bad_wp)\n    assert \"Unable to cast from non-held to held instance\" in str(excinfo.value)\n\n    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(copy)\n    assert s.set_holder(copy)\n\n    holder_ref = (\n        s.holder_ref\n    )  # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_ref)\n    assert s.set_holder(holder_ref)\n\n    holder_copy = (\n        s.holder_copy\n    )  # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_copy)\n    assert s.set_holder(holder_copy)\n\n    del ref, bad_wp, copy, holder_ref, holder_copy, s\n    assert stats.alive() == 0\n\n    z = m.SharedFromThisVirt.get()\n    y = m.SharedFromThisVirt.get()\n    assert y is z\n\n\ndef test_move_only_holder():\n    a = m.TypeWithMoveOnlyHolder.make()\n    b = m.TypeWithMoveOnlyHolder.make_as_object()\n    stats = ConstructorStats.get(m.TypeWithMoveOnlyHolder)\n    assert stats.alive() == 2\n    del b\n    assert stats.alive() == 1\n    del a\n    assert stats.alive() == 0\n\n\ndef test_holder_with_addressof_operator():\n    # this test must not throw exception from c++\n    a = m.TypeForHolderWithAddressOf.make()\n    a.print_object_1()\n    a.print_object_2()\n    a.print_object_3()\n    a.print_object_4()\n\n    stats = ConstructorStats.get(m.TypeForHolderWithAddressOf)\n    assert stats.alive() == 1\n\n    np = m.TypeForHolderWithAddressOf.make()\n    assert stats.alive() == 2\n    del a\n    assert stats.alive() == 1\n    del np\n    assert stats.alive() == 0\n\n    b = m.TypeForHolderWithAddressOf.make()\n    c = b\n    assert b.get() is c.get()\n    assert stats.alive() == 1\n\n    del b\n    assert stats.alive() == 1\n\n    del c\n    assert stats.alive() == 0\n\n\ndef test_move_only_holder_with_addressof_operator():\n    a = m.TypeForMoveOnlyHolderWithAddressOf.make()\n    a.print_object()\n\n    stats = ConstructorStats.get(m.TypeForMoveOnlyHolderWithAddressOf)\n    assert stats.alive() == 1\n\n    a.value = 42\n    assert a.value == 42\n\n    del a\n    assert stats.alive() == 0\n\n\ndef test_smart_ptr_from_default():\n    instance = m.HeldByDefaultHolder()\n    with pytest.raises(RuntimeError) as excinfo:\n        m.HeldByDefaultHolder.load_shared_ptr(instance)\n    assert (\n        \"Unable to load a custom holder type from a \"\n        \"default-holder instance\" in str(excinfo.value)\n    )\n\n\ndef test_shared_ptr_gc():\n    \"\"\"#187: issue involving std::shared_ptr<> return value policy & garbage collection\"\"\"\n    el = m.ElementList()\n    for i in range(10):\n        el.add(m.ElementA(i))\n    pytest.gc_collect()\n    for i, v in enumerate(el.get()):\n        assert i == v.value()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_stl.cpp",
    "content": "/*\n    tests/test_stl.cpp -- STL type casters\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#ifndef PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL\n#    define PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL\n#endif\n#include <pybind11/stl/filesystem.h>\n\n#include <string>\n#include <vector>\n\n#if defined(PYBIND11_TEST_BOOST)\n#    include <boost/optional.hpp>\n\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <typename T>\nstruct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};\n\ntemplate <>\nstruct type_caster<boost::none_t> : void_caster<boost::none_t> {};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n#endif\n\n// Test with `std::variant` in C++17 mode, or with `boost::variant` in C++11/14\n#if defined(PYBIND11_HAS_VARIANT)\nusing std::variant;\n#    define PYBIND11_TEST_VARIANT 1\n#elif defined(PYBIND11_TEST_BOOST)\n#    include <boost/variant.hpp>\n#    define PYBIND11_TEST_VARIANT 1\nusing boost::variant;\n\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <typename... Ts>\nstruct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};\n\ntemplate <>\nstruct visit_helper<boost::variant> {\n    template <typename... Args>\n    static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {\n        return boost::apply_visitor(args...);\n    }\n};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n#endif\n\nPYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);\n\n/// Issue #528: templated constructor\nstruct TplCtorClass {\n    template <typename T>\n    explicit TplCtorClass(const T &) {}\n    bool operator==(const TplCtorClass &) const { return true; }\n};\n\nnamespace std {\ntemplate <>\nstruct hash<TplCtorClass> {\n    size_t operator()(const TplCtorClass &) const { return 0; }\n};\n} // namespace std\n\ntemplate <template <typename> class OptionalImpl, typename T>\nstruct OptionalHolder {\n    // NOLINTNEXTLINE(modernize-use-equals-default): breaks GCC 4.8\n    OptionalHolder(){};\n    bool member_initialized() const { return member && member->initialized; }\n    OptionalImpl<T> member = T{};\n};\n\nenum class EnumType {\n    kSet = 42,\n    kUnset = 85,\n};\n\n// This is used to test that return-by-ref and return-by-copy policies are\n// handled properly for optional types. This is a regression test for a dangling\n// reference issue. The issue seemed to require the enum value type to\n// reproduce - it didn't seem to happen if the value type is just an integer.\ntemplate <template <typename> class OptionalImpl>\nclass OptionalProperties {\npublic:\n    using OptionalEnumValue = OptionalImpl<EnumType>;\n\n    OptionalProperties() : value(EnumType::kSet) {}\n    ~OptionalProperties() {\n        // Reset value to detect use-after-destruction.\n        // This is set to a specific value rather than nullopt to ensure that\n        // the memory that contains the value gets re-written.\n        value = EnumType::kUnset;\n    }\n\n    OptionalEnumValue &access_by_ref() { return value; }\n    OptionalEnumValue access_by_copy() { return value; }\n\nprivate:\n    OptionalEnumValue value;\n};\n\n// This type mimics aspects of boost::optional from old versions of Boost,\n// which exposed a dangling reference bug in Pybind11. Recent versions of\n// boost::optional, as well as libstdc++'s std::optional, don't seem to be\n// affected by the same issue. This is meant to be a minimal implementation\n// required to reproduce the issue, not fully standard-compliant.\n// See issue #3330 for more details.\ntemplate <typename T>\nclass ReferenceSensitiveOptional {\npublic:\n    using value_type = T;\n\n    ReferenceSensitiveOptional() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    ReferenceSensitiveOptional(const T &value) : storage{value} {}\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    ReferenceSensitiveOptional(T &&value) : storage{std::move(value)} {}\n    ReferenceSensitiveOptional &operator=(const T &value) {\n        storage = {value};\n        return *this;\n    }\n    ReferenceSensitiveOptional &operator=(T &&value) {\n        storage = {std::move(value)};\n        return *this;\n    }\n\n    template <typename... Args>\n    T &emplace(Args &&...args) {\n        storage.clear();\n        storage.emplace_back(std::forward<Args>(args)...);\n        return storage.back();\n    }\n\n    const T &value() const noexcept {\n        assert(!storage.empty());\n        return storage[0];\n    }\n\n    const T &operator*() const noexcept { return value(); }\n\n    const T *operator->() const noexcept { return &value(); }\n\n    explicit operator bool() const noexcept { return !storage.empty(); }\n\nprivate:\n    std::vector<T> storage;\n};\n\nnamespace PYBIND11_NAMESPACE {\nnamespace detail {\ntemplate <typename T>\nstruct type_caster<ReferenceSensitiveOptional<T>>\n    : optional_caster<ReferenceSensitiveOptional<T>> {};\n} // namespace detail\n} // namespace PYBIND11_NAMESPACE\n\nTEST_SUBMODULE(stl, m) {\n    // test_vector\n    m.def(\"cast_vector\", []() { return std::vector<int>{1}; });\n    m.def(\"load_vector\", [](const std::vector<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });\n    // `std::vector<bool>` is special because it returns proxy objects instead of references\n    m.def(\"cast_bool_vector\", []() { return std::vector<bool>{true, false}; });\n    m.def(\"load_bool_vector\",\n          [](const std::vector<bool> &v) { return v.at(0) == true && v.at(1) == false; });\n    // Unnumbered regression (caused by #936): pointers to stl containers aren't castable\n    m.def(\n        \"cast_ptr_vector\",\n        []() {\n            // Using no-destructor idiom to side-step warnings from overzealous compilers.\n            static auto *v = new std::vector<RValueCaster>{2};\n            return v;\n        },\n        py::return_value_policy::reference);\n\n    // test_deque\n    m.def(\"cast_deque\", []() { return std::deque<int>{1}; });\n    m.def(\"load_deque\", [](const std::deque<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });\n\n    // test_array\n    m.def(\"cast_array\", []() { return std::array<int, 2>{{1, 2}}; });\n    m.def(\"load_array\", [](const std::array<int, 2> &a) { return a[0] == 1 && a[1] == 2; });\n\n    // test_valarray\n    m.def(\"cast_valarray\", []() { return std::valarray<int>{1, 4, 9}; });\n    m.def(\"load_valarray\", [](const std::valarray<int> &v) {\n        return v.size() == 3 && v[0] == 1 && v[1] == 4 && v[2] == 9;\n    });\n\n    // test_map\n    m.def(\"cast_map\", []() { return std::map<std::string, std::string>{{\"key\", \"value\"}}; });\n    m.def(\"load_map\", [](const std::map<std::string, std::string> &map) {\n        return map.at(\"key\") == \"value\" && map.at(\"key2\") == \"value2\";\n    });\n\n    // test_set\n    m.def(\"cast_set\", []() { return std::set<std::string>{\"key1\", \"key2\"}; });\n    m.def(\"load_set\", [](const std::set<std::string> &set) {\n        return (set.count(\"key1\") != 0u) && (set.count(\"key2\") != 0u) && (set.count(\"key3\") != 0u);\n    });\n\n    // test_recursive_casting\n    m.def(\"cast_rv_vector\", []() { return std::vector<RValueCaster>{2}; });\n    m.def(\"cast_rv_array\", []() { return std::array<RValueCaster, 3>(); });\n    // NB: map and set keys are `const`, so while we technically do move them (as `const Type &&`),\n    // casters don't typically do anything with that, which means they fall to the `const Type &`\n    // caster.\n    m.def(\"cast_rv_map\", []() {\n        return std::unordered_map<std::string, RValueCaster>{{\"a\", RValueCaster{}}};\n    });\n    m.def(\"cast_rv_nested\", []() {\n        std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;\n        v.emplace_back();           // add an array\n        v.back()[0].emplace_back(); // add a map to the array\n        v.back()[0].back().emplace(\"b\", RValueCaster{});\n        v.back()[0].back().emplace(\"c\", RValueCaster{});\n        v.back()[1].emplace_back(); // add a map to the array\n        v.back()[1].back().emplace(\"a\", RValueCaster{});\n        return v;\n    });\n    static std::array<RValueCaster, 2> lva;\n    static std::unordered_map<std::string, RValueCaster> lvm{{\"a\", RValueCaster{}},\n                                                             {\"b\", RValueCaster{}}};\n    static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>>\n        lvn;\n    lvn[\"a\"].emplace_back();        // add a list\n    lvn[\"a\"].back().emplace_back(); // add an array\n    lvn[\"a\"].emplace_back();        // another list\n    lvn[\"a\"].back().emplace_back(); // add an array\n    lvn[\"b\"].emplace_back();        // add a list\n    lvn[\"b\"].back().emplace_back(); // add an array\n    lvn[\"b\"].back().emplace_back(); // add another array\n    static std::vector<RValueCaster> lvv{2};\n    m.def(\"cast_lv_vector\", []() -> const decltype(lvv) & { return lvv; });\n    m.def(\"cast_lv_array\", []() -> const decltype(lva) & { return lva; });\n    m.def(\"cast_lv_map\", []() -> const decltype(lvm) & { return lvm; });\n    m.def(\"cast_lv_nested\", []() -> const decltype(lvn) & { return lvn; });\n    // #853:\n    m.def(\"cast_unique_ptr_vector\", []() {\n        std::vector<std::unique_ptr<UserType>> v;\n        v.emplace_back(new UserType{7});\n        v.emplace_back(new UserType{42});\n        return v;\n    });\n\n    pybind11::enum_<EnumType>(m, \"EnumType\")\n        .value(\"kSet\", EnumType::kSet)\n        .value(\"kUnset\", EnumType::kUnset);\n\n    // test_move_out_container\n    struct MoveOutContainer {\n        struct Value {\n            int value;\n        };\n        std::list<Value> move_list() const { return {{0}, {1}, {2}}; }\n    };\n    py::class_<MoveOutContainer::Value>(m, \"MoveOutContainerValue\")\n        .def_readonly(\"value\", &MoveOutContainer::Value::value);\n    py::class_<MoveOutContainer>(m, \"MoveOutContainer\")\n        .def(py::init<>())\n        .def_property_readonly(\"move_list\", &MoveOutContainer::move_list);\n\n    // Class that can be move- and copy-constructed, but not assigned\n    struct NoAssign {\n        int value;\n\n        explicit NoAssign(int value = 0) : value(value) {}\n        NoAssign(const NoAssign &) = default;\n        NoAssign(NoAssign &&) = default;\n\n        NoAssign &operator=(const NoAssign &) = delete;\n        NoAssign &operator=(NoAssign &&) = delete;\n    };\n    py::class_<NoAssign>(m, \"NoAssign\", \"Class with no C++ assignment operators\")\n        .def(py::init<>())\n        .def(py::init<int>());\n\n    struct MoveOutDetector {\n        MoveOutDetector() = default;\n        MoveOutDetector(const MoveOutDetector &) = default;\n        MoveOutDetector(MoveOutDetector &&other) noexcept : initialized(other.initialized) {\n            // steal underlying resource\n            other.initialized = false;\n        }\n        bool initialized = true;\n    };\n    py::class_<MoveOutDetector>(m, \"MoveOutDetector\", \"Class with move tracking\")\n        .def(py::init<>())\n        .def_readonly(\"initialized\", &MoveOutDetector::initialized);\n\n#ifdef PYBIND11_HAS_OPTIONAL\n    // test_optional\n    m.attr(\"has_optional\") = true;\n\n    using opt_int = std::optional<int>;\n    using opt_no_assign = std::optional<NoAssign>;\n    m.def(\"double_or_zero\", [](const opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none\", [](int x) -> opt_int { return x != 0 ? opt_int(x / 2) : opt_int(); });\n    m.def(\n        \"test_nullopt\",\n        [](opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", std::nullopt, \"None\"));\n    m.def(\n        \"test_no_assign\",\n        [](const opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", std::nullopt, \"None\"));\n\n    m.def(\"nodefer_none_optional\", [](std::optional<int>) { return true; });\n    m.def(\"nodefer_none_optional\", [](const py::none &) { return false; });\n\n    using opt_holder = OptionalHolder<std::optional, MoveOutDetector>;\n    py::class_<opt_holder>(m, \"OptionalHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_holder::member)\n        .def(\"member_initialized\", &opt_holder::member_initialized);\n\n    using opt_props = OptionalProperties<std::optional>;\n    pybind11::class_<opt_props>(m, \"OptionalProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_props::access_by_copy);\n#endif\n\n#ifdef PYBIND11_HAS_EXP_OPTIONAL\n    // test_exp_optional\n    m.attr(\"has_exp_optional\") = true;\n\n    using exp_opt_int = std::experimental::optional<int>;\n    using exp_opt_no_assign = std::experimental::optional<NoAssign>;\n    m.def(\"double_or_zero_exp\", [](const exp_opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none_exp\",\n          [](int x) -> exp_opt_int { return x ? exp_opt_int(x / 2) : exp_opt_int(); });\n    m.def(\n        \"test_nullopt_exp\",\n        [](exp_opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", std::experimental::nullopt, \"None\"));\n    m.def(\n        \"test_no_assign_exp\",\n        [](const exp_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", std::experimental::nullopt, \"None\"));\n\n    using opt_exp_holder = OptionalHolder<std::experimental::optional, MoveOutDetector>;\n    py::class_<opt_exp_holder>(m, \"OptionalExpHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_exp_holder::member)\n        .def(\"member_initialized\", &opt_exp_holder::member_initialized);\n\n    using opt_exp_props = OptionalProperties<std::experimental::optional>;\n    pybind11::class_<opt_exp_props>(m, \"OptionalExpProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_exp_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_exp_props::access_by_copy);\n#endif\n\n#if defined(PYBIND11_TEST_BOOST)\n    // test_boost_optional\n    m.attr(\"has_boost_optional\") = true;\n\n    using boost_opt_int = boost::optional<int>;\n    using boost_opt_no_assign = boost::optional<NoAssign>;\n    m.def(\"double_or_zero_boost\", [](const boost_opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none_boost\",\n          [](int x) -> boost_opt_int { return x != 0 ? boost_opt_int(x / 2) : boost_opt_int(); });\n    m.def(\n        \"test_nullopt_boost\",\n        [](boost_opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", boost::none, \"None\"));\n    m.def(\n        \"test_no_assign_boost\",\n        [](const boost_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", boost::none, \"None\"));\n\n    using opt_boost_holder = OptionalHolder<boost::optional, MoveOutDetector>;\n    py::class_<opt_boost_holder>(m, \"OptionalBoostHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_boost_holder::member)\n        .def(\"member_initialized\", &opt_boost_holder::member_initialized);\n\n    using opt_boost_props = OptionalProperties<boost::optional>;\n    pybind11::class_<opt_boost_props>(m, \"OptionalBoostProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_boost_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_boost_props::access_by_copy);\n#endif\n\n    // test_refsensitive_optional\n    using refsensitive_opt_int = ReferenceSensitiveOptional<int>;\n    using refsensitive_opt_no_assign = ReferenceSensitiveOptional<NoAssign>;\n    m.def(\"double_or_zero_refsensitive\",\n          [](const refsensitive_opt_int &x) -> int { return (x ? x.value() : 0) * 2; });\n    m.def(\"half_or_none_refsensitive\", [](int x) -> refsensitive_opt_int {\n        return x != 0 ? refsensitive_opt_int(x / 2) : refsensitive_opt_int();\n    });\n    m.def(\n        \"test_nullopt_refsensitive\",\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        [](refsensitive_opt_int x) { return x ? x.value() : 42; },\n        py::arg_v(\"x\", refsensitive_opt_int(), \"None\"));\n    m.def(\n        \"test_no_assign_refsensitive\",\n        [](const refsensitive_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", refsensitive_opt_no_assign(), \"None\"));\n\n    using opt_refsensitive_holder = OptionalHolder<ReferenceSensitiveOptional, MoveOutDetector>;\n    py::class_<opt_refsensitive_holder>(\n        m, \"OptionalRefSensitiveHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_refsensitive_holder::member)\n        .def(\"member_initialized\", &opt_refsensitive_holder::member_initialized);\n\n    using opt_refsensitive_props = OptionalProperties<ReferenceSensitiveOptional>;\n    pybind11::class_<opt_refsensitive_props>(m, \"OptionalRefSensitiveProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_refsensitive_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_refsensitive_props::access_by_copy);\n\n#ifdef PYBIND11_HAS_FILESYSTEM\n    // test_fs_path\n    m.attr(\"has_filesystem\") = true;\n    m.def(\"parent_path\", [](const std::filesystem::path &p) { return p.parent_path(); });\n#endif\n\n#ifdef PYBIND11_TEST_VARIANT\n    static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,\n                  \"visitor::result_type is required by boost::variant in C++11 mode\");\n\n    struct visitor {\n        using result_type = const char *;\n\n        result_type operator()(int) { return \"int\"; }\n        result_type operator()(const std::string &) { return \"std::string\"; }\n        result_type operator()(double) { return \"double\"; }\n        result_type operator()(std::nullptr_t) { return \"std::nullptr_t\"; }\n#    if defined(PYBIND11_HAS_VARIANT)\n        result_type operator()(std::monostate) { return \"std::monostate\"; }\n#    endif\n    };\n\n    // test_variant\n    m.def(\"load_variant\", [](const variant<int, std::string, double, std::nullptr_t> &v) {\n        return py::detail::visit_helper<variant>::call(visitor(), v);\n    });\n    m.def(\"load_variant_2pass\", [](variant<double, int> v) {\n        return py::detail::visit_helper<variant>::call(visitor(), v);\n    });\n    m.def(\"cast_variant\", []() {\n        using V = variant<int, std::string>;\n        return py::make_tuple(V(5), V(\"Hello\"));\n    });\n\n#    if defined(PYBIND11_HAS_VARIANT)\n    // std::monostate tests.\n    m.def(\"load_monostate_variant\",\n          [](const variant<std::monostate, int, std::string> &v) -> const char * {\n              return py::detail::visit_helper<variant>::call(visitor(), v);\n          });\n    m.def(\"cast_monostate_variant\", []() {\n        using V = variant<std::monostate, int, std::string>;\n        return py::make_tuple(V{}, V(5), V(\"Hello\"));\n    });\n#    endif\n#endif\n\n    // #528: templated constructor\n    // (no python tests: the test here is that this compiles)\n    m.def(\"tpl_ctor_vector\", [](std::vector<TplCtorClass> &) {});\n    m.def(\"tpl_ctor_map\", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});\n    m.def(\"tpl_ctor_set\", [](std::unordered_set<TplCtorClass> &) {});\n#if defined(PYBIND11_HAS_OPTIONAL)\n    m.def(\"tpl_constr_optional\", [](std::optional<TplCtorClass> &) {});\n#endif\n#if defined(PYBIND11_HAS_EXP_OPTIONAL)\n    m.def(\"tpl_constr_optional_exp\", [](std::experimental::optional<TplCtorClass> &) {});\n#endif\n#if defined(PYBIND11_TEST_BOOST)\n    m.def(\"tpl_constr_optional_boost\", [](boost::optional<TplCtorClass> &) {});\n#endif\n\n    // test_vec_of_reference_wrapper\n    // #171: Can't return STL structures containing reference wrapper\n    m.def(\"return_vec_of_reference_wrapper\", [](std::reference_wrapper<UserType> p4) {\n        static UserType p1{1}, p2{2}, p3{3};\n        return std::vector<std::reference_wrapper<UserType>>{\n            std::ref(p1), std::ref(p2), std::ref(p3), p4};\n    });\n\n    // test_stl_pass_by_pointer\n    m.def(\n        \"stl_pass_by_pointer\", [](std::vector<int> *v) { return *v; }, \"v\"_a = nullptr);\n\n    // #1258: pybind11/stl.h converts string to vector<string>\n    m.def(\"func_with_string_or_vector_string_arg_overload\",\n          [](const std::vector<std::string> &) { return 1; });\n    m.def(\"func_with_string_or_vector_string_arg_overload\",\n          [](const std::list<std::string> &) { return 2; });\n    m.def(\"func_with_string_or_vector_string_arg_overload\", [](const std::string &) { return 3; });\n\n    class Placeholder {\n    public:\n        Placeholder() { print_created(this); }\n        Placeholder(const Placeholder &) = delete;\n        ~Placeholder() { print_destroyed(this); }\n    };\n    py::class_<Placeholder>(m, \"Placeholder\");\n\n    /// test_stl_vector_ownership\n    m.def(\n        \"test_stl_ownership\",\n        []() {\n            std::vector<Placeholder *> result;\n            result.push_back(new Placeholder());\n            return result;\n        },\n        py::return_value_policy::take_ownership);\n\n    m.def(\"array_cast_sequence\", [](std::array<int, 3> x) { return x; });\n\n    /// test_issue_1561\n    struct Issue1561Inner {\n        std::string data;\n    };\n    struct Issue1561Outer {\n        std::vector<Issue1561Inner> list;\n    };\n\n    py::class_<Issue1561Inner>(m, \"Issue1561Inner\")\n        .def(py::init<std::string>())\n        .def_readwrite(\"data\", &Issue1561Inner::data);\n\n    py::class_<Issue1561Outer>(m, \"Issue1561Outer\")\n        .def(py::init<>())\n        .def_readwrite(\"list\", &Issue1561Outer::list);\n\n    m.def(\n        \"return_vector_bool_raw_ptr\",\n        []() { return new std::vector<bool>(4513); },\n        // Without explicitly specifying `take_ownership`, this function leaks.\n        py::return_value_policy::take_ownership);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_stl.py",
    "content": "import pytest\n\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import stl as m\n\n\ndef test_vector(doc):\n    \"\"\"std::vector <-> list\"\"\"\n    lst = m.cast_vector()\n    assert lst == [1]\n    lst.append(2)\n    assert m.load_vector(lst)\n    assert m.load_vector(tuple(lst))\n\n    assert m.cast_bool_vector() == [True, False]\n    assert m.load_bool_vector([True, False])\n    assert m.load_bool_vector(tuple([True, False]))\n\n    assert doc(m.cast_vector) == \"cast_vector() -> List[int]\"\n    assert doc(m.load_vector) == \"load_vector(arg0: List[int]) -> bool\"\n\n    # Test regression caused by 936: pointers to stl containers weren't castable\n    assert m.cast_ptr_vector() == [\"lvalue\", \"lvalue\"]\n\n\ndef test_deque(doc):\n    \"\"\"std::deque <-> list\"\"\"\n    lst = m.cast_deque()\n    assert lst == [1]\n    lst.append(2)\n    assert m.load_deque(lst)\n    assert m.load_deque(tuple(lst))\n\n\ndef test_array(doc):\n    \"\"\"std::array <-> list\"\"\"\n    lst = m.cast_array()\n    assert lst == [1, 2]\n    assert m.load_array(lst)\n    assert m.load_array(tuple(lst))\n\n    assert doc(m.cast_array) == \"cast_array() -> List[int[2]]\"\n    assert doc(m.load_array) == \"load_array(arg0: List[int[2]]) -> bool\"\n\n\ndef test_valarray(doc):\n    \"\"\"std::valarray <-> list\"\"\"\n    lst = m.cast_valarray()\n    assert lst == [1, 4, 9]\n    assert m.load_valarray(lst)\n    assert m.load_valarray(tuple(lst))\n\n    assert doc(m.cast_valarray) == \"cast_valarray() -> List[int]\"\n    assert doc(m.load_valarray) == \"load_valarray(arg0: List[int]) -> bool\"\n\n\ndef test_map(doc):\n    \"\"\"std::map <-> dict\"\"\"\n    d = m.cast_map()\n    assert d == {\"key\": \"value\"}\n    assert \"key\" in d\n    d[\"key2\"] = \"value2\"\n    assert \"key2\" in d\n    assert m.load_map(d)\n\n    assert doc(m.cast_map) == \"cast_map() -> Dict[str, str]\"\n    assert doc(m.load_map) == \"load_map(arg0: Dict[str, str]) -> bool\"\n\n\ndef test_set(doc):\n    \"\"\"std::set <-> set\"\"\"\n    s = m.cast_set()\n    assert s == {\"key1\", \"key2\"}\n    s.add(\"key3\")\n    assert m.load_set(s)\n    assert m.load_set(frozenset(s))\n\n    assert doc(m.cast_set) == \"cast_set() -> Set[str]\"\n    assert doc(m.load_set) == \"load_set(arg0: Set[str]) -> bool\"\n\n\ndef test_recursive_casting():\n    \"\"\"Tests that stl casters preserve lvalue/rvalue context for container values\"\"\"\n    assert m.cast_rv_vector() == [\"rvalue\", \"rvalue\"]\n    assert m.cast_lv_vector() == [\"lvalue\", \"lvalue\"]\n    assert m.cast_rv_array() == [\"rvalue\", \"rvalue\", \"rvalue\"]\n    assert m.cast_lv_array() == [\"lvalue\", \"lvalue\"]\n    assert m.cast_rv_map() == {\"a\": \"rvalue\"}\n    assert m.cast_lv_map() == {\"a\": \"lvalue\", \"b\": \"lvalue\"}\n    assert m.cast_rv_nested() == [[[{\"b\": \"rvalue\", \"c\": \"rvalue\"}], [{\"a\": \"rvalue\"}]]]\n    assert m.cast_lv_nested() == {\n        \"a\": [[[\"lvalue\", \"lvalue\"]], [[\"lvalue\", \"lvalue\"]]],\n        \"b\": [[[\"lvalue\", \"lvalue\"], [\"lvalue\", \"lvalue\"]]],\n    }\n\n    # Issue #853 test case:\n    z = m.cast_unique_ptr_vector()\n    assert z[0].value == 7 and z[1].value == 42\n\n\ndef test_move_out_container():\n    \"\"\"Properties use the `reference_internal` policy by default. If the underlying function\n    returns an rvalue, the policy is automatically changed to `move` to avoid referencing\n    a temporary. In case the return value is a container of user-defined types, the policy\n    also needs to be applied to the elements, not just the container.\"\"\"\n    c = m.MoveOutContainer()\n    moved_out_list = c.move_list\n    assert [x.value for x in moved_out_list] == [0, 1, 2]\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_optional\"), reason=\"no <optional>\")\ndef test_optional():\n    assert m.double_or_zero(None) == 0\n    assert m.double_or_zero(42) == 84\n    pytest.raises(TypeError, m.double_or_zero, \"foo\")\n\n    assert m.half_or_none(0) is None\n    assert m.half_or_none(42) == 21\n    pytest.raises(TypeError, m.half_or_none, \"foo\")\n\n    assert m.test_nullopt() == 42\n    assert m.test_nullopt(None) == 42\n    assert m.test_nullopt(42) == 42\n    assert m.test_nullopt(43) == 43\n\n    assert m.test_no_assign() == 42\n    assert m.test_no_assign(None) == 42\n    assert m.test_no_assign(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign, 43)\n\n    assert m.nodefer_none_optional(None)\n\n    holder = m.OptionalHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(\n    not hasattr(m, \"has_exp_optional\"), reason=\"no <experimental/optional>\"\n)\ndef test_exp_optional():\n    assert m.double_or_zero_exp(None) == 0\n    assert m.double_or_zero_exp(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_exp, \"foo\")\n\n    assert m.half_or_none_exp(0) is None\n    assert m.half_or_none_exp(42) == 21\n    pytest.raises(TypeError, m.half_or_none_exp, \"foo\")\n\n    assert m.test_nullopt_exp() == 42\n    assert m.test_nullopt_exp(None) == 42\n    assert m.test_nullopt_exp(42) == 42\n    assert m.test_nullopt_exp(43) == 43\n\n    assert m.test_no_assign_exp() == 42\n    assert m.test_no_assign_exp(None) == 42\n    assert m.test_no_assign_exp(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_exp, 43)\n\n    holder = m.OptionalExpHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalExpProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_boost_optional\"), reason=\"no <boost/optional>\")\ndef test_boost_optional():\n    assert m.double_or_zero_boost(None) == 0\n    assert m.double_or_zero_boost(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_boost, \"foo\")\n\n    assert m.half_or_none_boost(0) is None\n    assert m.half_or_none_boost(42) == 21\n    pytest.raises(TypeError, m.half_or_none_boost, \"foo\")\n\n    assert m.test_nullopt_boost() == 42\n    assert m.test_nullopt_boost(None) == 42\n    assert m.test_nullopt_boost(42) == 42\n    assert m.test_nullopt_boost(43) == 43\n\n    assert m.test_no_assign_boost() == 42\n    assert m.test_no_assign_boost(None) == 42\n    assert m.test_no_assign_boost(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_boost, 43)\n\n    holder = m.OptionalBoostHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalBoostProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\ndef test_reference_sensitive_optional():\n    assert m.double_or_zero_refsensitive(None) == 0\n    assert m.double_or_zero_refsensitive(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_refsensitive, \"foo\")\n\n    assert m.half_or_none_refsensitive(0) is None\n    assert m.half_or_none_refsensitive(42) == 21\n    pytest.raises(TypeError, m.half_or_none_refsensitive, \"foo\")\n\n    assert m.test_nullopt_refsensitive() == 42\n    assert m.test_nullopt_refsensitive(None) == 42\n    assert m.test_nullopt_refsensitive(42) == 42\n    assert m.test_nullopt_refsensitive(43) == 43\n\n    assert m.test_no_assign_refsensitive() == 42\n    assert m.test_no_assign_refsensitive(None) == 42\n    assert m.test_no_assign_refsensitive(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_refsensitive, 43)\n\n    holder = m.OptionalRefSensitiveHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalRefSensitiveProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_filesystem\"), reason=\"no <filesystem>\")\ndef test_fs_path():\n    from pathlib import Path\n\n    class PseudoStrPath:\n        def __fspath__(self):\n            return \"foo/bar\"\n\n    class PseudoBytesPath:\n        def __fspath__(self):\n            return b\"foo/bar\"\n\n    assert m.parent_path(Path(\"foo/bar\")) == Path(\"foo\")\n    assert m.parent_path(\"foo/bar\") == Path(\"foo\")\n    assert m.parent_path(b\"foo/bar\") == Path(\"foo\")\n    assert m.parent_path(PseudoStrPath()) == Path(\"foo\")\n    assert m.parent_path(PseudoBytesPath()) == Path(\"foo\")\n\n\n@pytest.mark.skipif(not hasattr(m, \"load_variant\"), reason=\"no <variant>\")\ndef test_variant(doc):\n    assert m.load_variant(1) == \"int\"\n    assert m.load_variant(\"1\") == \"std::string\"\n    assert m.load_variant(1.0) == \"double\"\n    assert m.load_variant(None) == \"std::nullptr_t\"\n\n    assert m.load_variant_2pass(1) == \"int\"\n    assert m.load_variant_2pass(1.0) == \"double\"\n\n    assert m.cast_variant() == (5, \"Hello\")\n\n    assert (\n        doc(m.load_variant) == \"load_variant(arg0: Union[int, str, float, None]) -> str\"\n    )\n\n\n@pytest.mark.skipif(\n    not hasattr(m, \"load_monostate_variant\"), reason=\"no std::monostate\"\n)\ndef test_variant_monostate(doc):\n    assert m.load_monostate_variant(None) == \"std::monostate\"\n    assert m.load_monostate_variant(1) == \"int\"\n    assert m.load_monostate_variant(\"1\") == \"std::string\"\n\n    assert m.cast_monostate_variant() == (None, 5, \"Hello\")\n\n    assert (\n        doc(m.load_monostate_variant)\n        == \"load_monostate_variant(arg0: Union[None, int, str]) -> str\"\n    )\n\n\ndef test_vec_of_reference_wrapper():\n    \"\"\"#171: Can't return reference wrappers (or STL structures containing them)\"\"\"\n    assert (\n        str(m.return_vec_of_reference_wrapper(UserType(4)))\n        == \"[UserType(1), UserType(2), UserType(3), UserType(4)]\"\n    )\n\n\ndef test_stl_pass_by_pointer(msg):\n    \"\"\"Passing nullptr or None to an STL container pointer is not expected to work\"\"\"\n    with pytest.raises(TypeError) as excinfo:\n        m.stl_pass_by_pointer()  # default value is `nullptr`\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:\n            1. (v: List[int] = None) -> List[int]\n\n        Invoked with:\n    \"\"\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.stl_pass_by_pointer(None)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:\n            1. (v: List[int] = None) -> List[int]\n\n        Invoked with: None\n    \"\"\"\n    )\n\n    assert m.stl_pass_by_pointer([1, 2, 3]) == [1, 2, 3]\n\n\ndef test_missing_header_message():\n    \"\"\"Trying convert `list` to a `std::vector`, or vice versa, without including\n    <pybind11/stl.h> should result in a helpful suggestion in the error message\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    expected_message = (\n        \"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\\n\"\n        \"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\\n\"\n        \"conversions are optional and require extra headers to be included\\n\"\n        \"when compiling your pybind11 module.\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.missing_header_arg([1.0, 2.0, 3.0])\n    assert expected_message in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.missing_header_return()\n    assert expected_message in str(excinfo.value)\n\n\ndef test_function_with_string_and_vector_string_arg():\n    \"\"\"Check if a string is NOT implicitly converted to a list, which was the\n    behavior before fix of issue #1258\"\"\"\n    assert m.func_with_string_or_vector_string_arg_overload((\"A\", \"B\")) == 2\n    assert m.func_with_string_or_vector_string_arg_overload([\"A\", \"B\"]) == 2\n    assert m.func_with_string_or_vector_string_arg_overload(\"A\") == 3\n\n\ndef test_stl_ownership():\n    cstats = ConstructorStats.get(m.Placeholder)\n    assert cstats.alive() == 0\n    r = m.test_stl_ownership()\n    assert len(r) == 1\n    del r\n    assert cstats.alive() == 0\n\n\ndef test_array_cast_sequence():\n    assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]\n\n\ndef test_issue_1561():\n    \"\"\"check fix for issue #1561\"\"\"\n    bar = m.Issue1561Outer()\n    bar.list = [m.Issue1561Inner(\"bar\")]\n    bar.list\n    assert bar.list[0].data == \"bar\"\n\n\ndef test_return_vector_bool_raw_ptr():\n    # Add `while True:` for manual leak checking.\n    v = m.return_vector_bool_raw_ptr()\n    assert isinstance(v, list)\n    assert len(v) == 4513\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_stl_binders.cpp",
    "content": "/*\n    tests/test_stl_binders.cpp -- Usage of stl_binders functions\n\n    Copyright (c) 2016 Sergey Lyskov\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n#include <pybind11/stl_bind.h>\n\n#include \"pybind11_tests.h\"\n\n#include <deque>\n#include <map>\n#include <unordered_map>\n\nclass El {\npublic:\n    El() = delete;\n    explicit El(int v) : a(v) {}\n\n    int a;\n};\n\nstd::ostream &operator<<(std::ostream &s, El const &v) {\n    s << \"El{\" << v.a << '}';\n    return s;\n}\n\n/// Issue #487: binding std::vector<E> with E non-copyable\nclass E_nc {\npublic:\n    explicit E_nc(int i) : value{i} {}\n    E_nc(const E_nc &) = delete;\n    E_nc &operator=(const E_nc &) = delete;\n    E_nc(E_nc &&) = default;\n    E_nc &operator=(E_nc &&) = default;\n\n    int value;\n};\n\ntemplate <class Container>\nContainer *one_to_n(int n) {\n    auto *v = new Container();\n    for (int i = 1; i <= n; i++) {\n        v->emplace_back(i);\n    }\n    return v;\n}\n\ntemplate <class Map>\nMap *times_ten(int n) {\n    auto *m = new Map();\n    for (int i = 1; i <= n; i++) {\n        m->emplace(int(i), E_nc(10 * i));\n    }\n    return m;\n}\n\ntemplate <class NestMap>\nNestMap *times_hundred(int n) {\n    auto *m = new NestMap();\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= n; j++) {\n            (*m)[i].emplace(int(j * 10), E_nc(100 * j));\n        }\n    }\n    return m;\n}\n\nTEST_SUBMODULE(stl_binders, m) {\n    // test_vector_int\n    py::bind_vector<std::vector<unsigned int>>(m, \"VectorInt\", py::buffer_protocol());\n\n    // test_vector_custom\n    py::class_<El>(m, \"El\").def(py::init<int>());\n    py::bind_vector<std::vector<El>>(m, \"VectorEl\");\n    py::bind_vector<std::vector<std::vector<El>>>(m, \"VectorVectorEl\");\n\n    // test_map_string_double\n    py::bind_map<std::map<std::string, double>>(m, \"MapStringDouble\");\n    py::bind_map<std::unordered_map<std::string, double>>(m, \"UnorderedMapStringDouble\");\n\n    // test_map_string_double_const\n    py::bind_map<std::map<std::string, double const>>(m, \"MapStringDoubleConst\");\n    py::bind_map<std::unordered_map<std::string, double const>>(m,\n                                                                \"UnorderedMapStringDoubleConst\");\n\n    py::class_<E_nc>(m, \"ENC\").def(py::init<int>()).def_readwrite(\"value\", &E_nc::value);\n\n    // test_noncopyable_containers\n    py::bind_vector<std::vector<E_nc>>(m, \"VectorENC\");\n    m.def(\"get_vnc\", &one_to_n<std::vector<E_nc>>);\n    py::bind_vector<std::deque<E_nc>>(m, \"DequeENC\");\n    m.def(\"get_dnc\", &one_to_n<std::deque<E_nc>>);\n    py::bind_map<std::map<int, E_nc>>(m, \"MapENC\");\n    m.def(\"get_mnc\", &times_ten<std::map<int, E_nc>>);\n    py::bind_map<std::unordered_map<int, E_nc>>(m, \"UmapENC\");\n    m.def(\"get_umnc\", &times_ten<std::unordered_map<int, E_nc>>);\n    // Issue #1885: binding nested std::map<X, Container<E>> with E non-copyable\n    py::bind_map<std::map<int, std::vector<E_nc>>>(m, \"MapVecENC\");\n    m.def(\"get_nvnc\", [](int n) {\n        auto *m = new std::map<int, std::vector<E_nc>>();\n        for (int i = 1; i <= n; i++) {\n            for (int j = 1; j <= n; j++) {\n                (*m)[i].emplace_back(j);\n            }\n        }\n        return m;\n    });\n    py::bind_map<std::map<int, std::map<int, E_nc>>>(m, \"MapMapENC\");\n    m.def(\"get_nmnc\", &times_hundred<std::map<int, std::map<int, E_nc>>>);\n    py::bind_map<std::unordered_map<int, std::unordered_map<int, E_nc>>>(m, \"UmapUmapENC\");\n    m.def(\"get_numnc\", &times_hundred<std::unordered_map<int, std::unordered_map<int, E_nc>>>);\n\n    // test_vector_buffer\n    py::bind_vector<std::vector<unsigned char>>(m, \"VectorUChar\", py::buffer_protocol());\n    // no dtype declared for this version:\n    struct VUndeclStruct {\n        bool w;\n        uint32_t x;\n        double y;\n        bool z;\n    };\n    m.def(\"create_undeclstruct\", [m]() mutable {\n        py::bind_vector<std::vector<VUndeclStruct>>(\n            m, \"VectorUndeclStruct\", py::buffer_protocol());\n    });\n\n    // The rest depends on numpy:\n    try {\n        py::module_::import(\"numpy\");\n    } catch (...) {\n        return;\n    }\n\n    // test_vector_buffer_numpy\n    struct VStruct {\n        bool w;\n        uint32_t x;\n        double y;\n        bool z;\n    };\n    PYBIND11_NUMPY_DTYPE(VStruct, w, x, y, z);\n    py::class_<VStruct>(m, \"VStruct\").def_readwrite(\"x\", &VStruct::x);\n    py::bind_vector<std::vector<VStruct>>(m, \"VectorStruct\", py::buffer_protocol());\n    m.def(\"get_vectorstruct\", [] {\n        return std::vector<VStruct>{{false, 5, 3.0, true}, {true, 30, -1e4, false}};\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_stl_binders.py",
    "content": "import pytest\n\nfrom pybind11_tests import stl_binders as m\n\n\ndef test_vector_int():\n    v_int = m.VectorInt([0, 0])\n    assert len(v_int) == 2\n    assert bool(v_int) is True\n\n    # test construction from a generator\n    v_int1 = m.VectorInt(x for x in range(5))\n    assert v_int1 == m.VectorInt([0, 1, 2, 3, 4])\n\n    v_int2 = m.VectorInt([0, 0])\n    assert v_int == v_int2\n    v_int2[1] = 1\n    assert v_int != v_int2\n\n    v_int2.append(2)\n    v_int2.insert(0, 1)\n    v_int2.insert(0, 2)\n    v_int2.insert(0, 3)\n    v_int2.insert(6, 3)\n    assert str(v_int2) == \"VectorInt[3, 2, 1, 0, 1, 2, 3]\"\n    with pytest.raises(IndexError):\n        v_int2.insert(8, 4)\n\n    v_int.append(99)\n    v_int2[2:-2] = v_int\n    assert v_int2 == m.VectorInt([3, 2, 0, 0, 99, 2, 3])\n    del v_int2[1:3]\n    assert v_int2 == m.VectorInt([3, 0, 99, 2, 3])\n    del v_int2[0]\n    assert v_int2 == m.VectorInt([0, 99, 2, 3])\n\n    v_int2.extend(m.VectorInt([4, 5]))\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5])\n\n    v_int2.extend([6, 7])\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])\n\n    # test error handling, and that the vector is unchanged\n    with pytest.raises(RuntimeError):\n        v_int2.extend([8, \"a\"])\n\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])\n\n    # test extending from a generator\n    v_int2.extend(x for x in range(5))\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4])\n\n    # test negative indexing\n    assert v_int2[-1] == 4\n\n    # insert with negative index\n    v_int2.insert(-1, 88)\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88, 4])\n\n    # delete negative index\n    del v_int2[-1]\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88])\n\n    v_int2.clear()\n    assert len(v_int2) == 0\n\n\n# Older PyPy's failed here, related to the PyPy's buffer protocol.\ndef test_vector_buffer():\n    b = bytearray([1, 2, 3, 4])\n    v = m.VectorUChar(b)\n    assert v[1] == 2\n    v[2] = 5\n    mv = memoryview(v)  # We expose the buffer interface\n    assert mv[2] == 5\n    mv[2] = 6\n    assert v[2] == 6\n\n    mv = memoryview(b)\n    v = m.VectorUChar(mv[::2])\n    assert v[1] == 3\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.create_undeclstruct()  # Undeclared struct contents, no buffer interface\n    assert \"NumPy type info missing for \" in str(excinfo.value)\n\n\ndef test_vector_buffer_numpy():\n    np = pytest.importorskip(\"numpy\")\n    a = np.array([1, 2, 3, 4], dtype=np.int32)\n    with pytest.raises(TypeError):\n        m.VectorInt(a)\n\n    a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.uintc)\n    v = m.VectorInt(a[0, :])\n    assert len(v) == 4\n    assert v[2] == 3\n    ma = np.asarray(v)\n    ma[2] = 5\n    assert v[2] == 5\n\n    v = m.VectorInt(a[:, 1])\n    assert len(v) == 3\n    assert v[2] == 10\n\n    v = m.get_vectorstruct()\n    assert v[0].x == 5\n    ma = np.asarray(v)\n    ma[1][\"x\"] = 99\n    assert v[1].x == 99\n\n    v = m.VectorStruct(\n        np.zeros(\n            3,\n            dtype=np.dtype(\n                [(\"w\", \"bool\"), (\"x\", \"I\"), (\"y\", \"float64\"), (\"z\", \"bool\")], align=True\n            ),\n        )\n    )\n    assert len(v) == 3\n\n    b = np.array([1, 2, 3, 4], dtype=np.uint8)\n    v = m.VectorUChar(b[::2])\n    assert v[1] == 3\n\n\ndef test_vector_bool():\n    import pybind11_cross_module_tests as cm\n\n    vv_c = cm.VectorBool()\n    for i in range(10):\n        vv_c.append(i % 2 == 0)\n    for i in range(10):\n        assert vv_c[i] == (i % 2 == 0)\n    assert str(vv_c) == \"VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]\"\n\n\ndef test_vector_custom():\n    v_a = m.VectorEl()\n    v_a.append(m.El(1))\n    v_a.append(m.El(2))\n    assert str(v_a) == \"VectorEl[El{1}, El{2}]\"\n\n    vv_a = m.VectorVectorEl()\n    vv_a.append(v_a)\n    vv_b = vv_a[0]\n    assert str(vv_b) == \"VectorEl[El{1}, El{2}]\"\n\n\ndef test_map_string_double():\n    mm = m.MapStringDouble()\n    mm[\"a\"] = 1\n    mm[\"b\"] = 2.5\n\n    assert list(mm) == [\"a\", \"b\"]\n    assert str(mm) == \"MapStringDouble{a: 1, b: 2.5}\"\n    assert \"b\" in mm\n    assert \"c\" not in mm\n    assert 123 not in mm\n\n    # Check that keys, values, items are views, not merely iterable\n    keys = mm.keys()\n    values = mm.values()\n    items = mm.items()\n    assert list(keys) == [\"a\", \"b\"]\n    assert len(keys) == 2\n    assert \"a\" in keys\n    assert \"c\" not in keys\n    assert 123 not in keys\n    assert list(items) == [(\"a\", 1), (\"b\", 2.5)]\n    assert len(items) == 2\n    assert (\"b\", 2.5) in items\n    assert \"hello\" not in items\n    assert (\"b\", 2.5, None) not in items\n    assert list(values) == [1, 2.5]\n    assert len(values) == 2\n    assert 1 in values\n    assert 2 not in values\n    # Check that views update when the map is updated\n    mm[\"c\"] = -1\n    assert list(keys) == [\"a\", \"b\", \"c\"]\n    assert list(values) == [1, 2.5, -1]\n    assert list(items) == [(\"a\", 1), (\"b\", 2.5), (\"c\", -1)]\n\n    um = m.UnorderedMapStringDouble()\n    um[\"ua\"] = 1.1\n    um[\"ub\"] = 2.6\n\n    assert sorted(list(um)) == [\"ua\", \"ub\"]\n    assert list(um.keys()) == list(um)\n    assert sorted(list(um.items())) == [(\"ua\", 1.1), (\"ub\", 2.6)]\n    assert list(zip(um.keys(), um.values())) == list(um.items())\n    assert \"UnorderedMapStringDouble\" in str(um)\n\n\ndef test_map_string_double_const():\n    mc = m.MapStringDoubleConst()\n    mc[\"a\"] = 10\n    mc[\"b\"] = 20.5\n    assert str(mc) == \"MapStringDoubleConst{a: 10, b: 20.5}\"\n\n    umc = m.UnorderedMapStringDoubleConst()\n    umc[\"a\"] = 11\n    umc[\"b\"] = 21.5\n\n    str(umc)\n\n\ndef test_noncopyable_containers():\n    # std::vector\n    vnc = m.get_vnc(5)\n    for i in range(0, 5):\n        assert vnc[i].value == i + 1\n\n    for i, j in enumerate(vnc, start=1):\n        assert j.value == i\n\n    # std::deque\n    dnc = m.get_dnc(5)\n    for i in range(0, 5):\n        assert dnc[i].value == i + 1\n\n    i = 1\n    for j in dnc:\n        assert j.value == i\n        i += 1\n\n    # std::map\n    mnc = m.get_mnc(5)\n    for i in range(1, 6):\n        assert mnc[i].value == 10 * i\n\n    vsum = 0\n    for k, v in mnc.items():\n        assert v.value == 10 * k\n        vsum += v.value\n\n    assert vsum == 150\n\n    # std::unordered_map\n    mnc = m.get_umnc(5)\n    for i in range(1, 6):\n        assert mnc[i].value == 10 * i\n\n    vsum = 0\n    for k, v in mnc.items():\n        assert v.value == 10 * k\n        vsum += v.value\n\n    assert vsum == 150\n\n    # nested std::map<std::vector>\n    nvnc = m.get_nvnc(5)\n    for i in range(1, 6):\n        for j in range(0, 5):\n            assert nvnc[i][j].value == j + 1\n\n    # Note: maps do not have .values()\n    for _, v in nvnc.items():\n        for i, j in enumerate(v, start=1):\n            assert j.value == i\n\n    # nested std::map<std::map>\n    nmnc = m.get_nmnc(5)\n    for i in range(1, 6):\n        for j in range(10, 60, 10):\n            assert nmnc[i][j].value == 10 * j\n\n    vsum = 0\n    for _, v_o in nmnc.items():\n        for k_i, v_i in v_o.items():\n            assert v_i.value == 10 * k_i\n            vsum += v_i.value\n\n    assert vsum == 7500\n\n    # nested std::unordered_map<std::unordered_map>\n    numnc = m.get_numnc(5)\n    for i in range(1, 6):\n        for j in range(10, 60, 10):\n            assert numnc[i][j].value == 10 * j\n\n    vsum = 0\n    for _, v_o in numnc.items():\n        for k_i, v_i in v_o.items():\n            assert v_i.value == 10 * k_i\n            vsum += v_i.value\n\n    assert vsum == 7500\n\n\ndef test_map_delitem():\n    mm = m.MapStringDouble()\n    mm[\"a\"] = 1\n    mm[\"b\"] = 2.5\n\n    assert list(mm) == [\"a\", \"b\"]\n    assert list(mm.items()) == [(\"a\", 1), (\"b\", 2.5)]\n    del mm[\"a\"]\n    assert list(mm) == [\"b\"]\n    assert list(mm.items()) == [(\"b\", 2.5)]\n\n    um = m.UnorderedMapStringDouble()\n    um[\"ua\"] = 1.1\n    um[\"ub\"] = 2.6\n\n    assert sorted(list(um)) == [\"ua\", \"ub\"]\n    assert sorted(list(um.items())) == [(\"ua\", 1.1), (\"ub\", 2.6)]\n    del um[\"ua\"]\n    assert sorted(list(um)) == [\"ub\"]\n    assert sorted(list(um.items())) == [(\"ub\", 2.6)]\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_tagbased_polymorphic.cpp",
    "content": "/*\n    tests/test_tagbased_polymorphic.cpp -- test of polymorphic_type_hook\n\n    Copyright (c) 2018 Hudson River Trading LLC <opensource@hudson-trading.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\nstruct Animal {\n    // Make this type also a \"standard\" polymorphic type, to confirm that\n    // specializing polymorphic_type_hook using enable_if_t still works\n    // (https://github.com/pybind/pybind11/pull/2016/).\n    virtual ~Animal() = default;\n\n    // Enum for tag-based polymorphism.\n    enum class Kind {\n        Unknown = 0,\n        Dog = 100,\n        Labrador,\n        Chihuahua,\n        LastDog = 199,\n        Cat = 200,\n        Panther,\n        LastCat = 299\n    };\n    static const std::type_info *type_of_kind(Kind kind);\n    static std::string name_of_kind(Kind kind);\n\n    const Kind kind;\n    const std::string name;\n\nprotected:\n    Animal(const std::string &_name, Kind _kind) : kind(_kind), name(_name) {}\n};\n\nstruct Dog : Animal {\n    explicit Dog(const std::string &_name, Kind _kind = Kind::Dog) : Animal(_name, _kind) {}\n    std::string bark() const { return name_of_kind(kind) + \" \" + name + \" goes \" + sound; }\n    std::string sound = \"WOOF!\";\n};\n\nstruct Labrador : Dog {\n    explicit Labrador(const std::string &_name, int _excitement = 9001)\n        : Dog(_name, Kind::Labrador), excitement(_excitement) {}\n    int excitement;\n};\n\nstruct Chihuahua : Dog {\n    explicit Chihuahua(const std::string &_name) : Dog(_name, Kind::Chihuahua) {\n        sound = \"iyiyiyiyiyi\";\n    }\n    std::string bark() const { return Dog::bark() + \" and runs in circles\"; }\n};\n\nstruct Cat : Animal {\n    explicit Cat(const std::string &_name, Kind _kind = Kind::Cat) : Animal(_name, _kind) {}\n    std::string purr() const { return \"mrowr\"; }\n};\n\nstruct Panther : Cat {\n    explicit Panther(const std::string &_name) : Cat(_name, Kind::Panther) {}\n    std::string purr() const { return \"mrrrRRRRRR\"; }\n};\n\nstd::vector<std::unique_ptr<Animal>> create_zoo() {\n    std::vector<std::unique_ptr<Animal>> ret;\n    ret.emplace_back(new Labrador(\"Fido\", 15000));\n\n    // simulate some new type of Dog that the Python bindings\n    // haven't been updated for; it should still be considered\n    // a Dog, not just an Animal.\n    ret.emplace_back(new Dog(\"Ginger\", Dog::Kind(150)));\n\n    ret.emplace_back(new Chihuahua(\"Hertzl\"));\n    ret.emplace_back(new Cat(\"Tiger\", Cat::Kind::Cat));\n    ret.emplace_back(new Panther(\"Leo\"));\n    return ret;\n}\n\nconst std::type_info *Animal::type_of_kind(Kind kind) {\n    switch (kind) {\n        case Kind::Unknown:\n        case Kind::Dog:\n            break;\n\n        case Kind::Labrador:\n            return &typeid(Labrador);\n        case Kind::Chihuahua:\n            return &typeid(Chihuahua);\n\n        case Kind::LastDog:\n        case Kind::Cat:\n            break;\n        case Kind::Panther:\n            return &typeid(Panther);\n        case Kind::LastCat:\n            break;\n    }\n\n    if (kind >= Kind::Dog && kind <= Kind::LastDog) {\n        return &typeid(Dog);\n    }\n    if (kind >= Kind::Cat && kind <= Kind::LastCat) {\n        return &typeid(Cat);\n    }\n    return nullptr;\n}\n\nstd::string Animal::name_of_kind(Kind kind) {\n    std::string raw_name = type_of_kind(kind)->name();\n    py::detail::clean_type_id(raw_name);\n    return raw_name;\n}\n\nnamespace PYBIND11_NAMESPACE {\ntemplate <typename itype>\nstruct polymorphic_type_hook<itype, detail::enable_if_t<std::is_base_of<Animal, itype>::value>> {\n    static const void *get(const itype *src, const std::type_info *&type) {\n        type = src ? Animal::type_of_kind(src->kind) : nullptr;\n        return src;\n    }\n};\n} // namespace PYBIND11_NAMESPACE\n\nTEST_SUBMODULE(tagbased_polymorphic, m) {\n    py::class_<Animal>(m, \"Animal\").def_readonly(\"name\", &Animal::name);\n    py::class_<Dog, Animal>(m, \"Dog\")\n        .def(py::init<std::string>())\n        .def_readwrite(\"sound\", &Dog::sound)\n        .def(\"bark\", &Dog::bark);\n    py::class_<Labrador, Dog>(m, \"Labrador\")\n        .def(py::init<std::string, int>(), \"name\"_a, \"excitement\"_a = 9001)\n        .def_readwrite(\"excitement\", &Labrador::excitement);\n    py::class_<Chihuahua, Dog>(m, \"Chihuahua\")\n        .def(py::init<std::string>())\n        .def(\"bark\", &Chihuahua::bark);\n    py::class_<Cat, Animal>(m, \"Cat\").def(py::init<std::string>()).def(\"purr\", &Cat::purr);\n    py::class_<Panther, Cat>(m, \"Panther\")\n        .def(py::init<std::string>())\n        .def(\"purr\", &Panther::purr);\n    m.def(\"create_zoo\", &create_zoo);\n};\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_tagbased_polymorphic.py",
    "content": "from pybind11_tests import tagbased_polymorphic as m\n\n\ndef test_downcast():\n    zoo = m.create_zoo()\n    assert [type(animal) for animal in zoo] == [\n        m.Labrador,\n        m.Dog,\n        m.Chihuahua,\n        m.Cat,\n        m.Panther,\n    ]\n    assert [animal.name for animal in zoo] == [\n        \"Fido\",\n        \"Ginger\",\n        \"Hertzl\",\n        \"Tiger\",\n        \"Leo\",\n    ]\n    zoo[1].sound = \"woooooo\"\n    assert [dog.bark() for dog in zoo[:3]] == [\n        \"Labrador Fido goes WOOF!\",\n        \"Dog Ginger goes woooooo\",\n        \"Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles\",\n    ]\n    assert [cat.purr() for cat in zoo[3:]] == [\"mrowr\", \"mrrrRRRRRR\"]\n    zoo[0].excitement -= 1000\n    assert zoo[0].excitement == 14000\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_thread.cpp",
    "content": "/*\n    tests/test_thread.cpp -- call pybind11 bound methods in threads\n\n    Copyright (c) 2021 Laramie Leavitt (Google LLC) <lar@google.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/cast.h>\n#include <pybind11/pybind11.h>\n\n#include \"pybind11_tests.h\"\n\n#include <chrono>\n#include <thread>\n\nnamespace py = pybind11;\n\nnamespace {\n\nstruct IntStruct {\n    explicit IntStruct(int v) : value(v){};\n    ~IntStruct() { value = -value; }\n    IntStruct(const IntStruct &) = default;\n    IntStruct &operator=(const IntStruct &) = default;\n\n    int value;\n};\n\n} // namespace\n\nTEST_SUBMODULE(thread, m) {\n\n    py::class_<IntStruct>(m, \"IntStruct\").def(py::init([](const int i) { return IntStruct(i); }));\n\n    // implicitly_convertible uses loader_life_support when an implicit\n    // conversion is required in order to lifetime extend the reference.\n    //\n    // This test should be run with ASAN for better effectiveness.\n    py::implicitly_convertible<int, IntStruct>();\n\n    m.def(\"test\", [](int expected, const IntStruct &in) {\n        {\n            py::gil_scoped_release release;\n            std::this_thread::sleep_for(std::chrono::milliseconds(5));\n        }\n\n        if (in.value != expected) {\n            throw std::runtime_error(\"Value changed!!\");\n        }\n    });\n\n    m.def(\n        \"test_no_gil\",\n        [](int expected, const IntStruct &in) {\n            std::this_thread::sleep_for(std::chrono::milliseconds(5));\n            if (in.value != expected) {\n                throw std::runtime_error(\"Value changed!!\");\n            }\n        },\n        py::call_guard<py::gil_scoped_release>());\n\n    // NOTE: std::string_view also uses loader_life_support to ensure that\n    // the string contents remain alive, but that's a C++ 17 feature.\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_thread.py",
    "content": "import threading\n\nfrom pybind11_tests import thread as m\n\n\nclass Thread(threading.Thread):\n    def __init__(self, fn):\n        super().__init__()\n        self.fn = fn\n        self.e = None\n\n    def run(self):\n        try:\n            for i in range(10):\n                self.fn(i, i)\n        except Exception as e:\n            self.e = e\n\n    def join(self):\n        super().join()\n        if self.e:\n            raise self.e\n\n\ndef test_implicit_conversion():\n    a = Thread(m.test)\n    b = Thread(m.test)\n    c = Thread(m.test)\n    for x in [a, b, c]:\n        x.start()\n    for x in [c, b, a]:\n        x.join()\n\n\ndef test_implicit_conversion_no_gil():\n    a = Thread(m.test_no_gil)\n    b = Thread(m.test_no_gil)\n    c = Thread(m.test_no_gil)\n    for x in [a, b, c]:\n        x.start()\n    for x in [c, b, a]:\n        x.join()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_union.cpp",
    "content": "/*\n    tests/test_class.cpp -- test py::class_ definitions and basic functionality\n\n    Copyright (c) 2019 Roland Dreier <roland.dreier@gmail.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(union_, m) {\n    union TestUnion {\n        int value_int;\n        unsigned value_uint;\n    };\n\n    py::class_<TestUnion>(m, \"TestUnion\")\n        .def(py::init<>())\n        .def_readonly(\"as_int\", &TestUnion::value_int)\n        .def_readwrite(\"as_uint\", &TestUnion::value_uint);\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_union.py",
    "content": "from pybind11_tests import union_ as m\n\n\ndef test_union():\n    instance = m.TestUnion()\n\n    instance.as_uint = 10\n    assert instance.as_int == 10\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_virtual_functions.cpp",
    "content": "/*\n    tests/test_virtual_functions.cpp -- overriding virtual functions from Python\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <thread>\n\n/* This is an example class that we'll want to be able to extend from Python */\nclass ExampleVirt {\npublic:\n    explicit ExampleVirt(int state) : state(state) { print_created(this, state); }\n    ExampleVirt(const ExampleVirt &e) : state(e.state) { print_copy_created(this); }\n    ExampleVirt(ExampleVirt &&e) noexcept : state(e.state) {\n        print_move_created(this);\n        e.state = 0;\n    }\n    virtual ~ExampleVirt() { print_destroyed(this); }\n\n    virtual int run(int value) {\n        py::print(\"Original implementation of \"\n                  \"ExampleVirt::run(state={}, value={}, str1={}, str2={})\"_s.format(\n                      state, value, get_string1(), *get_string2()));\n        return state + value;\n    }\n\n    virtual bool run_bool() = 0;\n    virtual void pure_virtual() = 0;\n\n    // Returning a reference/pointer to a type converted from python (numbers, strings, etc.) is a\n    // bit trickier, because the actual int& or std::string& or whatever only exists temporarily,\n    // so we have to handle it specially in the trampoline class (see below).\n    virtual const std::string &get_string1() { return str1; }\n    virtual const std::string *get_string2() { return &str2; }\n\nprivate:\n    int state;\n    const std::string str1{\"default1\"}, str2{\"default2\"};\n};\n\n/* This is a wrapper class that must be generated */\nclass PyExampleVirt : public ExampleVirt {\npublic:\n    using ExampleVirt::ExampleVirt; /* Inherit constructors */\n\n    int run(int value) override {\n        /* Generate wrapping code that enables native function overloading */\n        PYBIND11_OVERRIDE(int,         /* Return type */\n                          ExampleVirt, /* Parent class */\n                          run,         /* Name of function */\n                          value        /* Argument(s) */\n        );\n    }\n\n    bool run_bool() override {\n        PYBIND11_OVERRIDE_PURE(bool,        /* Return type */\n                               ExampleVirt, /* Parent class */\n                               run_bool,    /* Name of function */\n                                            /* This function has no arguments. The trailing comma\n                                               in the previous line is needed for some compilers */\n        );\n    }\n\n    void pure_virtual() override {\n        PYBIND11_OVERRIDE_PURE(void,         /* Return type */\n                               ExampleVirt,  /* Parent class */\n                               pure_virtual, /* Name of function */\n                                             /* This function has no arguments. The trailing comma\n                                                in the previous line is needed for some compilers */\n        );\n    }\n\n    // We can return reference types for compatibility with C++ virtual interfaces that do so, but\n    // note they have some significant limitations (see the documentation).\n    const std::string &get_string1() override {\n        PYBIND11_OVERRIDE(const std::string &, /* Return type */\n                          ExampleVirt,         /* Parent class */\n                          get_string1,         /* Name of function */\n                                               /* (no arguments) */\n        );\n    }\n\n    const std::string *get_string2() override {\n        PYBIND11_OVERRIDE(const std::string *, /* Return type */\n                          ExampleVirt,         /* Parent class */\n                          get_string2,         /* Name of function */\n                                               /* (no arguments) */\n        );\n    }\n};\n\nclass NonCopyable {\npublic:\n    NonCopyable(int a, int b) : value{new int(a * b)} { print_created(this, a, b); }\n    NonCopyable(NonCopyable &&o) noexcept : value{std::move(o.value)} { print_move_created(this); }\n    NonCopyable(const NonCopyable &) = delete;\n    NonCopyable() = delete;\n    void operator=(const NonCopyable &) = delete;\n    void operator=(NonCopyable &&) = delete;\n    std::string get_value() const {\n        if (value) {\n            return std::to_string(*value);\n        }\n        return \"(null)\";\n    }\n    ~NonCopyable() { print_destroyed(this); }\n\nprivate:\n    std::unique_ptr<int> value;\n};\n\n// This is like the above, but is both copy and movable.  In effect this means it should get moved\n// when it is not referenced elsewhere, but copied if it is still referenced.\nclass Movable {\npublic:\n    Movable(int a, int b) : value{a + b} { print_created(this, a, b); }\n    Movable(const Movable &m) : value{m.value} { print_copy_created(this); }\n    Movable(Movable &&m) noexcept : value{m.value} { print_move_created(this); }\n    std::string get_value() const { return std::to_string(value); }\n    ~Movable() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\nclass NCVirt {\npublic:\n    virtual ~NCVirt() = default;\n    NCVirt() = default;\n    NCVirt(const NCVirt &) = delete;\n    virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); }\n    virtual Movable get_movable(int a, int b) = 0;\n\n    std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); }\n    std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); }\n};\nclass NCVirtTrampoline : public NCVirt {\n#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)\n    NonCopyable get_noncopyable(int a, int b) override {\n        PYBIND11_OVERRIDE(NonCopyable, NCVirt, get_noncopyable, a, b);\n    }\n#endif\n    Movable get_movable(int a, int b) override {\n        PYBIND11_OVERRIDE_PURE(Movable, NCVirt, get_movable, a, b);\n    }\n};\n\nstruct Base {\n    virtual std::string dispatch() const = 0;\n    virtual ~Base() = default;\n    Base() = default;\n    Base(const Base &) = delete;\n};\n\nstruct DispatchIssue : Base {\n    std::string dispatch() const override {\n        PYBIND11_OVERRIDE_PURE(std::string, Base, dispatch, /* no arguments */);\n    }\n};\n\n// An abstract adder class that uses visitor pattern to add two data\n// objects and send the result to the visitor functor\nstruct AdderBase {\n    struct Data {};\n    using DataVisitor = std::function<void(const Data &)>;\n\n    virtual void\n    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const = 0;\n    virtual ~AdderBase() = default;\n    AdderBase() = default;\n    AdderBase(const AdderBase &) = delete;\n};\n\nstruct Adder : AdderBase {\n    void\n    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const override {\n        PYBIND11_OVERRIDE_PURE_NAME(\n            void, AdderBase, \"__call__\", operator(), first, second, visitor);\n    }\n};\n\nstatic void test_gil() {\n    {\n        py::gil_scoped_acquire lock;\n        py::print(\"1st lock acquired\");\n    }\n\n    {\n        py::gil_scoped_acquire lock;\n        py::print(\"2nd lock acquired\");\n    }\n}\n\nstatic void test_gil_from_thread() {\n    py::gil_scoped_release release;\n\n    std::thread t(test_gil);\n    t.join();\n}\n\nclass test_override_cache_helper {\n\npublic:\n    virtual int func() { return 0; }\n\n    test_override_cache_helper() = default;\n    virtual ~test_override_cache_helper() = default;\n    // Non-copyable\n    test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;\n    test_override_cache_helper(test_override_cache_helper const &Copy) = delete;\n};\n\nclass test_override_cache_helper_trampoline : public test_override_cache_helper {\n    int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }\n};\n\ninline int test_override_cache(std::shared_ptr<test_override_cache_helper> const &instance) {\n    return instance->func();\n}\n\n// Forward declaration (so that we can put the main tests here; the inherited virtual approaches\n// are rather long).\nvoid initialize_inherited_virtuals(py::module_ &m);\n\nTEST_SUBMODULE(virtual_functions, m) {\n    // test_override\n    py::class_<ExampleVirt, PyExampleVirt>(m, \"ExampleVirt\")\n        .def(py::init<int>())\n        /* Reference original class in function definitions */\n        .def(\"run\", &ExampleVirt::run)\n        .def(\"run_bool\", &ExampleVirt::run_bool)\n        .def(\"pure_virtual\", &ExampleVirt::pure_virtual);\n\n    py::class_<NonCopyable>(m, \"NonCopyable\").def(py::init<int, int>());\n\n    py::class_<Movable>(m, \"Movable\").def(py::init<int, int>());\n\n    // test_move_support\n#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)\n    py::class_<NCVirt, NCVirtTrampoline>(m, \"NCVirt\")\n        .def(py::init<>())\n        .def(\"get_noncopyable\", &NCVirt::get_noncopyable)\n        .def(\"get_movable\", &NCVirt::get_movable)\n        .def(\"print_nc\", &NCVirt::print_nc)\n        .def(\"print_movable\", &NCVirt::print_movable);\n#endif\n\n    m.def(\"runExampleVirt\", [](ExampleVirt *ex, int value) { return ex->run(value); });\n    m.def(\"runExampleVirtBool\", [](ExampleVirt *ex) { return ex->run_bool(); });\n    m.def(\"runExampleVirtVirtual\", [](ExampleVirt *ex) { ex->pure_virtual(); });\n\n    m.def(\"cstats_debug\", &ConstructorStats::get<ExampleVirt>);\n    initialize_inherited_virtuals(m);\n\n    // test_alias_delay_initialization1\n    // don't invoke Python dispatch classes by default when instantiating C++ classes\n    // that were not extended on the Python side\n    struct A {\n        A() = default;\n        A(const A &) = delete;\n        virtual ~A() = default;\n        virtual void f() { py::print(\"A.f()\"); }\n    };\n\n    struct PyA : A {\n        PyA() { py::print(\"PyA.PyA()\"); }\n        PyA(const PyA &) = delete;\n        ~PyA() override { py::print(\"PyA.~PyA()\"); }\n\n        void f() override {\n            py::print(\"PyA.f()\");\n            // This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to\n            // protect a type containing a ,\n            PYBIND11_OVERRIDE(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);\n        }\n    };\n\n    py::class_<A, PyA>(m, \"A\").def(py::init<>()).def(\"f\", &A::f);\n\n    m.def(\"call_f\", [](A *a) { a->f(); });\n\n    // test_alias_delay_initialization2\n    // ... unless we explicitly request it, as in this example:\n    struct A2 {\n        A2() = default;\n        A2(const A2 &) = delete;\n        virtual ~A2() = default;\n        virtual void f() { py::print(\"A2.f()\"); }\n    };\n\n    struct PyA2 : A2 {\n        PyA2() { py::print(\"PyA2.PyA2()\"); }\n        PyA2(const PyA2 &) = delete;\n        ~PyA2() override { py::print(\"PyA2.~PyA2()\"); }\n        void f() override {\n            py::print(\"PyA2.f()\");\n            PYBIND11_OVERRIDE(void, A2, f);\n        }\n    };\n\n    py::class_<A2, PyA2>(m, \"A2\")\n        .def(py::init_alias<>())\n        .def(py::init([](int) { return new PyA2(); }))\n        .def(\"f\", &A2::f);\n\n    m.def(\"call_f\", [](A2 *a2) { a2->f(); });\n\n    // test_dispatch_issue\n    // #159: virtual function dispatch has problems with similar-named functions\n    py::class_<Base, DispatchIssue>(m, \"DispatchIssue\")\n        .def(py::init<>())\n        .def(\"dispatch\", &Base::dispatch);\n\n    m.def(\"dispatch_issue_go\", [](const Base *b) { return b->dispatch(); });\n\n    // test_recursive_dispatch_issue\n    // #3357: Recursive dispatch fails to find python function override\n    pybind11::class_<AdderBase, Adder>(m, \"Adder\")\n        .def(pybind11::init<>())\n        .def(\"__call__\", &AdderBase::operator());\n\n    pybind11::class_<AdderBase::Data>(m, \"Data\").def(pybind11::init<>());\n\n    m.def(\"add2\",\n          [](const AdderBase::Data &first,\n             const AdderBase::Data &second,\n             const AdderBase &adder,\n             const AdderBase::DataVisitor &visitor) { adder(first, second, visitor); });\n\n    m.def(\"add3\",\n          [](const AdderBase::Data &first,\n             const AdderBase::Data &second,\n             const AdderBase::Data &third,\n             const AdderBase &adder,\n             const AdderBase::DataVisitor &visitor) {\n              adder(first, second, [&](const AdderBase::Data &first_plus_second) {\n                  // NOLINTNEXTLINE(readability-suspicious-call-argument)\n                  adder(first_plus_second, third, visitor);\n              });\n          });\n\n    // test_override_ref\n    // #392/397: overriding reference-returning functions\n    class OverrideTest {\n    public:\n        struct A {\n            std::string value = \"hi\";\n        };\n        std::string v;\n        A a;\n        explicit OverrideTest(const std::string &v) : v{v} {}\n        OverrideTest() = default;\n        OverrideTest(const OverrideTest &) = delete;\n        virtual std::string str_value() { return v; }\n        virtual std::string &str_ref() { return v; }\n        virtual A A_value() { return a; }\n        virtual A &A_ref() { return a; }\n        virtual ~OverrideTest() = default;\n    };\n\n    class PyOverrideTest : public OverrideTest {\n    public:\n        using OverrideTest::OverrideTest;\n        std::string str_value() override {\n            PYBIND11_OVERRIDE(std::string, OverrideTest, str_value);\n        }\n        // Not allowed (enabling the below should hit a static_assert failure): we can't get a\n        // reference to a python numeric value, since we only copy values in the numeric type\n        // caster:\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n        std::string &str_ref() override {\n            PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref);\n        }\n#endif\n        // But we can work around it like this:\n    private:\n        std::string _tmp;\n        std::string str_ref_helper() { PYBIND11_OVERRIDE(std::string, OverrideTest, str_ref); }\n\n    public:\n        std::string &str_ref() override { return _tmp = str_ref_helper(); }\n\n        A A_value() override { PYBIND11_OVERRIDE(A, OverrideTest, A_value); }\n        A &A_ref() override { PYBIND11_OVERRIDE(A &, OverrideTest, A_ref); }\n    };\n\n    py::class_<OverrideTest::A>(m, \"OverrideTest_A\")\n        .def_readwrite(\"value\", &OverrideTest::A::value);\n    py::class_<OverrideTest, PyOverrideTest>(m, \"OverrideTest\")\n        .def(py::init<const std::string &>())\n        .def(\"str_value\", &OverrideTest::str_value)\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n        .def(\"str_ref\", &OverrideTest::str_ref)\n#endif\n        .def(\"A_value\", &OverrideTest::A_value)\n        .def(\"A_ref\", &OverrideTest::A_ref);\n\n    py::class_<test_override_cache_helper,\n               test_override_cache_helper_trampoline,\n               std::shared_ptr<test_override_cache_helper>>(m, \"test_override_cache_helper\")\n        .def(py::init_alias<>())\n        .def(\"func\", &test_override_cache_helper::func);\n\n    m.def(\"test_override_cache\", test_override_cache);\n}\n\n// Inheriting virtual methods.  We do two versions here: the repeat-everything version and the\n// templated trampoline versions mentioned in docs/advanced.rst.\n//\n// These base classes are exactly the same, but we technically need distinct\n// classes for this example code because we need to be able to bind them\n// properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to\n// multiple python classes).\nclass A_Repeat {\n#define A_METHODS                                                                                 \\\npublic:                                                                                           \\\n    virtual int unlucky_number() = 0;                                                             \\\n    virtual std::string say_something(unsigned times) {                                           \\\n        std::string s = \"\";                                                                       \\\n        for (unsigned i = 0; i < times; ++i)                                                      \\\n            s += \"hi\";                                                                            \\\n        return s;                                                                                 \\\n    }                                                                                             \\\n    std::string say_everything() {                                                                \\\n        return say_something(1) + \" \" + std::to_string(unlucky_number());                         \\\n    }\n    A_METHODS\n    A_Repeat() = default;\n    A_Repeat(const A_Repeat &) = delete;\n    virtual ~A_Repeat() = default;\n};\nclass B_Repeat : public A_Repeat {\n#define B_METHODS                                                                                 \\\npublic:                                                                                           \\\n    int unlucky_number() override { return 13; }                                                  \\\n    std::string say_something(unsigned times) override {                                          \\\n        return \"B says hi \" + std::to_string(times) + \" times\";                                   \\\n    }                                                                                             \\\n    virtual double lucky_number() { return 7.0; }\n    B_METHODS\n};\nclass C_Repeat : public B_Repeat {\n#define C_METHODS                                                                                 \\\npublic:                                                                                           \\\n    int unlucky_number() override { return 4444; }                                                \\\n    double lucky_number() override { return 888; }\n    C_METHODS\n};\nclass D_Repeat : public C_Repeat {\n#define D_METHODS // Nothing overridden.\n    D_METHODS\n};\n\n// Base classes for templated inheritance trampolines.  Identical to the repeat-everything version:\nclass A_Tpl {\n    A_METHODS;\n    A_Tpl() = default;\n    A_Tpl(const A_Tpl &) = delete;\n    virtual ~A_Tpl() = default;\n};\nclass B_Tpl : public A_Tpl {\n    B_METHODS\n};\nclass C_Tpl : public B_Tpl {\n    C_METHODS\n};\nclass D_Tpl : public C_Tpl {\n    D_METHODS\n};\n\n// Inheritance approach 1: each trampoline gets every virtual method (11 in total)\nclass PyA_Repeat : public A_Repeat {\npublic:\n    using A_Repeat::A_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, A_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, A_Repeat, say_something, times);\n    }\n};\nclass PyB_Repeat : public B_Repeat {\npublic:\n    using B_Repeat::B_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, B_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, B_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, B_Repeat, lucky_number, ); }\n};\nclass PyC_Repeat : public C_Repeat {\npublic:\n    using C_Repeat::C_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, C_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, C_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, C_Repeat, lucky_number, ); }\n};\nclass PyD_Repeat : public D_Repeat {\npublic:\n    using D_Repeat::D_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, D_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, D_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, D_Repeat, lucky_number, ); }\n};\n\n// Inheritance approach 2: templated trampoline classes.\n//\n// Advantages:\n// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one\n//   for any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes\n//   and 11 methods (repeat).\n// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and\n//   can properly inherit constructors.\n//\n// Disadvantage:\n// - the compiler must still generate and compile 14 different methods (more, even, than the 11\n//   required for the repeat approach) instead of the 6 required for MI.  (If there was no pure\n//   method (or no pure method override), the number would drop down to the same 11 as the repeat\n//   approach).\ntemplate <class Base = A_Tpl>\nclass PyA_Tpl : public Base {\npublic:\n    using Base::Base; // Inherit constructors\n    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, Base, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, Base, say_something, times);\n    }\n};\ntemplate <class Base = B_Tpl>\nclass PyB_Tpl : public PyA_Tpl<Base> {\npublic:\n    using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)\n    // NOLINTNEXTLINE(bugprone-parent-virtual-call)\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }\n};\n// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these\n// (we can use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):\n/*\ntemplate <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> {\npublic:\n    using PyB_Tpl<Base>::PyB_Tpl;\n};\ntemplate <class Base = D_Tpl> class PyD_Tpl : public PyC_Tpl<Base> {\npublic:\n    using PyC_Tpl<Base>::PyC_Tpl;\n};\n*/\n\nvoid initialize_inherited_virtuals(py::module_ &m) {\n    // test_inherited_virtuals\n\n    // Method 1: repeat\n    py::class_<A_Repeat, PyA_Repeat>(m, \"A_Repeat\")\n        .def(py::init<>())\n        .def(\"unlucky_number\", &A_Repeat::unlucky_number)\n        .def(\"say_something\", &A_Repeat::say_something)\n        .def(\"say_everything\", &A_Repeat::say_everything);\n    py::class_<B_Repeat, A_Repeat, PyB_Repeat>(m, \"B_Repeat\")\n        .def(py::init<>())\n        .def(\"lucky_number\", &B_Repeat::lucky_number);\n    py::class_<C_Repeat, B_Repeat, PyC_Repeat>(m, \"C_Repeat\").def(py::init<>());\n    py::class_<D_Repeat, C_Repeat, PyD_Repeat>(m, \"D_Repeat\").def(py::init<>());\n\n    // test_\n    // Method 2: Templated trampolines\n    py::class_<A_Tpl, PyA_Tpl<>>(m, \"A_Tpl\")\n        .def(py::init<>())\n        .def(\"unlucky_number\", &A_Tpl::unlucky_number)\n        .def(\"say_something\", &A_Tpl::say_something)\n        .def(\"say_everything\", &A_Tpl::say_everything);\n    py::class_<B_Tpl, A_Tpl, PyB_Tpl<>>(m, \"B_Tpl\")\n        .def(py::init<>())\n        .def(\"lucky_number\", &B_Tpl::lucky_number);\n    py::class_<C_Tpl, B_Tpl, PyB_Tpl<C_Tpl>>(m, \"C_Tpl\").def(py::init<>());\n    py::class_<D_Tpl, C_Tpl, PyB_Tpl<D_Tpl>>(m, \"D_Tpl\").def(py::init<>());\n\n    // Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)\n    m.def(\"test_gil\", &test_gil);\n    m.def(\"test_gil_from_thread\", &test_gil_from_thread);\n};\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/test_virtual_functions.py",
    "content": "import pytest\n\nimport env  # noqa: F401\n\nm = pytest.importorskip(\"pybind11_tests.virtual_functions\")\nfrom pybind11_tests import ConstructorStats  # noqa: E402\n\n\ndef test_override(capture, msg):\n    class ExtendedExampleVirt(m.ExampleVirt):\n        def __init__(self, state):\n            super().__init__(state + 1)\n            self.data = \"Hello world\"\n\n        def run(self, value):\n            print(f\"ExtendedExampleVirt::run({value}), calling parent..\")\n            return super().run(value + 1)\n\n        def run_bool(self):\n            print(\"ExtendedExampleVirt::run_bool()\")\n            return False\n\n        def get_string1(self):\n            return \"override1\"\n\n        def pure_virtual(self):\n            print(f\"ExtendedExampleVirt::pure_virtual(): {self.data}\")\n\n    class ExtendedExampleVirt2(ExtendedExampleVirt):\n        def __init__(self, state):\n            super().__init__(state + 1)\n\n        def get_string2(self):\n            return \"override2\"\n\n    ex12 = m.ExampleVirt(10)\n    with capture:\n        assert m.runExampleVirt(ex12, 20) == 30\n    assert (\n        capture\n        == \"\"\"\n        Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)\n    \"\"\"\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.runExampleVirtVirtual(ex12)\n    assert (\n        msg(excinfo.value)\n        == 'Tried to call pure virtual function \"ExampleVirt::pure_virtual\"'\n    )\n\n    ex12p = ExtendedExampleVirt(10)\n    with capture:\n        assert m.runExampleVirt(ex12p, 20) == 32\n    assert (\n        capture\n        == \"\"\"\n        ExtendedExampleVirt::run(20), calling parent..\n        Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)\n    \"\"\"\n    )\n    with capture:\n        assert m.runExampleVirtBool(ex12p) is False\n    assert capture == \"ExtendedExampleVirt::run_bool()\"\n    with capture:\n        m.runExampleVirtVirtual(ex12p)\n    assert capture == \"ExtendedExampleVirt::pure_virtual(): Hello world\"\n\n    ex12p2 = ExtendedExampleVirt2(15)\n    with capture:\n        assert m.runExampleVirt(ex12p2, 50) == 68\n    assert (\n        capture\n        == \"\"\"\n        ExtendedExampleVirt::run(50), calling parent..\n        Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)\n    \"\"\"\n    )\n\n    cstats = ConstructorStats.get(m.ExampleVirt)\n    assert cstats.alive() == 3\n    del ex12, ex12p, ex12p2\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"10\", \"11\", \"17\"]\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 0\n\n\ndef test_alias_delay_initialization1(capture):\n    \"\"\"`A` only initializes its trampoline class when we inherit from it\n\n    If we just create and use an A instance directly, the trampoline initialization is\n    bypassed and we only initialize an A() instead (for performance reasons).\n    \"\"\"\n\n    class B(m.A):\n        def __init__(self):\n            super().__init__()\n\n        def f(self):\n            print(\"In python f()\")\n\n    # C++ version\n    with capture:\n        a = m.A()\n        m.call_f(a)\n        del a\n        pytest.gc_collect()\n    assert capture == \"A.f()\"\n\n    # Python version\n    with capture:\n        b = B()\n        m.call_f(b)\n        del b\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA.PyA()\n        PyA.f()\n        In python f()\n        PyA.~PyA()\n    \"\"\"\n    )\n\n\ndef test_alias_delay_initialization2(capture):\n    \"\"\"`A2`, unlike the above, is configured to always initialize the alias\n\n    While the extra initialization and extra class layer has small virtual dispatch\n    performance penalty, it also allows us to do more things with the trampoline\n    class such as defining local variables and performing construction/destruction.\n    \"\"\"\n\n    class B2(m.A2):\n        def __init__(self):\n            super().__init__()\n\n        def f(self):\n            print(\"In python B2.f()\")\n\n    # No python subclass version\n    with capture:\n        a2 = m.A2()\n        m.call_f(a2)\n        del a2\n        pytest.gc_collect()\n        a3 = m.A2(1)\n        m.call_f(a3)\n        del a3\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA2.PyA2()\n        PyA2.f()\n        A2.f()\n        PyA2.~PyA2()\n        PyA2.PyA2()\n        PyA2.f()\n        A2.f()\n        PyA2.~PyA2()\n    \"\"\"\n    )\n\n    # Python subclass version\n    with capture:\n        b2 = B2()\n        m.call_f(b2)\n        del b2\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA2.PyA2()\n        PyA2.f()\n        In python B2.f()\n        PyA2.~PyA2()\n    \"\"\"\n    )\n\n\n# PyPy: Reference count > 1 causes call with noncopyable instance\n# to fail in ncv1.print_nc()\n@pytest.mark.xfail(\"env.PYPY\")\n@pytest.mark.skipif(\n    not hasattr(m, \"NCVirt\"), reason=\"NCVirt does not work on Intel/PGI/NVCC compilers\"\n)\ndef test_move_support():\n    class NCVirtExt(m.NCVirt):\n        def get_noncopyable(self, a, b):\n            # Constructs and returns a new instance:\n            nc = m.NonCopyable(a * a, b * b)\n            return nc\n\n        def get_movable(self, a, b):\n            # Return a referenced copy\n            self.movable = m.Movable(a, b)\n            return self.movable\n\n    class NCVirtExt2(m.NCVirt):\n        def get_noncopyable(self, a, b):\n            # Keep a reference: this is going to throw an exception\n            self.nc = m.NonCopyable(a, b)\n            return self.nc\n\n        def get_movable(self, a, b):\n            # Return a new instance without storing it\n            return m.Movable(a, b)\n\n    ncv1 = NCVirtExt()\n    assert ncv1.print_nc(2, 3) == \"36\"\n    assert ncv1.print_movable(4, 5) == \"9\"\n    ncv2 = NCVirtExt2()\n    assert ncv2.print_movable(7, 7) == \"14\"\n    # Don't check the exception message here because it differs under debug/non-debug mode\n    with pytest.raises(RuntimeError):\n        ncv2.print_nc(9, 9)\n\n    nc_stats = ConstructorStats.get(m.NonCopyable)\n    mv_stats = ConstructorStats.get(m.Movable)\n    assert nc_stats.alive() == 1\n    assert mv_stats.alive() == 1\n    del ncv1, ncv2\n    assert nc_stats.alive() == 0\n    assert mv_stats.alive() == 0\n    assert nc_stats.values() == [\"4\", \"9\", \"9\", \"9\"]\n    assert mv_stats.values() == [\"4\", \"5\", \"7\", \"7\"]\n    assert nc_stats.copy_constructions == 0\n    assert mv_stats.copy_constructions == 1\n    assert nc_stats.move_constructions >= 0\n    assert mv_stats.move_constructions >= 0\n\n\ndef test_dispatch_issue(msg):\n    \"\"\"#159: virtual function dispatch has problems with similar-named functions\"\"\"\n\n    class PyClass1(m.DispatchIssue):\n        def dispatch(self):\n            return \"Yay..\"\n\n    class PyClass2(m.DispatchIssue):\n        def dispatch(self):\n            with pytest.raises(RuntimeError) as excinfo:\n                super().dispatch()\n            assert (\n                msg(excinfo.value)\n                == 'Tried to call pure virtual function \"Base::dispatch\"'\n            )\n\n            return m.dispatch_issue_go(PyClass1())\n\n    b = PyClass2()\n    assert m.dispatch_issue_go(b) == \"Yay..\"\n\n\ndef test_recursive_dispatch_issue(msg):\n    \"\"\"#3357: Recursive dispatch fails to find python function override\"\"\"\n\n    class Data(m.Data):\n        def __init__(self, value):\n            super().__init__()\n            self.value = value\n\n    class Adder(m.Adder):\n        def __call__(self, first, second, visitor):\n            # lambda is a workaround, which adds extra frame to the\n            # current CPython thread. Removing lambda reveals the bug\n            # [https://github.com/pybind/pybind11/issues/3357]\n            (lambda: visitor(Data(first.value + second.value)))()\n\n    class StoreResultVisitor:\n        def __init__(self):\n            self.result = None\n\n        def __call__(self, data):\n            self.result = data.value\n\n    store = StoreResultVisitor()\n\n    m.add2(Data(1), Data(2), Adder(), store)\n    assert store.result == 3\n\n    # without lambda in Adder class, this function fails with\n    # RuntimeError: Tried to call pure virtual function \"AdderBase::__call__\"\n    m.add3(Data(1), Data(2), Data(3), Adder(), store)\n    assert store.result == 6\n\n\ndef test_override_ref():\n    \"\"\"#392/397: overriding reference-returning functions\"\"\"\n    o = m.OverrideTest(\"asdf\")\n\n    # Not allowed (see associated .cpp comment)\n    # i = o.str_ref()\n    # assert o.str_ref() == \"asdf\"\n    assert o.str_value() == \"asdf\"\n\n    assert o.A_value().value == \"hi\"\n    a = o.A_ref()\n    assert a.value == \"hi\"\n    a.value = \"bye\"\n    assert a.value == \"bye\"\n\n\ndef test_inherited_virtuals():\n    class AR(m.A_Repeat):\n        def unlucky_number(self):\n            return 99\n\n    class AT(m.A_Tpl):\n        def unlucky_number(self):\n            return 999\n\n    obj = AR()\n    assert obj.say_something(3) == \"hihihi\"\n    assert obj.unlucky_number() == 99\n    assert obj.say_everything() == \"hi 99\"\n\n    obj = AT()\n    assert obj.say_something(3) == \"hihihi\"\n    assert obj.unlucky_number() == 999\n    assert obj.say_everything() == \"hi 999\"\n\n    for obj in [m.B_Repeat(), m.B_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 13\n        assert obj.lucky_number() == 7.0\n        assert obj.say_everything() == \"B says hi 1 times 13\"\n\n    for obj in [m.C_Repeat(), m.C_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 4444\n        assert obj.lucky_number() == 888.0\n        assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CR(m.C_Repeat):\n        def lucky_number(self):\n            return m.C_Repeat.lucky_number(self) + 1.25\n\n    obj = CR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 889.25\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CT(m.C_Tpl):\n        pass\n\n    obj = CT()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 888.0\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CCR(CR):\n        def lucky_number(self):\n            return CR.lucky_number(self) * 10\n\n    obj = CCR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 8892.5\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CCT(CT):\n        def lucky_number(self):\n            return CT.lucky_number(self) * 1000\n\n    obj = CCT()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 888000.0\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class DR(m.D_Repeat):\n        def unlucky_number(self):\n            return 123\n\n        def lucky_number(self):\n            return 42.0\n\n    for obj in [m.D_Repeat(), m.D_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 4444\n        assert obj.lucky_number() == 888.0\n        assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    obj = DR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 123\n    assert obj.lucky_number() == 42.0\n    assert obj.say_everything() == \"B says hi 1 times 123\"\n\n    class DT(m.D_Tpl):\n        def say_something(self, times):\n            return \"DT says:\" + (\" quack\" * times)\n\n        def unlucky_number(self):\n            return 1234\n\n        def lucky_number(self):\n            return -4.25\n\n    obj = DT()\n    assert obj.say_something(3) == \"DT says: quack quack quack\"\n    assert obj.unlucky_number() == 1234\n    assert obj.lucky_number() == -4.25\n    assert obj.say_everything() == \"DT says: quack 1234\"\n\n    class DT2(DT):\n        def say_something(self, times):\n            return \"DT2: \" + (\"QUACK\" * times)\n\n        def unlucky_number(self):\n            return -3\n\n    class BT(m.B_Tpl):\n        def say_something(self, times):\n            return \"BT\" * times\n\n        def unlucky_number(self):\n            return -7\n\n        def lucky_number(self):\n            return -1.375\n\n    obj = BT()\n    assert obj.say_something(3) == \"BTBTBT\"\n    assert obj.unlucky_number() == -7\n    assert obj.lucky_number() == -1.375\n    assert obj.say_everything() == \"BT -7\"\n\n\ndef test_issue_1454():\n    # Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)\n    m.test_gil()\n    m.test_gil_from_thread()\n\n\ndef test_python_override():\n    def func():\n        class Test(m.test_override_cache_helper):\n            def func(self):\n                return 42\n\n        return Test()\n\n    def func2():\n        class Test(m.test_override_cache_helper):\n            pass\n\n        return Test()\n\n    for _ in range(1500):\n        assert m.test_override_cache(func()) == 42\n        assert m.test_override_cache(func2()) == 0\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/valgrind-numpy-scipy.supp",
    "content": "# Valgrind suppression file for NumPy & SciPy errors and leaks in pybind11 tests\n#\n# On updating a dependency, to get a list of \"default\" leaks in e.g. NumPy, run\n# `PYTHONMALLOC=malloc valgrind --leak-check=full --show-leak-kinds=definite,indirect python3.9-dbg -c \"import numpy\"`\n# To use these suppression files, add e.g. `--suppressions=valgrind-numpy-scipy.supp`\n\n{\n   Leaks when importing NumPy\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_Pack\n   ...\n   fun:__pyx_pymod_exec_*\n}\n\n{\n   Leaks when importing NumPy (bis)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_New\n   fun:PyCode_NewWithPosOnlyArgs\n   fun:PyCode_New\n   ...\n   fun:__pyx_pymod_exec_*\n}\n\n{\n   Leaks when importing NumPy (ter)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:_PyTuple_FromArray\n   fun:_PyObject_MakeTpCall\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n   fun:_PyFunction_Vectorcall\n}\n\n{\n   Leaks when importing NumPy (quater)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:_PyTuple_FromArray\n   fun:_PyObject_MakeTpCall\n   fun:_PyObject_VectorcallTstate\n   fun:_PyObject_CallFunctionVa\n   fun:PyObject_CallFunction\n   fun:PyImport_Import\n}\n\n{\n   Leaks when importing NumPy (quinquies)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_New\n   fun:r_object\n   fun:r_object\n   fun:r_object\n   fun:r_object\n}\n\n{\n   Leaks when importing NumPy (sexies)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_New\n   fun:dictiter_iternextitem\n   fun:list_extend\n   fun:_PyList_Extend\n   fun:PySequence_List\n}\n\n{\n   Leak when importing scipy.fft\n   Memcheck:Leak\n   fun:_Znwm\n   fun:PyInit_pypocketfft\n   fun:_PyImport_LoadDynamicModuleWithSpec\n   fun:_imp_create_dynamic_impl*\n   fun:_imp_create_dynamic\n   fun:cfunction_vectorcall_FASTCALL\n   fun:PyVectorcall_Call\n   fun:_PyObject_Call\n   fun:PyObject_Call\n   fun:do_call_core\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:_PyEval_EvalCode\n}\n\n{\n   NumPy leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   ...\n   fun:_buffer_get_info\n   fun:array_getbuffer\n   fun:PyObject_GetBuffer\n   fun:__Pyx__GetBufferAndValidate*\n   fun:__pyx_f_5numpy_6random_13bit_generator_12SeedSequence_mix_entropy\n   fun:__pyx_pw_5numpy_6random_13bit_generator_12SeedSequence_1__init__\n   fun:type_call\n   fun:__Pyx__PyObject_CallOneArg\n   fun:__pyx_pw_5numpy_6random_13bit_generator_12BitGenerator_1__init__\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tests/valgrind-python.supp",
    "content": "# Valgrind suppression file for CPython errors and leaks in pybind11 tests\n\n# Taken verbatim from https://github.com/python/cpython/blob/3.9/Misc/valgrind-python.supp#L266-L272\n{\n   Uninitialised byte(s) false alarm, see bpo-35561\n   Memcheck:Param\n   epoll_ctl(event)\n   fun:epoll_ctl\n   fun:pyepoll_internal_ctl\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyEval_InitState\n   fun:PyInterpreterState_New\n   ...\n   fun:pyinit_core*\n   fun:Py_InitializeFromConfig\n   fun:pymain_init\n   fun:pymain_main\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:_PyMem_DebugRawAlloc\n   fun:_PyMem_DebugRawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyRuntimeState_Init_impl\n   fun:_PyRuntimeState_Init\n   fun:_PyRuntime_Initialize\n   fun:pymain_init\n   fun:pymain_main\n   fun:Py_BytesMain\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyImport_AcquireLock\n   fun:_imp_acquire_lock_impl*\n   fun:_imp_acquire_lock\n   fun:cfunction_vectorcall_NOARGS\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:newlockobject\n   ...\n   fun:cfunction_vectorcall_NOARGS\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n   fun:_PyFunction_Vectorcall\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:rlock_new\n   fun:type_call\n   fun:_PyObject_Call\n   fun:PyObject_Call\n   fun:do_call_core\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:_PyEval_EvalCode\n   fun:_PyFunction_Vectorcall\n}\n\n# Not really CPython-specific, see link\n{\n   dlopen leak (https://stackoverflow.com/questions/1542457/memory-leak-reported-by-valgrind-in-dlopen)\n   Memcheck:Leak\n   fun:malloc\n   ...\n   fun:dl_open_worker\n   fun:_dl_catch_exception\n   fun:_dl_open\n   fun:dlopen_doit\n   fun:_dl_catch_exception\n   fun:_dl_catch_error\n   fun:_dlerror_run\n   fun:dlopen@@GLIBC_2.2.5\n   fun:_PyImport_FindSharedFuncptr\n   fun:_PyImport_LoadDynamicModuleWithSpec\n}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/FindCatch.cmake",
    "content": "# - Find the Catch test framework or download it (single header)\n#\n# This is a quick module for internal use. It assumes that Catch is\n# REQUIRED and that a minimum version is provided (not EXACT). If\n# a suitable version isn't found locally, the single header file\n# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR.\n#\n# This code sets the following variables:\n#  CATCH_INCLUDE_DIR      - path to catch.hpp\n#  CATCH_VERSION          - version number\n\noption(DOWNLOAD_CATCH \"Download catch2 if not found\")\n\nif(NOT Catch_FIND_VERSION)\n  message(FATAL_ERROR \"A version number must be specified.\")\nelseif(Catch_FIND_REQUIRED)\n  message(FATAL_ERROR \"This module assumes Catch is not required.\")\nelseif(Catch_FIND_VERSION_EXACT)\n  message(FATAL_ERROR \"Exact version numbers are not supported, only minimum.\")\nendif()\n\n# Extract the version number from catch.hpp\nfunction(_get_catch_version)\n  file(\n    STRINGS \"${CATCH_INCLUDE_DIR}/catch.hpp\" version_line\n    REGEX \"Catch v.*\"\n    LIMIT_COUNT 1)\n  if(version_line MATCHES \"Catch v([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)\")\n    set(CATCH_VERSION\n        \"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}\"\n        PARENT_SCOPE)\n  endif()\nendfunction()\n\n# Download the single-header version of Catch\nfunction(_download_catch version destination_dir)\n  message(STATUS \"Downloading catch v${version}...\")\n  set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)\n  file(DOWNLOAD ${url} \"${destination_dir}/catch.hpp\" STATUS status)\n  list(GET status 0 error)\n  if(error)\n    message(FATAL_ERROR \"Could not download ${url}\")\n  endif()\n  set(CATCH_INCLUDE_DIR\n      \"${destination_dir}\"\n      CACHE INTERNAL \"\")\nendfunction()\n\n# Look for catch locally\nfind_path(\n  CATCH_INCLUDE_DIR\n  NAMES catch.hpp\n  PATH_SUFFIXES catch2)\nif(CATCH_INCLUDE_DIR)\n  _get_catch_version()\nendif()\n\n# Download the header if it wasn't found or if it's outdated\nif(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})\n  if(DOWNLOAD_CATCH)\n    _download_catch(${Catch_FIND_VERSION} \"${PROJECT_BINARY_DIR}/catch/\")\n    _get_catch_version()\n  else()\n    set(CATCH_FOUND FALSE)\n    return()\n  endif()\nendif()\n\nadd_library(Catch2::Catch2 IMPORTED INTERFACE)\nset_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES \"${CATCH_INCLUDE_DIR}\")\n\nset(CATCH_FOUND TRUE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/FindEigen3.cmake",
    "content": "# - Try to find Eigen3 lib\n#\n# This module supports requiring a minimum version, e.g. you can do\n#   find_package(Eigen3 3.1.2)\n# to require version 3.1.2 or newer of Eigen3.\n#\n# Once done this will define\n#\n#  EIGEN3_FOUND - system has eigen lib with correct version\n#  EIGEN3_INCLUDE_DIR - the eigen include directory\n#  EIGEN3_VERSION - eigen version\n\n# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>\n# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>\n# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>\n# Redistribution and use is allowed according to the terms of the 2-clause BSD license.\n\nif(NOT Eigen3_FIND_VERSION)\n  if(NOT Eigen3_FIND_VERSION_MAJOR)\n    set(Eigen3_FIND_VERSION_MAJOR 2)\n  endif(NOT Eigen3_FIND_VERSION_MAJOR)\n  if(NOT Eigen3_FIND_VERSION_MINOR)\n    set(Eigen3_FIND_VERSION_MINOR 91)\n  endif(NOT Eigen3_FIND_VERSION_MINOR)\n  if(NOT Eigen3_FIND_VERSION_PATCH)\n    set(Eigen3_FIND_VERSION_PATCH 0)\n  endif(NOT Eigen3_FIND_VERSION_PATCH)\n\n  set(Eigen3_FIND_VERSION\n      \"${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}\")\nendif(NOT Eigen3_FIND_VERSION)\n\nmacro(_eigen3_check_version)\n  file(READ \"${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h\" _eigen3_version_header)\n\n  string(REGEX MATCH \"define[ \\t]+EIGEN_WORLD_VERSION[ \\t]+([0-9]+)\" _eigen3_world_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_WORLD_VERSION \"${CMAKE_MATCH_1}\")\n  string(REGEX MATCH \"define[ \\t]+EIGEN_MAJOR_VERSION[ \\t]+([0-9]+)\" _eigen3_major_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_MAJOR_VERSION \"${CMAKE_MATCH_1}\")\n  string(REGEX MATCH \"define[ \\t]+EIGEN_MINOR_VERSION[ \\t]+([0-9]+)\" _eigen3_minor_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_MINOR_VERSION \"${CMAKE_MATCH_1}\")\n\n  set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})\n  if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n    set(EIGEN3_VERSION_OK FALSE)\n  else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n    set(EIGEN3_VERSION_OK TRUE)\n  endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n\n  if(NOT EIGEN3_VERSION_OK)\n\n    message(STATUS \"Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, \"\n                   \"but at least version ${Eigen3_FIND_VERSION} is required\")\n  endif(NOT EIGEN3_VERSION_OK)\nendmacro(_eigen3_check_version)\n\nif(EIGEN3_INCLUDE_DIR)\n\n  # in cache already\n  _eigen3_check_version()\n  set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})\n\nelse(EIGEN3_INCLUDE_DIR)\n  if(NOT DEFINED KDE4_INCLUDE_DIR)\n    set(KDE4_INCLUDE_DIR \"\")\n  endif()\n\n  find_path(\n    EIGEN3_INCLUDE_DIR\n    NAMES signature_of_eigen3_matrix_library\n    PATHS ${CMAKE_INSTALL_PREFIX}/include ${KDE4_INCLUDE_DIR}\n    PATH_SUFFIXES eigen3 eigen)\n\n  if(EIGEN3_INCLUDE_DIR)\n    _eigen3_check_version()\n  endif(EIGEN3_INCLUDE_DIR)\n\n  include(FindPackageHandleStandardArgs)\n  find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)\n\n  mark_as_advanced(EIGEN3_INCLUDE_DIR)\n\nendif(EIGEN3_INCLUDE_DIR)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/FindPythonLibsNew.cmake",
    "content": "# - Find python libraries\n# This module finds the libraries corresponding to the Python interpreter\n# FindPythonInterp provides.\n# This code sets the following variables:\n#\n#  PYTHONLIBS_FOUND           - have the Python libs been found\n#  PYTHON_PREFIX              - path to the Python installation\n#  PYTHON_LIBRARIES           - path to the python library\n#  PYTHON_INCLUDE_DIRS        - path to where Python.h is found\n#  PYTHON_MODULE_EXTENSION    - lib extension, e.g. '.so' or '.pyd'\n#  PYTHON_MODULE_PREFIX       - lib name prefix: usually an empty string\n#  PYTHON_SITE_PACKAGES       - path to installation site-packages\n#  PYTHON_IS_DEBUG            - whether the Python interpreter is a debug build\n#\n# Thanks to talljimbo for the patch adding the 'LDVERSION' config\n# variable usage.\n\n#=============================================================================\n# Copyright 2001-2009 Kitware, Inc.\n# Copyright 2012 Continuum Analytics, Inc.\n#\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n# * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#\n# * Redistributions in binary form must reproduce the above copyright\n# notice, this list of conditions and the following disclaimer in the\n# documentation and/or other materials provided with the distribution.\n#\n# * Neither the names of Kitware, Inc., the Insight Software Consortium,\n# nor the names of their contributors may be used to endorse or promote\n# products derived from this software without specific prior written\n# permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#=============================================================================\n\n# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`.\nif(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)\n  return()\nendif()\n\nif(PythonLibsNew_FIND_QUIETLY)\n  set(_pythonlibs_quiet QUIET)\nelse()\n  set(_pythonlibs_quiet \"\")\nendif()\n\nif(PythonLibsNew_FIND_REQUIRED)\n  set(_pythonlibs_required REQUIRED)\nendif()\n\n# Check to see if the `python` command is present and from a virtual\n# environment, conda, or GHA activation - if it is, try to use that.\n\nif(NOT DEFINED PYTHON_EXECUTABLE)\n  if(DEFINED ENV{VIRTUAL_ENV})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{VIRTUAL_ENV}\" \"$ENV{VIRTUAL_ENV}/bin\"\n      NO_DEFAULT_PATH)\n  elseif(DEFINED ENV{CONDA_PREFIX})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{CONDA_PREFIX}\" \"$ENV{CONDA_PREFIX}/bin\"\n      NO_DEFAULT_PATH)\n  elseif(DEFINED ENV{pythonLocation})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{pythonLocation}\" \"$ENV{pythonLocation}/bin\"\n      NO_DEFAULT_PATH)\n  endif()\n  if(NOT PYTHON_EXECUTABLE)\n    unset(PYTHON_EXECUTABLE)\n  endif()\nendif()\n\n# Use the Python interpreter to find the libs.\nif(NOT PythonLibsNew_FIND_VERSION)\n  set(PythonLibsNew_FIND_VERSION \"3.6\")\nendif()\n\nfind_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}\n             ${_pythonlibs_quiet})\n\nif(NOT PYTHONINTERP_FOUND)\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\n# According to https://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter\n# testing whether sys has the gettotalrefcount function is a reliable, cross-platform\n# way to detect a CPython debug interpreter.\n#\n# The library suffix is from the config var LDVERSION sometimes, otherwise\n# VERSION. VERSION will typically be like \"2.7\" on unix, and \"27\" on windows.\nexecute_process(\n  COMMAND\n    \"${PYTHON_EXECUTABLE}\" \"-c\" \"\nimport sys;import struct;\nimport sysconfig as s\nUSE_SYSCONFIG = sys.version_info >= (3, 10)\nif not USE_SYSCONFIG:\n    from distutils import sysconfig as ds\nprint('.'.join(str(v) for v in sys.version_info));\nprint(sys.prefix);\nif USE_SYSCONFIG:\n    scheme = s.get_default_scheme()\n    if scheme == 'posix_local':\n        # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/\n        scheme = 'posix_prefix'\n    print(s.get_path('platinclude', scheme))\n    print(s.get_path('platlib'))\n    print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))\nelse:\n    print(ds.get_python_inc(plat_specific=True));\n    print(ds.get_python_lib(plat_specific=True));\n    print(ds.get_config_var('EXT_SUFFIX') or ds.get_config_var('SO'));\nprint(hasattr(sys, 'gettotalrefcount')+0);\nprint(struct.calcsize('@P'));\nprint(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));\nprint(s.get_config_var('LIBDIR') or '');\nprint(s.get_config_var('MULTIARCH') or '');\n\"\n  RESULT_VARIABLE _PYTHON_SUCCESS\n  OUTPUT_VARIABLE _PYTHON_VALUES\n  ERROR_VARIABLE _PYTHON_ERROR_VALUE)\n\nif(NOT _PYTHON_SUCCESS MATCHES 0)\n  if(PythonLibsNew_FIND_REQUIRED)\n    message(FATAL_ERROR \"Python config failure:\\n${_PYTHON_ERROR_VALUE}\")\n  endif()\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\noption(\n  PYBIND11_PYTHONLIBS_OVERWRITE\n  \"Overwrite cached values read from Python library (classic search). Turn off if cross-compiling and manually setting these values.\"\n  ON)\n# Can manually set values when cross-compiling\nmacro(_PYBIND11_GET_IF_UNDEF lst index name)\n  if(PYBIND11_PYTHONLIBS_OVERWRITE OR NOT DEFINED \"${name}\")\n    list(GET \"${lst}\" \"${index}\" \"${name}\")\n  endif()\nendmacro()\n\n# Convert the process output into a list\nif(WIN32)\n  string(REGEX REPLACE \"\\\\\\\\\" \"/\" _PYTHON_VALUES ${_PYTHON_VALUES})\nendif()\nstring(REGEX REPLACE \";\" \"\\\\\\\\;\" _PYTHON_VALUES ${_PYTHON_VALUES})\nstring(REGEX REPLACE \"\\n\" \";\" _PYTHON_VALUES ${_PYTHON_VALUES})\n_pybind11_get_if_undef(_PYTHON_VALUES 0 _PYTHON_VERSION_LIST)\n_pybind11_get_if_undef(_PYTHON_VALUES 1 PYTHON_PREFIX)\n_pybind11_get_if_undef(_PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)\n_pybind11_get_if_undef(_PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)\n_pybind11_get_if_undef(_PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)\n_pybind11_get_if_undef(_PYTHON_VALUES 5 PYTHON_IS_DEBUG)\n_pybind11_get_if_undef(_PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)\n_pybind11_get_if_undef(_PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)\n_pybind11_get_if_undef(_PYTHON_VALUES 8 PYTHON_LIBDIR)\n_pybind11_get_if_undef(_PYTHON_VALUES 9 PYTHON_MULTIARCH)\n\n# Make sure the Python has the same pointer-size as the chosen compiler\n# Skip if CMAKE_SIZEOF_VOID_P is not defined\n# This should be skipped for (non-Apple) cross-compiles (like EMSCRIPTEN)\nif(NOT CMAKE_CROSSCOMPILING\n   AND CMAKE_SIZEOF_VOID_P\n   AND (NOT \"${PYTHON_SIZEOF_VOID_P}\" STREQUAL \"${CMAKE_SIZEOF_VOID_P}\"))\n  if(PythonLibsNew_FIND_REQUIRED)\n    math(EXPR _PYTHON_BITS \"${PYTHON_SIZEOF_VOID_P} * 8\")\n    math(EXPR _CMAKE_BITS \"${CMAKE_SIZEOF_VOID_P} * 8\")\n    message(FATAL_ERROR \"Python config failure: Python is ${_PYTHON_BITS}-bit, \"\n                        \"chosen compiler is  ${_CMAKE_BITS}-bit\")\n  endif()\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\n# The built-in FindPython didn't always give the version numbers\nstring(REGEX REPLACE \"\\\\.\" \";\" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})\nlist(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)\nlist(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)\nlist(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)\nset(PYTHON_VERSION \"${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}\")\n\n# Make sure all directory separators are '/'\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_PREFIX \"${PYTHON_PREFIX}\")\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_INCLUDE_DIR \"${PYTHON_INCLUDE_DIR}\")\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_SITE_PACKAGES \"${PYTHON_SITE_PACKAGES}\")\n\nif(CMAKE_HOST_WIN32)\n  set(PYTHON_LIBRARY \"${PYTHON_PREFIX}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib\")\n\n  # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the\n  # original python installation. They may be found relative to PYTHON_INCLUDE_DIR.\n  if(NOT EXISTS \"${PYTHON_LIBRARY}\")\n    get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)\n    set(PYTHON_LIBRARY \"${_PYTHON_ROOT}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib\")\n  endif()\n\n  # if we are in MSYS & MINGW, and we didn't find windows python lib, look for system python lib\n  if(DEFINED ENV{MSYSTEM}\n     AND MINGW\n     AND NOT EXISTS \"${PYTHON_LIBRARY}\")\n    if(PYTHON_MULTIARCH)\n      set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}\" \"${PYTHON_LIBDIR}\")\n    else()\n      set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}\")\n    endif()\n    unset(PYTHON_LIBRARY)\n    find_library(\n      PYTHON_LIBRARY\n      NAMES \"python${PYTHON_LIBRARY_SUFFIX}\"\n      PATHS ${_PYTHON_LIBS_SEARCH}\n      NO_DEFAULT_PATH)\n  endif()\n\n  # raise an error if the python libs are still not found.\n  if(NOT EXISTS \"${PYTHON_LIBRARY}\")\n    message(FATAL_ERROR \"Python libraries not found\")\n  endif()\n\nelse()\n  if(PYTHON_MULTIARCH)\n    set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}\" \"${PYTHON_LIBDIR}\")\n  else()\n    set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}\")\n  endif()\n  #message(STATUS \"Searching for Python libs in ${_PYTHON_LIBS_SEARCH}\")\n  # Probably this needs to be more involved. It would be nice if the config\n  # information the python interpreter itself gave us were more complete.\n  find_library(\n    PYTHON_LIBRARY\n    NAMES \"python${PYTHON_LIBRARY_SUFFIX}\"\n    PATHS ${_PYTHON_LIBS_SEARCH}\n    NO_DEFAULT_PATH)\n\n  # If all else fails, just set the name/version and let the linker figure out the path.\n  if(NOT PYTHON_LIBRARY)\n    set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})\n  endif()\nendif()\n\nmark_as_advanced(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)\n\n# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the\n# cache entries because they are meant to specify the location of a single\n# library. We now set the variables listed by the documentation for this\n# module.\nset(PYTHON_INCLUDE_DIRS \"${PYTHON_INCLUDE_DIR}\")\nset(PYTHON_LIBRARIES \"${PYTHON_LIBRARY}\")\nif(NOT PYTHON_DEBUG_LIBRARY)\n  set(PYTHON_DEBUG_LIBRARY \"\")\nendif()\nset(PYTHON_DEBUG_LIBRARIES \"${PYTHON_DEBUG_LIBRARY}\")\n\nfind_package_message(PYTHON \"Found PythonLibs: ${PYTHON_LIBRARY}\"\n                     \"${PYTHON_EXECUTABLE}${PYTHON_VERSION_STRING}\")\n\nset(PYTHONLIBS_FOUND TRUE)\nset(PythonLibsNew_FOUND TRUE)\n\nif(NOT PYTHON_MODULE_PREFIX)\n  set(PYTHON_MODULE_PREFIX \"\")\nendif()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/JoinPaths.cmake",
    "content": "# This module provides function for joining paths\n# known from most languages\n#\n# SPDX-License-Identifier: (MIT OR CC0-1.0)\n# Copyright 2020 Jan Tojnar\n# https://github.com/jtojnar/cmake-snips\n#\n# Modelled after Python’s os.path.join\n# https://docs.python.org/3.7/library/os.path.html#os.path.join\n# Windows not supported\nfunction(join_paths joined_path first_path_segment)\n    set(temp_path \"${first_path_segment}\")\n    foreach(current_segment IN LISTS ARGN)\n        if(NOT (\"${current_segment}\" STREQUAL \"\"))\n            if(IS_ABSOLUTE \"${current_segment}\")\n                set(temp_path \"${current_segment}\")\n            else()\n                set(temp_path \"${temp_path}/${current_segment}\")\n            endif()\n        endif()\n    endforeach()\n    set(${joined_path} \"${temp_path}\" PARENT_SCOPE)\nendfunction()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/check-style.sh",
    "content": "#!/bin/bash\n#\n# Script to check include/test code for common pybind11 code style errors.\n#\n# This script currently checks for\n#\n# 1. missing space between keyword and parenthesis, e.g.: for(, if(, while(\n# 2. Missing space between right parenthesis and brace, e.g. 'for (...){'\n# 3. opening brace on its own line. It should always be on the same line as the\n#    if/while/for/do statement.\n#\n# Invoke as: tools/check-style.sh <filenames>\n#\n\ncheck_style_errors=0\nIFS=$'\\n'\n\n\nfound=\"$(grep '\\<\\(if\\|for\\|while\\|catch\\)(\\|){' \"$@\" -rn --color=always)\"\nif [ -n \"$found\" ]; then\n    echo -e '\\033[31;01mError: found the following coding style problems:\\033[0m'\n    check_style_errors=1\n    echo \"${found//^/    /}\"\nfi\n\nfound=\"$(awk '\nfunction prefix(filename, lineno) {\n    return \"    \\033[35m\" filename \"\\033[36m:\\033[32m\" lineno \"\\033[36m:\\033[0m\"\n}\nfunction mark(pattern, string) { sub(pattern, \"\\033[01;31m&\\033[0m\", string); return string }\nlast && /^\\s*{/ {\n    print prefix(FILENAME, FNR-1) mark(\"\\\\)\\\\s*$\", last)\n    print prefix(FILENAME, FNR)   mark(\"^\\\\s*{\", $0)\n    last=\"\"\n}\n{ last = /(if|for|while|catch|switch)\\s*\\(.*\\)\\s*$/ ? $0 : \"\" }\n' \"$(find include -type f)\" \"$@\")\"\nif [ -n \"$found\" ]; then\n    check_style_errors=1\n    echo -e '\\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\\033[0m'\n    echo \"$found\"\nfi\n\nexit $check_style_errors\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/cmake_uninstall.cmake.in",
    "content": "# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake\n\nif(NOT EXISTS \"@CMAKE_BINARY_DIR@/install_manifest.txt\")\n  message(FATAL_ERROR \"Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt\")\nendif()\n\nfile(READ \"@CMAKE_BINARY_DIR@/install_manifest.txt\" files)\nstring(REGEX REPLACE \"\\n\" \";\" files \"${files}\")\nforeach(file ${files})\n  message(STATUS \"Uninstalling $ENV{DESTDIR}${file}\")\n  if(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    exec_program(\n      \"@CMAKE_COMMAND@\" ARGS\n      \"-E remove \\\"$ENV{DESTDIR}${file}\\\"\"\n      OUTPUT_VARIABLE rm_out\n      RETURN_VALUE rm_retval)\n    if(NOT \"${rm_retval}\" STREQUAL 0)\n      message(FATAL_ERROR \"Problem when removing $ENV{DESTDIR}${file}\")\n    endif()\n  else(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    message(STATUS \"File $ENV{DESTDIR}${file} does not exist.\")\n  endif()\nendforeach()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/codespell_ignore_lines_from_errors.py",
    "content": "\"\"\"Simple script for rebuilding .codespell-ignore-lines\n\nUsage:\n\ncat < /dev/null > .codespell-ignore-lines\npre-commit run --all-files codespell >& /tmp/codespell_errors.txt\npython3 tools/codespell_ignore_lines_from_errors.py /tmp/codespell_errors.txt > .codespell-ignore-lines\n\ngit diff to review changes, then commit, push.\n\"\"\"\n\nimport sys\nfrom typing import List\n\n\ndef run(args: List[str]) -> None:\n    assert len(args) == 1, \"codespell_errors.txt\"\n    cache = {}\n    done = set()\n    for line in sorted(open(args[0]).read().splitlines()):\n        i = line.find(\" ==> \")\n        if i > 0:\n            flds = line[:i].split(\":\")\n            if len(flds) >= 2:\n                filename, line_num = flds[:2]\n                if filename not in cache:\n                    cache[filename] = open(filename).read().splitlines()\n                supp = cache[filename][int(line_num) - 1]\n                if supp not in done:\n                    print(supp)\n                    done.add(supp)\n\n\nif __name__ == \"__main__\":\n    run(args=sys.argv[1:])\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/libsize.py",
    "content": "import os\nimport sys\n\n# Internal build script for generating debugging test .so size.\n# Usage:\n#     python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the\n#                                           size in it, then overwrites save.txt with the new size for future runs.\n\nif len(sys.argv) != 3:\n    sys.exit(\"Invalid arguments: usage: python libsize.py file.so save.txt\")\n\nlib = sys.argv[1]\nsave = sys.argv[2]\n\nif not os.path.exists(lib):\n    sys.exit(f\"Error: requested file ({lib}) does not exist\")\n\nlibsize = os.path.getsize(lib)\n\nprint(\"------\", os.path.basename(lib), \"file size:\", libsize, end=\"\")\n\nif os.path.exists(save):\n    with open(save) as sf:\n        oldsize = int(sf.readline())\n\n    if oldsize > 0:\n        change = libsize - oldsize\n        if change == 0:\n            print(\" (no change)\")\n        else:\n            print(f\" (change of {change:+} bytes = {change / oldsize:+.2%})\")\nelse:\n    print()\n\nwith open(save, \"w\") as sf:\n    sf.write(str(libsize))\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/make_changelog.py",
    "content": "#!/usr/bin/env python3\n\nimport re\n\nimport ghapi.all\nfrom rich import print\nfrom rich.syntax import Syntax\n\nENTRY = re.compile(\n    r\"\"\"\n    Suggested \\s changelog \\s entry:\n    .*\n    ```rst\n    \\s*\n    (.*?)\n    \\s*\n    ```\n\"\"\",\n    re.DOTALL | re.VERBOSE,\n)\n\nprint()\n\n\napi = ghapi.all.GhApi(owner=\"pybind\", repo=\"pybind11\")\n\nissues_pages = ghapi.page.paged(\n    api.issues.list_for_repo, labels=\"needs changelog\", state=\"closed\"\n)\nissues = (issue for page in issues_pages for issue in page)\nmissing = []\n\nfor issue in issues:\n    changelog = ENTRY.findall(issue.body)\n    if changelog:\n        (msg,) = changelog\n        if not msg.startswith(\"* \"):\n            msg = \"* \" + msg\n        if not msg.endswith(\".\"):\n            msg += \".\"\n\n        msg += f\"\\n  `#{issue.number} <{issue.html_url}>`_\"\n\n        print(Syntax(msg, \"rst\", theme=\"ansi_light\", word_wrap=True))\n        print()\n\n    else:\n        missing.append(issue)\n\nif missing:\n    print()\n    print(\"[blue]\" + \"-\" * 30)\n    print()\n\n    for issue in missing:\n        print(f\"[red bold]Missing:[/red bold][red] {issue.title}\")\n        print(f\"[red]  {issue.html_url}\\n\")\n\n    print(\"[bold]Template:\\n\")\n    msg = \"## Suggested changelog entry:\\n\\n```rst\\n\\n```\"\n    print(Syntax(msg, \"md\", theme=\"ansi_light\"))\n\nprint()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pybind11.pc.in",
    "content": "prefix=@prefix_for_pc_file@\nincludedir=@includedir_for_pc_file@\n\nName: @PROJECT_NAME@\nDescription: Seamless operability between C++11 and Python\nVersion: @PROJECT_VERSION@\nCflags: -I${includedir}\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pybind11Common.cmake",
    "content": "#[======================================================[.rst\n\nAdds the following targets::\n\n    pybind11::pybind11 - link to headers and pybind11\n    pybind11::module - Adds module links\n    pybind11::embed - Adds embed links\n    pybind11::lto - Link time optimizations (manual selection)\n    pybind11::thin_lto - Link time optimizations (manual selection)\n    pybind11::python_link_helper - Adds link to Python libraries\n    pybind11::windows_extras - MSVC bigobj and mp for building multithreaded\n    pybind11::opt_size - avoid optimizations that increase code size\n\nAdds the following functions::\n\n    pybind11_strip(target) - strip target after building on linux/macOS\n    pybind11_find_import(module) - See if a module is installed.\n\n#]======================================================]\n\n# CMake 3.10 has an include_guard command, but we can't use that yet\n# include_guard(global) (pre-CMake 3.10)\nif(TARGET pybind11::lto)\n  return()\nendif()\n\n# If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we\n# are in CONFIG mode, they should be \"normal\" targets instead.\n# In CMake 3.11+ you can promote a target to global after you create it,\n# which might be simpler than this check.\nget_property(\n  is_config\n  TARGET pybind11::headers\n  PROPERTY IMPORTED)\nif(NOT is_config)\n  set(optional_global GLOBAL)\nendif()\n\n# If not run in Python mode, we still would like this to at least\n# include pybind11's include directory:\nset(pybind11_INCLUDE_DIRS\n    \"${pybind11_INCLUDE_DIR}\"\n    CACHE INTERNAL \"Include directory for pybind11 (Python not requested)\")\n\n# --------------------- Shared targets ----------------------------\n\n# Build an interface library target:\nadd_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::pybind11\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)\n\n# Build a module target:\nadd_library(pybind11::module IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::module\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)\n\n# Build an embed library target:\nadd_library(pybind11::embed IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::embed\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)\n\n# --------------------------- link helper ---------------------------\n\nadd_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})\n\nif(CMAKE_VERSION VERSION_LESS 3.13)\n  # In CMake 3.11+, you can set INTERFACE properties via the normal methods, and\n  # this would be simpler.\n  set_property(\n    TARGET pybind11::python_link_helper\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES \"$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>\")\nelse()\n  # link_options was added in 3.13+\n  # This is safer, because you are ensured the deduplication pass in CMake will not consider\n  # these separate and remove one but not the other.\n  set_property(\n    TARGET pybind11::python_link_helper\n    APPEND\n    PROPERTY INTERFACE_LINK_OPTIONS \"$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>\")\nendif()\n\n# ------------------------ Windows extras -------------------------\n\nadd_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})\n\nif(MSVC) # That's also clang-cl\n  # /bigobj is needed for bigger binding projects due to the limit to 64k\n  # addressable sections\n  set_property(\n    TARGET pybind11::windows_extras\n    APPEND\n    PROPERTY INTERFACE_COMPILE_OPTIONS $<$<COMPILE_LANGUAGE:CXX>:/bigobj>)\n\n  # /MP enables multithreaded builds (relevant when there are many files) for MSVC\n  if(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"MSVC\") # no Clang no Intel\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      set_property(\n        TARGET pybind11::windows_extras\n        APPEND\n        PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)\n    else()\n      # Only set these options for C++ files.  This is important so that, for\n      # instance, projects that include other types of source files like CUDA\n      # .cu files don't get these options propagated to nvcc since that would\n      # cause the build to fail.\n      set_property(\n        TARGET pybind11::windows_extras\n        APPEND\n        PROPERTY INTERFACE_COMPILE_OPTIONS\n                 $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)\n    endif()\n  endif()\nendif()\n\n# ----------------------- Optimize binary size --------------------------\n\nadd_library(pybind11::opt_size IMPORTED INTERFACE ${optional_global})\n\nif(MSVC)\n  set(PYBIND11_OPT_SIZE /Os)\nelse()\n  set(PYBIND11_OPT_SIZE -Os)\nendif()\n\nset_property(\n  TARGET pybind11::opt_size\n  APPEND\n  PROPERTY INTERFACE_COMPILE_OPTIONS $<$<CONFIG:Release>:${PYBIND11_OPT_SIZE}>\n           $<$<CONFIG:MinSizeRel>:${PYBIND11_OPT_SIZE}>\n           $<$<CONFIG:RelWithDebInfo>:${PYBIND11_OPT_SIZE}>)\n\n# ----------------------- Legacy option --------------------------\n\n# Warn or error if old variable name used\nif(PYBIND11_CPP_STANDARD)\n  string(REGEX MATCH [[..$]] VAL \"${PYBIND11_CPP_STANDARD}\")\n  if(CMAKE_CXX_STANDARD)\n    if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)\n      message(WARNING \"CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match \"\n                      \"PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, \"\n                      \"please remove PYBIND11_CPP_STANDARD from your cache\")\n    endif()\n  else()\n    set(supported_standards 11 14 17 20)\n    if(\"${VAL}\" IN_LIST supported_standards)\n      message(WARNING \"USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_CPP_STANDARD\")\n      set(CMAKE_CXX_STANDARD\n          ${VAL}\n          CACHE STRING \"From PYBIND11_CPP_STANDARD\")\n    else()\n      message(FATAL_ERROR \"PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD \"\n                          \"(last two chars: ${VAL} not understood as a valid CXX std)\")\n    endif()\n  endif()\nendif()\n\n# --------------------- Python specifics -------------------------\n\n# Check to see which Python mode we are in, new, old, or no python\nif(PYBIND11_NOPYTHON)\n  set(_pybind11_nopython ON)\nelseif(\n  PYBIND11_FINDPYTHON\n  OR Python_FOUND\n  OR Python2_FOUND\n  OR Python3_FOUND)\n  # New mode\n  include(\"${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake\")\n\nelse()\n\n  # Classic mode\n  include(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake\")\n\nendif()\n\n# --------------------- pybind11_find_import -------------------------------\n\nif(NOT _pybind11_nopython)\n  # Check to see if modules are importable. Use REQUIRED to force an error if\n  # one of the modules is not found. <package_name>_FOUND will be set if the\n  # package was found (underscores replace dashes if present). QUIET will hide\n  # the found message, and VERSION will require a minimum version. A successful\n  # find will cache the result.\n  function(pybind11_find_import PYPI_NAME)\n    # CMake variables need underscores (PyPI doesn't care)\n    string(REPLACE \"-\" \"_\" NORM_PYPI_NAME \"${PYPI_NAME}\")\n\n    # Return if found previously\n    if(${NORM_PYPI_NAME}_FOUND)\n      return()\n    endif()\n\n    set(options \"REQUIRED;QUIET\")\n    set(oneValueArgs \"VERSION\")\n    cmake_parse_arguments(ARG \"${options}\" \"${oneValueArgs}\" \"\" ${ARGN})\n\n    if(ARG_REQUIRED)\n      set(status_level FATAL_ERROR)\n    else()\n      set(status_level WARNING)\n    endif()\n\n    execute_process(\n      COMMAND\n        ${${_Python}_EXECUTABLE} -c\n        \"from pkg_resources import get_distribution; print(get_distribution('${PYPI_NAME}').version)\"\n      RESULT_VARIABLE RESULT_PRESENT\n      OUTPUT_VARIABLE PKG_VERSION\n      ERROR_QUIET)\n\n    string(STRIP \"${PKG_VERSION}\" PKG_VERSION)\n\n    # If a result is present, this failed\n    if(RESULT_PRESENT)\n      set(${NORM_PYPI_NAME}_FOUND\n          ${NORM_PYPI_NAME}-NOTFOUND\n          CACHE INTERNAL \"\")\n      # Always warn or error\n      message(\n        ${status_level}\n        \"Missing: ${PYPI_NAME} ${ARG_VERSION}\\nTry: ${${_Python}_EXECUTABLE} -m pip install ${PYPI_NAME}\"\n      )\n    else()\n      if(ARG_VERSION AND PKG_VERSION VERSION_LESS ARG_VERSION)\n        message(\n          ${status_level}\n          \"Version incorrect: ${PYPI_NAME} ${PKG_VERSION} found, ${ARG_VERSION} required - try upgrading\"\n        )\n      else()\n        set(${NORM_PYPI_NAME}_FOUND\n            YES\n            CACHE INTERNAL \"\")\n        set(${NORM_PYPI_NAME}_VERSION\n            ${PKG_VERSION}\n            CACHE INTERNAL \"\")\n      endif()\n      if(NOT ARG_QUIET)\n        message(STATUS \"Found ${PYPI_NAME} ${PKG_VERSION}\")\n      endif()\n    endif()\n    if(NOT ARG_VERSION OR (NOT PKG_VERSION VERSION_LESS ARG_VERSION))\n      # We have successfully found a good version, cache to avoid calling again.\n    endif()\n  endfunction()\nendif()\n\n# --------------------- LTO -------------------------------\n\ninclude(CheckCXXCompilerFlag)\n\n# Checks whether the given CXX/linker flags can compile and link a cxx file.\n# cxxflags and linkerflags are lists of flags to use.  The result variable is a\n# unique variable name for each set of flags: the compilation result will be\n# cached base on the result variable.  If the flags work, sets them in\n# cxxflags_out/linkerflags_out internal cache variables (in addition to\n# ${result}).\nfunction(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out\n         linkerflags_out)\n  set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})\n  check_cxx_compiler_flag(\"${cxxflags}\" ${result})\n  if(${result})\n    set(${cxxflags_out}\n        \"${cxxflags}\"\n        PARENT_SCOPE)\n    set(${linkerflags_out}\n        \"${linkerflags}\"\n        PARENT_SCOPE)\n  endif()\nendfunction()\n\nfunction(_pybind11_generate_lto target prefer_thin_lto)\n  if(MINGW)\n    message(STATUS \"${target} disabled (problems with undefined symbols for MinGW for now)\")\n    return()\n  endif()\n\n  if(CMAKE_CXX_COMPILER_ID MATCHES \"GNU|Clang\")\n    set(cxx_append \"\")\n    set(linker_append \"\")\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\" AND NOT APPLE)\n      # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it\n      set(linker_append \";$<$<CONFIG:MinSizeRel>:-O3>\")\n    elseif(CMAKE_CXX_COMPILER_ID MATCHES \"GNU\" AND NOT MINGW)\n      set(cxx_append \";-fno-fat-lto-objects\")\n    endif()\n\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"ppc64le\" OR CMAKE_SYSTEM_PROCESSOR MATCHES \"mips64\")\n      set(NO_FLTO_ARCH TRUE)\n    else()\n      set(NO_FLTO_ARCH FALSE)\n    endif()\n\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\"\n       AND prefer_thin_lto\n       AND NOT NO_FLTO_ARCH)\n      _pybind11_return_if_cxx_and_linker_flags_work(\n        HAS_FLTO_THIN \"-flto=thin${cxx_append}\" \"-flto=thin${linker_append}\"\n        PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n    endif()\n\n    if(NOT HAS_FLTO_THIN AND NOT NO_FLTO_ARCH)\n      _pybind11_return_if_cxx_and_linker_flags_work(\n        HAS_FLTO \"-flto${cxx_append}\" \"-flto${linker_append}\" PYBIND11_LTO_CXX_FLAGS\n        PYBIND11_LTO_LINKER_FLAGS)\n    endif()\n  elseif(CMAKE_CXX_COMPILER_ID MATCHES \"Intel\")\n    # Intel equivalent to LTO is called IPO\n    _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO \"-ipo\" \"-ipo\"\n                                                  PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n  elseif(MSVC)\n    # cmake only interprets libraries as linker flags when they start with a - (otherwise it\n    # converts /LTCG to \\LTCG as if it was a Windows path).  Luckily MSVC supports passing flags\n    # with - instead of /, even if it is a bit non-standard:\n    _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG \"/GL\" \"-LTCG\"\n                                                  PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n  endif()\n\n  # Enable LTO flags if found, except for Debug builds\n  if(PYBIND11_LTO_CXX_FLAGS)\n    # CONFIG takes multiple values in CMake 3.19+, until then we have to use OR\n    set(is_debug \"$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>\")\n    set(not_debug \"$<NOT:${is_debug}>\")\n    set(cxx_lang \"$<COMPILE_LANGUAGE:CXX>\")\n    if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)\n      set(genex \"${not_debug}\")\n    else()\n      set(genex \"$<AND:${not_debug},${cxx_lang}>\")\n    endif()\n    set_property(\n      TARGET ${target}\n      APPEND\n      PROPERTY INTERFACE_COMPILE_OPTIONS \"$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>\")\n    if(CMAKE_PROJECT_NAME STREQUAL \"pybind11\")\n      message(STATUS \"${target} enabled\")\n    endif()\n  else()\n    if(CMAKE_PROJECT_NAME STREQUAL \"pybind11\")\n      message(STATUS \"${target} disabled (not supported by the compiler and/or linker)\")\n    endif()\n  endif()\n\n  if(PYBIND11_LTO_LINKER_FLAGS)\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      set_property(\n        TARGET ${target}\n        APPEND\n        PROPERTY INTERFACE_LINK_LIBRARIES \"$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>\")\n    else()\n      set_property(\n        TARGET ${target}\n        APPEND\n        PROPERTY INTERFACE_LINK_OPTIONS \"$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>\")\n    endif()\n  endif()\nendfunction()\n\nadd_library(pybind11::lto IMPORTED INTERFACE ${optional_global})\n_pybind11_generate_lto(pybind11::lto FALSE)\n\nadd_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})\n_pybind11_generate_lto(pybind11::thin_lto TRUE)\n\n# ---------------------- pybind11_strip -----------------------------\n\nfunction(pybind11_strip target_name)\n  # Strip unnecessary sections of the binary on Linux/macOS\n  if(CMAKE_STRIP)\n    if(APPLE)\n      set(x_opt -x)\n    endif()\n\n    add_custom_command(\n      TARGET ${target_name}\n      POST_BUILD\n      COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)\n  endif()\nendfunction()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pybind11Config.cmake.in",
    "content": "#[=============================================================================[.rst:\n\npybind11Config.cmake\n####################\n\nExported variables\n==================\n\nThis module sets the following variables in your project:\n\n``pybind11_FOUND``\n  true if pybind11 and all required components found on the system\n``pybind11_VERSION``\n  pybind11 version in format Major.Minor.Release\n``pybind11_VERSION_TYPE``\n  pybind11 version type (``dev*`` or empty for a release)\n``pybind11_INCLUDE_DIRS``\n  Directories where pybind11 and python headers are located.\n``pybind11_INCLUDE_DIR``\n  Directory where pybind11 headers are located.\n``pybind11_DEFINITIONS``\n  Definitions necessary to use pybind11, namely USING_pybind11.\n``pybind11_LIBRARIES``\n  Compile flags and python libraries (as needed) to link against.\n``pybind11_LIBRARY``\n  Empty.\n\nAvailable components: None\n\n\nExported targets\n================\n\nIf pybind11 is found, this module defines the following ``IMPORTED``\ninterface library targets:\n\n``pybind11::module``\n  for extension modules.\n``pybind11::embed``\n  for embedding the Python interpreter.\n\nPython headers, libraries (as needed by platform), and the C++ standard\nare attached to the target.\n\nAdvanced targets are also supplied - these are primary for users building\ncomplex applications, and they are available in all modes:\n\n``pybind11::headers``\n  Just the pybind11 headers and minimum compile requirements.\n``pybind11::pybind11``\n  Python headers too.\n``pybind11::python_link_helper``\n  Just the \"linking\" part of ``pybind11:module``, for CMake < 3.15.\n``pybind11::thin_lto``\n  An alternative to ``INTERPROCEDURAL_OPTIMIZATION``.\n``pybind11::lto``\n  An alternative to ``INTERPROCEDURAL_OPTIMIZATION`` (also avoids thin LTO on clang).\n``pybind11::windows_extras``\n  Adds bigobj and mp for MSVC.\n\nModes\n=====\n\nThere are two modes provided; classic, which is built on the old Python\ndiscovery packages in CMake, or the new FindPython mode, which uses FindPython\nfrom 3.12+ forward (3.15+ _highly_ recommended).\n\nNew FindPython mode\n^^^^^^^^^^^^^^^^^^^\n\nTo activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``\nbefore finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,\nyou can either use the basic targets, or use the FindPython tools:\n\n.. code-block:: cmake\n\n  find_package(Python COMPONENTS Interpreter Development)\n  find_package(pybind11 CONFIG)\n\n  # pybind11 method:\n  pybind11_add_module(MyModule1 src1.cpp)\n\n  # Python method:\n  Python_add_library(MyModule2 src2.cpp)\n  target_link_libraries(MyModule2 pybind11::headers)\n  set_target_properties(MyModule2 PROPERTIES\n                                  INTERPROCEDURAL_OPTIMIZATION ON\n                                  CXX_VISIBILITY_PRESET ON\n                                  VISIBILITY_INLINES_HIDDEN ON)\n\nIf you build targets yourself, you may be interested in stripping the output\nfor reduced size; this is the one other feature that the helper function gives you.\n\nClassic mode\n^^^^^^^^^^^^\n\nSet PythonLibsNew variables to influence python detection and\nCMAKE_CXX_STANDARD to influence standard setting.\n\n.. code-block:: cmake\n\n  find_package(pybind11 CONFIG REQUIRED)\n\n  # Create an extension module\n  add_library(mylib MODULE main.cpp)\n  target_link_libraries(mylib PUBLIC pybind11::module)\n\n  # Or embed the Python interpreter into an executable\n  add_executable(myexe main.cpp)\n  target_link_libraries(myexe PUBLIC pybind11::embed)\n\n\nHints\n=====\n\nThe following variables can be set to guide the search for this package:\n\n``pybind11_DIR``\n  CMake variable, set to directory containing this Config file.\n``CMAKE_PREFIX_PATH``\n  CMake variable, set to root directory of this package.\n``PATH``\n  Environment variable, set to bin directory of this package.\n``CMAKE_DISABLE_FIND_PACKAGE_pybind11``\n  CMake variable, disables ``find_package(pybind11)`` when not ``REQUIRED``,\n  perhaps to force internal build.\n\nCommands\n========\n\npybind11_add_module\n^^^^^^^^^^^^^^^^^^^\n\nThis module defines the following commands to assist with creating Python modules:\n\n.. code-block:: cmake\n\n  pybind11_add_module(<target>\n    [STATIC|SHARED|MODULE]\n    [THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]\n    <files>...\n    )\n\nAdd a module and setup all helpers. You can select the type of the library; the\ndefault is ``MODULE``. There are several options:\n\n``OPT_SIZE``\n  Optimize for size, even if the ``CMAKE_BUILD_TYPE`` is not ``MinSizeRel``.\n``THIN_LTO``\n  Use thin TLO instead of regular if there's a choice (pybind11's selection\n  is disabled if ``CMAKE_INTERPROCEDURAL_OPTIMIZATIONS`` is set).\n``WITHOUT_SOABI``\n  Disable the SOABI component (``PYBIND11_NEWPYTHON`` mode only).\n``NO_EXTRAS``\n  Disable all extras, exit immediately after making the module.\n\npybind11_strip\n^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n  pybind11_strip(<target>)\n\nStrip a target after building it (linux/macOS), called by ``pybind11_add_module``.\n\npybind11_extension\n^^^^^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n    pybind11_extension(<target>)\n\nSets the Python extension name correctly for Python on your platform, called by\n``pybind11_add_module``.\n\npybind11_find_import(module)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n    pybind11_find_import(<module> [VERSION <number>] [REQUIRED] [QUIET])\n\nSee if a module is installed. Use the registered name (the one on PyPI). You\ncan specify a ``VERSION``, and you can specify ``REQUIRED`` or ``QUIET``. Only available if\n``NOPYTHON`` mode is not active.  Sets ``module_VERSION`` and ``module_FOUND``. Caches the\nresult once a valid install is found.\n\nSuggested usage\n===============\n\nUsing ``find_package`` with version info is not recommended except for release versions.\n\n.. code-block:: cmake\n\n  find_package(pybind11 CONFIG)\n  find_package(pybind11 2.9 EXACT CONFIG REQUIRED)\n\n#]=============================================================================]\n@PACKAGE_INIT@\n\n# Location of pybind11/pybind11.h\n# This will be relative unless explicitly set as absolute\nset(pybind11_INCLUDE_DIR \"@pybind11_INCLUDEDIR@\")\n\nset(pybind11_LIBRARY \"\")\nset(pybind11_DEFINITIONS USING_pybind11)\nset(pybind11_VERSION_TYPE \"@pybind11_VERSION_TYPE@\")\n\ncheck_required_components(pybind11)\n\nif(TARGET pybind11::python_link_helper)\n  # This has already been setup elsewhere, such as with a previous call or\n  # add_subdirectory\n  return()\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake\")\n\n# Easier to use / remember\nadd_library(pybind11::headers IMPORTED INTERFACE)\nset_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES\n                                                   pybind11::pybind11_headers)\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake\")\n\nif(NOT pybind11_FIND_QUIETLY)\n  message(\n    STATUS\n      \"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \\\"${pybind11_VERSION}${pybind11_VERSION_TYPE}\\\")\"\n  )\nendif()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pybind11NewTools.cmake",
    "content": "# tools/pybind11NewTools.cmake -- Build system for the pybind11 modules\n#\n# Copyright (c) 2020 Wenzel Jakob <wenzel@inf.ethz.ch> and Henry Schreiner\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\nif(CMAKE_VERSION VERSION_LESS 3.12)\n  message(FATAL_ERROR \"You cannot use the new FindPython module with CMake < 3.12\")\nendif()\n\ninclude_guard(GLOBAL)\n\nget_property(\n  is_config\n  TARGET pybind11::headers\n  PROPERTY IMPORTED)\n\nif(pybind11_FIND_QUIETLY)\n  set(_pybind11_quiet QUIET)\nelse()\n  set(_pybind11_quiet \"\")\nendif()\n\nif(NOT Python_FOUND AND NOT Python3_FOUND)\n  if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)\n    set(Python_FIND_IMPLEMENTATIONS CPython PyPy)\n  endif()\n\n  # GitHub Actions like activation\n  if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})\n    set(Python_ROOT_DIR \"$ENV{pythonLocation}\")\n  endif()\n\n  find_package(Python 3.6 REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})\n\n  # If we are in submodule mode, export the Python targets to global targets.\n  # If this behavior is not desired, FindPython _before_ pybind11.\n  if(NOT is_config)\n    set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)\n    set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)\n    if(TARGET Python::Module)\n      set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)\n    endif()\n  endif()\nendif()\n\nif(Python_FOUND)\n  set(_Python\n      Python\n      CACHE INTERNAL \"\" FORCE)\nelseif(Python3_FOUND)\n  set(_Python\n      Python3\n      CACHE INTERNAL \"\" FORCE)\nendif()\n\nif(PYBIND11_MASTER_PROJECT)\n  if(${_Python}_INTERPRETER_ID MATCHES \"PyPy\")\n    message(STATUS \"PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})\")\n  else()\n    message(STATUS \"${_Python} ${${_Python}_VERSION}\")\n  endif()\nendif()\n\n# If a user finds Python, they may forget to include the Interpreter component\n# and the following two steps require it. It is highly recommended by CMake\n# when finding development libraries anyway, so we will require it.\nif(NOT DEFINED ${_Python}_EXECUTABLE)\n  message(\n    FATAL_ERROR\n      \"${_Python} was found without the Interpreter component. Pybind11 requires this component.\")\n\nendif()\n\nif(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)\n  # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed\n  unset(PYTHON_IS_DEBUG CACHE)\n  unset(PYTHON_MODULE_EXTENSION CACHE)\n  set(PYBIND11_PYTHON_EXECUTABLE_LAST\n      \"${${_Python}_EXECUTABLE}\"\n      CACHE INTERNAL \"Python executable during the last CMake run\")\nendif()\n\nif(NOT DEFINED PYTHON_IS_DEBUG)\n  # Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter\n  execute_process(\n    COMMAND \"${${_Python}_EXECUTABLE}\" \"-c\"\n            \"import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))\"\n    RESULT_VARIABLE _PYTHON_IS_DEBUG)\n  set(PYTHON_IS_DEBUG\n      \"${_PYTHON_IS_DEBUG}\"\n      CACHE INTERNAL \"Python debug status\")\nendif()\n\n# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is\n# required for PyPy3 (as of 7.3.1)\nif(NOT DEFINED PYTHON_MODULE_EXTENSION)\n  execute_process(\n    COMMAND\n      \"${${_Python}_EXECUTABLE}\" \"-c\"\n      \"import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))\"\n    OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION\n    ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR\n    OUTPUT_STRIP_TRAILING_WHITESPACE)\n\n  if(_PYTHON_MODULE_EXTENSION STREQUAL \"\")\n    message(\n      FATAL_ERROR \"pybind11 could not query the module file extension, likely the 'distutils'\"\n                  \"package is not installed. Full error message:\\n${_PYTHON_MODULE_EXTENSION_ERR}\")\n  endif()\n\n  # This needs to be available for the pybind11_extension function\n  set(PYTHON_MODULE_EXTENSION\n      \"${_PYTHON_MODULE_EXTENSION}\"\n      CACHE INTERNAL \"\")\nendif()\n\n# Python debug libraries expose slightly different objects before 3.8\n# https://docs.python.org/3.6/c-api/intro.html#debugging-builds\n# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib\nif(PYTHON_IS_DEBUG)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)\nendif()\n\n# Check on every access - since Python can change - do nothing in that case.\n\nif(DEFINED ${_Python}_INCLUDE_DIRS)\n  # Only add Python for build - must be added during the import for config\n  # since it has to be re-discovered.\n  #\n  # This needs to be a target to be included after the local pybind11\n  # directory, just in case there there is an installed pybind11 sitting\n  # next to Python's includes. It also ensures Python is a SYSTEM library.\n  add_library(pybind11::python_headers INTERFACE IMPORTED)\n  set_property(\n    TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                             \"$<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>\")\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)\n  set(pybind11_INCLUDE_DIRS\n      \"${pybind11_INCLUDE_DIR}\" \"${${_Python}_INCLUDE_DIRS}\"\n      CACHE INTERNAL \"Directories where pybind11 and possibly Python headers are located\")\nendif()\n\n# In CMake 3.18+, you can find these separately, so include an if\nif(TARGET ${_Python}::Python)\n  set_property(\n    TARGET pybind11::embed\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Python)\nendif()\n\n# CMake 3.15+ has this\nif(TARGET ${_Python}::Module)\n  set_property(\n    TARGET pybind11::module\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)\nelse()\n  set_property(\n    TARGET pybind11::module\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)\nendif()\n\n# WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.\n# WITH_SOABI is passed on to python_add_library.\nfunction(pybind11_add_module target_name)\n  cmake_parse_arguments(PARSE_ARGV 1 ARG\n                        \"STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI\" \"\" \"\")\n\n  if(ARG_STATIC)\n    set(lib_type STATIC)\n  elseif(ARG_SHARED)\n    set(lib_type SHARED)\n  else()\n    set(lib_type MODULE)\n  endif()\n\n  if(\"${_Python}\" STREQUAL \"Python\")\n    python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})\n  elseif(\"${_Python}\" STREQUAL \"Python3\")\n    python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})\n  else()\n    message(FATAL_ERROR \"Cannot detect FindPython version: ${_Python}\")\n  endif()\n\n  target_link_libraries(${target_name} PRIVATE pybind11::headers)\n\n  if(lib_type STREQUAL \"MODULE\")\n    target_link_libraries(${target_name} PRIVATE pybind11::module)\n  else()\n    target_link_libraries(${target_name} PRIVATE pybind11::embed)\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  # -fvisibility=hidden is required to allow multiple modules compiled against\n  # different pybind versions to work properly, and for some features (e.g.\n  # py::module_local).  We force it on everything inside the `pybind11`\n  # namespace; also turning it on for a pybind module compilation here avoids\n  # potential warnings or issues from having mixed hidden/non-hidden types.\n  if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions\n  if(NOT ARG_WITHOUT_SOABI AND NOT \"WITH_SOABI\" IN_LIST ARG_UNPARSED_ARGUMENTS)\n    pybind11_extension(${target_name})\n  endif()\n\n  if(ARG_NO_EXTRAS)\n    return()\n  endif()\n\n  if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)\n    if(ARG_THIN_LTO)\n      target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)\n    else()\n      target_link_libraries(${target_name} PRIVATE pybind11::lto)\n    endif()\n  endif()\n\n  # Use case-insensitive comparison to match the result of $<CONFIG:cfgs>\n  string(TOUPPER \"${CMAKE_BUILD_TYPE}\" uppercase_CMAKE_BUILD_TYPE)\n  if(NOT MSVC AND NOT \"${uppercase_CMAKE_BUILD_TYPE}\" MATCHES DEBUG|RELWITHDEBINFO)\n    # Strip unnecessary sections of the binary on Linux/macOS\n    pybind11_strip(${target_name})\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  if(ARG_OPT_SIZE)\n    target_link_libraries(${target_name} PRIVATE pybind11::opt_size)\n  endif()\nendfunction()\n\nfunction(pybind11_extension name)\n  # The extension is precomputed\n  set_target_properties(${name} PROPERTIES PREFIX \"\" SUFFIX \"${PYTHON_MODULE_EXTENSION}\")\n\nendfunction()\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pybind11Tools.cmake",
    "content": "# tools/pybind11Tools.cmake -- Build system for the pybind11 modules\n#\n# Copyright (c) 2020 Wenzel Jakob <wenzel.jakob@epfl.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\n# include_guard(global) (pre-CMake 3.10)\nif(TARGET pybind11::python_headers)\n  return()\nendif()\n\n# Built-in in CMake 3.5+\ninclude(CMakeParseArguments)\n\nif(pybind11_FIND_QUIETLY)\n  set(_pybind11_quiet QUIET)\nelse()\n  set(_pybind11_quiet \"\")\nendif()\n\n# If this is the first run, PYTHON_VERSION can stand in for PYBIND11_PYTHON_VERSION\nif(NOT DEFINED PYBIND11_PYTHON_VERSION AND DEFINED PYTHON_VERSION)\n  message(WARNING \"Set PYBIND11_PYTHON_VERSION to search for a specific version, not \"\n                  \"PYTHON_VERSION (which is an output). Assuming that is what you \"\n                  \"meant to do and continuing anyway.\")\n  set(PYBIND11_PYTHON_VERSION\n      \"${PYTHON_VERSION}\"\n      CACHE STRING \"Python version to use for compiling modules\")\n  unset(PYTHON_VERSION)\n  unset(PYTHON_VERSION CACHE)\nelseif(DEFINED PYBIND11_PYTHON_VERSION)\n  # If this is set as a normal variable, promote it\n  set(PYBIND11_PYTHON_VERSION\n      \"${PYBIND11_PYTHON_VERSION}\"\n      CACHE STRING \"Python version to use for compiling modules\")\nelse()\n  # Make an empty cache variable.\n  set(PYBIND11_PYTHON_VERSION\n      \"\"\n      CACHE STRING \"Python version to use for compiling modules\")\nendif()\n\n# A user can set versions manually too\nset(Python_ADDITIONAL_VERSIONS\n    \"3.11;3.10;3.9;3.8;3.7;3.6\"\n    CACHE INTERNAL \"\")\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")\nfind_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet})\nlist(REMOVE_AT CMAKE_MODULE_PATH -1)\n\n# Makes a normal variable a cached variable\nmacro(_PYBIND11_PROMOTE_TO_CACHE NAME)\n  set(_tmp_ptc \"${${NAME}}\")\n  # CMake 3.21 complains if a cached variable is shadowed by a normal one\n  unset(${NAME})\n  set(${NAME}\n      \"${_tmp_ptc}\"\n      CACHE INTERNAL \"\")\nendmacro()\n\n# Cache variables so pybind11_add_module can be used in parent projects\n_pybind11_promote_to_cache(PYTHON_INCLUDE_DIRS)\n_pybind11_promote_to_cache(PYTHON_LIBRARIES)\n_pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)\n_pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)\n_pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)\n_pybind11_promote_to_cache(PYTHON_VERSION_MINOR)\n_pybind11_promote_to_cache(PYTHON_VERSION)\n_pybind11_promote_to_cache(PYTHON_IS_DEBUG)\n\nif(PYBIND11_MASTER_PROJECT)\n  if(PYTHON_MODULE_EXTENSION MATCHES \"pypy\")\n    if(NOT DEFINED PYPY_VERSION)\n      execute_process(\n        COMMAND ${PYTHON_EXECUTABLE} -c\n                [=[import sys; sys.stdout.write(\".\".join(map(str, sys.pypy_version_info[:3])))]=]\n        OUTPUT_VARIABLE pypy_version)\n      set(PYPY_VERSION\n          ${pypy_version}\n          CACHE INTERNAL \"\")\n    endif()\n    message(STATUS \"PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})\")\n  else()\n    message(STATUS \"PYTHON ${PYTHON_VERSION}\")\n  endif()\nendif()\n\n# Only add Python for build - must be added during the import for config since\n# it has to be re-discovered.\n#\n# This needs to be an target to it is included after the local pybind11\n# directory, just in case there are multiple versions of pybind11, we want the\n# one we expect.\nadd_library(pybind11::python_headers INTERFACE IMPORTED)\nset_property(TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                      \"$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>\")\nset_property(\n  TARGET pybind11::pybind11\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)\n\nset(pybind11_INCLUDE_DIRS\n    \"${pybind11_INCLUDE_DIR}\" \"${PYTHON_INCLUDE_DIRS}\"\n    CACHE INTERNAL \"Directories where pybind11 and possibly Python headers are located\")\n\n# Python debug libraries expose slightly different objects before 3.8\n# https://docs.python.org/3.6/c-api/intro.html#debugging-builds\n# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib\nif(PYTHON_IS_DEBUG)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)\nendif()\n\n# The <3.11 code here does not support release/debug builds at the same time, like on vcpkg\nif(CMAKE_VERSION VERSION_LESS 3.11)\n  set_property(\n    TARGET pybind11::module\n    APPEND\n    PROPERTY\n      INTERFACE_LINK_LIBRARIES\n      pybind11::python_link_helper\n      \"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>\"\n  )\n\n  set_property(\n    TARGET pybind11::embed\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)\nelse()\n  # The IMPORTED INTERFACE library here is to ensure that \"debug\" and \"release\" get processed outside\n  # of a generator expression - https://gitlab.kitware.com/cmake/cmake/-/issues/18424, as they are\n  # target_link_library keywords rather than real libraries.\n  add_library(pybind11::_ClassicPythonLibraries IMPORTED INTERFACE)\n  target_link_libraries(pybind11::_ClassicPythonLibraries INTERFACE ${PYTHON_LIBRARIES})\n  target_link_libraries(\n    pybind11::module\n    INTERFACE\n      pybind11::python_link_helper\n      \"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:pybind11::_ClassicPythonLibraries>\")\n\n  target_link_libraries(pybind11::embed INTERFACE pybind11::pybind11\n                                                  pybind11::_ClassicPythonLibraries)\nendif()\n\nfunction(pybind11_extension name)\n  # The prefix and extension are provided by FindPythonLibsNew.cmake\n  set_target_properties(${name} PROPERTIES PREFIX \"${PYTHON_MODULE_PREFIX}\"\n                                           SUFFIX \"${PYTHON_MODULE_EXTENSION}\")\nendfunction()\n\n# Build a Python extension module:\n# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]\n#                     [NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])\n#\nfunction(pybind11_add_module target_name)\n  set(options \"MODULE;SHARED;EXCLUDE_FROM_ALL;NO_EXTRAS;SYSTEM;THIN_LTO;OPT_SIZE\")\n  cmake_parse_arguments(ARG \"${options}\" \"\" \"\" ${ARGN})\n\n  if(ARG_MODULE AND ARG_SHARED)\n    message(FATAL_ERROR \"Can't be both MODULE and SHARED\")\n  elseif(ARG_SHARED)\n    set(lib_type SHARED)\n  else()\n    set(lib_type MODULE)\n  endif()\n\n  if(ARG_EXCLUDE_FROM_ALL)\n    set(exclude_from_all EXCLUDE_FROM_ALL)\n  else()\n    set(exclude_from_all \"\")\n  endif()\n\n  add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})\n\n  target_link_libraries(${target_name} PRIVATE pybind11::module)\n\n  if(ARG_SYSTEM)\n    message(\n      STATUS\n        \"Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets\"\n    )\n  endif()\n\n  pybind11_extension(${target_name})\n\n  # -fvisibility=hidden is required to allow multiple modules compiled against\n  # different pybind versions to work properly, and for some features (e.g.\n  # py::module_local).  We force it on everything inside the `pybind11`\n  # namespace; also turning it on for a pybind module compilation here avoids\n  # potential warnings or issues from having mixed hidden/non-hidden types.\n  if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(ARG_NO_EXTRAS)\n    return()\n  endif()\n\n  if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)\n    if(ARG_THIN_LTO)\n      target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)\n    else()\n      target_link_libraries(${target_name} PRIVATE pybind11::lto)\n    endif()\n  endif()\n\n  # Use case-insensitive comparison to match the result of $<CONFIG:cfgs>\n  string(TOUPPER \"${CMAKE_BUILD_TYPE}\" uppercase_CMAKE_BUILD_TYPE)\n  if(NOT MSVC AND NOT \"${uppercase_CMAKE_BUILD_TYPE}\" MATCHES DEBUG|RELWITHDEBINFO)\n    pybind11_strip(${target_name})\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  if(ARG_OPT_SIZE)\n    target_link_libraries(${target_name} PRIVATE pybind11::opt_size)\n  endif()\nendfunction()\n\n# Provide general way to call common Python commands in \"common\" file.\nset(_Python\n    PYTHON\n    CACHE INTERNAL \"\" FORCE)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/setup_global.py.in",
    "content": "#!/usr/bin/env python3\n\n# Setup script for pybind11-global (in the sdist or in tools/setup_global.py in the repository)\n# This package is targeted for easy use from CMake.\n\nimport glob\nimport os\nimport re\n\n# Setuptools has to be before distutils\nfrom setuptools import setup\n\nfrom distutils.command.install_headers import install_headers\n\nclass InstallHeadersNested(install_headers):\n    def run(self):\n        headers = self.distribution.headers or []\n        for header in headers:\n            # Remove pybind11/include/\n            short_header = header.split(\"/\", 2)[-1]\n\n            dst = os.path.join(self.install_dir, os.path.dirname(short_header))\n            self.mkpath(dst)\n            (out, _) = self.copy_file(header, dst)\n            self.outfiles.append(out)\n\n\nmain_headers = glob.glob(\"pybind11/include/pybind11/*.h\")\ndetail_headers = glob.glob(\"pybind11/include/pybind11/detail/*.h\")\neigen_headers = glob.glob(\"pybind11/include/pybind11/eigen/*.h\")\nstl_headers = glob.glob(\"pybind11/include/pybind11/stl/*.h\")\ncmake_files = glob.glob(\"pybind11/share/cmake/pybind11/*.cmake\")\npkgconfig_files = glob.glob(\"pybind11/share/pkgconfig/*.pc\")\nheaders = main_headers + detail_headers + stl_headers + eigen_headers\n\ncmdclass = {\"install_headers\": InstallHeadersNested}\n$extra_cmd\n\n# This will _not_ affect installing from wheels,\n# only building wheels or installing from SDist.\n# Primarily intended on Windows, where this is sometimes\n# customized (for example, conda-forge uses Library/)\nbase = os.environ.get(\"PYBIND11_GLOBAL_PREFIX\", \"\")\n\n# Must have a separator\nif base and not base.endswith(\"/\"):\n    base += \"/\"\n\nsetup(\n    name=\"pybind11_global\",\n    version=\"$version\",\n    packages=[],\n    headers=headers,\n    data_files=[\n        (base + \"share/cmake/pybind11\", cmake_files),\n        (base + \"share/pkgconfig\", pkgconfig_files),\n        (base + \"include/pybind11\", main_headers),\n        (base + \"include/pybind11/detail\", detail_headers),\n        (base + \"include/pybind11/eigen\", eigen_headers),\n        (base + \"include/pybind11/stl\", stl_headers),\n    ],\n    cmdclass=cmdclass,\n)\n"
  },
  {
    "path": "external/pybind11_2.11_dev1/tools/setup_main.py.in",
    "content": "#!/usr/bin/env python3\n\n# Setup script (in the sdist or in tools/setup_main.py in the repository)\n\nfrom setuptools import setup\n\ncmdclass = {}\n$extra_cmd\n\nsetup(\n    name=\"pybind11\",\n    version=\"$version\",\n    download_url='https://github.com/pybind/pybind11/tarball/v$version',\n    packages=[\n        \"pybind11\",\n        \"pybind11.include.pybind11\",\n        \"pybind11.include.pybind11.detail\",\n        \"pybind11.include.pybind11.eigen\",\n        \"pybind11.include.pybind11.stl\",\n        \"pybind11.share.cmake.pybind11\",\n        \"pybind11.share.pkgconfig\",\n    ],\n    package_data={\n        \"pybind11\": [\"py.typed\"],\n        \"pybind11.include.pybind11\": [\"*.h\"],\n        \"pybind11.include.pybind11.detail\": [\"*.h\"],\n        \"pybind11.include.pybind11.eigen\": [\"*.h\"],\n        \"pybind11.include.pybind11.stl\": [\"*.h\"],\n        \"pybind11.share.cmake.pybind11\": [\"*.cmake\"],\n        \"pybind11.share.pkgconfig\": [\"*.pc\"],\n    },\n    extras_require={\n        \"global\": [\"pybind11_global==$version\"]\n        },\n    entry_points={\n        \"console_scripts\": [\n             \"pybind11-config = pybind11.__main__:main\",\n        ],\n        \"pipx.run\": [\n             \"pybind11 = pybind11.__main__:main\",\n        ]\n    },\n    cmdclass=cmdclass\n)\n"
  },
  {
    "path": "external/pybind11_2.9.2/.appveyor.yml",
    "content": "version: 1.0.{build}\nimage:\n- Visual Studio 2015\ntest: off\nskip_branch_with_pr: true\nbuild:\n  parallel: true\nplatform:\n- x86\nenvironment:\n  matrix:\n  - PYTHON: 36\n    CONFIG: Debug\n  - PYTHON: 27\n    CONFIG: Debug\ninstall:\n- ps: |\n    $env:CMAKE_GENERATOR = \"Visual Studio 14 2015\"\n    if ($env:PLATFORM -eq \"x64\") { $env:PYTHON = \"$env:PYTHON-x64\" }\n    $env:PATH = \"C:\\Python$env:PYTHON\\;C:\\Python$env:PYTHON\\Scripts\\;$env:PATH\"\n    python -W ignore -m pip install --upgrade pip wheel\n    python -W ignore -m pip install pytest numpy --no-warn-script-location pytest-timeout\n- ps: |\n    Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'\n    7z x eigen-3.3.7.zip -y > $null\n    $env:CMAKE_INCLUDE_PATH = \"eigen-3.3.7;$env:CMAKE_INCLUDE_PATH\"\nbuild_script:\n- cmake -G \"%CMAKE_GENERATOR%\" -A \"%CMAKE_ARCH%\"\n    -DCMAKE_CXX_STANDARD=14\n    -DPYBIND11_WERROR=ON\n    -DDOWNLOAD_CATCH=ON\n    -DCMAKE_SUPPRESS_REGENERATION=1\n    .\n- set MSBuildLogger=\"C:\\Program Files\\AppVeyor\\BuildAgent\\Appveyor.MSBuildLogger.dll\"\n- cmake --build . --config %CONFIG% --target pytest -- /m /v:m /logger:%MSBuildLogger%\n- cmake --build . --config %CONFIG% --target cpptest -- /m /v:m /logger:%MSBuildLogger%\non_failure: if exist \"tests\\test_cmake_build\" type tests\\test_cmake_build\\*.log*\n"
  },
  {
    "path": "external/pybind11_2.9.2/.clang-format",
    "content": "---\n# See all possible options and defaults with:\n# clang-format --style=llvm --dump-config\nBasedOnStyle: LLVM\nAccessModifierOffset: -4\nAllowShortLambdasOnASingleLine: true\nAlwaysBreakTemplateDeclarations: Yes\nBinPackArguments: false\nBinPackParameters: false\nBreakBeforeBinaryOperators: All\nBreakConstructorInitializers: BeforeColon\nColumnLimit: 99\nCommentPragmas: 'NOLINT:.*|^ IWYU pragma:'\nIncludeBlocks: Regroup\nIndentCaseLabels: true\nIndentPPDirectives: AfterHash\nIndentWidth: 4\nLanguage: Cpp\nSpaceAfterCStyleCast: true\nStandard: Cpp11\nStatementMacros: ['PyObject_HEAD']\nTabWidth: 4\nIncludeCategories:\n  - Regex:           '<pybind11/.*'\n    Priority:        -1\n  - Regex:           'pybind11.h\"$'\n    Priority:        1\n  - Regex:           '^\".*/?detail/'\n    Priority:        1\n    SortPriority:    2\n  - Regex:           '^\"'\n    Priority:        1\n    SortPriority:    3\n  - Regex:           '<[[:alnum:]._]+>'\n    Priority:        4\n  - Regex:           '.*'\n    Priority:        5\n...\n"
  },
  {
    "path": "external/pybind11_2.9.2/.clang-tidy",
    "content": "FormatStyle: file\n\nChecks: '\n*bugprone*,\nclang-analyzer-optin.performance.Padding,\nclang-analyzer-optin.cplusplus.VirtualCall,\ncppcoreguidelines-init-variables,\ncppcoreguidelines-prefer-member-initializer,\ncppcoreguidelines-pro-type-static-cast-downcast,\ncppcoreguidelines-slicing,\ngoogle-explicit-constructor,\nllvm-namespace-comment,\nmisc-misplaced-const,\nmisc-non-copyable-objects,\nmisc-static-assert,\nmisc-throw-by-value-catch-by-reference,\nmisc-uniqueptr-reset-release,\nmisc-unused-parameters,\nmodernize-avoid-bind,\nmodernize-make-shared,\nmodernize-redundant-void-arg,\nmodernize-replace-auto-ptr,\nmodernize-replace-disallow-copy-and-assign-macro,\nmodernize-replace-random-shuffle,\nmodernize-shrink-to-fit,\nmodernize-use-auto,\nmodernize-use-bool-literals,\nmodernize-use-equals-default,\nmodernize-use-equals-delete,\nmodernize-use-default-member-init,\nmodernize-use-noexcept,\nmodernize-use-emplace,\nmodernize-use-override,\nmodernize-use-using,\n*performance*,\nreadability-avoid-const-params-in-decls,\nreadability-braces-around-statements,\nreadability-const-return-type,\nreadability-container-size-empty,\nreadability-delete-null-pointer,\nreadability-else-after-return,\nreadability-implicit-bool-conversion,\nreadability-inconsistent-declaration-parameter-name,\nreadability-make-member-function-const,\nreadability-misplaced-array-index,\nreadability-non-const-parameter,\nreadability-qualified-auto,\nreadability-redundant-function-ptr-dereference,\nreadability-redundant-smartptr-get,\nreadability-redundant-string-cstr,\nreadability-simplify-subscript-expr,\nreadability-static-accessed-through-instance,\nreadability-static-definition-in-anonymous-namespace,\nreadability-string-compare,\nreadability-suspicious-call-argument,\nreadability-uniqueptr-delete-release,\n-bugprone-exception-escape,\n-bugprone-reserved-identifier,\n-bugprone-unused-raii,\n'\n\nCheckOptions:\n- key:             performance-for-range-copy.WarnOnAllAutoCopies\n  value:           true\n- key:             performance-unnecessary-value-param.AllowedTypes\n  value:           'exception_ptr$;'\n- key:             readability-implicit-bool-conversion.AllowPointerConditions\n  value:           true\n\nHeaderFilterRegex: 'pybind11/.*h'\n\nWarningsAsErrors: '*'\n"
  },
  {
    "path": "external/pybind11_2.9.2/.cmake-format.yaml",
    "content": "parse:\n  additional_commands:\n    pybind11_add_module:\n      flags:\n        - THIN_LTO\n        - MODULE\n        - SHARED\n        - NO_EXTRAS\n        - EXCLUDE_FROM_ALL\n        - SYSTEM\n\nformat:\n  line_width: 99\n  tab_size: 2\n\n  # If an argument group contains more than this many sub-groups\n  # (parg or kwarg groups) then force it to a vertical layout.\n  max_subgroups_hwrap: 2\n\n  # If a positional argument group contains more than this many\n  # arguments, then force it to a vertical layout.\n  max_pargs_hwrap: 6\n\n  # If a cmdline positional group consumes more than this many\n  # lines without nesting, then invalidate the layout (and nest)\n  max_rows_cmdline: 2\n  separate_ctrl_name_with_space: false\n  separate_fn_name_with_space: false\n  dangle_parens: false\n\n  # If the trailing parenthesis must be 'dangled' on its on\n  # 'line, then align it to this reference: `prefix`: the start'\n  # 'of the statement,  `prefix-indent`: the start of the'\n  # 'statement, plus one indentation  level, `child`: align to'\n  # the column of the arguments\n  dangle_align: prefix\n  # If the statement spelling length (including space and\n  # parenthesis) is smaller than this amount, then force reject\n  # nested layouts.\n  min_prefix_chars: 4\n\n  # If the statement spelling length (including space and\n  # parenthesis) is larger than the tab width by more than this\n  # amount, then force reject un-nested layouts.\n  max_prefix_chars: 10\n\n  # If a candidate layout is wrapped horizontally but it exceeds\n  # this many lines, then reject the layout.\n  max_lines_hwrap: 2\n\n  line_ending: unix\n\n  # Format command names consistently as 'lower' or 'upper' case\n  command_case: canonical\n\n  # Format keywords consistently as 'lower' or 'upper' case\n  # unchanged is valid too\n  keyword_case: 'upper'\n\n  # A list of command names which should always be wrapped\n  always_wrap: []\n\n  # If true, the argument lists which are known to be sortable\n  # will be sorted lexicographically\n  enable_sort: true\n\n  # If true, the parsers may infer whether or not an argument\n  # list is sortable (without annotation).\n  autosort: false\n\n# Causes a few issues - can be solved later, possibly.\nmarkup:\n  enable_markup: false\n"
  },
  {
    "path": "external/pybind11_2.9.2/.gitignore",
    "content": "CMakeCache.txt\nCMakeFiles\nMakefile\ncmake_install.cmake\ncmake_uninstall.cmake\n.DS_Store\n*.so\n*.pyd\n*.dll\n*.sln\n*.sdf\n*.opensdf\n*.vcxproj\n*.vcxproj.user\n*.filters\nexample.dir\nWin32\nx64\nRelease\nDebug\n.vs\nCTestTestfile.cmake\nTesting\nautogen\nMANIFEST\n/.ninja_*\n/*.ninja\n/docs/.build\n*.py[co]\n*.egg-info\n*~\n.*.swp\n.DS_Store\n/dist\n/*build*\n.cache/\nsosize-*.txt\npybind11Config*.cmake\npybind11Targets.cmake\n/*env*\n/.vscode\n/pybind11/include/*\n/pybind11/share/*\n/docs/_build/*\n.ipynb_checkpoints/\n"
  },
  {
    "path": "external/pybind11_2.9.2/.readthedocs.yml",
    "content": "python:\n  version: 3\nrequirements_file: docs/requirements.txt\n"
  },
  {
    "path": "external/pybind11_2.9.2/CMakeLists.txt",
    "content": "# CMakeLists.txt -- Build system for the pybind11 modules\n#\n# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\ncmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.22)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.22)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.22)\nendif()\n\n# Avoid infinite recursion if tests include this as a subdirectory\nif(DEFINED PYBIND11_MASTER_PROJECT)\n  return()\nendif()\n\n# Extract project version from source\nfile(STRINGS \"${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h\"\n     pybind11_version_defines REGEX \"#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) \")\n\nforeach(ver ${pybind11_version_defines})\n  if(ver MATCHES [[#define PYBIND11_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$]])\n    set(PYBIND11_VERSION_${CMAKE_MATCH_1} \"${CMAKE_MATCH_2}\")\n  endif()\nendforeach()\n\nif(PYBIND11_VERSION_PATCH MATCHES [[\\.([a-zA-Z0-9]+)$]])\n  set(pybind11_VERSION_TYPE \"${CMAKE_MATCH_1}\")\nendif()\nstring(REGEX MATCH \"^[0-9]+\" PYBIND11_VERSION_PATCH \"${PYBIND11_VERSION_PATCH}\")\n\nproject(\n  pybind11\n  LANGUAGES CXX\n  VERSION \"${PYBIND11_VERSION_MAJOR}.${PYBIND11_VERSION_MINOR}.${PYBIND11_VERSION_PATCH}\")\n\n# Standard includes\ninclude(GNUInstallDirs)\ninclude(CMakePackageConfigHelpers)\ninclude(CMakeDependentOption)\n\nif(NOT pybind11_FIND_QUIETLY)\n  message(STATUS \"pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}\")\nendif()\n\n# Check if pybind11 is being used directly or via add_subdirectory\nif(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)\n  ### Warn if not an out-of-source builds\n  if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n    set(lines\n        \"You are building in-place. If that is not what you intended to \"\n        \"do, you can clean the source directory with:\\n\"\n        \"rm -r CMakeCache.txt CMakeFiles/ cmake_uninstall.cmake pybind11Config.cmake \"\n        \"pybind11ConfigVersion.cmake tests/CMakeFiles/\\n\")\n    message(AUTHOR_WARNING ${lines})\n  endif()\n\n  set(PYBIND11_MASTER_PROJECT ON)\n\n  if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)\n    # Bug in macOS CMake < 3.7 is unable to download catch\n    message(WARNING \"CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended\")\n  elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)\n    # Only tested with 3.8+ in CI.\n    message(WARNING \"CMAKE 3.8+ tested on Windows, previous versions untested\")\n  endif()\n\n  message(STATUS \"CMake ${CMAKE_VERSION}\")\n\n  if(CMAKE_CXX_STANDARD)\n    set(CMAKE_CXX_EXTENSIONS OFF)\n    set(CMAKE_CXX_STANDARD_REQUIRED ON)\n  endif()\n\n  set(pybind11_system \"\")\n\n  set_property(GLOBAL PROPERTY USE_FOLDERS ON)\nelse()\n  set(PYBIND11_MASTER_PROJECT OFF)\n  set(pybind11_system SYSTEM)\nendif()\n\n# Options\noption(PYBIND11_INSTALL \"Install pybind11 header files?\" ${PYBIND11_MASTER_PROJECT})\noption(PYBIND11_TEST \"Build pybind11 test suite?\" ${PYBIND11_MASTER_PROJECT})\noption(PYBIND11_NOPYTHON \"Disable search for Python\" OFF)\nset(PYBIND11_INTERNALS_VERSION\n    \"\"\n    CACHE STRING \"Override the ABI version, may be used to enable the unstable ABI.\")\n\ncmake_dependent_option(\n  USE_PYTHON_INCLUDE_DIR\n  \"Install pybind11 headers in Python include directory instead of default installation prefix\"\n  OFF \"PYBIND11_INSTALL\" OFF)\n\ncmake_dependent_option(PYBIND11_FINDPYTHON \"Force new FindPython\" OFF\n                       \"NOT CMAKE_VERSION VERSION_LESS 3.12\" OFF)\n\n# NB: when adding a header don't forget to also add it to setup.py\nset(PYBIND11_HEADERS\n    include/pybind11/detail/class.h\n    include/pybind11/detail/common.h\n    include/pybind11/detail/descr.h\n    include/pybind11/detail/init.h\n    include/pybind11/detail/internals.h\n    include/pybind11/detail/type_caster_base.h\n    include/pybind11/detail/typeid.h\n    include/pybind11/attr.h\n    include/pybind11/buffer_info.h\n    include/pybind11/cast.h\n    include/pybind11/chrono.h\n    include/pybind11/common.h\n    include/pybind11/complex.h\n    include/pybind11/options.h\n    include/pybind11/eigen.h\n    include/pybind11/embed.h\n    include/pybind11/eval.h\n    include/pybind11/gil.h\n    include/pybind11/iostream.h\n    include/pybind11/functional.h\n    include/pybind11/numpy.h\n    include/pybind11/operators.h\n    include/pybind11/pybind11.h\n    include/pybind11/pytypes.h\n    include/pybind11/stl.h\n    include/pybind11/stl_bind.h\n    include/pybind11/stl/filesystem.h)\n\n# Compare with grep and warn if mismatched\nif(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)\n  file(\n    GLOB_RECURSE _pybind11_header_check\n    LIST_DIRECTORIES false\n    RELATIVE \"${CMAKE_CURRENT_SOURCE_DIR}\"\n    CONFIGURE_DEPENDS \"include/pybind11/*.h\")\n  set(_pybind11_here_only ${PYBIND11_HEADERS})\n  set(_pybind11_disk_only ${_pybind11_header_check})\n  list(REMOVE_ITEM _pybind11_here_only ${_pybind11_header_check})\n  list(REMOVE_ITEM _pybind11_disk_only ${PYBIND11_HEADERS})\n  if(_pybind11_here_only)\n    message(AUTHOR_WARNING \"PYBIND11_HEADERS has extra files:\" ${_pybind11_here_only})\n  endif()\n  if(_pybind11_disk_only)\n    message(AUTHOR_WARNING \"PYBIND11_HEADERS is missing files:\" ${_pybind11_disk_only})\n  endif()\nendif()\n\n# CMake 3.12 added list(TRANSFORM <list> PREPEND\n# But we can't use it yet\nstring(REPLACE \"include/\" \"${CMAKE_CURRENT_SOURCE_DIR}/include/\" PYBIND11_HEADERS\n               \"${PYBIND11_HEADERS}\")\n\n# Cache variable so this can be used in parent projects\nset(pybind11_INCLUDE_DIR\n    \"${CMAKE_CURRENT_LIST_DIR}/include\"\n    CACHE INTERNAL \"Directory where pybind11 headers are located\")\n\n# Backward compatible variable for add_subdirectory mode\nif(NOT PYBIND11_MASTER_PROJECT)\n  set(PYBIND11_INCLUDE_DIR\n      \"${pybind11_INCLUDE_DIR}\"\n      CACHE INTERNAL \"\")\nendif()\n\n# Note: when creating targets, you cannot use if statements at configure time -\n# you need generator expressions, because those will be placed in the target file.\n# You can also place ifs *in* the Config.in, but not here.\n\n# This section builds targets, but does *not* touch Python\n# Non-IMPORT targets cannot be defined twice\nif(NOT TARGET pybind11_headers)\n  # Build the headers-only target (no Python included):\n  # (long name used here to keep this from clashing in subdirectory mode)\n  add_library(pybind11_headers INTERFACE)\n  add_library(pybind11::pybind11_headers ALIAS pybind11_headers) # to match exported target\n  add_library(pybind11::headers ALIAS pybind11_headers) # easier to use/remember\n\n  target_include_directories(\n    pybind11_headers ${pybind11_system} INTERFACE $<BUILD_INTERFACE:${pybind11_INCLUDE_DIR}>\n                                                  $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)\n\n  target_compile_features(pybind11_headers INTERFACE cxx_inheriting_constructors cxx_user_literals\n                                                     cxx_right_angle_brackets)\n  if(NOT \"${PYBIND11_INTERNALS_VERSION}\" STREQUAL \"\")\n    target_compile_definitions(\n      pybind11_headers INTERFACE \"PYBIND11_INTERNALS_VERSION=${PYBIND11_INTERNALS_VERSION}\")\n  endif()\nelse()\n  # It is invalid to install a target twice, too.\n  set(PYBIND11_INSTALL OFF)\nendif()\n\ninclude(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/pybind11Common.cmake\")\n\n# Relative directory setting\nif(USE_PYTHON_INCLUDE_DIR AND DEFINED Python_INCLUDE_DIRS)\n  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${Python_INCLUDE_DIRS})\nelseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)\n  file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX} ${PYTHON_INCLUDE_DIRS})\nendif()\n\nif(PYBIND11_INSTALL)\n  install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})\n  set(PYBIND11_CMAKECONFIG_INSTALL_DIR\n      \"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}\"\n      CACHE STRING \"install path for pybind11Config.cmake\")\n\n  if(IS_ABSOLUTE \"${CMAKE_INSTALL_INCLUDEDIR}\")\n    set(pybind11_INCLUDEDIR \"${CMAKE_INSTALL_FULL_INCLUDEDIR}\")\n  else()\n    set(pybind11_INCLUDEDIR \"\\$\\{PACKAGE_PREFIX_DIR\\}/${CMAKE_INSTALL_INCLUDEDIR}\")\n  endif()\n\n  configure_package_config_file(\n    tools/${PROJECT_NAME}Config.cmake.in \"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake\"\n    INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  if(CMAKE_VERSION VERSION_LESS 3.14)\n    # Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does\n    # not depend on architecture specific settings or libraries.\n    set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})\n    unset(CMAKE_SIZEOF_VOID_P)\n\n    write_basic_package_version_file(\n      ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n      VERSION ${PROJECT_VERSION}\n      COMPATIBILITY AnyNewerVersion)\n\n    set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})\n  else()\n    # CMake 3.14+ natively supports header-only libraries\n    write_basic_package_version_file(\n      ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n      VERSION ${PROJECT_VERSION}\n      COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)\n  endif()\n\n  install(\n    FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake\n          ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake\n          tools/FindPythonLibsNew.cmake\n          tools/pybind11Common.cmake\n          tools/pybind11Tools.cmake\n          tools/pybind11NewTools.cmake\n    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  if(NOT PYBIND11_EXPORT_NAME)\n    set(PYBIND11_EXPORT_NAME \"${PROJECT_NAME}Targets\")\n  endif()\n\n  install(TARGETS pybind11_headers EXPORT \"${PYBIND11_EXPORT_NAME}\")\n\n  install(\n    EXPORT \"${PYBIND11_EXPORT_NAME}\"\n    NAMESPACE \"pybind11::\"\n    DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})\n\n  # Uninstall target\n  if(PYBIND11_MASTER_PROJECT)\n    configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in\"\n                   \"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake\" IMMEDIATE @ONLY)\n\n    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P\n                                        ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)\n  endif()\nendif()\n\n# BUILD_TESTING takes priority, but only if this is the master project\nif(PYBIND11_MASTER_PROJECT AND DEFINED BUILD_TESTING)\n  if(BUILD_TESTING)\n    if(_pybind11_nopython)\n      message(FATAL_ERROR \"Cannot activate tests in NOPYTHON mode\")\n    else()\n      add_subdirectory(tests)\n    endif()\n  endif()\nelse()\n  if(PYBIND11_TEST)\n    if(_pybind11_nopython)\n      message(FATAL_ERROR \"Cannot activate tests in NOPYTHON mode\")\n    else()\n      add_subdirectory(tests)\n    endif()\n  endif()\nendif()\n\n# Better symmetry with find_package(pybind11 CONFIG) mode.\nif(NOT PYBIND11_MASTER_PROJECT)\n  set(pybind11_FOUND\n      TRUE\n      CACHE INTERNAL \"True if pybind11 and all required components found on the system\")\nendif()\n"
  },
  {
    "path": "external/pybind11_2.9.2/LICENSE",
    "content": "Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n   may be used to endorse or promote products derived from this software\n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nPlease also refer to the file .github/CONTRIBUTING.md, which clarifies licensing of\nexternal contributions to this project including patches, pull requests, etc.\n"
  },
  {
    "path": "external/pybind11_2.9.2/MANIFEST.in",
    "content": "recursive-include pybind11/include/pybind11 *.h\nrecursive-include pybind11 *.py\nrecursive-include pybind11 py.typed\nrecursive-include pybind11 *.pyi\ninclude pybind11/share/cmake/pybind11/*.cmake\ninclude LICENSE README.rst pyproject.toml setup.py setup.cfg\n"
  },
  {
    "path": "external/pybind11_2.9.2/README.rst",
    "content": ".. figure:: https://github.com/pybind/pybind11/raw/master/docs/pybind11-logo.png\n   :alt: pybind11 logo\n\n**pybind11 — Seamless operability between C++11 and Python**\n\n|Latest Documentation Status| |Stable Documentation Status| |Gitter chat| |GitHub Discussions| |CI| |Build status|\n\n|Repology| |PyPI package| |Conda-forge| |Python Versions|\n\n`Setuptools example <https://github.com/pybind/python_example>`_\n• `Scikit-build example <https://github.com/pybind/scikit_build_example>`_\n• `CMake example <https://github.com/pybind/cmake_example>`_\n\n.. start\n\n\n**pybind11** is a lightweight header-only library that exposes C++ types\nin Python and vice versa, mainly to create Python bindings of existing\nC++ code. Its goals and syntax are similar to the excellent\n`Boost.Python <http://www.boost.org/doc/libs/1_58_0/libs/python/doc/>`_\nlibrary by David Abrahams: to minimize boilerplate code in traditional\nextension modules by inferring type information using compile-time\nintrospection.\n\nThe main issue with Boost.Python—and the reason for creating such a\nsimilar project—is Boost. Boost is an enormously large and complex suite\nof utility libraries that works with almost every C++ compiler in\nexistence. This compatibility has its cost: arcane template tricks and\nworkarounds are necessary to support the oldest and buggiest of compiler\nspecimens. Now that C++11-compatible compilers are widely available,\nthis heavy machinery has become an excessively large and unnecessary\ndependency.\n\nThink of this library as a tiny self-contained version of Boost.Python\nwith everything stripped away that isn’t relevant for binding\ngeneration. Without comments, the core header files only require ~4K\nlines of code and depend on Python (2.7 or 3.5+, or PyPy) and the C++\nstandard library. This compact implementation was possible thanks to\nsome of the new C++11 language features (specifically: tuples, lambda\nfunctions and variadic templates). Since its creation, this library has\ngrown beyond Boost.Python in many ways, leading to dramatically simpler\nbinding code in many common situations.\n\nTutorial and reference documentation is provided at\n`pybind11.readthedocs.io <https://pybind11.readthedocs.io/en/latest>`_.\nA PDF version of the manual is available\n`here <https://pybind11.readthedocs.io/_/downloads/en/latest/pdf/>`_.\nAnd the source code is always available at\n`github.com/pybind/pybind11 <https://github.com/pybind/pybind11>`_.\n\n\nCore features\n-------------\n\n\npybind11 can map the following core C++ features to Python:\n\n- Functions accepting and returning custom data structures per value,\n  reference, or pointer\n- Instance methods and static methods\n- Overloaded functions\n- Instance attributes and static attributes\n- Arbitrary exception types\n- Enumerations\n- Callbacks\n- Iterators and ranges\n- Custom operators\n- Single and multiple inheritance\n- STL data structures\n- Smart pointers with reference counting like ``std::shared_ptr``\n- Internal references with correct reference counting\n- C++ classes with virtual (and pure virtual) methods can be extended\n  in Python\n\nGoodies\n-------\n\nIn addition to the core functionality, pybind11 provides some extra\ngoodies:\n\n- Python 2.7, 3.5+, and PyPy/PyPy3 7.3 are supported with an\n  implementation-agnostic interface.\n\n- It is possible to bind C++11 lambda functions with captured\n  variables. The lambda capture data is stored inside the resulting\n  Python function object.\n\n- pybind11 uses C++11 move constructors and move assignment operators\n  whenever possible to efficiently transfer custom data types.\n\n- It’s easy to expose the internal storage of custom data types through\n  Pythons’ buffer protocols. This is handy e.g. for fast conversion\n  between C++ matrix classes like Eigen and NumPy without expensive\n  copy operations.\n\n- pybind11 can automatically vectorize functions so that they are\n  transparently applied to all entries of one or more NumPy array\n  arguments.\n\n- Python's slice-based access and assignment operations can be\n  supported with just a few lines of code.\n\n- Everything is contained in just a few header files; there is no need\n  to link against any additional libraries.\n\n- Binaries are generally smaller by a factor of at least 2 compared to\n  equivalent bindings generated by Boost.Python. A recent pybind11\n  conversion of PyRosetta, an enormous Boost.Python binding project,\n  `reported <https://graylab.jhu.edu/Sergey/2016.RosettaCon/PyRosetta-4.pdf>`_\n  a binary size reduction of **5.4x** and compile time reduction by\n  **5.8x**.\n\n- Function signatures are precomputed at compile time (using\n  ``constexpr``), leading to smaller binaries.\n\n- With little extra effort, C++ types can be pickled and unpickled\n  similar to regular Python objects.\n\nSupported compilers\n-------------------\n\n1. Clang/LLVM 3.3 or newer (for Apple Xcode’s clang, this is 5.0.0 or\n   newer)\n2. GCC 4.8 or newer\n3. Microsoft Visual Studio 2015 Update 3 or newer\n4. Intel classic C++ compiler 18 or newer (ICC 20.2 tested in CI)\n5. Cygwin/GCC (previously tested on 2.5.1)\n6. NVCC (CUDA 11.0 tested in CI)\n7. NVIDIA PGI (20.9 tested in CI)\n\nAbout\n-----\n\nThis project was created by `Wenzel\nJakob <http://rgl.epfl.ch/people/wjakob>`_. Significant features and/or\nimprovements to the code were contributed by Jonas Adler, Lori A. Burns,\nSylvain Corlay, Eric Cousineau, Aaron Gokaslan, Ralf Grosse-Kunstleve, Trent Houliston, Axel\nHuebl, @hulucc, Yannick Jadoul, Sergey Lyskov Johan Mabille, Tomasz Miąsko,\nDean Moldovan, Ben Pritchard, Jason Rhinelander, Boris Schäling, Pim\nSchellart, Henry Schreiner, Ivan Smirnov, Boris Staletic, and Patrick Stewart.\n\nWe thank Google for a generous financial contribution to the continuous\nintegration infrastructure used by this project.\n\n\nContributing\n~~~~~~~~~~~~\n\nSee the `contributing\nguide <https://github.com/pybind/pybind11/blob/master/.github/CONTRIBUTING.md>`_\nfor information on building and contributing to pybind11.\n\nLicense\n~~~~~~~\n\npybind11 is provided under a BSD-style license that can be found in the\n`LICENSE <https://github.com/pybind/pybind11/blob/master/LICENSE>`_\nfile. By using, distributing, or contributing to this project, you agree\nto the terms and conditions of this license.\n\n.. |Latest Documentation Status| image:: https://readthedocs.org/projects/pybind11/badge?version=latest\n   :target: http://pybind11.readthedocs.org/en/latest\n.. |Stable Documentation Status| image:: https://img.shields.io/badge/docs-stable-blue.svg\n   :target: http://pybind11.readthedocs.org/en/stable\n.. |Gitter chat| image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg\n   :target: https://gitter.im/pybind/Lobby\n.. |CI| image:: https://github.com/pybind/pybind11/workflows/CI/badge.svg\n   :target: https://github.com/pybind/pybind11/actions\n.. |Build status| image:: https://ci.appveyor.com/api/projects/status/riaj54pn4h08xy40?svg=true\n   :target: https://ci.appveyor.com/project/wjakob/pybind11\n.. |PyPI package| image:: https://img.shields.io/pypi/v/pybind11.svg\n   :target: https://pypi.org/project/pybind11/\n.. |Conda-forge| image:: https://img.shields.io/conda/vn/conda-forge/pybind11.svg\n   :target: https://github.com/conda-forge/pybind11-feedstock\n.. |Repology| image:: https://repology.org/badge/latest-versions/python:pybind11.svg\n   :target: https://repology.org/project/python:pybind11/versions\n.. |Python Versions| image:: https://img.shields.io/pypi/pyversions/pybind11.svg\n   :target: https://pypi.org/project/pybind11/\n.. |GitHub Discussions| image:: https://img.shields.io/static/v1?label=Discussions&message=Ask&color=blue&logo=github\n   :target: https://github.com/pybind/pybind11/discussions\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/attr.h",
    "content": "/*\n    pybind11/attr.h: Infrastructure for processing custom\n    type and function attributes\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"cast.h\"\n\n#include <functional>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n/// \\addtogroup annotations\n/// @{\n\n/// Annotation for methods\nstruct is_method {\n    handle class_;\n    explicit is_method(const handle &c) : class_(c) {}\n};\n\n/// Annotation for operators\nstruct is_operator {};\n\n/// Annotation for classes that cannot be subclassed\nstruct is_final {};\n\n/// Annotation for parent scope\nstruct scope {\n    handle value;\n    explicit scope(const handle &s) : value(s) {}\n};\n\n/// Annotation for documentation\nstruct doc {\n    const char *value;\n    explicit doc(const char *value) : value(value) {}\n};\n\n/// Annotation for function names\nstruct name {\n    const char *value;\n    explicit name(const char *value) : value(value) {}\n};\n\n/// Annotation indicating that a function is an overload associated with a given \"sibling\"\nstruct sibling {\n    handle value;\n    explicit sibling(const handle &value) : value(value.ptr()) {}\n};\n\n/// Annotation indicating that a class derives from another given type\ntemplate <typename T>\nstruct base {\n\n    PYBIND11_DEPRECATED(\n        \"base<T>() was deprecated in favor of specifying 'T' as a template argument to class_\")\n    base() {} // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute\n};\n\n/// Keep patient alive while nurse lives\ntemplate <size_t Nurse, size_t Patient>\nstruct keep_alive {};\n\n/// Annotation indicating that a class is involved in a multiple inheritance relationship\nstruct multiple_inheritance {};\n\n/// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class\nstruct dynamic_attr {};\n\n/// Annotation which enables the buffer protocol for a type\nstruct buffer_protocol {};\n\n/// Annotation which requests that a special metaclass is created for a type\nstruct metaclass {\n    handle value;\n\n    PYBIND11_DEPRECATED(\"py::metaclass() is no longer required. It's turned on by default now.\")\n    // NOLINTNEXTLINE(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute\n    metaclass() {}\n\n    /// Override pybind11's default metaclass\n    explicit metaclass(handle value) : value(value) {}\n};\n\n/// Specifies a custom callback with signature `void (PyHeapTypeObject*)` that\n/// may be used to customize the Python type.\n///\n/// The callback is invoked immediately before `PyType_Ready`.\n///\n/// Note: This is an advanced interface, and uses of it may require changes to\n/// work with later versions of pybind11.  You may wish to consult the\n/// implementation of `make_new_python_type` in `detail/classes.h` to understand\n/// the context in which the callback will be run.\nstruct custom_type_setup {\n    using callback = std::function<void(PyHeapTypeObject *heap_type)>;\n\n    explicit custom_type_setup(callback value) : value(std::move(value)) {}\n\n    callback value;\n};\n\n/// Annotation that marks a class as local to the module:\nstruct module_local {\n    const bool value;\n    constexpr explicit module_local(bool v = true) : value(v) {}\n};\n\n/// Annotation to mark enums as an arithmetic type\nstruct arithmetic {};\n\n/// Mark a function for addition at the beginning of the existing overload chain instead of the end\nstruct prepend {};\n\n/** \\rst\n    A call policy which places one or more guard variables (``Ts...``) around the function call.\n\n    For example, this definition:\n\n    .. code-block:: cpp\n\n        m.def(\"foo\", foo, py::call_guard<T>());\n\n    is equivalent to the following pseudocode:\n\n    .. code-block:: cpp\n\n        m.def(\"foo\", [](args...) {\n            T scope_guard;\n            return foo(args...); // forwarded arguments\n        });\n \\endrst */\ntemplate <typename... Ts>\nstruct call_guard;\n\ntemplate <>\nstruct call_guard<> {\n    using type = detail::void_type;\n};\n\ntemplate <typename T>\nstruct call_guard<T> {\n    static_assert(std::is_default_constructible<T>::value,\n                  \"The guard type must be default constructible\");\n\n    using type = T;\n};\n\ntemplate <typename T, typename... Ts>\nstruct call_guard<T, Ts...> {\n    struct type {\n        T guard{}; // Compose multiple guard types with left-to-right default-constructor order\n        typename call_guard<Ts...>::type next{};\n    };\n};\n\n/// @} annotations\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n/* Forward declarations */\nenum op_id : int;\nenum op_type : int;\nstruct undefined_t;\ntemplate <op_id id, op_type ot, typename L = undefined_t, typename R = undefined_t>\nstruct op_;\nvoid keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret);\n\n/// Internal data structure which holds metadata about a keyword argument\nstruct argument_record {\n    const char *name;  ///< Argument name\n    const char *descr; ///< Human-readable version of the argument value\n    handle value;      ///< Associated Python object\n    bool convert : 1;  ///< True if the argument is allowed to convert when loading\n    bool none : 1;     ///< True if None is allowed when loading\n\n    argument_record(const char *name, const char *descr, handle value, bool convert, bool none)\n        : name(name), descr(descr), value(value), convert(convert), none(none) {}\n};\n\n/// Internal data structure which holds metadata about a bound function (signature, overloads,\n/// etc.)\nstruct function_record {\n    function_record()\n        : is_constructor(false), is_new_style_constructor(false), is_stateless(false),\n          is_operator(false), is_method(false), has_args(false), has_kwargs(false),\n          prepend(false) {}\n\n    /// Function name\n    char *name = nullptr; /* why no C++ strings? They generate heavier code.. */\n\n    // User-specified documentation string\n    char *doc = nullptr;\n\n    /// Human-readable version of the function signature\n    char *signature = nullptr;\n\n    /// List of registered keyword arguments\n    std::vector<argument_record> args;\n\n    /// Pointer to lambda function which converts arguments and performs the actual call\n    handle (*impl)(function_call &) = nullptr;\n\n    /// Storage for the wrapped function pointer and captured data, if any\n    void *data[3] = {};\n\n    /// Pointer to custom destructor for 'data' (if needed)\n    void (*free_data)(function_record *ptr) = nullptr;\n\n    /// Return value policy associated with this function\n    return_value_policy policy = return_value_policy::automatic;\n\n    /// True if name == '__init__'\n    bool is_constructor : 1;\n\n    /// True if this is a new-style `__init__` defined in `detail/init.h`\n    bool is_new_style_constructor : 1;\n\n    /// True if this is a stateless function pointer\n    bool is_stateless : 1;\n\n    /// True if this is an operator (__add__), etc.\n    bool is_operator : 1;\n\n    /// True if this is a method\n    bool is_method : 1;\n\n    /// True if the function has a '*args' argument\n    bool has_args : 1;\n\n    /// True if the function has a '**kwargs' argument\n    bool has_kwargs : 1;\n\n    /// True if this function is to be inserted at the beginning of the overload resolution chain\n    bool prepend : 1;\n\n    /// Number of arguments (including py::args and/or py::kwargs, if present)\n    std::uint16_t nargs;\n\n    /// Number of leading positional arguments, which are terminated by a py::args or py::kwargs\n    /// argument or by a py::kw_only annotation.\n    std::uint16_t nargs_pos = 0;\n\n    /// Number of leading arguments (counted in `nargs`) that are positional-only\n    std::uint16_t nargs_pos_only = 0;\n\n    /// Python method object\n    PyMethodDef *def = nullptr;\n\n    /// Python handle to the parent scope (a class or a module)\n    handle scope;\n\n    /// Python handle to the sibling function representing an overload chain\n    handle sibling;\n\n    /// Pointer to next overload\n    function_record *next = nullptr;\n};\n\n/// Special data structure which (temporarily) holds metadata about a bound class\nstruct type_record {\n    PYBIND11_NOINLINE type_record()\n        : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false),\n          default_holder(true), module_local(false), is_final(false) {}\n\n    /// Handle to the parent scope\n    handle scope;\n\n    /// Name of the class\n    const char *name = nullptr;\n\n    // Pointer to RTTI type_info data structure\n    const std::type_info *type = nullptr;\n\n    /// How large is the underlying C++ type?\n    size_t type_size = 0;\n\n    /// What is the alignment of the underlying C++ type?\n    size_t type_align = 0;\n\n    /// How large is the type's holder?\n    size_t holder_size = 0;\n\n    /// The global operator new can be overridden with a class-specific variant\n    void *(*operator_new)(size_t) = nullptr;\n\n    /// Function pointer to class_<..>::init_instance\n    void (*init_instance)(instance *, const void *) = nullptr;\n\n    /// Function pointer to class_<..>::dealloc\n    void (*dealloc)(detail::value_and_holder &) = nullptr;\n\n    /// List of base classes of the newly created type\n    list bases;\n\n    /// Optional docstring\n    const char *doc = nullptr;\n\n    /// Custom metaclass (optional)\n    handle metaclass;\n\n    /// Custom type setup.\n    custom_type_setup::callback custom_type_setup_callback;\n\n    /// Multiple inheritance marker\n    bool multiple_inheritance : 1;\n\n    /// Does the class manage a __dict__?\n    bool dynamic_attr : 1;\n\n    /// Does the class implement the buffer protocol?\n    bool buffer_protocol : 1;\n\n    /// Is the default (unique_ptr) holder type used?\n    bool default_holder : 1;\n\n    /// Is the class definition local to the module shared object?\n    bool module_local : 1;\n\n    /// Is the class inheritable from python classes?\n    bool is_final : 1;\n\n    PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) {\n        auto *base_info = detail::get_type_info(base, false);\n        if (!base_info) {\n            std::string tname(base.name());\n            detail::clean_type_id(tname);\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(name)\n                          + \"\\\" referenced unknown base type \\\"\" + tname + \"\\\"\");\n        }\n\n        if (default_holder != base_info->default_holder) {\n            std::string tname(base.name());\n            detail::clean_type_id(tname);\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(name) + \"\\\" \"\n                          + (default_holder ? \"does not have\" : \"has\")\n                          + \" a non-default holder type while its base \\\"\" + tname + \"\\\" \"\n                          + (base_info->default_holder ? \"does not\" : \"does\"));\n        }\n\n        bases.append((PyObject *) base_info->type);\n\n        if (base_info->type->tp_dictoffset != 0) {\n            dynamic_attr = true;\n        }\n\n        if (caster) {\n            base_info->implicit_casts.emplace_back(type, caster);\n        }\n    }\n};\n\ninline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) {\n    args.reserve(f.nargs);\n    args_convert.reserve(f.nargs);\n}\n\n/// Tag for a new-style `__init__` defined in `detail/init.h`\nstruct is_new_style_constructor {};\n\n/**\n * Partial template specializations to process custom attributes provided to\n * cpp_function_ and class_. These are either used to initialize the respective\n * fields in the type_record and function_record data structures or executed at\n * runtime to deal with custom call policies (e.g. keep_alive).\n */\ntemplate <typename T, typename SFINAE = void>\nstruct process_attribute;\n\ntemplate <typename T>\nstruct process_attribute_default {\n    /// Default implementation: do nothing\n    static void init(const T &, function_record *) {}\n    static void init(const T &, type_record *) {}\n    static void precall(function_call &) {}\n    static void postcall(function_call &, handle) {}\n};\n\n/// Process an attribute specifying the function's name\ntemplate <>\nstruct process_attribute<name> : process_attribute_default<name> {\n    static void init(const name &n, function_record *r) { r->name = const_cast<char *>(n.value); }\n};\n\n/// Process an attribute specifying the function's docstring\ntemplate <>\nstruct process_attribute<doc> : process_attribute_default<doc> {\n    static void init(const doc &n, function_record *r) { r->doc = const_cast<char *>(n.value); }\n};\n\n/// Process an attribute specifying the function's docstring (provided as a C-style string)\ntemplate <>\nstruct process_attribute<const char *> : process_attribute_default<const char *> {\n    static void init(const char *d, function_record *r) { r->doc = const_cast<char *>(d); }\n    static void init(const char *d, type_record *r) { r->doc = const_cast<char *>(d); }\n};\ntemplate <>\nstruct process_attribute<char *> : process_attribute<const char *> {};\n\n/// Process an attribute indicating the function's return value policy\ntemplate <>\nstruct process_attribute<return_value_policy> : process_attribute_default<return_value_policy> {\n    static void init(const return_value_policy &p, function_record *r) { r->policy = p; }\n};\n\n/// Process an attribute which indicates that this is an overloaded function associated with a\n/// given sibling\ntemplate <>\nstruct process_attribute<sibling> : process_attribute_default<sibling> {\n    static void init(const sibling &s, function_record *r) { r->sibling = s.value; }\n};\n\n/// Process an attribute which indicates that this function is a method\ntemplate <>\nstruct process_attribute<is_method> : process_attribute_default<is_method> {\n    static void init(const is_method &s, function_record *r) {\n        r->is_method = true;\n        r->scope = s.class_;\n    }\n};\n\n/// Process an attribute which indicates the parent scope of a method\ntemplate <>\nstruct process_attribute<scope> : process_attribute_default<scope> {\n    static void init(const scope &s, function_record *r) { r->scope = s.value; }\n};\n\n/// Process an attribute which indicates that this function is an operator\ntemplate <>\nstruct process_attribute<is_operator> : process_attribute_default<is_operator> {\n    static void init(const is_operator &, function_record *r) { r->is_operator = true; }\n};\n\ntemplate <>\nstruct process_attribute<is_new_style_constructor>\n    : process_attribute_default<is_new_style_constructor> {\n    static void init(const is_new_style_constructor &, function_record *r) {\n        r->is_new_style_constructor = true;\n    }\n};\n\ninline void check_kw_only_arg(const arg &a, function_record *r) {\n    if (r->args.size() > r->nargs_pos && (!a.name || a.name[0] == '\\0')) {\n        pybind11_fail(\"arg(): cannot specify an unnamed argument after a kw_only() annotation or \"\n                      \"args() argument\");\n    }\n}\n\ninline void append_self_arg_if_needed(function_record *r) {\n    if (r->is_method && r->args.empty()) {\n        r->args.emplace_back(\"self\", nullptr, handle(), /*convert=*/true, /*none=*/false);\n    }\n}\n\n/// Process a keyword argument attribute (*without* a default value)\ntemplate <>\nstruct process_attribute<arg> : process_attribute_default<arg> {\n    static void init(const arg &a, function_record *r) {\n        append_self_arg_if_needed(r);\n        r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none);\n\n        check_kw_only_arg(a, r);\n    }\n};\n\n/// Process a keyword argument attribute (*with* a default value)\ntemplate <>\nstruct process_attribute<arg_v> : process_attribute_default<arg_v> {\n    static void init(const arg_v &a, function_record *r) {\n        if (r->is_method && r->args.empty()) {\n            r->args.emplace_back(\n                \"self\", /*descr=*/nullptr, /*parent=*/handle(), /*convert=*/true, /*none=*/false);\n        }\n\n        if (!a.value) {\n#if !defined(NDEBUG)\n            std::string descr(\"'\");\n            if (a.name) {\n                descr += std::string(a.name) + \": \";\n            }\n            descr += a.type + \"'\";\n            if (r->is_method) {\n                if (r->name) {\n                    descr += \" in method '\" + (std::string) str(r->scope) + \".\"\n                             + (std::string) r->name + \"'\";\n                } else {\n                    descr += \" in method of '\" + (std::string) str(r->scope) + \"'\";\n                }\n            } else if (r->name) {\n                descr += \" in function '\" + (std::string) r->name + \"'\";\n            }\n            pybind11_fail(\"arg(): could not convert default argument \" + descr\n                          + \" into a Python object (type not registered yet?)\");\n#else\n            pybind11_fail(\"arg(): could not convert default argument \"\n                          \"into a Python object (type not registered yet?). \"\n                          \"Compile in debug mode for more information.\");\n#endif\n        }\n        r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);\n\n        check_kw_only_arg(a, r);\n    }\n};\n\n/// Process a keyword-only-arguments-follow pseudo argument\ntemplate <>\nstruct process_attribute<kw_only> : process_attribute_default<kw_only> {\n    static void init(const kw_only &, function_record *r) {\n        append_self_arg_if_needed(r);\n        if (r->has_args && r->nargs_pos != static_cast<std::uint16_t>(r->args.size())) {\n            pybind11_fail(\"Mismatched args() and kw_only(): they must occur at the same relative \"\n                          \"argument location (or omit kw_only() entirely)\");\n        }\n        r->nargs_pos = static_cast<std::uint16_t>(r->args.size());\n    }\n};\n\n/// Process a positional-only-argument maker\ntemplate <>\nstruct process_attribute<pos_only> : process_attribute_default<pos_only> {\n    static void init(const pos_only &, function_record *r) {\n        append_self_arg_if_needed(r);\n        r->nargs_pos_only = static_cast<std::uint16_t>(r->args.size());\n        if (r->nargs_pos_only > r->nargs_pos) {\n            pybind11_fail(\"pos_only(): cannot follow a py::args() argument\");\n        }\n        // It also can't follow a kw_only, but a static_assert in pybind11.h checks that\n    }\n};\n\n/// Process a parent class attribute.  Single inheritance only (class_ itself already guarantees\n/// that)\ntemplate <typename T>\nstruct process_attribute<T, enable_if_t<is_pyobject<T>::value>>\n    : process_attribute_default<handle> {\n    static void init(const handle &h, type_record *r) { r->bases.append(h); }\n};\n\n/// Process a parent class attribute (deprecated, does not support multiple inheritance)\ntemplate <typename T>\nstruct process_attribute<base<T>> : process_attribute_default<base<T>> {\n    static void init(const base<T> &, type_record *r) { r->add_base(typeid(T), nullptr); }\n};\n\n/// Process a multiple inheritance attribute\ntemplate <>\nstruct process_attribute<multiple_inheritance> : process_attribute_default<multiple_inheritance> {\n    static void init(const multiple_inheritance &, type_record *r) {\n        r->multiple_inheritance = true;\n    }\n};\n\ntemplate <>\nstruct process_attribute<dynamic_attr> : process_attribute_default<dynamic_attr> {\n    static void init(const dynamic_attr &, type_record *r) { r->dynamic_attr = true; }\n};\n\ntemplate <>\nstruct process_attribute<custom_type_setup> {\n    static void init(const custom_type_setup &value, type_record *r) {\n        r->custom_type_setup_callback = value.value;\n    }\n};\n\ntemplate <>\nstruct process_attribute<is_final> : process_attribute_default<is_final> {\n    static void init(const is_final &, type_record *r) { r->is_final = true; }\n};\n\ntemplate <>\nstruct process_attribute<buffer_protocol> : process_attribute_default<buffer_protocol> {\n    static void init(const buffer_protocol &, type_record *r) { r->buffer_protocol = true; }\n};\n\ntemplate <>\nstruct process_attribute<metaclass> : process_attribute_default<metaclass> {\n    static void init(const metaclass &m, type_record *r) { r->metaclass = m.value; }\n};\n\ntemplate <>\nstruct process_attribute<module_local> : process_attribute_default<module_local> {\n    static void init(const module_local &l, type_record *r) { r->module_local = l.value; }\n};\n\n/// Process a 'prepend' attribute, putting this at the beginning of the overload chain\ntemplate <>\nstruct process_attribute<prepend> : process_attribute_default<prepend> {\n    static void init(const prepend &, function_record *r) { r->prepend = true; }\n};\n\n/// Process an 'arithmetic' attribute for enums (does nothing here)\ntemplate <>\nstruct process_attribute<arithmetic> : process_attribute_default<arithmetic> {};\n\ntemplate <typename... Ts>\nstruct process_attribute<call_guard<Ts...>> : process_attribute_default<call_guard<Ts...>> {};\n\n/**\n * Process a keep_alive call policy -- invokes keep_alive_impl during the\n * pre-call handler if both Nurse, Patient != 0 and use the post-call handler\n * otherwise\n */\ntemplate <size_t Nurse, size_t Patient>\nstruct process_attribute<keep_alive<Nurse, Patient>>\n    : public process_attribute_default<keep_alive<Nurse, Patient>> {\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>\n    static void precall(function_call &call) {\n        keep_alive_impl(Nurse, Patient, call, handle());\n    }\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N != 0 && P != 0, int> = 0>\n    static void postcall(function_call &, handle) {}\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>\n    static void precall(function_call &) {}\n    template <size_t N = Nurse, size_t P = Patient, enable_if_t<N == 0 || P == 0, int> = 0>\n    static void postcall(function_call &call, handle ret) {\n        keep_alive_impl(Nurse, Patient, call, ret);\n    }\n};\n\n/// Recursively iterate over variadic template arguments\ntemplate <typename... Args>\nstruct process_attributes {\n    static void init(const Args &...args, function_record *r) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);\n        using expander = int[];\n        (void) expander{\n            0, ((void) process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};\n    }\n    static void init(const Args &...args, type_record *r) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(r);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(r);\n        using expander = int[];\n        (void) expander{0,\n                        (process_attribute<typename std::decay<Args>::type>::init(args, r), 0)...};\n    }\n    static void precall(function_call &call) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call);\n        using expander = int[];\n        (void) expander{0,\n                        (process_attribute<typename std::decay<Args>::type>::precall(call), 0)...};\n    }\n    static void postcall(function_call &call, handle fn_ret) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(call, fn_ret);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(fn_ret);\n        using expander = int[];\n        (void) expander{\n            0, (process_attribute<typename std::decay<Args>::type>::postcall(call, fn_ret), 0)...};\n    }\n};\n\ntemplate <typename T>\nusing is_call_guard = is_instantiation<call_guard, T>;\n\n/// Extract the ``type`` from the first `call_guard` in `Extras...` (or `void_type` if none found)\ntemplate <typename... Extra>\nusing extract_guard_t = typename exactly_one_t<is_call_guard, call_guard<>, Extra...>::type;\n\n/// Check the number of named arguments at compile time\ntemplate <typename... Extra,\n          size_t named = constexpr_sum(std::is_base_of<arg, Extra>::value...),\n          size_t self = constexpr_sum(std::is_same<is_method, Extra>::value...)>\nconstexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(nargs, has_args, has_kwargs);\n    return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs;\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/buffer_info.h",
    "content": "/*\n    pybind11/buffer_info.h: Python buffer object interface\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Default, C-style strides\ninline std::vector<ssize_t> c_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {\n    auto ndim = shape.size();\n    std::vector<ssize_t> strides(ndim, itemsize);\n    if (ndim > 0) {\n        for (size_t i = ndim - 1; i > 0; --i) {\n            strides[i - 1] = strides[i] * shape[i];\n        }\n    }\n    return strides;\n}\n\n// F-style strides; default when constructing an array_t with `ExtraFlags & f_style`\ninline std::vector<ssize_t> f_strides(const std::vector<ssize_t> &shape, ssize_t itemsize) {\n    auto ndim = shape.size();\n    std::vector<ssize_t> strides(ndim, itemsize);\n    for (size_t i = 1; i < ndim; ++i) {\n        strides[i] = strides[i - 1] * shape[i - 1];\n    }\n    return strides;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Information record describing a Python buffer object\nstruct buffer_info {\n    void *ptr = nullptr;          // Pointer to the underlying storage\n    ssize_t itemsize = 0;         // Size of individual items in bytes\n    ssize_t size = 0;             // Total number of entries\n    std::string format;           // For homogeneous buffers, this should be set to\n                                  // format_descriptor<T>::format()\n    ssize_t ndim = 0;             // Number of dimensions\n    std::vector<ssize_t> shape;   // Shape of the tensor (1 entry per dimension)\n    std::vector<ssize_t> strides; // Number of bytes between adjacent entries\n                                  // (for each per dimension)\n    bool readonly = false;        // flag to indicate if the underlying storage may be written to\n\n    buffer_info() = default;\n\n    buffer_info(void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t ndim,\n                detail::any_container<ssize_t> shape_in,\n                detail::any_container<ssize_t> strides_in,\n                bool readonly = false)\n        : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim),\n          shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) {\n        if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) {\n            pybind11_fail(\"buffer_info: ndim doesn't match shape and/or strides length\");\n        }\n        for (size_t i = 0; i < (size_t) ndim; ++i) {\n            size *= shape[i];\n        }\n    }\n\n    template <typename T>\n    buffer_info(T *ptr,\n                detail::any_container<ssize_t> shape_in,\n                detail::any_container<ssize_t> strides_in,\n                bool readonly = false)\n        : buffer_info(private_ctr_tag(),\n                      ptr,\n                      sizeof(T),\n                      format_descriptor<T>::format(),\n                      static_cast<ssize_t>(shape_in->size()),\n                      std::move(shape_in),\n                      std::move(strides_in),\n                      readonly) {}\n\n    buffer_info(void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t size,\n                bool readonly = false)\n        : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {}\n\n    template <typename T>\n    buffer_info(T *ptr, ssize_t size, bool readonly = false)\n        : buffer_info(ptr, sizeof(T), format_descriptor<T>::format(), size, readonly) {}\n\n    template <typename T>\n    buffer_info(const T *ptr, ssize_t size, bool readonly = true)\n        : buffer_info(\n            const_cast<T *>(ptr), sizeof(T), format_descriptor<T>::format(), size, readonly) {}\n\n    explicit buffer_info(Py_buffer *view, bool ownview = true)\n        : buffer_info(\n            view->buf,\n            view->itemsize,\n            view->format,\n            view->ndim,\n            {view->shape, view->shape + view->ndim},\n            /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects\n             * ignore this flag and return a view with NULL strides.\n             * When strides are NULL, build them manually.  */\n            view->strides\n                ? std::vector<ssize_t>(view->strides, view->strides + view->ndim)\n                : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize),\n            (view->readonly != 0)) {\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        this->m_view = view;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        this->ownview = ownview;\n    }\n\n    buffer_info(const buffer_info &) = delete;\n    buffer_info &operator=(const buffer_info &) = delete;\n\n    buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); }\n\n    buffer_info &operator=(buffer_info &&rhs) noexcept {\n        ptr = rhs.ptr;\n        itemsize = rhs.itemsize;\n        size = rhs.size;\n        format = std::move(rhs.format);\n        ndim = rhs.ndim;\n        shape = std::move(rhs.shape);\n        strides = std::move(rhs.strides);\n        std::swap(m_view, rhs.m_view);\n        std::swap(ownview, rhs.ownview);\n        readonly = rhs.readonly;\n        return *this;\n    }\n\n    ~buffer_info() {\n        if (m_view && ownview) {\n            PyBuffer_Release(m_view);\n            delete m_view;\n        }\n    }\n\n    Py_buffer *view() const { return m_view; }\n    Py_buffer *&view() { return m_view; }\n\nprivate:\n    struct private_ctr_tag {};\n\n    buffer_info(private_ctr_tag,\n                void *ptr,\n                ssize_t itemsize,\n                const std::string &format,\n                ssize_t ndim,\n                detail::any_container<ssize_t> &&shape_in,\n                detail::any_container<ssize_t> &&strides_in,\n                bool readonly)\n        : buffer_info(\n            ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {}\n\n    Py_buffer *m_view = nullptr;\n    bool ownview = false;\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T, typename SFINAE = void>\nstruct compare_buffer_info {\n    static bool compare(const buffer_info &b) {\n        return b.format == format_descriptor<T>::format() && b.itemsize == (ssize_t) sizeof(T);\n    }\n};\n\ntemplate <typename T>\nstruct compare_buffer_info<T, detail::enable_if_t<std::is_integral<T>::value>> {\n    static bool compare(const buffer_info &b) {\n        return (size_t) b.itemsize == sizeof(T)\n               && (b.format == format_descriptor<T>::value\n                   || ((sizeof(T) == sizeof(long))\n                       && b.format == (std::is_unsigned<T>::value ? \"L\" : \"l\"))\n                   || ((sizeof(T) == sizeof(size_t))\n                       && b.format == (std::is_unsigned<T>::value ? \"N\" : \"n\")));\n    }\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/cast.h",
    "content": "/*\n    pybind11/cast.h: Partial template specializations to cast between\n    C++ and Python types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"detail/descr.h\"\n#include \"detail/type_caster_base.h\"\n#include \"detail/typeid.h\"\n#include \"pytypes.h\"\n\n#include <array>\n#include <cstring>\n#include <functional>\n#include <iosfwd>\n#include <iterator>\n#include <memory>\n#include <string>\n#include <tuple>\n#include <type_traits>\n#include <utility>\n#include <vector>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename type, typename SFINAE = void>\nclass type_caster : public type_caster_base<type> {};\ntemplate <typename type>\nusing make_caster = type_caster<intrinsic_t<type>>;\n\n// Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T\ntemplate <typename T>\ntypename make_caster<T>::template cast_op_type<T> cast_op(make_caster<T> &caster) {\n    return caster.operator typename make_caster<T>::template cast_op_type<T>();\n}\ntemplate <typename T>\ntypename make_caster<T>::template cast_op_type<typename std::add_rvalue_reference<T>::type>\ncast_op(make_caster<T> &&caster) {\n    return std::move(caster).operator typename make_caster<T>::\n        template cast_op_type<typename std::add_rvalue_reference<T>::type>();\n}\n\ntemplate <typename type>\nclass type_caster<std::reference_wrapper<type>> {\nprivate:\n    using caster_t = make_caster<type>;\n    caster_t subcaster;\n    using reference_t = type &;\n    using subcaster_cast_op_type = typename caster_t::template cast_op_type<reference_t>;\n\n    static_assert(\n        std::is_same<typename std::remove_const<type>::type &, subcaster_cast_op_type>::value\n            || std::is_same<reference_t, subcaster_cast_op_type>::value,\n        \"std::reference_wrapper<T> caster requires T to have a caster with an \"\n        \"`operator T &()` or `operator const T &()`\");\n\npublic:\n    bool load(handle src, bool convert) { return subcaster.load(src, convert); }\n    static constexpr auto name = caster_t::name;\n    static handle\n    cast(const std::reference_wrapper<type> &src, return_value_policy policy, handle parent) {\n        // It is definitely wrong to take ownership of this pointer, so mask that rvp\n        if (policy == return_value_policy::take_ownership\n            || policy == return_value_policy::automatic) {\n            policy = return_value_policy::automatic_reference;\n        }\n        return caster_t::cast(&src.get(), policy, parent);\n    }\n    template <typename T>\n    using cast_op_type = std::reference_wrapper<type>;\n    explicit operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }\n};\n\n#define PYBIND11_TYPE_CASTER(type, py_name)                                                       \\\nprotected:                                                                                        \\\n    type value;                                                                                   \\\n                                                                                                  \\\npublic:                                                                                           \\\n    static constexpr auto name = py_name;                                                         \\\n    template <typename T_,                                                                        \\\n              ::pybind11::detail::enable_if_t<                                                    \\\n                  std::is_same<type, ::pybind11::detail::remove_cv_t<T_>>::value,                 \\\n                  int> = 0>                                                                       \\\n    static ::pybind11::handle cast(                                                               \\\n        T_ *src, ::pybind11::return_value_policy policy, ::pybind11::handle parent) {             \\\n        if (!src)                                                                                 \\\n            return ::pybind11::none().release();                                                  \\\n        if (policy == ::pybind11::return_value_policy::take_ownership) {                          \\\n            auto h = cast(std::move(*src), policy, parent);                                       \\\n            delete src;                                                                           \\\n            return h;                                                                             \\\n        }                                                                                         \\\n        return cast(*src, policy, parent);                                                        \\\n    }                                                                                             \\\n    operator type *() { return &value; }               /* NOLINT(bugprone-macro-parentheses) */   \\\n    operator type &() { return value; }                /* NOLINT(bugprone-macro-parentheses) */   \\\n    operator type &&() && { return std::move(value); } /* NOLINT(bugprone-macro-parentheses) */   \\\n    template <typename T_>                                                                        \\\n    using cast_op_type = ::pybind11::detail::movable_cast_op_type<T_>\n\ntemplate <typename CharT>\nusing is_std_char_type = any_of<std::is_same<CharT, char>, /* std::string */\n#if defined(PYBIND11_HAS_U8STRING)\n                                std::is_same<CharT, char8_t>, /* std::u8string */\n#endif\n                                std::is_same<CharT, char16_t>, /* std::u16string */\n                                std::is_same<CharT, char32_t>, /* std::u32string */\n                                std::is_same<CharT, wchar_t>   /* std::wstring */\n                                >;\n\ntemplate <typename T>\nstruct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_type<T>::value>> {\n    using _py_type_0 = conditional_t<sizeof(T) <= sizeof(long), long, long long>;\n    using _py_type_1 = conditional_t<std::is_signed<T>::value,\n                                     _py_type_0,\n                                     typename std::make_unsigned<_py_type_0>::type>;\n    using py_type = conditional_t<std::is_floating_point<T>::value, double, _py_type_1>;\n\npublic:\n    bool load(handle src, bool convert) {\n        py_type py_value;\n\n        if (!src) {\n            return false;\n        }\n\n#if !defined(PYPY_VERSION)\n        auto index_check = [](PyObject *o) { return PyIndex_Check(o); };\n#else\n        // In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,\n        // while CPython only considers the existence of `nb_index`/`__index__`.\n        auto index_check = [](PyObject *o) { return hasattr(o, \"__index__\"); };\n#endif\n\n        if (std::is_floating_point<T>::value) {\n            if (convert || PyFloat_Check(src.ptr())) {\n                py_value = (py_type) PyFloat_AsDouble(src.ptr());\n            } else {\n                return false;\n            }\n        } else if (PyFloat_Check(src.ptr())\n                   || (!convert && !PYBIND11_LONG_CHECK(src.ptr()) && !index_check(src.ptr()))) {\n            return false;\n        } else {\n            handle src_or_index = src;\n            // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.\n#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)\n            object index;\n            if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr())\n                index = reinterpret_steal<object>(PyNumber_Index(src.ptr()));\n                if (!index) {\n                    PyErr_Clear();\n                    if (!convert)\n                        return false;\n                } else {\n                    src_or_index = index;\n                }\n            }\n#endif\n            if (std::is_unsigned<py_type>::value) {\n                py_value = as_unsigned<py_type>(src_or_index.ptr());\n            } else { // signed integer:\n                py_value = sizeof(T) <= sizeof(long)\n                               ? (py_type) PyLong_AsLong(src_or_index.ptr())\n                               : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr());\n            }\n        }\n\n        // Python API reported an error\n        bool py_err = py_value == (py_type) -1 && PyErr_Occurred();\n\n        // Check to see if the conversion is valid (integers should match exactly)\n        // Signed/unsigned checks happen elsewhere\n        if (py_err\n            || (std::is_integral<T>::value && sizeof(py_type) != sizeof(T)\n                && py_value != (py_type) (T) py_value)) {\n            PyErr_Clear();\n            if (py_err && convert && (PyNumber_Check(src.ptr()) != 0)) {\n                auto tmp = reinterpret_steal<object>(std::is_floating_point<T>::value\n                                                         ? PyNumber_Float(src.ptr())\n                                                         : PyNumber_Long(src.ptr()));\n                PyErr_Clear();\n                return load(tmp, false);\n            }\n            return false;\n        }\n\n        value = (T) py_value;\n        return true;\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<std::is_floating_point<U>::value, handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyFloat_FromDouble((double) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value\n                                       && (sizeof(U) <= sizeof(long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PYBIND11_LONG_FROM_SIGNED((long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value\n                                       && (sizeof(U) <= sizeof(unsigned long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_signed<U>::value\n                                       && (sizeof(U) > sizeof(long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyLong_FromLongLong((long long) src);\n    }\n\n    template <typename U = T>\n    static typename std::enable_if<!std::is_floating_point<U>::value && std::is_unsigned<U>::value\n                                       && (sizeof(U) > sizeof(unsigned long)),\n                                   handle>::type\n    cast(U src, return_value_policy /* policy */, handle /* parent */) {\n        return PyLong_FromUnsignedLongLong((unsigned long long) src);\n    }\n\n    PYBIND11_TYPE_CASTER(T, const_name<std::is_integral<T>::value>(\"int\", \"float\"));\n};\n\ntemplate <typename T>\nstruct void_caster {\npublic:\n    bool load(handle src, bool) {\n        if (src && src.is_none()) {\n            return true;\n        }\n        return false;\n    }\n    static handle cast(T, return_value_policy /* policy */, handle /* parent */) {\n        return none().inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(T, const_name(\"None\"));\n};\n\ntemplate <>\nclass type_caster<void_type> : public void_caster<void_type> {};\n\ntemplate <>\nclass type_caster<void> : public type_caster<void_type> {\npublic:\n    using type_caster<void_type>::cast;\n\n    bool load(handle h, bool) {\n        if (!h) {\n            return false;\n        }\n        if (h.is_none()) {\n            value = nullptr;\n            return true;\n        }\n\n        /* Check if this is a capsule */\n        if (isinstance<capsule>(h)) {\n            value = reinterpret_borrow<capsule>(h);\n            return true;\n        }\n\n        /* Check if this is a C++ type */\n        const auto &bases = all_type_info((PyTypeObject *) type::handle_of(h).ptr());\n        if (bases.size() == 1) { // Only allowing loading from a single-value type\n            value = values_and_holders(reinterpret_cast<instance *>(h.ptr())).begin()->value_ptr();\n            return true;\n        }\n\n        /* Fail */\n        return false;\n    }\n\n    static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {\n        if (ptr) {\n            return capsule(ptr).release();\n        }\n        return none().inc_ref();\n    }\n\n    template <typename T>\n    using cast_op_type = void *&;\n    explicit operator void *&() { return value; }\n    static constexpr auto name = const_name(\"capsule\");\n\nprivate:\n    void *value = nullptr;\n};\n\ntemplate <>\nclass type_caster<std::nullptr_t> : public void_caster<std::nullptr_t> {};\n\ntemplate <>\nclass type_caster<bool> {\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.ptr() == Py_True) {\n            value = true;\n            return true;\n        }\n        if (src.ptr() == Py_False) {\n            value = false;\n            return true;\n        }\n        if (convert || (std::strcmp(\"numpy.bool_\", Py_TYPE(src.ptr())->tp_name) == 0)) {\n            // (allow non-implicit conversion for numpy booleans)\n\n            Py_ssize_t res = -1;\n            if (src.is_none()) {\n                res = 0; // None is implicitly converted to False\n            }\n#if defined(PYPY_VERSION)\n            // On PyPy, check that \"__bool__\" (or \"__nonzero__\" on Python 2.7) attr exists\n            else if (hasattr(src, PYBIND11_BOOL_ATTR)) {\n                res = PyObject_IsTrue(src.ptr());\n            }\n#else\n            // Alternate approach for CPython: this does the same as the above, but optimized\n            // using the CPython API so as to avoid an unneeded attribute lookup.\n            else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) {\n                if (PYBIND11_NB_BOOL(tp_as_number)) {\n                    res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());\n                }\n            }\n#endif\n            if (res == 0 || res == 1) {\n                value = (res != 0);\n                return true;\n            }\n            PyErr_Clear();\n        }\n        return false;\n    }\n    static handle cast(bool src, return_value_policy /* policy */, handle /* parent */) {\n        return handle(src ? Py_True : Py_False).inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(bool, const_name(\"bool\"));\n};\n\n// Helper class for UTF-{8,16,32} C++ stl strings:\ntemplate <typename StringType, bool IsView = false>\nstruct string_caster {\n    using CharT = typename StringType::value_type;\n\n    // Simplify life by being able to assume standard char sizes (the standard only guarantees\n    // minimums, but Python requires exact sizes)\n    static_assert(!std::is_same<CharT, char>::value || sizeof(CharT) == 1,\n                  \"Unsupported char size != 1\");\n#if defined(PYBIND11_HAS_U8STRING)\n    static_assert(!std::is_same<CharT, char8_t>::value || sizeof(CharT) == 1,\n                  \"Unsupported char8_t size != 1\");\n#endif\n    static_assert(!std::is_same<CharT, char16_t>::value || sizeof(CharT) == 2,\n                  \"Unsupported char16_t size != 2\");\n    static_assert(!std::is_same<CharT, char32_t>::value || sizeof(CharT) == 4,\n                  \"Unsupported char32_t size != 4\");\n    // wchar_t can be either 16 bits (Windows) or 32 (everywhere else)\n    static_assert(!std::is_same<CharT, wchar_t>::value || sizeof(CharT) == 2 || sizeof(CharT) == 4,\n                  \"Unsupported wchar_t size != 2/4\");\n    static constexpr size_t UTF_N = 8 * sizeof(CharT);\n\n    bool load(handle src, bool) {\n#if PY_MAJOR_VERSION < 3\n        object temp;\n#endif\n        handle load_src = src;\n        if (!src) {\n            return false;\n        }\n        if (!PyUnicode_Check(load_src.ptr())) {\n#if PY_MAJOR_VERSION >= 3\n            return load_bytes(load_src);\n#else\n            if (std::is_same<CharT, char>::value) {\n                return load_bytes(load_src);\n            }\n\n            // The below is a guaranteed failure in Python 3 when PyUnicode_Check returns false\n            if (!PYBIND11_BYTES_CHECK(load_src.ptr()))\n                return false;\n\n            temp = reinterpret_steal<object>(PyUnicode_FromObject(load_src.ptr()));\n            if (!temp) {\n                PyErr_Clear();\n                return false;\n            }\n            load_src = temp;\n#endif\n        }\n\n#if PY_VERSION_HEX >= 0x03030000\n        // On Python >= 3.3, for UTF-8 we avoid the need for a temporary `bytes`\n        // object by using `PyUnicode_AsUTF8AndSize`.\n        if (PYBIND11_SILENCE_MSVC_C4127(UTF_N == 8)) {\n            Py_ssize_t size = -1;\n            const auto *buffer\n                = reinterpret_cast<const CharT *>(PyUnicode_AsUTF8AndSize(load_src.ptr(), &size));\n            if (!buffer) {\n                PyErr_Clear();\n                return false;\n            }\n            value = StringType(buffer, static_cast<size_t>(size));\n            return true;\n        }\n#endif\n\n        auto utfNbytes\n            = reinterpret_steal<object>(PyUnicode_AsEncodedString(load_src.ptr(),\n                                                                  UTF_N == 8    ? \"utf-8\"\n                                                                  : UTF_N == 16 ? \"utf-16\"\n                                                                                : \"utf-32\",\n                                                                  nullptr));\n        if (!utfNbytes) {\n            PyErr_Clear();\n            return false;\n        }\n\n        const auto *buffer\n            = reinterpret_cast<const CharT *>(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr()));\n        size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT);\n        // Skip BOM for UTF-16/32\n        if (PYBIND11_SILENCE_MSVC_C4127(UTF_N > 8)) {\n            buffer++;\n            length--;\n        }\n        value = StringType(buffer, length);\n\n        // If we're loading a string_view we need to keep the encoded Python object alive:\n        if (IsView) {\n            loader_life_support::add_patient(utfNbytes);\n        }\n\n        return true;\n    }\n\n    static handle\n    cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) {\n        const char *buffer = reinterpret_cast<const char *>(src.data());\n        auto nbytes = ssize_t(src.size() * sizeof(CharT));\n        handle s = decode_utfN(buffer, nbytes);\n        if (!s) {\n            throw error_already_set();\n        }\n        return s;\n    }\n\n    PYBIND11_TYPE_CASTER(StringType, const_name(PYBIND11_STRING_NAME));\n\nprivate:\n    static handle decode_utfN(const char *buffer, ssize_t nbytes) {\n#if !defined(PYPY_VERSION)\n        return UTF_N == 8    ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr)\n               : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr)\n                             : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);\n#else\n        // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as\n        // well), so bypass the whole thing by just passing the encoding as a string value, which\n        // works properly:\n        return PyUnicode_Decode(buffer,\n                                nbytes,\n                                UTF_N == 8    ? \"utf-8\"\n                                : UTF_N == 16 ? \"utf-16\"\n                                              : \"utf-32\",\n                                nullptr);\n#endif\n    }\n\n    // When loading into a std::string or char*, accept a bytes object as-is (i.e.\n    // without any encoding/decoding attempt).  For other C++ char sizes this is a no-op.\n    // which supports loading a unicode from a str, doesn't take this path.\n    template <typename C = CharT>\n    bool load_bytes(enable_if_t<std::is_same<C, char>::value, handle> src) {\n        if (PYBIND11_BYTES_CHECK(src.ptr())) {\n            // We were passed a Python 3 raw bytes; accept it into a std::string or char*\n            // without any encoding attempt.\n            const char *bytes = PYBIND11_BYTES_AS_STRING(src.ptr());\n            if (bytes) {\n                value = StringType(bytes, (size_t) PYBIND11_BYTES_SIZE(src.ptr()));\n                return true;\n            }\n        }\n\n        return false;\n    }\n\n    template <typename C = CharT>\n    bool load_bytes(enable_if_t<!std::is_same<C, char>::value, handle>) {\n        return false;\n    }\n};\n\ntemplate <typename CharT, class Traits, class Allocator>\nstruct type_caster<std::basic_string<CharT, Traits, Allocator>,\n                   enable_if_t<is_std_char_type<CharT>::value>>\n    : string_caster<std::basic_string<CharT, Traits, Allocator>> {};\n\n#ifdef PYBIND11_HAS_STRING_VIEW\ntemplate <typename CharT, class Traits>\nstruct type_caster<std::basic_string_view<CharT, Traits>,\n                   enable_if_t<is_std_char_type<CharT>::value>>\n    : string_caster<std::basic_string_view<CharT, Traits>, true> {};\n#endif\n\n// Type caster for C-style strings.  We basically use a std::string type caster, but also add the\n// ability to use None as a nullptr char* (which the string caster doesn't allow).\ntemplate <typename CharT>\nstruct type_caster<CharT, enable_if_t<is_std_char_type<CharT>::value>> {\n    using StringType = std::basic_string<CharT>;\n    using StringCaster = type_caster<StringType>;\n    StringCaster str_caster;\n    bool none = false;\n    CharT one_char = 0;\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            none = true;\n            return true;\n        }\n        return str_caster.load(src, convert);\n    }\n\n    static handle cast(const CharT *src, return_value_policy policy, handle parent) {\n        if (src == nullptr) {\n            return pybind11::none().inc_ref();\n        }\n        return StringCaster::cast(StringType(src), policy, parent);\n    }\n\n    static handle cast(CharT src, return_value_policy policy, handle parent) {\n        if (std::is_same<char, CharT>::value) {\n            handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr);\n            if (!s) {\n                throw error_already_set();\n            }\n            return s;\n        }\n        return StringCaster::cast(StringType(1, src), policy, parent);\n    }\n\n    explicit operator CharT *() {\n        return none ? nullptr : const_cast<CharT *>(static_cast<StringType &>(str_caster).c_str());\n    }\n    explicit operator CharT &() {\n        if (none) {\n            throw value_error(\"Cannot convert None to a character\");\n        }\n\n        auto &value = static_cast<StringType &>(str_caster);\n        size_t str_len = value.size();\n        if (str_len == 0) {\n            throw value_error(\"Cannot convert empty string to a character\");\n        }\n\n        // If we're in UTF-8 mode, we have two possible failures: one for a unicode character that\n        // is too high, and one for multiple unicode characters (caught later), so we need to\n        // figure out how long the first encoded character is in bytes to distinguish between these\n        // two errors.  We also allow want to allow unicode characters U+0080 through U+00FF, as\n        // those can fit into a single char value.\n        if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 8) && str_len > 1 && str_len <= 4) {\n            auto v0 = static_cast<unsigned char>(value[0]);\n            // low bits only: 0-127\n            // 0b110xxxxx - start of 2-byte sequence\n            // 0b1110xxxx - start of 3-byte sequence\n            // 0b11110xxx - start of 4-byte sequence\n            size_t char0_bytes = (v0 & 0x80) == 0      ? 1\n                                 : (v0 & 0xE0) == 0xC0 ? 2\n                                 : (v0 & 0xF0) == 0xE0 ? 3\n                                                       : 4;\n\n            if (char0_bytes == str_len) {\n                // If we have a 128-255 value, we can decode it into a single char:\n                if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx\n                    one_char = static_cast<CharT>(((v0 & 3) << 6)\n                                                  + (static_cast<unsigned char>(value[1]) & 0x3F));\n                    return one_char;\n                }\n                // Otherwise we have a single character, but it's > U+00FF\n                throw value_error(\"Character code point not in range(0x100)\");\n            }\n        }\n\n        // UTF-16 is much easier: we can only have a surrogate pair for values above U+FFFF, thus a\n        // surrogate pair with total length 2 instantly indicates a range error (but not a \"your\n        // string was too long\" error).\n        else if (PYBIND11_SILENCE_MSVC_C4127(StringCaster::UTF_N == 16) && str_len == 2) {\n            one_char = static_cast<CharT>(value[0]);\n            if (one_char >= 0xD800 && one_char < 0xE000) {\n                throw value_error(\"Character code point not in range(0x10000)\");\n            }\n        }\n\n        if (str_len != 1) {\n            throw value_error(\"Expected a character, but multi-character string found\");\n        }\n\n        one_char = value[0];\n        return one_char;\n    }\n\n    static constexpr auto name = const_name(PYBIND11_STRING_NAME);\n    template <typename _T>\n    using cast_op_type = pybind11::detail::cast_op_type<_T>;\n};\n\n// Base implementation for std::tuple and std::pair\ntemplate <template <typename...> class Tuple, typename... Ts>\nclass tuple_caster {\n    using type = Tuple<Ts...>;\n    static constexpr auto size = sizeof...(Ts);\n    using indices = make_index_sequence<size>;\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src)) {\n            return false;\n        }\n        const auto seq = reinterpret_borrow<sequence>(src);\n        if (seq.size() != size) {\n            return false;\n        }\n        return load_impl(seq, convert, indices{});\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        return cast_impl(std::forward<T>(src), policy, parent, indices{});\n    }\n\n    // copied from the PYBIND11_TYPE_CASTER macro\n    template <typename T>\n    static handle cast(T *src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().release();\n        }\n        if (policy == return_value_policy::take_ownership) {\n            auto h = cast(std::move(*src), policy, parent);\n            delete src;\n            return h;\n        }\n        return cast(*src, policy, parent);\n    }\n\n    static constexpr auto name\n        = const_name(\"Tuple[\") + concat(make_caster<Ts>::name...) + const_name(\"]\");\n\n    template <typename T>\n    using cast_op_type = type;\n\n    explicit operator type() & { return implicit_cast(indices{}); }\n    explicit operator type() && { return std::move(*this).implicit_cast(indices{}); }\n\nprotected:\n    template <size_t... Is>\n    type implicit_cast(index_sequence<Is...>) & {\n        return type(cast_op<Ts>(std::get<Is>(subcasters))...);\n    }\n    template <size_t... Is>\n    type implicit_cast(index_sequence<Is...>) && {\n        return type(cast_op<Ts>(std::move(std::get<Is>(subcasters)))...);\n    }\n\n    static constexpr bool load_impl(const sequence &, bool, index_sequence<>) { return true; }\n\n    template <size_t... Is>\n    bool load_impl(const sequence &seq, bool convert, index_sequence<Is...>) {\n#ifdef __cpp_fold_expressions\n        if ((... || !std::get<Is>(subcasters).load(seq[Is], convert))) {\n            return false;\n        }\n#else\n        for (bool r : {std::get<Is>(subcasters).load(seq[Is], convert)...}) {\n            if (!r) {\n                return false;\n            }\n        }\n#endif\n        return true;\n    }\n\n    /* Implementation: Convert a C++ tuple into a Python tuple */\n    template <typename T, size_t... Is>\n    static handle\n    cast_impl(T &&src, return_value_policy policy, handle parent, index_sequence<Is...>) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(src, policy, parent);\n        PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(policy, parent);\n        std::array<object, size> entries{{reinterpret_steal<object>(\n            make_caster<Ts>::cast(std::get<Is>(std::forward<T>(src)), policy, parent))...}};\n        for (const auto &entry : entries) {\n            if (!entry) {\n                return handle();\n            }\n        }\n        tuple result(size);\n        int counter = 0;\n        for (auto &entry : entries) {\n            PyTuple_SET_ITEM(result.ptr(), counter++, entry.release().ptr());\n        }\n        return result.release();\n    }\n\n    Tuple<make_caster<Ts>...> subcasters;\n};\n\ntemplate <typename T1, typename T2>\nclass type_caster<std::pair<T1, T2>> : public tuple_caster<std::pair, T1, T2> {};\n\ntemplate <typename... Ts>\nclass type_caster<std::tuple<Ts...>> : public tuple_caster<std::tuple, Ts...> {};\n\n/// Helper class which abstracts away certain actions. Users can provide specializations for\n/// custom holders, but it's only necessary if the type has a non-standard interface.\ntemplate <typename T>\nstruct holder_helper {\n    static auto get(const T &p) -> decltype(p.get()) { return p.get(); }\n};\n\n/// Type caster for holder types like std::shared_ptr, etc.\n/// The SFINAE hook is provided to help work around the current lack of support\n/// for smart-pointer interoperability. Please consider it an implementation\n/// detail that may change in the future, as formal support for smart-pointer\n/// interoperability is added into pybind11.\ntemplate <typename type, typename holder_type, typename SFINAE = void>\nstruct copyable_holder_caster : public type_caster_base<type> {\npublic:\n    using base = type_caster_base<type>;\n    static_assert(std::is_base_of<base, type_caster<type>>::value,\n                  \"Holder classes are only supported for custom types\");\n    using base::base;\n    using base::cast;\n    using base::typeinfo;\n    using base::value;\n\n    bool load(handle src, bool convert) {\n        return base::template load_impl<copyable_holder_caster<type, holder_type>>(src, convert);\n    }\n\n    explicit operator type *() { return this->value; }\n    // static_cast works around compiler error with MSVC 17 and CUDA 10.2\n    // see issue #2180\n    explicit operator type &() { return *(static_cast<type *>(this->value)); }\n    explicit operator holder_type *() { return std::addressof(holder); }\n    explicit operator holder_type &() { return holder; }\n\n    static handle cast(const holder_type &src, return_value_policy, handle) {\n        const auto *ptr = holder_helper<holder_type>::get(src);\n        return type_caster_base<type>::cast_holder(ptr, &src);\n    }\n\nprotected:\n    friend class type_caster_generic;\n    void check_holder_compat() {\n        if (typeinfo->default_holder) {\n            throw cast_error(\"Unable to load a custom holder type from a default-holder instance\");\n        }\n    }\n\n    bool load_value(value_and_holder &&v_h) {\n        if (v_h.holder_constructed()) {\n            value = v_h.value_ptr();\n            holder = v_h.template holder<holder_type>();\n            return true;\n        }\n        throw cast_error(\"Unable to cast from non-held to held instance (T& to Holder<T>) \"\n#if defined(NDEBUG)\n                         \"(compile in debug mode for type information)\");\n#else\n                         \"of type '\"\n                         + type_id<holder_type>() + \"''\");\n#endif\n    }\n\n    template <typename T = holder_type,\n              detail::enable_if_t<!std::is_constructible<T, const T &, type *>::value, int> = 0>\n    bool try_implicit_casts(handle, bool) {\n        return false;\n    }\n\n    template <typename T = holder_type,\n              detail::enable_if_t<std::is_constructible<T, const T &, type *>::value, int> = 0>\n    bool try_implicit_casts(handle src, bool convert) {\n        for (auto &cast : typeinfo->implicit_casts) {\n            copyable_holder_caster sub_caster(*cast.first);\n            if (sub_caster.load(src, convert)) {\n                value = cast.second(sub_caster.value);\n                holder = holder_type(sub_caster.holder, (type *) value);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    static bool try_direct_conversions(handle) { return false; }\n\n    holder_type holder;\n};\n\n/// Specialize for the common std::shared_ptr, so users don't need to\ntemplate <typename T>\nclass type_caster<std::shared_ptr<T>> : public copyable_holder_caster<T, std::shared_ptr<T>> {};\n\n/// Type caster for holder types like std::unique_ptr.\n/// Please consider the SFINAE hook an implementation detail, as explained\n/// in the comment for the copyable_holder_caster.\ntemplate <typename type, typename holder_type, typename SFINAE = void>\nstruct move_only_holder_caster {\n    static_assert(std::is_base_of<type_caster_base<type>, type_caster<type>>::value,\n                  \"Holder classes are only supported for custom types\");\n\n    static handle cast(holder_type &&src, return_value_policy, handle) {\n        auto *ptr = holder_helper<holder_type>::get(src);\n        return type_caster_base<type>::cast_holder(ptr, std::addressof(src));\n    }\n    static constexpr auto name = type_caster_base<type>::name;\n};\n\ntemplate <typename type, typename deleter>\nclass type_caster<std::unique_ptr<type, deleter>>\n    : public move_only_holder_caster<type, std::unique_ptr<type, deleter>> {};\n\ntemplate <typename type, typename holder_type>\nusing type_caster_holder = conditional_t<is_copy_constructible<holder_type>::value,\n                                         copyable_holder_caster<type, holder_type>,\n                                         move_only_holder_caster<type, holder_type>>;\n\ntemplate <typename T, bool Value = false>\nstruct always_construct_holder {\n    static constexpr bool value = Value;\n};\n\n/// Create a specialization for custom holder types (silently ignores std::shared_ptr)\n#define PYBIND11_DECLARE_HOLDER_TYPE(type, holder_type, ...)                                      \\\n    namespace pybind11 {                                                                          \\\n    namespace detail {                                                                            \\\n    template <typename type>                                                                      \\\n    struct always_construct_holder<holder_type> : always_construct_holder<void, ##__VA_ARGS__> {  \\\n    };                                                                                            \\\n    template <typename type>                                                                      \\\n    class type_caster<holder_type, enable_if_t<!is_shared_ptr<holder_type>::value>>               \\\n        : public type_caster_holder<type, holder_type> {};                                        \\\n    }                                                                                             \\\n    }\n\n// PYBIND11_DECLARE_HOLDER_TYPE holder types:\ntemplate <typename base, typename holder>\nstruct is_holder_type\n    : std::is_base_of<detail::type_caster_holder<base, holder>, detail::type_caster<holder>> {};\n// Specialization for always-supported unique_ptr holders:\ntemplate <typename base, typename deleter>\nstruct is_holder_type<base, std::unique_ptr<base, deleter>> : std::true_type {};\n\ntemplate <typename T>\nstruct handle_type_name {\n    static constexpr auto name = const_name<T>();\n};\ntemplate <>\nstruct handle_type_name<bool_> {\n    static constexpr auto name = const_name(\"bool\");\n};\ntemplate <>\nstruct handle_type_name<bytes> {\n    static constexpr auto name = const_name(PYBIND11_BYTES_NAME);\n};\ntemplate <>\nstruct handle_type_name<int_> {\n    static constexpr auto name = const_name(\"int\");\n};\ntemplate <>\nstruct handle_type_name<iterable> {\n    static constexpr auto name = const_name(\"Iterable\");\n};\ntemplate <>\nstruct handle_type_name<iterator> {\n    static constexpr auto name = const_name(\"Iterator\");\n};\ntemplate <>\nstruct handle_type_name<float_> {\n    static constexpr auto name = const_name(\"float\");\n};\ntemplate <>\nstruct handle_type_name<none> {\n    static constexpr auto name = const_name(\"None\");\n};\ntemplate <>\nstruct handle_type_name<args> {\n    static constexpr auto name = const_name(\"*args\");\n};\ntemplate <>\nstruct handle_type_name<kwargs> {\n    static constexpr auto name = const_name(\"**kwargs\");\n};\n\ntemplate <typename type>\nstruct pyobject_caster {\n    template <typename T = type, enable_if_t<std::is_same<T, handle>::value, int> = 0>\n    bool load(handle src, bool /* convert */) {\n        value = src;\n        return static_cast<bool>(value);\n    }\n\n    template <typename T = type, enable_if_t<std::is_base_of<object, T>::value, int> = 0>\n    bool load(handle src, bool /* convert */) {\n#if PY_MAJOR_VERSION < 3 && !defined(PYBIND11_STR_LEGACY_PERMISSIVE)\n        // For Python 2, without this implicit conversion, Python code would\n        // need to be cluttered with six.ensure_text() or similar, only to be\n        // un-cluttered later after Python 2 support is dropped.\n        if (PYBIND11_SILENCE_MSVC_C4127(std::is_same<T, str>::value) && isinstance<bytes>(src)) {\n            PyObject *str_from_bytes = PyUnicode_FromEncodedObject(src.ptr(), \"utf-8\", nullptr);\n            if (!str_from_bytes)\n                throw error_already_set();\n            value = reinterpret_steal<type>(str_from_bytes);\n            return true;\n        }\n#endif\n        if (!isinstance<type>(src)) {\n            return false;\n        }\n        value = reinterpret_borrow<type>(src);\n        return true;\n    }\n\n    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {\n        return src.inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);\n};\n\ntemplate <typename T>\nclass type_caster<T, enable_if_t<is_pyobject<T>::value>> : public pyobject_caster<T> {};\n\n// Our conditions for enabling moving are quite restrictive:\n// At compile time:\n// - T needs to be a non-const, non-pointer, non-reference type\n// - type_caster<T>::operator T&() must exist\n// - the type must be move constructible (obviously)\n// At run-time:\n// - if the type is non-copy-constructible, the object must be the sole owner of the type (i.e. it\n//   must have ref_count() == 1)h\n// If any of the above are not satisfied, we fall back to copying.\ntemplate <typename T>\nusing move_is_plain_type\n    = satisfies_none_of<T, std::is_void, std::is_pointer, std::is_reference, std::is_const>;\ntemplate <typename T, typename SFINAE = void>\nstruct move_always : std::false_type {};\ntemplate <typename T>\nstruct move_always<\n    T,\n    enable_if_t<\n        all_of<move_is_plain_type<T>,\n               negation<is_copy_constructible<T>>,\n               std::is_move_constructible<T>,\n               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>\n    : std::true_type {};\ntemplate <typename T, typename SFINAE = void>\nstruct move_if_unreferenced : std::false_type {};\ntemplate <typename T>\nstruct move_if_unreferenced<\n    T,\n    enable_if_t<\n        all_of<move_is_plain_type<T>,\n               negation<move_always<T>>,\n               std::is_move_constructible<T>,\n               std::is_same<decltype(std::declval<make_caster<T>>().operator T &()), T &>>::value>>\n    : std::true_type {};\ntemplate <typename T>\nusing move_never = none_of<move_always<T>, move_if_unreferenced<T>>;\n\n// Detect whether returning a `type` from a cast on type's type_caster is going to result in a\n// reference or pointer to a local variable of the type_caster.  Basically, only\n// non-reference/pointer `type`s and reference/pointers from a type_caster_generic are safe;\n// everything else returns a reference/pointer to a local variable.\ntemplate <typename type>\nusing cast_is_temporary_value_reference\n    = bool_constant<(std::is_reference<type>::value || std::is_pointer<type>::value)\n                    && !std::is_base_of<type_caster_generic, make_caster<type>>::value\n                    && !std::is_same<intrinsic_t<type>, void>::value>;\n\n// When a value returned from a C++ function is being cast back to Python, we almost always want to\n// force `policy = move`, regardless of the return value policy the function/method was declared\n// with.\ntemplate <typename Return, typename SFINAE = void>\nstruct return_value_policy_override {\n    static return_value_policy policy(return_value_policy p) { return p; }\n};\n\ntemplate <typename Return>\nstruct return_value_policy_override<\n    Return,\n    detail::enable_if_t<std::is_base_of<type_caster_generic, make_caster<Return>>::value, void>> {\n    static return_value_policy policy(return_value_policy p) {\n        return !std::is_lvalue_reference<Return>::value && !std::is_pointer<Return>::value\n                   ? return_value_policy::move\n                   : p;\n    }\n};\n\n// Basic python -> C++ casting; throws if casting fails\ntemplate <typename T, typename SFINAE>\ntype_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {\n    if (!conv.load(handle, true)) {\n#if defined(NDEBUG)\n        throw cast_error(\n            \"Unable to cast Python instance to C++ type (compile in debug mode for details)\");\n#else\n        throw cast_error(\"Unable to cast Python instance of type \"\n                         + (std::string) str(type::handle_of(handle)) + \" to C++ type '\"\n                         + type_id<T>() + \"'\");\n#endif\n    }\n    return conv;\n}\n// Wrapper around the above that also constructs and returns a type_caster\ntemplate <typename T>\nmake_caster<T> load_type(const handle &handle) {\n    make_caster<T> conv;\n    load_type(conv, handle);\n    return conv;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n// pytype -> C++ type\ntemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>\nT cast(const handle &handle) {\n    using namespace detail;\n    static_assert(!cast_is_temporary_value_reference<T>::value,\n                  \"Unable to cast type to reference: value is local to type caster\");\n    return cast_op<T>(load_type<T>(handle));\n}\n\n// pytype -> pytype (calls converting constructor)\ntemplate <typename T, detail::enable_if_t<detail::is_pyobject<T>::value, int> = 0>\nT cast(const handle &handle) {\n    return T(reinterpret_borrow<object>(handle));\n}\n\n// C++ type -> py::object\ntemplate <typename T, detail::enable_if_t<!detail::is_pyobject<T>::value, int> = 0>\nobject cast(T &&value,\n            return_value_policy policy = return_value_policy::automatic_reference,\n            handle parent = handle()) {\n    using no_ref_T = typename std::remove_reference<T>::type;\n    if (policy == return_value_policy::automatic) {\n        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::take_ownership\n                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy\n                                                      : return_value_policy::move;\n    } else if (policy == return_value_policy::automatic_reference) {\n        policy = std::is_pointer<no_ref_T>::value     ? return_value_policy::reference\n                 : std::is_lvalue_reference<T>::value ? return_value_policy::copy\n                                                      : return_value_policy::move;\n    }\n    return reinterpret_steal<object>(\n        detail::make_caster<T>::cast(std::forward<T>(value), policy, parent));\n}\n\ntemplate <typename T>\nT handle::cast() const {\n    return pybind11::cast<T>(*this);\n}\ntemplate <>\ninline void handle::cast() const {\n    return;\n}\n\ntemplate <typename T>\ndetail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {\n    if (obj.ref_count() > 1) {\n#if defined(NDEBUG)\n        throw cast_error(\n            \"Unable to cast Python instance to C++ rvalue: instance has multiple references\"\n            \" (compile in debug mode for details)\");\n#else\n        throw cast_error(\"Unable to move from Python \" + (std::string) str(type::handle_of(obj))\n                         + \" instance to C++ \" + type_id<T>()\n                         + \" instance: instance has multiple references\");\n#endif\n    }\n\n    // Move into a temporary and return that, because the reference may be a local value of `conv`\n    T ret = std::move(detail::load_type<T>(obj).operator T &());\n    return ret;\n}\n\n// Calling cast() on an rvalue calls pybind11::cast with the object rvalue, which does:\n// - If we have to move (because T has no copy constructor), do it.  This will fail if the moved\n//   object has multiple references, but trying to copy will fail to compile.\n// - If both movable and copyable, check ref count: if 1, move; otherwise copy\n// - Otherwise (not movable), copy.\ntemplate <typename T>\ndetail::enable_if_t<detail::move_always<T>::value, T> cast(object &&object) {\n    return move<T>(std::move(object));\n}\ntemplate <typename T>\ndetail::enable_if_t<detail::move_if_unreferenced<T>::value, T> cast(object &&object) {\n    if (object.ref_count() > 1) {\n        return cast<T>(object);\n    }\n    return move<T>(std::move(object));\n}\ntemplate <typename T>\ndetail::enable_if_t<detail::move_never<T>::value, T> cast(object &&object) {\n    return cast<T>(object);\n}\n\ntemplate <typename T>\nT object::cast() const & {\n    return pybind11::cast<T>(*this);\n}\ntemplate <typename T>\nT object::cast() && {\n    return pybind11::cast<T>(std::move(*this));\n}\ntemplate <>\ninline void object::cast() const & {\n    return;\n}\ntemplate <>\ninline void object::cast() && {\n    return;\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Declared in pytypes.h:\ntemplate <typename T, enable_if_t<!is_pyobject<T>::value, int>>\nobject object_or_cast(T &&o) {\n    return pybind11::cast(std::forward<T>(o));\n}\n\n// Placeholder type for the unneeded (and dead code) static variable in the\n// PYBIND11_OVERRIDE_OVERRIDE macro\nstruct override_unused {};\ntemplate <typename ret_type>\nusing override_caster_t = conditional_t<cast_is_temporary_value_reference<ret_type>::value,\n                                        make_caster<ret_type>,\n                                        override_unused>;\n\n// Trampoline use: for reference/pointer types to value-converted values, we do a value cast, then\n// store the result in the given variable.  For other types, this is a no-op.\ntemplate <typename T>\nenable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&o,\n                                                                     make_caster<T> &caster) {\n    return cast_op<T>(load_type(caster, o));\n}\ntemplate <typename T>\nenable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_ref(object &&,\n                                                                      override_unused &) {\n    pybind11_fail(\"Internal error: cast_ref fallback invoked\");\n}\n\n// Trampoline use: Having a pybind11::cast with an invalid reference type is going to\n// static_assert, even though if it's in dead code, so we provide a \"trampoline\" to pybind11::cast\n// that only does anything in cases where pybind11::cast is valid.\ntemplate <typename T>\nenable_if_t<!cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&o) {\n    return pybind11::cast<T>(std::move(o));\n}\ntemplate <typename T>\nenable_if_t<cast_is_temporary_value_reference<T>::value, T> cast_safe(object &&) {\n    pybind11_fail(\"Internal error: cast_safe fallback invoked\");\n}\ntemplate <>\ninline void cast_safe<void>(object &&) {}\n\nPYBIND11_NAMESPACE_END(detail)\n\n// The overloads could coexist, i.e. the #if is not strictly speaking needed,\n// but it is an easy minor optimization.\n#if defined(NDEBUG)\ninline cast_error cast_error_unable_to_convert_call_arg() {\n    return cast_error(\n        \"Unable to convert call argument to Python object (compile in debug mode for details)\");\n}\n#else\ninline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,\n                                                        const std::string &type) {\n    return cast_error(\"Unable to convert call argument '\" + name + \"' of type '\" + type\n                      + \"' to Python object\");\n}\n#endif\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\ntuple make_tuple() {\n    return tuple(0);\n}\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>\ntuple make_tuple(Args &&...args_) {\n    constexpr size_t size = sizeof...(Args);\n    std::array<object, size> args{{reinterpret_steal<object>(\n        detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};\n    for (size_t i = 0; i < args.size(); i++) {\n        if (!args[i]) {\n#if defined(NDEBUG)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            std::array<std::string, size> argtypes{{type_id<Args>()...}};\n            throw cast_error_unable_to_convert_call_arg(std::to_string(i), argtypes[i]);\n#endif\n        }\n    }\n    tuple result(size);\n    int counter = 0;\n    for (auto &arg_value : args) {\n        PyTuple_SET_ITEM(result.ptr(), counter++, arg_value.release().ptr());\n    }\n    return result;\n}\n\n/// \\ingroup annotations\n/// Annotation for arguments\nstruct arg {\n    /// Constructs an argument with the name of the argument; if null or omitted, this is a\n    /// positional argument.\n    constexpr explicit arg(const char *name = nullptr)\n        : name(name), flag_noconvert(false), flag_none(true) {}\n    /// Assign a value to this argument\n    template <typename T>\n    arg_v operator=(T &&value) const;\n    /// Indicate that the type should not be converted in the type caster\n    arg &noconvert(bool flag = true) {\n        flag_noconvert = flag;\n        return *this;\n    }\n    /// Indicates that the argument should/shouldn't allow None (e.g. for nullable pointer args)\n    arg &none(bool flag = true) {\n        flag_none = flag;\n        return *this;\n    }\n\n    const char *name;        ///< If non-null, this is a named kwargs argument\n    bool flag_noconvert : 1; ///< If set, do not allow conversion (requires a supporting type\n                             ///< caster!)\n    bool flag_none : 1;      ///< If set (the default), allow None to be passed to this argument\n};\n\n/// \\ingroup annotations\n/// Annotation for arguments with values\nstruct arg_v : arg {\nprivate:\n    template <typename T>\n    arg_v(arg &&base, T &&x, const char *descr = nullptr)\n        : arg(base), value(reinterpret_steal<object>(\n                         detail::make_caster<T>::cast(x, return_value_policy::automatic, {}))),\n          descr(descr)\n#if !defined(NDEBUG)\n          ,\n          type(type_id<T>())\n#endif\n    {\n        // Workaround! See:\n        // https://github.com/pybind/pybind11/issues/2336\n        // https://github.com/pybind/pybind11/pull/2685#issuecomment-731286700\n        if (PyErr_Occurred()) {\n            PyErr_Clear();\n        }\n    }\n\npublic:\n    /// Direct construction with name, default, and description\n    template <typename T>\n    arg_v(const char *name, T &&x, const char *descr = nullptr)\n        : arg_v(arg(name), std::forward<T>(x), descr) {}\n\n    /// Called internally when invoking `py::arg(\"a\") = value`\n    template <typename T>\n    arg_v(const arg &base, T &&x, const char *descr = nullptr)\n        : arg_v(arg(base), std::forward<T>(x), descr) {}\n\n    /// Same as `arg::noconvert()`, but returns *this as arg_v&, not arg&\n    arg_v &noconvert(bool flag = true) {\n        arg::noconvert(flag);\n        return *this;\n    }\n\n    /// Same as `arg::nonone()`, but returns *this as arg_v&, not arg&\n    arg_v &none(bool flag = true) {\n        arg::none(flag);\n        return *this;\n    }\n\n    /// The default value\n    object value;\n    /// The (optional) description of the default value\n    const char *descr;\n#if !defined(NDEBUG)\n    /// The C++ type name of the default value (only available when compiled in debug mode)\n    std::string type;\n#endif\n};\n\n/// \\ingroup annotations\n/// Annotation indicating that all following arguments are keyword-only; the is the equivalent of\n/// an unnamed '*' argument (in Python 3)\nstruct kw_only {};\n\n/// \\ingroup annotations\n/// Annotation indicating that all previous arguments are positional-only; the is the equivalent of\n/// an unnamed '/' argument (in Python 3.8)\nstruct pos_only {};\n\ntemplate <typename T>\narg_v arg::operator=(T &&value) const {\n    return {*this, std::forward<T>(value)};\n}\n\n/// Alias for backward compatibility -- to be removed in version 2.0\ntemplate <typename /*unused*/>\nusing arg_t = arg_v;\n\ninline namespace literals {\n/** \\rst\n    String literal version of `arg`\n \\endrst */\nconstexpr arg operator\"\" _a(const char *name, size_t) { return arg(name); }\n} // namespace literals\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T>\nusing is_kw_only = std::is_same<intrinsic_t<T>, kw_only>;\ntemplate <typename T>\nusing is_pos_only = std::is_same<intrinsic_t<T>, pos_only>;\n\n// forward declaration (definition in attr.h)\nstruct function_record;\n\n/// Internal data associated with a single function call\nstruct function_call {\n    function_call(const function_record &f, handle p); // Implementation in attr.h\n\n    /// The function data:\n    const function_record &func;\n\n    /// Arguments passed to the function:\n    std::vector<handle> args;\n\n    /// The `convert` value the arguments should be loaded with\n    std::vector<bool> args_convert;\n\n    /// Extra references for the optional `py::args` and/or `py::kwargs` arguments (which, if\n    /// present, are also in `args` but without a reference).\n    object args_ref, kwargs_ref;\n\n    /// The parent, if any\n    handle parent;\n\n    /// If this is a call to an initializer, this argument contains `self`\n    handle init_self;\n};\n\n/// Helper class which loads arguments for C++ functions called from Python\ntemplate <typename... Args>\nclass argument_loader {\n    using indices = make_index_sequence<sizeof...(Args)>;\n\n    template <typename Arg>\n    using argument_is_args = std::is_same<intrinsic_t<Arg>, args>;\n    template <typename Arg>\n    using argument_is_kwargs = std::is_same<intrinsic_t<Arg>, kwargs>;\n    // Get kwargs argument position, or -1 if not present:\n    static constexpr auto kwargs_pos = constexpr_last<argument_is_kwargs, Args...>();\n\n    static_assert(kwargs_pos == -1 || kwargs_pos == (int) sizeof...(Args) - 1,\n                  \"py::kwargs is only permitted as the last argument of a function\");\n\npublic:\n    static constexpr bool has_kwargs = kwargs_pos != -1;\n\n    // py::args argument position; -1 if not present.\n    static constexpr int args_pos = constexpr_last<argument_is_args, Args...>();\n\n    static_assert(args_pos == -1 || args_pos == constexpr_first<argument_is_args, Args...>(),\n                  \"py::args cannot be specified more than once\");\n\n    static constexpr auto arg_names = concat(type_descr(make_caster<Args>::name)...);\n\n    bool load_args(function_call &call) { return load_impl_sequence(call, indices{}); }\n\n    template <typename Return, typename Guard, typename Func>\n    // NOLINTNEXTLINE(readability-const-return-type)\n    enable_if_t<!std::is_void<Return>::value, Return> call(Func &&f) && {\n        return std::move(*this).template call_impl<remove_cv_t<Return>>(\n            std::forward<Func>(f), indices{}, Guard{});\n    }\n\n    template <typename Return, typename Guard, typename Func>\n    enable_if_t<std::is_void<Return>::value, void_type> call(Func &&f) && {\n        std::move(*this).template call_impl<remove_cv_t<Return>>(\n            std::forward<Func>(f), indices{}, Guard{});\n        return void_type();\n    }\n\nprivate:\n    static bool load_impl_sequence(function_call &, index_sequence<>) { return true; }\n\n    template <size_t... Is>\n    bool load_impl_sequence(function_call &call, index_sequence<Is...>) {\n#ifdef __cpp_fold_expressions\n        if ((... || !std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is]))) {\n            return false;\n        }\n#else\n        for (bool r : {std::get<Is>(argcasters).load(call.args[Is], call.args_convert[Is])...}) {\n            if (!r) {\n                return false;\n            }\n        }\n#endif\n        return true;\n    }\n\n    template <typename Return, typename Func, size_t... Is, typename Guard>\n    Return call_impl(Func &&f, index_sequence<Is...>, Guard &&) && {\n        return std::forward<Func>(f)(cast_op<Args>(std::move(std::get<Is>(argcasters)))...);\n    }\n\n    std::tuple<make_caster<Args>...> argcasters;\n};\n\n/// Helper class which collects only positional arguments for a Python function call.\n/// A fancier version below can collect any argument, but this one is optimal for simple calls.\ntemplate <return_value_policy policy>\nclass simple_collector {\npublic:\n    template <typename... Ts>\n    explicit simple_collector(Ts &&...values)\n        : m_args(pybind11::make_tuple<policy>(std::forward<Ts>(values)...)) {}\n\n    const tuple &args() const & { return m_args; }\n    dict kwargs() const { return {}; }\n\n    tuple args() && { return std::move(m_args); }\n\n    /// Call a Python function and pass the collected arguments\n    object call(PyObject *ptr) const {\n        PyObject *result = PyObject_CallObject(ptr, m_args.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\nprivate:\n    tuple m_args;\n};\n\n/// Helper class which collects positional, keyword, * and ** arguments for a Python function call\ntemplate <return_value_policy policy>\nclass unpacking_collector {\npublic:\n    template <typename... Ts>\n    explicit unpacking_collector(Ts &&...values) {\n        // Tuples aren't (easily) resizable so a list is needed for collection,\n        // but the actual function call strictly requires a tuple.\n        auto args_list = list();\n        using expander = int[];\n        (void) expander{0, (process(args_list, std::forward<Ts>(values)), 0)...};\n\n        m_args = std::move(args_list);\n    }\n\n    const tuple &args() const & { return m_args; }\n    const dict &kwargs() const & { return m_kwargs; }\n\n    tuple args() && { return std::move(m_args); }\n    dict kwargs() && { return std::move(m_kwargs); }\n\n    /// Call a Python function and pass the collected arguments\n    object call(PyObject *ptr) const {\n        PyObject *result = PyObject_Call(ptr, m_args.ptr(), m_kwargs.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\nprivate:\n    template <typename T>\n    void process(list &args_list, T &&x) {\n        auto o = reinterpret_steal<object>(\n            detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));\n        if (!o) {\n#if defined(NDEBUG)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),\n                                                        type_id<T>());\n#endif\n        }\n        args_list.append(o);\n    }\n\n    void process(list &args_list, detail::args_proxy ap) {\n        for (auto a : ap) {\n            args_list.append(a);\n        }\n    }\n\n    void process(list & /*args_list*/, arg_v a) {\n        if (!a.name) {\n#if defined(NDEBUG)\n            nameless_argument_error();\n#else\n            nameless_argument_error(a.type);\n#endif\n        }\n        if (m_kwargs.contains(a.name)) {\n#if defined(NDEBUG)\n            multiple_values_error();\n#else\n            multiple_values_error(a.name);\n#endif\n        }\n        if (!a.value) {\n#if defined(NDEBUG)\n            throw cast_error_unable_to_convert_call_arg();\n#else\n            throw cast_error_unable_to_convert_call_arg(a.name, a.type);\n#endif\n        }\n        m_kwargs[a.name] = a.value;\n    }\n\n    void process(list & /*args_list*/, detail::kwargs_proxy kp) {\n        if (!kp) {\n            return;\n        }\n        for (auto k : reinterpret_borrow<dict>(kp)) {\n            if (m_kwargs.contains(k.first)) {\n#if defined(NDEBUG)\n                multiple_values_error();\n#else\n                multiple_values_error(str(k.first));\n#endif\n            }\n            m_kwargs[k.first] = k.second;\n        }\n    }\n\n    [[noreturn]] static void nameless_argument_error() {\n        throw type_error(\"Got kwargs without a name; only named arguments \"\n                         \"may be passed via py::arg() to a python function call. \"\n                         \"(compile in debug mode for details)\");\n    }\n    [[noreturn]] static void nameless_argument_error(const std::string &type) {\n        throw type_error(\"Got kwargs without a name of type '\" + type\n                         + \"'; only named \"\n                           \"arguments may be passed via py::arg() to a python function call. \");\n    }\n    [[noreturn]] static void multiple_values_error() {\n        throw type_error(\"Got multiple values for keyword argument \"\n                         \"(compile in debug mode for details)\");\n    }\n\n    [[noreturn]] static void multiple_values_error(const std::string &name) {\n        throw type_error(\"Got multiple values for keyword argument '\" + name + \"'\");\n    }\n\nprivate:\n    tuple m_args;\n    dict m_kwargs;\n};\n\n// [workaround(intel)] Separate function required here\n// We need to put this into a separate function because the Intel compiler\n// fails to compile enable_if_t<!all_of<is_positional<Args>...>::value>\n// (tested with ICC 2021.1 Beta 20200827).\ntemplate <typename... Args>\nconstexpr bool args_are_all_positional() {\n    return all_of<is_positional<Args>...>::value;\n}\n\n/// Collect only positional arguments for a Python function call\ntemplate <return_value_policy policy,\n          typename... Args,\n          typename = enable_if_t<args_are_all_positional<Args...>()>>\nsimple_collector<policy> collect_arguments(Args &&...args) {\n    return simple_collector<policy>(std::forward<Args>(args)...);\n}\n\n/// Collect all arguments, including keywords and unpacking (only instantiated when needed)\ntemplate <return_value_policy policy,\n          typename... Args,\n          typename = enable_if_t<!args_are_all_positional<Args...>()>>\nunpacking_collector<policy> collect_arguments(Args &&...args) {\n    // Following argument order rules for generalized unpacking according to PEP 448\n    static_assert(constexpr_last<is_positional, Args...>()\n                          < constexpr_first<is_keyword_or_ds, Args...>()\n                      && constexpr_last<is_s_unpacking, Args...>()\n                             < constexpr_first<is_ds_unpacking, Args...>(),\n                  \"Invalid function call: positional args must precede keywords and ** unpacking; \"\n                  \"* unpacking must precede ** unpacking\");\n    return unpacking_collector<policy>(std::forward<Args>(args)...);\n}\n\ntemplate <typename Derived>\ntemplate <return_value_policy policy, typename... Args>\nobject object_api<Derived>::operator()(Args &&...args) const {\n#if !defined(NDEBUG) && PY_VERSION_HEX >= 0x03060000\n    if (!PyGILState_Check()) {\n        pybind11_fail(\"pybind11::object_api<>::operator() PyGILState_Check() failure.\");\n    }\n#endif\n    return detail::collect_arguments<policy>(std::forward<Args>(args)...).call(derived().ptr());\n}\n\ntemplate <typename Derived>\ntemplate <return_value_policy policy, typename... Args>\nobject object_api<Derived>::call(Args &&...args) const {\n    return operator()<policy>(std::forward<Args>(args)...);\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename T>\nhandle type::handle_of() {\n    static_assert(std::is_base_of<detail::type_caster_generic, detail::make_caster<T>>::value,\n                  \"py::type::of<T> only supports the case where T is a registered C++ types.\");\n\n    return detail::get_type_handle(typeid(T), true);\n}\n\n#define PYBIND11_MAKE_OPAQUE(...)                                                                 \\\n    namespace pybind11 {                                                                          \\\n    namespace detail {                                                                            \\\n    template <>                                                                                   \\\n    class type_caster<__VA_ARGS__> : public type_caster_base<__VA_ARGS__> {};                     \\\n    }                                                                                             \\\n    }\n\n/// Lets you pass a type containing a `,` through a macro parameter without needing a separate\n/// typedef, e.g.:\n/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`\n#define PYBIND11_TYPE(...) __VA_ARGS__\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/chrono.h",
    "content": "/*\n    pybind11/chrono.h: Transparent conversion between std::chrono and python's datetime\n\n    Copyright (c) 2016 Trent Houliston <trent@houliston.me> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <chrono>\n#include <cmath>\n#include <ctime>\n#include <datetime.h>\n#include <mutex>\n\n// Backport the PyDateTime_DELTA functions from Python3.3 if required\n#ifndef PyDateTime_DELTA_GET_DAYS\n#    define PyDateTime_DELTA_GET_DAYS(o) (((PyDateTime_Delta *) o)->days)\n#endif\n#ifndef PyDateTime_DELTA_GET_SECONDS\n#    define PyDateTime_DELTA_GET_SECONDS(o) (((PyDateTime_Delta *) o)->seconds)\n#endif\n#ifndef PyDateTime_DELTA_GET_MICROSECONDS\n#    define PyDateTime_DELTA_GET_MICROSECONDS(o) (((PyDateTime_Delta *) o)->microseconds)\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename type>\nclass duration_caster {\npublic:\n    using rep = typename type::rep;\n    using period = typename type::period;\n\n    // signed 25 bits required by the standard.\n    using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;\n\n    bool load(handle src, bool) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        if (!src) {\n            return false;\n        }\n        // If invoked with datetime.delta object\n        if (PyDelta_Check(src.ptr())) {\n            value = type(duration_cast<duration<rep, period>>(\n                days(PyDateTime_DELTA_GET_DAYS(src.ptr()))\n                + seconds(PyDateTime_DELTA_GET_SECONDS(src.ptr()))\n                + microseconds(PyDateTime_DELTA_GET_MICROSECONDS(src.ptr()))));\n            return true;\n        }\n        // If invoked with a float we assume it is seconds and convert\n        if (PyFloat_Check(src.ptr())) {\n            value = type(duration_cast<duration<rep, period>>(\n                duration<double>(PyFloat_AsDouble(src.ptr()))));\n            return true;\n        }\n        return false;\n    }\n\n    // If this is a duration just return it back\n    static const std::chrono::duration<rep, period> &\n    get_duration(const std::chrono::duration<rep, period> &src) {\n        return src;\n    }\n\n    // If this is a time_point get the time_since_epoch\n    template <typename Clock>\n    static std::chrono::duration<rep, period>\n    get_duration(const std::chrono::time_point<Clock, std::chrono::duration<rep, period>> &src) {\n        return src.time_since_epoch();\n    }\n\n    static handle cast(const type &src, return_value_policy /* policy */, handle /* parent */) {\n        using namespace std::chrono;\n\n        // Use overloaded function to get our duration from our source\n        // Works out if it is a duration or time_point and get the duration\n        auto d = get_duration(src);\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        // Declare these special duration types so the conversions happen with the correct\n        // primitive types (int)\n        using dd_t = duration<int, std::ratio<86400>>;\n        using ss_t = duration<int, std::ratio<1>>;\n        using us_t = duration<int, std::micro>;\n\n        auto dd = duration_cast<dd_t>(d);\n        auto subd = d - dd;\n        auto ss = duration_cast<ss_t>(subd);\n        auto us = duration_cast<us_t>(subd - ss);\n        return PyDelta_FromDSU(dd.count(), ss.count(), us.count());\n    }\n\n    PYBIND11_TYPE_CASTER(type, const_name(\"datetime.timedelta\"));\n};\n\ninline std::tm *localtime_thread_safe(const std::time_t *time, std::tm *buf) {\n#if (defined(__STDC_LIB_EXT1__) && defined(__STDC_WANT_LIB_EXT1__)) || defined(_MSC_VER)\n    if (localtime_s(buf, time))\n        return nullptr;\n    return buf;\n#else\n    static std::mutex mtx;\n    std::lock_guard<std::mutex> lock(mtx);\n    std::tm *tm_ptr = std::localtime(time);\n    if (tm_ptr != nullptr) {\n        *buf = *tm_ptr;\n    }\n    return tm_ptr;\n#endif\n}\n\n// This is for casting times on the system clock into datetime.datetime instances\ntemplate <typename Duration>\nclass type_caster<std::chrono::time_point<std::chrono::system_clock, Duration>> {\npublic:\n    using type = std::chrono::time_point<std::chrono::system_clock, Duration>;\n    bool load(handle src, bool) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        if (!src) {\n            return false;\n        }\n\n        std::tm cal;\n        microseconds msecs;\n\n        if (PyDateTime_Check(src.ptr())) {\n            cal.tm_sec = PyDateTime_DATE_GET_SECOND(src.ptr());\n            cal.tm_min = PyDateTime_DATE_GET_MINUTE(src.ptr());\n            cal.tm_hour = PyDateTime_DATE_GET_HOUR(src.ptr());\n            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());\n            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;\n            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;\n            cal.tm_isdst = -1;\n            msecs = microseconds(PyDateTime_DATE_GET_MICROSECOND(src.ptr()));\n        } else if (PyDate_Check(src.ptr())) {\n            cal.tm_sec = 0;\n            cal.tm_min = 0;\n            cal.tm_hour = 0;\n            cal.tm_mday = PyDateTime_GET_DAY(src.ptr());\n            cal.tm_mon = PyDateTime_GET_MONTH(src.ptr()) - 1;\n            cal.tm_year = PyDateTime_GET_YEAR(src.ptr()) - 1900;\n            cal.tm_isdst = -1;\n            msecs = microseconds(0);\n        } else if (PyTime_Check(src.ptr())) {\n            cal.tm_sec = PyDateTime_TIME_GET_SECOND(src.ptr());\n            cal.tm_min = PyDateTime_TIME_GET_MINUTE(src.ptr());\n            cal.tm_hour = PyDateTime_TIME_GET_HOUR(src.ptr());\n            cal.tm_mday = 1;  // This date (day, month, year) = (1, 0, 70)\n            cal.tm_mon = 0;   // represents 1-Jan-1970, which is the first\n            cal.tm_year = 70; // earliest available date for Python's datetime\n            cal.tm_isdst = -1;\n            msecs = microseconds(PyDateTime_TIME_GET_MICROSECOND(src.ptr()));\n        } else {\n            return false;\n        }\n\n        value = time_point_cast<Duration>(system_clock::from_time_t(std::mktime(&cal)) + msecs);\n        return true;\n    }\n\n    static handle cast(const std::chrono::time_point<std::chrono::system_clock, Duration> &src,\n                       return_value_policy /* policy */,\n                       handle /* parent */) {\n        using namespace std::chrono;\n\n        // Lazy initialise the PyDateTime import\n        if (!PyDateTimeAPI) {\n            PyDateTime_IMPORT;\n        }\n\n        // Get out microseconds, and make sure they are positive, to avoid bug in eastern\n        // hemisphere time zones (cfr. https://github.com/pybind/pybind11/issues/2417)\n        using us_t = duration<int, std::micro>;\n        auto us = duration_cast<us_t>(src.time_since_epoch() % seconds(1));\n        if (us.count() < 0) {\n            us += seconds(1);\n        }\n\n        // Subtract microseconds BEFORE `system_clock::to_time_t`, because:\n        // > If std::time_t has lower precision, it is implementation-defined whether the value is\n        // rounded or truncated. (https://en.cppreference.com/w/cpp/chrono/system_clock/to_time_t)\n        std::time_t tt\n            = system_clock::to_time_t(time_point_cast<system_clock::duration>(src - us));\n\n        std::tm localtime;\n        std::tm *localtime_ptr = localtime_thread_safe(&tt, &localtime);\n        if (!localtime_ptr) {\n            throw cast_error(\"Unable to represent system_clock in local time\");\n        }\n        return PyDateTime_FromDateAndTime(localtime.tm_year + 1900,\n                                          localtime.tm_mon + 1,\n                                          localtime.tm_mday,\n                                          localtime.tm_hour,\n                                          localtime.tm_min,\n                                          localtime.tm_sec,\n                                          us.count());\n    }\n    PYBIND11_TYPE_CASTER(type, const_name(\"datetime.datetime\"));\n};\n\n// Other clocks that are not the system clock are not measured as datetime.datetime objects\n// since they are not measured on calendar time. So instead we just make them timedeltas\n// Or if they have passed us a time as a float we convert that\ntemplate <typename Clock, typename Duration>\nclass type_caster<std::chrono::time_point<Clock, Duration>>\n    : public duration_caster<std::chrono::time_point<Clock, Duration>> {};\n\ntemplate <typename Rep, typename Period>\nclass type_caster<std::chrono::duration<Rep, Period>>\n    : public duration_caster<std::chrono::duration<Rep, Period>> {};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/common.h",
    "content": "#include \"detail/common.h\"\n#warning \"Including 'common.h' is deprecated. It will be removed in v3.0. Use 'pybind11.h'.\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/complex.h",
    "content": "/*\n    pybind11/complex.h: Complex number support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <complex>\n\n/// glibc defines I as a macro which breaks things, e.g., boost template names\n#ifdef I\n#    undef I\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\ntemplate <typename T>\nstruct format_descriptor<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr const char c = format_descriptor<T>::c;\n    static constexpr const char value[3] = {'Z', c, '\\0'};\n    static std::string format() { return std::string(value); }\n};\n\n#ifndef PYBIND11_CPP17\n\ntemplate <typename T>\nconstexpr const char\n    format_descriptor<std::complex<T>,\n                      detail::enable_if_t<std::is_floating_point<T>::value>>::value[3];\n\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename T>\nstruct is_fmt_numeric<std::complex<T>, detail::enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr bool value = true;\n    static constexpr int index = is_fmt_numeric<T>::index + 3;\n};\n\ntemplate <typename T>\nclass type_caster<std::complex<T>> {\npublic:\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (!convert && !PyComplex_Check(src.ptr())) {\n            return false;\n        }\n        Py_complex result = PyComplex_AsCComplex(src.ptr());\n        if (result.real == -1.0 && PyErr_Occurred()) {\n            PyErr_Clear();\n            return false;\n        }\n        value = std::complex<T>((T) result.real, (T) result.imag);\n        return true;\n    }\n\n    static handle\n    cast(const std::complex<T> &src, return_value_policy /* policy */, handle /* parent */) {\n        return PyComplex_FromDoubles((double) src.real(), (double) src.imag());\n    }\n\n    PYBIND11_TYPE_CASTER(std::complex<T>, const_name(\"complex\"));\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/class.h",
    "content": "/*\n    pybind11/detail/class.h: Python C API implementation details for py::class_\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../attr.h\"\n#include \"../options.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if PY_VERSION_HEX >= 0x03030000 && !defined(PYPY_VERSION)\n#    define PYBIND11_BUILTIN_QUALNAME\n#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)\n#else\n// In pre-3.3 Python, we still set __qualname__ so that we can produce reliable function type\n// signatures; in 3.3+ this macro expands to nothing:\n#    define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)                                             \\\n        setattr((PyObject *) obj, \"__qualname__\", nameobj)\n#endif\n\ninline std::string get_fully_qualified_tp_name(PyTypeObject *type) {\n#if !defined(PYPY_VERSION)\n    return type->tp_name;\n#else\n    auto module_name = handle((PyObject *) type).attr(\"__module__\").cast<std::string>();\n    if (module_name == PYBIND11_BUILTINS_MODULE)\n        return type->tp_name;\n    else\n        return std::move(module_name) + \".\" + type->tp_name;\n#endif\n}\n\ninline PyTypeObject *type_incref(PyTypeObject *type) {\n    Py_INCREF(type);\n    return type;\n}\n\n#if !defined(PYPY_VERSION)\n\n/// `pybind11_static_property.__get__()`: Always pass the class instead of the instance.\nextern \"C\" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) {\n    return PyProperty_Type.tp_descr_get(self, cls, cls);\n}\n\n/// `pybind11_static_property.__set__()`: Just like the above `__get__()`.\nextern \"C\" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {\n    PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);\n    return PyProperty_Type.tp_descr_set(self, cls, value);\n}\n\n/** A `static_property` is the same as a `property` but the `__get__()` and `__set__()`\n    methods are modified to always use the object type instead of a concrete instance.\n    Return value: New reference. */\ninline PyTypeObject *make_static_property_type() {\n    constexpr auto *name = \"pybind11_static_property\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_static_property_type(): error allocating type!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#    ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#    endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyProperty_Type);\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n    type->tp_descr_get = pybind11_static_get;\n    type->tp_descr_set = pybind11_static_set;\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"make_static_property_type(): failure in PyType_Ready()!\");\n    }\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    return type;\n}\n\n#else // PYPY\n\n/** PyPy has some issues with the above C API, so we evaluate Python code instead.\n    This function will only be called once so performance isn't really a concern.\n    Return value: New reference. */\ninline PyTypeObject *make_static_property_type() {\n    auto d = dict();\n    PyObject *result = PyRun_String(R\"(\\\nclass pybind11_static_property(property):\n    def __get__(self, obj, cls):\n        return property.__get__(self, cls, cls)\n\n    def __set__(self, obj, value):\n        cls = obj if isinstance(obj, type) else type(obj)\n        property.__set__(self, cls, value)\n)\",\n                                    Py_file_input,\n                                    d.ptr(),\n                                    d.ptr());\n    if (result == nullptr)\n        throw error_already_set();\n    Py_DECREF(result);\n    return (PyTypeObject *) d[\"pybind11_static_property\"].cast<object>().release().ptr();\n}\n\n#endif // PYPY\n\n/** Types with static properties need to handle `Type.static_prop = x` in a specific way.\n    By default, Python replaces the `static_property` itself, but for wrapped C++ types\n    we need to call `static_property.__set__()` in order to propagate the new value to\n    the underlying C++ data structure. */\nextern \"C\" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) {\n    // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw\n    // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`).\n    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);\n\n    // The following assignment combinations are possible:\n    //   1. `Type.static_prop = value`             --> descr_set: `Type.static_prop.__set__(value)`\n    //   2. `Type.static_prop = other_static_prop` --> setattro:  replace existing `static_prop`\n    //   3. `Type.regular_attribute = value`       --> setattro:  regular attribute assignment\n    auto *const static_prop = (PyObject *) get_internals().static_property_type;\n    const auto call_descr_set = (descr != nullptr) && (value != nullptr)\n                                && (PyObject_IsInstance(descr, static_prop) != 0)\n                                && (PyObject_IsInstance(value, static_prop) == 0);\n    if (call_descr_set) {\n        // Call `static_property.__set__()` instead of replacing the `static_property`.\n#if !defined(PYPY_VERSION)\n        return Py_TYPE(descr)->tp_descr_set(descr, obj, value);\n#else\n        if (PyObject *result = PyObject_CallMethod(descr, \"__set__\", \"OO\", obj, value)) {\n            Py_DECREF(result);\n            return 0;\n        } else {\n            return -1;\n        }\n#endif\n    } else {\n        // Replace existing attribute.\n        return PyType_Type.tp_setattro(obj, name, value);\n    }\n}\n\n#if PY_MAJOR_VERSION >= 3\n/**\n * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing\n * methods via cls.attr(\"m2\") = cls.attr(\"m1\"): instead the tp_descr_get returns a plain function,\n * when called on a class, or a PyMethod, when called on an instance.  Override that behaviour here\n * to do a special case bypass for PyInstanceMethod_Types.\n */\nextern \"C\" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {\n    PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);\n    if (descr && PyInstanceMethod_Check(descr)) {\n        Py_INCREF(descr);\n        return descr;\n    }\n    return PyType_Type.tp_getattro(obj, name);\n}\n#endif\n\n/// metaclass `__call__` function that is used to create all pybind11 objects.\nextern \"C\" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) {\n\n    // use the default metaclass call to create/initialize the object\n    PyObject *self = PyType_Type.tp_call(type, args, kwargs);\n    if (self == nullptr) {\n        return nullptr;\n    }\n\n    // This must be a pybind11 instance\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n\n    // Ensure that the base __init__ function(s) were called\n    for (const auto &vh : values_and_holders(instance)) {\n        if (!vh.holder_constructed()) {\n            PyErr_Format(PyExc_TypeError,\n                         \"%.200s.__init__() must be called when overriding __init__\",\n                         get_fully_qualified_tp_name(vh.type->type).c_str());\n            Py_DECREF(self);\n            return nullptr;\n        }\n    }\n\n    return self;\n}\n\n/// Cleanup the type-info for a pybind11-registered type.\nextern \"C\" inline void pybind11_meta_dealloc(PyObject *obj) {\n    auto *type = (PyTypeObject *) obj;\n    auto &internals = get_internals();\n\n    // A pybind11-registered type will:\n    // 1) be found in internals.registered_types_py\n    // 2) have exactly one associated `detail::type_info`\n    auto found_type = internals.registered_types_py.find(type);\n    if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1\n        && found_type->second[0]->type == type) {\n\n        auto *tinfo = found_type->second[0];\n        auto tindex = std::type_index(*tinfo->cpptype);\n        internals.direct_conversions.erase(tindex);\n\n        if (tinfo->module_local) {\n            get_local_internals().registered_types_cpp.erase(tindex);\n        } else {\n            internals.registered_types_cpp.erase(tindex);\n        }\n        internals.registered_types_py.erase(tinfo->type);\n\n        // Actually just `std::erase_if`, but that's only available in C++20\n        auto &cache = internals.inactive_override_cache;\n        for (auto it = cache.begin(), last = cache.end(); it != last;) {\n            if (it->first == (PyObject *) tinfo->type) {\n                it = cache.erase(it);\n            } else {\n                ++it;\n            }\n        }\n\n        delete tinfo;\n    }\n\n    PyType_Type.tp_dealloc(obj);\n}\n\n/** This metaclass is assigned by default to all pybind11 types and is required in order\n    for static properties to function correctly. Users may override this using `py::metaclass`.\n    Return value: New reference. */\ninline PyTypeObject *make_default_metaclass() {\n    constexpr auto *name = \"pybind11_type\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_default_metaclass(): error allocating metaclass!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyType_Type);\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n\n    type->tp_call = pybind11_meta_call;\n\n    type->tp_setattro = pybind11_meta_setattro;\n#if PY_MAJOR_VERSION >= 3\n    type->tp_getattro = pybind11_meta_getattro;\n#endif\n\n    type->tp_dealloc = pybind11_meta_dealloc;\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"make_default_metaclass(): failure in PyType_Ready()!\");\n    }\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    return type;\n}\n\n/// For multiple inheritance types we need to recursively register/deregister base pointers for any\n/// base classes with pointers that are difference from the instance value pointer so that we can\n/// correctly recognize an offset base class pointer. This calls a function with any offset base\n/// ptrs.\ninline void traverse_offset_bases(void *valueptr,\n                                  const detail::type_info *tinfo,\n                                  instance *self,\n                                  bool (*f)(void * /*parentptr*/, instance * /*self*/)) {\n    for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {\n        if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {\n            for (auto &c : parent_tinfo->implicit_casts) {\n                if (c.first == tinfo->cpptype) {\n                    auto *parentptr = c.second(valueptr);\n                    if (parentptr != valueptr) {\n                        f(parentptr, self);\n                    }\n                    traverse_offset_bases(parentptr, parent_tinfo, self, f);\n                    break;\n                }\n            }\n        }\n    }\n}\n\ninline bool register_instance_impl(void *ptr, instance *self) {\n    get_internals().registered_instances.emplace(ptr, self);\n    return true; // unused, but gives the same signature as the deregister func\n}\ninline bool deregister_instance_impl(void *ptr, instance *self) {\n    auto &registered_instances = get_internals().registered_instances;\n    auto range = registered_instances.equal_range(ptr);\n    for (auto it = range.first; it != range.second; ++it) {\n        if (self == it->second) {\n            registered_instances.erase(it);\n            return true;\n        }\n    }\n    return false;\n}\n\ninline void register_instance(instance *self, void *valptr, const type_info *tinfo) {\n    register_instance_impl(valptr, self);\n    if (!tinfo->simple_ancestors) {\n        traverse_offset_bases(valptr, tinfo, self, register_instance_impl);\n    }\n}\n\ninline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {\n    bool ret = deregister_instance_impl(valptr, self);\n    if (!tinfo->simple_ancestors) {\n        traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);\n    }\n    return ret;\n}\n\n/// Instance creation function for all pybind11 types. It allocates the internal instance layout\n/// for holding C++ objects and holders.  Allocation is done lazily (the first time the instance is\n/// cast to a reference or pointer), and initialization is done by an `__init__` function.\ninline PyObject *make_new_instance(PyTypeObject *type) {\n#if defined(PYPY_VERSION)\n    // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first\n    // inherited object is a plain Python type (i.e. not derived from an extension type).  Fix it.\n    ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));\n    if (type->tp_basicsize < instance_size) {\n        type->tp_basicsize = instance_size;\n    }\n#endif\n    PyObject *self = type->tp_alloc(type, 0);\n    auto *inst = reinterpret_cast<instance *>(self);\n    // Allocate the value/holder internals:\n    inst->allocate_layout();\n\n    return self;\n}\n\n/// Instance creation function for all pybind11 types. It only allocates space for the\n/// C++ object, but doesn't call the constructor -- an `__init__` function must do that.\nextern \"C\" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {\n    return make_new_instance(type);\n}\n\n/// An `__init__` function constructs the C++ object. Users should provide at least one\n/// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the\n/// following default function will be used which simply throws an exception.\nextern \"C\" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {\n    PyTypeObject *type = Py_TYPE(self);\n    std::string msg = get_fully_qualified_tp_name(type) + \": No constructor defined!\";\n    PyErr_SetString(PyExc_TypeError, msg.c_str());\n    return -1;\n}\n\ninline void add_patient(PyObject *nurse, PyObject *patient) {\n    auto &internals = get_internals();\n    auto *instance = reinterpret_cast<detail::instance *>(nurse);\n    instance->has_patients = true;\n    Py_INCREF(patient);\n    internals.patients[nurse].push_back(patient);\n}\n\ninline void clear_patients(PyObject *self) {\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n    auto &internals = get_internals();\n    auto pos = internals.patients.find(self);\n    assert(pos != internals.patients.end());\n    // Clearing the patients can cause more Python code to run, which\n    // can invalidate the iterator. Extract the vector of patients\n    // from the unordered_map first.\n    auto patients = std::move(pos->second);\n    internals.patients.erase(pos);\n    instance->has_patients = false;\n    for (PyObject *&patient : patients) {\n        Py_CLEAR(patient);\n    }\n}\n\n/// Clears all internal data from the instance and removes it from registered instances in\n/// preparation for deallocation.\ninline void clear_instance(PyObject *self) {\n    auto *instance = reinterpret_cast<detail::instance *>(self);\n\n    // Deallocate any values/holders, if present:\n    for (auto &v_h : values_and_holders(instance)) {\n        if (v_h) {\n\n            // We have to deregister before we call dealloc because, for virtual MI types, we still\n            // need to be able to get the parent pointers.\n            if (v_h.instance_registered()\n                && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) {\n                pybind11_fail(\n                    \"pybind11_object_dealloc(): Tried to deallocate unregistered instance!\");\n            }\n\n            if (instance->owned || v_h.holder_constructed()) {\n                v_h.type->dealloc(v_h);\n            }\n        }\n    }\n    // Deallocate the value/holder layout internals:\n    instance->deallocate_layout();\n\n    if (instance->weakrefs) {\n        PyObject_ClearWeakRefs(self);\n    }\n\n    PyObject **dict_ptr = _PyObject_GetDictPtr(self);\n    if (dict_ptr) {\n        Py_CLEAR(*dict_ptr);\n    }\n\n    if (instance->has_patients) {\n        clear_patients(self);\n    }\n}\n\n/// Instance destructor function for all pybind11 types. It calls `type_info.dealloc`\n/// to destroy the C++ object itself, while the rest is Python bookkeeping.\nextern \"C\" inline void pybind11_object_dealloc(PyObject *self) {\n    clear_instance(self);\n\n    auto *type = Py_TYPE(self);\n    type->tp_free(self);\n\n#if PY_VERSION_HEX < 0x03080000\n    // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called\n    // as part of a derived type's dealloc, in which case we're not allowed to decref\n    // the type here. For cross-module compatibility, we shouldn't compare directly\n    // with `pybind11_object_dealloc`, but with the common one stashed in internals.\n    auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;\n    if (type->tp_dealloc == pybind11_object_type->tp_dealloc)\n        Py_DECREF(type);\n#else\n    // This was not needed before Python 3.8 (Python issue 35810)\n    // https://github.com/pybind/pybind11/issues/1946\n    Py_DECREF(type);\n#endif\n}\n\n/** Create the type which can be used as a common base for all classes.  This is\n    needed in order to satisfy Python's requirements for multiple inheritance.\n    Return value: New reference. */\ninline PyObject *make_object_base_type(PyTypeObject *metaclass) {\n    constexpr auto *name = \"pybind11_object\";\n    auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);\n    if (!heap_type) {\n        pybind11_fail(\"make_object_base_type(): error allocating type!\");\n    }\n\n    heap_type->ht_name = name_obj.inc_ref().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = name_obj.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = name;\n    type->tp_base = type_incref(&PyBaseObject_Type);\n    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));\n    type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;\n\n    type->tp_new = pybind11_object_new;\n    type->tp_init = pybind11_object_init;\n    type->tp_dealloc = pybind11_object_dealloc;\n\n    /* Support weak references (needed for the keep_alive feature) */\n    type->tp_weaklistoffset = offsetof(instance, weakrefs);\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(\"PyType_Ready failed in make_object_base_type():\" + error_string());\n    }\n\n    setattr((PyObject *) type, \"__module__\", str(\"pybind11_builtins\"));\n    PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);\n\n    assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));\n    return (PyObject *) heap_type;\n}\n\n/// dynamic_attr: Support for `d = instance.__dict__`.\nextern \"C\" inline PyObject *pybind11_get_dict(PyObject *self, void *) {\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    if (!dict) {\n        dict = PyDict_New();\n    }\n    Py_XINCREF(dict);\n    return dict;\n}\n\n/// dynamic_attr: Support for `instance.__dict__ = dict()`.\nextern \"C\" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) {\n    if (!PyDict_Check(new_dict)) {\n        PyErr_Format(PyExc_TypeError,\n                     \"__dict__ must be set to a dictionary, not a '%.200s'\",\n                     get_fully_qualified_tp_name(Py_TYPE(new_dict)).c_str());\n        return -1;\n    }\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    Py_INCREF(new_dict);\n    Py_CLEAR(dict);\n    dict = new_dict;\n    return 0;\n}\n\n/// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.\nextern \"C\" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    Py_VISIT(dict);\n    return 0;\n}\n\n/// dynamic_attr: Allow the GC to clear the dictionary.\nextern \"C\" inline int pybind11_clear(PyObject *self) {\n    PyObject *&dict = *_PyObject_GetDictPtr(self);\n    Py_CLEAR(dict);\n    return 0;\n}\n\n/// Give instances of this type a `__dict__` and opt into garbage collection.\ninline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {\n    auto *type = &heap_type->ht_type;\n    type->tp_flags |= Py_TPFLAGS_HAVE_GC;\n    type->tp_dictoffset = type->tp_basicsize;           // place dict at the end\n    type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it\n    type->tp_traverse = pybind11_traverse;\n    type->tp_clear = pybind11_clear;\n\n    static PyGetSetDef getset[] = {\n        {const_cast<char *>(\"__dict__\"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr},\n        {nullptr, nullptr, nullptr, nullptr, nullptr}};\n    type->tp_getset = getset;\n}\n\n/// buffer_protocol: Fill in the view as specified by flags.\nextern \"C\" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {\n    // Look for a `get_buffer` implementation in this type's info or any bases (following MRO).\n    type_info *tinfo = nullptr;\n    for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {\n        tinfo = get_type_info((PyTypeObject *) type.ptr());\n        if (tinfo && tinfo->get_buffer) {\n            break;\n        }\n    }\n    if (view == nullptr || !tinfo || !tinfo->get_buffer) {\n        if (view) {\n            view->obj = nullptr;\n        }\n        PyErr_SetString(PyExc_BufferError, \"pybind11_getbuffer(): Internal error\");\n        return -1;\n    }\n    std::memset(view, 0, sizeof(Py_buffer));\n    buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);\n    if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {\n        delete info;\n        // view->obj = nullptr;  // Was just memset to 0, so not necessary\n        PyErr_SetString(PyExc_BufferError, \"Writable buffer requested for readonly storage\");\n        return -1;\n    }\n    view->obj = obj;\n    view->ndim = 1;\n    view->internal = info;\n    view->buf = info->ptr;\n    view->itemsize = info->itemsize;\n    view->len = view->itemsize;\n    for (auto s : info->shape) {\n        view->len *= s;\n    }\n    view->readonly = static_cast<int>(info->readonly);\n    if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) {\n        view->format = const_cast<char *>(info->format.c_str());\n    }\n    if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {\n        view->ndim = (int) info->ndim;\n        view->strides = info->strides.data();\n        view->shape = info->shape.data();\n    }\n    Py_INCREF(view->obj);\n    return 0;\n}\n\n/// buffer_protocol: Release the resources of the buffer.\nextern \"C\" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {\n    delete (buffer_info *) view->internal;\n}\n\n/// Give this type a buffer interface.\ninline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {\n    heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;\n#if PY_MAJOR_VERSION < 3\n    heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;\n#endif\n\n    heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;\n    heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;\n}\n\n/** Create a brand new Python type according to the `type_record` specification.\n    Return value: New reference. */\ninline PyObject *make_new_python_type(const type_record &rec) {\n    auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));\n\n    auto qualname = name;\n    if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, \"__qualname__\")) {\n#if PY_MAJOR_VERSION >= 3\n        qualname = reinterpret_steal<object>(\n            PyUnicode_FromFormat(\"%U.%U\", rec.scope.attr(\"__qualname__\").ptr(), name.ptr()));\n#else\n        qualname = str(rec.scope.attr(\"__qualname__\").cast<std::string>() + \".\" + rec.name);\n#endif\n    }\n\n    object module_;\n    if (rec.scope) {\n        if (hasattr(rec.scope, \"__module__\")) {\n            module_ = rec.scope.attr(\"__module__\");\n        } else if (hasattr(rec.scope, \"__name__\")) {\n            module_ = rec.scope.attr(\"__name__\");\n        }\n    }\n\n    const auto *full_name = c_str(\n#if !defined(PYPY_VERSION)\n        module_ ? str(module_).cast<std::string>() + \".\" + rec.name :\n#endif\n                rec.name);\n\n    char *tp_doc = nullptr;\n    if (rec.doc && options::show_user_defined_docstrings()) {\n        /* Allocate memory for docstring (using PyObject_MALLOC, since\n           Python will free this later on) */\n        size_t size = std::strlen(rec.doc) + 1;\n        tp_doc = (char *) PyObject_MALLOC(size);\n        std::memcpy((void *) tp_doc, rec.doc, size);\n    }\n\n    auto &internals = get_internals();\n    auto bases = tuple(rec.bases);\n    auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr();\n\n    /* Danger zone: from now (and until PyType_Ready), make sure to\n       issue no Python C API calls which could potentially invoke the\n       garbage collector (the GC will call type_traverse(), which will in\n       turn find the newly constructed type in an invalid state) */\n    auto *metaclass\n        = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass;\n\n    auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);\n    if (!heap_type) {\n        pybind11_fail(std::string(rec.name) + \": Unable to create type object!\");\n    }\n\n    heap_type->ht_name = name.release().ptr();\n#ifdef PYBIND11_BUILTIN_QUALNAME\n    heap_type->ht_qualname = qualname.inc_ref().ptr();\n#endif\n\n    auto *type = &heap_type->ht_type;\n    type->tp_name = full_name;\n    type->tp_doc = tp_doc;\n    type->tp_base = type_incref((PyTypeObject *) base);\n    type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));\n    if (!bases.empty()) {\n        type->tp_bases = bases.release().ptr();\n    }\n\n    /* Don't inherit base __init__ */\n    type->tp_init = pybind11_object_init;\n\n    /* Supported protocols */\n    type->tp_as_number = &heap_type->as_number;\n    type->tp_as_sequence = &heap_type->as_sequence;\n    type->tp_as_mapping = &heap_type->as_mapping;\n#if PY_VERSION_HEX >= 0x03050000\n    type->tp_as_async = &heap_type->as_async;\n#endif\n\n    /* Flags */\n    type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;\n#if PY_MAJOR_VERSION < 3\n    type->tp_flags |= Py_TPFLAGS_CHECKTYPES;\n#endif\n    if (!rec.is_final) {\n        type->tp_flags |= Py_TPFLAGS_BASETYPE;\n    }\n\n    if (rec.dynamic_attr) {\n        enable_dynamic_attributes(heap_type);\n    }\n\n    if (rec.buffer_protocol) {\n        enable_buffer_protocol(heap_type);\n    }\n\n    if (rec.custom_type_setup_callback) {\n        rec.custom_type_setup_callback(heap_type);\n    }\n\n    if (PyType_Ready(type) < 0) {\n        pybind11_fail(std::string(rec.name) + \": PyType_Ready failed (\" + error_string() + \")!\");\n    }\n\n    assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));\n\n    /* Register type with the parent scope */\n    if (rec.scope) {\n        setattr(rec.scope, rec.name, (PyObject *) type);\n    } else {\n        Py_INCREF(type); // Keep it alive forever (reference leak)\n    }\n\n    if (module_) { // Needed by pydoc\n        setattr((PyObject *) type, \"__module__\", module_);\n    }\n\n    PYBIND11_SET_OLDPY_QUALNAME(type, qualname);\n\n    return (PyObject *) type;\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/common.h",
    "content": "/*\n    pybind11/detail/common.h -- Basic macros\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#define PYBIND11_VERSION_MAJOR 2\n#define PYBIND11_VERSION_MINOR 9\n#define PYBIND11_VERSION_PATCH 2\n\n// Similar to Python's convention: https://docs.python.org/3/c-api/apiabiversion.html\n// Additional convention: 0xD = dev\n#define PYBIND11_VERSION_HEX 0x02090200\n\n#define PYBIND11_NAMESPACE_BEGIN(name) namespace name {\n#define PYBIND11_NAMESPACE_END(name) }\n\n// Robust support for some features and loading modules compiled against different pybind versions\n// requires forcing hidden visibility on pybind code, so we enforce this by setting the attribute\n// on the main `pybind11` namespace.\n#if !defined(PYBIND11_NAMESPACE)\n#    ifdef __GNUG__\n#        define PYBIND11_NAMESPACE pybind11 __attribute__((visibility(\"hidden\")))\n#    else\n#        define PYBIND11_NAMESPACE pybind11\n#    endif\n#endif\n\n#if !(defined(_MSC_VER) && __cplusplus == 199711L)\n#    if __cplusplus >= 201402L\n#        define PYBIND11_CPP14\n#        if __cplusplus >= 201703L\n#            define PYBIND11_CPP17\n#            if __cplusplus >= 202002L\n#                define PYBIND11_CPP20\n#            endif\n#        endif\n#    endif\n#elif defined(_MSC_VER) && __cplusplus == 199711L\n// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully\n// implemented). Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3\n// or newer.\n#    if _MSVC_LANG >= 201402L\n#        define PYBIND11_CPP14\n#        if _MSVC_LANG > 201402L && _MSC_VER >= 1910\n#            define PYBIND11_CPP17\n#            if _MSVC_LANG >= 202002L\n#                define PYBIND11_CPP20\n#            endif\n#        endif\n#    endif\n#endif\n\n// Compiler version assertions\n#if defined(__INTEL_COMPILER)\n#    if __INTEL_COMPILER < 1800\n#        error pybind11 requires Intel C++ compiler v18 or newer\n#    elif __INTEL_COMPILER < 1900 && defined(PYBIND11_CPP14)\n#        error pybind11 supports only C++11 with Intel C++ compiler v18. Use v19 or newer for C++14.\n#    endif\n/* The following pragma cannot be pop'ed:\n   https://community.intel.com/t5/Intel-C-Compiler/Inline-and-no-inline-warning/td-p/1216764 */\n#    pragma warning disable 2196 // warning #2196: routine is both \"inline\" and \"noinline\"\n#elif defined(__clang__) && !defined(__apple_build_version__)\n#    if __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 3)\n#        error pybind11 requires clang 3.3 or newer\n#    endif\n#elif defined(__clang__)\n// Apple changes clang version macros to its Xcode version; the first Xcode release based on\n// (upstream) clang 3.3 was Xcode 5:\n#    if __clang_major__ < 5\n#        error pybind11 requires Xcode/clang 5.0 or newer\n#    endif\n#elif defined(__GNUG__)\n#    if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)\n#        error pybind11 requires gcc 4.8 or newer\n#    endif\n#elif defined(_MSC_VER)\n// Pybind hits various compiler bugs in 2015u2 and earlier, and also makes use of some stl features\n// (e.g. std::negation) added in 2015u3:\n#    if _MSC_FULL_VER < 190024210\n#        error pybind11 requires MSVC 2015 update 3 or newer\n#    endif\n#endif\n\n#if !defined(PYBIND11_EXPORT)\n#    if defined(WIN32) || defined(_WIN32)\n#        define PYBIND11_EXPORT __declspec(dllexport)\n#    else\n#        define PYBIND11_EXPORT __attribute__((visibility(\"default\")))\n#    endif\n#endif\n\n#if !defined(PYBIND11_EXPORT_EXCEPTION)\n#    ifdef __MINGW32__\n// workaround for:\n// error: 'dllexport' implies default visibility, but xxx has already been declared with a\n// different visibility\n#        define PYBIND11_EXPORT_EXCEPTION\n#    else\n#        define PYBIND11_EXPORT_EXCEPTION PYBIND11_EXPORT\n#    endif\n#endif\n\n// For CUDA, GCC7, GCC8:\n// PYBIND11_NOINLINE_FORCED is incompatible with `-Wattributes -Werror`.\n// When defining PYBIND11_NOINLINE_FORCED, it is best to also use `-Wno-attributes`.\n// However, the measured shared-library size saving when using noinline are only\n// 1.7% for CUDA, -0.2% for GCC7, and 0.0% for GCC8 (using -DCMAKE_BUILD_TYPE=MinSizeRel,\n// the default under pybind11/tests).\n#if !defined(PYBIND11_NOINLINE_FORCED)                                                            \\\n    && (defined(__CUDACC__) || (defined(__GNUC__) && (__GNUC__ == 7 || __GNUC__ == 8)))\n#    define PYBIND11_NOINLINE_DISABLED\n#endif\n\n// The PYBIND11_NOINLINE macro is for function DEFINITIONS.\n// In contrast, FORWARD DECLARATIONS should never use this macro:\n// https://stackoverflow.com/questions/9317473/forward-declaration-of-inline-functions\n#if defined(PYBIND11_NOINLINE_DISABLED) // Option for maximum portability and experimentation.\n#    define PYBIND11_NOINLINE inline\n#elif defined(_MSC_VER)\n#    define PYBIND11_NOINLINE __declspec(noinline) inline\n#else\n#    define PYBIND11_NOINLINE __attribute__((noinline)) inline\n#endif\n\n#if defined(__MINGW32__)\n// For unknown reasons all PYBIND11_DEPRECATED member trigger a warning when declared\n// whether it is used or not\n#    define PYBIND11_DEPRECATED(reason)\n#elif defined(PYBIND11_CPP14)\n#    define PYBIND11_DEPRECATED(reason) [[deprecated(reason)]]\n#else\n#    define PYBIND11_DEPRECATED(reason) __attribute__((deprecated(reason)))\n#endif\n\n#if defined(PYBIND11_CPP17)\n#    define PYBIND11_MAYBE_UNUSED [[maybe_unused]]\n#elif defined(_MSC_VER) && !defined(__clang__)\n#    define PYBIND11_MAYBE_UNUSED\n#else\n#    define PYBIND11_MAYBE_UNUSED __attribute__((__unused__))\n#endif\n\n/* Don't let Python.h #define (v)snprintf as macro because they are implemented\n   properly in Visual Studio since 2015. */\n#if defined(_MSC_VER) && _MSC_VER >= 1900\n#    define HAVE_SNPRINTF 1\n#endif\n\n/// Include Python header, disable linking to pythonX_d.lib on Windows in debug mode\n#if defined(_MSC_VER)\n#    pragma warning(push)\n// C4505: 'PySlice_GetIndicesEx': unreferenced local function has been removed (PyPy only)\n#    pragma warning(disable : 4505)\n#    if defined(_DEBUG) && !defined(Py_DEBUG)\n// Workaround for a VS 2022 issue.\n// NOTE: This workaround knowingly violates the Python.h include order requirement:\n// https://docs.python.org/3/c-api/intro.html#include-files\n// See https://github.com/pybind/pybind11/pull/3497 for full context.\n#        include <yvals.h>\n#        if _MSVC_STL_VERSION >= 143\n#            include <crtdefs.h>\n#        endif\n#        define PYBIND11_DEBUG_MARKER\n#        undef _DEBUG\n#    endif\n#endif\n\n// https://en.cppreference.com/w/c/chrono/localtime\n#if defined(__STDC_LIB_EXT1__) && !defined(__STDC_WANT_LIB_EXT1__)\n#    define __STDC_WANT_LIB_EXT1__\n#endif\n\n#ifdef __has_include\n// std::optional (but including it in c++14 mode isn't allowed)\n#    if defined(PYBIND11_CPP17) && __has_include(<optional>)\n#        define PYBIND11_HAS_OPTIONAL 1\n#    endif\n// std::experimental::optional (but not allowed in c++11 mode)\n#    if defined(PYBIND11_CPP14) && (__has_include(<experimental/optional>) && \\\n                                 !__has_include(<optional>))\n#        define PYBIND11_HAS_EXP_OPTIONAL 1\n#    endif\n// std::variant\n#    if defined(PYBIND11_CPP17) && __has_include(<variant>)\n#        define PYBIND11_HAS_VARIANT 1\n#    endif\n#elif defined(_MSC_VER) && defined(PYBIND11_CPP17)\n#    define PYBIND11_HAS_OPTIONAL 1\n#    define PYBIND11_HAS_VARIANT 1\n#endif\n\n#if defined(PYBIND11_CPP17)\n#    if defined(__has_include)\n#        if __has_include(<string_view>)\n#            define PYBIND11_HAS_STRING_VIEW\n#        endif\n#    elif defined(_MSC_VER)\n#        define PYBIND11_HAS_STRING_VIEW\n#    endif\n#endif\n\n#if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L\n#    define PYBIND11_HAS_U8STRING\n#endif\n\n#include <Python.h>\n#include <frameobject.h>\n#include <pythread.h>\n\n/* Python #defines overrides on all sorts of core functions, which\n   tends to weak havok in C++ codebases that expect these to work\n   like regular functions (potentially with several overloads) */\n#if defined(isalnum)\n#    undef isalnum\n#    undef isalpha\n#    undef islower\n#    undef isspace\n#    undef isupper\n#    undef tolower\n#    undef toupper\n#endif\n\n#if defined(copysign)\n#    undef copysign\n#endif\n\n#if defined(_MSC_VER)\n#    if defined(PYBIND11_DEBUG_MARKER)\n#        define _DEBUG\n#        undef PYBIND11_DEBUG_MARKER\n#    endif\n#    pragma warning(pop)\n#endif\n\n#include <cstddef>\n#include <cstring>\n#include <exception>\n#include <forward_list>\n#include <memory>\n#include <stdexcept>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <unordered_map>\n#include <unordered_set>\n#include <vector>\n#if defined(__has_include)\n#    if __has_include(<version>)\n#        include <version>\n#    endif\n#endif\n\n// #define PYBIND11_STR_LEGACY_PERMISSIVE\n// If DEFINED, pybind11::str can hold PyUnicodeObject or PyBytesObject\n//             (probably surprising and never documented, but this was the\n//             legacy behavior until and including v2.6.x). As a side-effect,\n//             pybind11::isinstance<str>() is true for both pybind11::str and\n//             pybind11::bytes.\n// If UNDEFINED, pybind11::str can only hold PyUnicodeObject, and\n//               pybind11::isinstance<str>() is true only for pybind11::str.\n//               However, for Python 2 only (!), the pybind11::str caster\n//               implicitly decodes bytes to PyUnicodeObject. This is to ease\n//               the transition from the legacy behavior to the non-permissive\n//               behavior.\n\n#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions\n#    define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyInstanceMethod_New(ptr)\n#    define PYBIND11_INSTANCE_METHOD_CHECK PyInstanceMethod_Check\n#    define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyInstanceMethod_GET_FUNCTION\n#    define PYBIND11_BYTES_CHECK PyBytes_Check\n#    define PYBIND11_BYTES_FROM_STRING PyBytes_FromString\n#    define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize\n#    define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize\n#    define PYBIND11_BYTES_AS_STRING PyBytes_AsString\n#    define PYBIND11_BYTES_SIZE PyBytes_Size\n#    define PYBIND11_LONG_CHECK(o) PyLong_Check(o)\n#    define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)\n#    define PYBIND11_LONG_FROM_SIGNED(o) PyLong_FromSsize_t((ssize_t) (o))\n#    define PYBIND11_LONG_FROM_UNSIGNED(o) PyLong_FromSize_t((size_t) (o))\n#    define PYBIND11_BYTES_NAME \"bytes\"\n#    define PYBIND11_STRING_NAME \"str\"\n#    define PYBIND11_SLICE_OBJECT PyObject\n#    define PYBIND11_FROM_STRING PyUnicode_FromString\n#    define PYBIND11_STR_TYPE ::pybind11::str\n#    define PYBIND11_BOOL_ATTR \"__bool__\"\n#    define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_bool)\n#    define PYBIND11_BUILTINS_MODULE \"builtins\"\n// Providing a separate declaration to make Clang's -Wmissing-prototypes happy.\n// See comment for PYBIND11_MODULE below for why this is marked \"maybe unused\".\n#    define PYBIND11_PLUGIN_IMPL(name)                                                            \\\n        extern \"C\" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT PyObject *PyInit_##name();               \\\n        extern \"C\" PYBIND11_EXPORT PyObject *PyInit_##name()\n\n#else\n#    define PYBIND11_INSTANCE_METHOD_NEW(ptr, class_) PyMethod_New(ptr, nullptr, class_)\n#    define PYBIND11_INSTANCE_METHOD_CHECK PyMethod_Check\n#    define PYBIND11_INSTANCE_METHOD_GET_FUNCTION PyMethod_GET_FUNCTION\n#    define PYBIND11_BYTES_CHECK PyString_Check\n#    define PYBIND11_BYTES_FROM_STRING PyString_FromString\n#    define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize\n#    define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize\n#    define PYBIND11_BYTES_AS_STRING PyString_AsString\n#    define PYBIND11_BYTES_SIZE PyString_Size\n#    define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o))\n#    define PYBIND11_LONG_AS_LONGLONG(o)                                                          \\\n        (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o))\n#    define PYBIND11_LONG_FROM_SIGNED(o) PyInt_FromSsize_t((ssize_t) o) // Returns long if needed.\n#    define PYBIND11_LONG_FROM_UNSIGNED(o) PyInt_FromSize_t((size_t) o) // Returns long if needed.\n#    define PYBIND11_BYTES_NAME \"str\"\n#    define PYBIND11_STRING_NAME \"unicode\"\n#    define PYBIND11_SLICE_OBJECT PySliceObject\n#    define PYBIND11_FROM_STRING PyString_FromString\n#    define PYBIND11_STR_TYPE ::pybind11::bytes\n#    define PYBIND11_BOOL_ATTR \"__nonzero__\"\n#    define PYBIND11_NB_BOOL(ptr) ((ptr)->nb_nonzero)\n#    define PYBIND11_BUILTINS_MODULE \"__builtin__\"\n// Providing a separate PyInit decl to make Clang's -Wmissing-prototypes happy.\n// See comment for PYBIND11_MODULE below for why this is marked \"maybe unused\".\n#    define PYBIND11_PLUGIN_IMPL(name)                                                            \\\n        static PyObject *pybind11_init_wrapper();                                                 \\\n        extern \"C\" PYBIND11_MAYBE_UNUSED PYBIND11_EXPORT void init##name();                       \\\n        extern \"C\" PYBIND11_EXPORT void init##name() { (void) pybind11_init_wrapper(); }          \\\n        PyObject *pybind11_init_wrapper()\n#endif\n\n#if PY_VERSION_HEX >= 0x03050000 && PY_VERSION_HEX < 0x03050200\nextern \"C\" {\nstruct _Py_atomic_address {\n    void *value;\n};\nPyAPI_DATA(_Py_atomic_address) _PyThreadState_Current;\n}\n#endif\n\n#define PYBIND11_TRY_NEXT_OVERLOAD ((PyObject *) 1) // special failure return code\n#define PYBIND11_STRINGIFY(x) #x\n#define PYBIND11_TOSTRING(x) PYBIND11_STRINGIFY(x)\n#define PYBIND11_CONCAT(first, second) first##second\n#define PYBIND11_ENSURE_INTERNALS_READY pybind11::detail::get_internals();\n\n#define PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n    {                                                                                             \\\n        const char *compiled_ver                                                                  \\\n            = PYBIND11_TOSTRING(PY_MAJOR_VERSION) \".\" PYBIND11_TOSTRING(PY_MINOR_VERSION);        \\\n        const char *runtime_ver = Py_GetVersion();                                                \\\n        size_t len = std::strlen(compiled_ver);                                                   \\\n        if (std::strncmp(runtime_ver, compiled_ver, len) != 0                                     \\\n            || (runtime_ver[len] >= '0' && runtime_ver[len] <= '9')) {                            \\\n            PyErr_Format(PyExc_ImportError,                                                       \\\n                         \"Python version mismatch: module was compiled for Python %s, \"           \\\n                         \"but the interpreter version is incompatible: %s.\",                      \\\n                         compiled_ver,                                                            \\\n                         runtime_ver);                                                            \\\n            return nullptr;                                                                       \\\n        }                                                                                         \\\n    }\n\n#if PY_VERSION_HEX >= 0x03030000\n\n#    define PYBIND11_CATCH_INIT_EXCEPTIONS                                                        \\\n        catch (pybind11::error_already_set & e) {                                                 \\\n            pybind11::raise_from(e, PyExc_ImportError, \"initialization failed\");                  \\\n            return nullptr;                                                                       \\\n        }                                                                                         \\\n        catch (const std::exception &e) {                                                         \\\n            PyErr_SetString(PyExc_ImportError, e.what());                                         \\\n            return nullptr;                                                                       \\\n        }\n\n#else\n\n#    define PYBIND11_CATCH_INIT_EXCEPTIONS                                                        \\\n        catch (pybind11::error_already_set & e) {                                                 \\\n            PyErr_SetString(PyExc_ImportError, e.what());                                         \\\n            return nullptr;                                                                       \\\n        }                                                                                         \\\n        catch (const std::exception &e) {                                                         \\\n            PyErr_SetString(PyExc_ImportError, e.what());                                         \\\n            return nullptr;                                                                       \\\n        }\n\n#endif\n\n/** \\rst\n    ***Deprecated in favor of PYBIND11_MODULE***\n\n    This macro creates the entry point that will be invoked when the Python interpreter\n    imports a plugin library. Please create a `module_` in the function body and return\n    the pointer to its underlying Python object at the end.\n\n    .. code-block:: cpp\n\n        PYBIND11_PLUGIN(example) {\n            pybind11::module_ m(\"example\", \"pybind11 example plugin\");\n            /// Set up bindings here\n            return m.ptr();\n        }\n\\endrst */\n#define PYBIND11_PLUGIN(name)                                                                     \\\n    PYBIND11_DEPRECATED(\"PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE\")                     \\\n    static PyObject *pybind11_init();                                                             \\\n    PYBIND11_PLUGIN_IMPL(name) {                                                                  \\\n        PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n        PYBIND11_ENSURE_INTERNALS_READY                                                           \\\n        try {                                                                                     \\\n            return pybind11_init();                                                               \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    PyObject *pybind11_init()\n\n/** \\rst\n    This macro creates the entry point that will be invoked when the Python interpreter\n    imports an extension module. The module name is given as the fist argument and it\n    should not be in quotes. The second macro argument defines a variable of type\n    `py::module_` which can be used to initialize the module.\n\n    The entry point is marked as \"maybe unused\" to aid dead-code detection analysis:\n    since the entry point is typically only looked up at runtime and not referenced\n    during translation, it would otherwise appear as unused (\"dead\") code.\n\n    .. code-block:: cpp\n\n        PYBIND11_MODULE(example, m) {\n            m.doc() = \"pybind11 example module\";\n\n            // Add bindings here\n            m.def(\"foo\", []() {\n                return \"Hello, World!\";\n            });\n        }\n\\endrst */\n#define PYBIND11_MODULE(name, variable)                                                           \\\n    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name)            \\\n        PYBIND11_MAYBE_UNUSED;                                                                    \\\n    PYBIND11_MAYBE_UNUSED                                                                         \\\n    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \\\n    PYBIND11_PLUGIN_IMPL(name) {                                                                  \\\n        PYBIND11_CHECK_PYTHON_VERSION                                                             \\\n        PYBIND11_ENSURE_INTERNALS_READY                                                           \\\n        auto m = ::pybind11::module_::create_extension_module(                                    \\\n            PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name));      \\\n        try {                                                                                     \\\n            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \\\n            return m.ptr();                                                                       \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ & (variable))\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nusing ssize_t = Py_ssize_t;\nusing size_t = std::size_t;\n\ntemplate <typename IntType>\ninline ssize_t ssize_t_cast(const IntType &val) {\n    static_assert(sizeof(IntType) <= sizeof(ssize_t), \"Implicit narrowing is not permitted.\");\n    return static_cast<ssize_t>(val);\n}\n\n/// Approach used to cast a previously unknown C++ instance into a Python object\nenum class return_value_policy : uint8_t {\n    /** This is the default return value policy, which falls back to the policy\n        return_value_policy::take_ownership when the return value is a pointer.\n        Otherwise, it uses return_value::move or return_value::copy for rvalue\n        and lvalue references, respectively. See below for a description of what\n        all of these different policies do. */\n    automatic = 0,\n\n    /** As above, but use policy return_value_policy::reference when the return\n        value is a pointer. This is the default conversion policy for function\n        arguments when calling Python functions manually from C++ code (i.e. via\n        handle::operator()). You probably won't need to use this. */\n    automatic_reference,\n\n    /** Reference an existing object (i.e. do not create a new copy) and take\n        ownership. Python will call the destructor and delete operator when the\n        object’s reference count reaches zero. Undefined behavior ensues when\n        the C++ side does the same.. */\n    take_ownership,\n\n    /** Create a new copy of the returned object, which will be owned by\n        Python. This policy is comparably safe because the lifetimes of the two\n        instances are decoupled. */\n    copy,\n\n    /** Use std::move to move the return value contents into a new instance\n        that will be owned by Python. This policy is comparably safe because the\n        lifetimes of the two instances (move source and destination) are\n        decoupled. */\n    move,\n\n    /** Reference an existing object, but do not take ownership. The C++ side\n        is responsible for managing the object’s lifetime and deallocating it\n        when it is no longer used. Warning: undefined behavior will ensue when\n        the C++ side deletes an object that is still referenced and used by\n        Python. */\n    reference,\n\n    /** This policy only applies to methods and properties. It references the\n        object without taking ownership similar to the above\n        return_value_policy::reference policy. In contrast to that policy, the\n        function or property’s implicit this argument (called the parent) is\n        considered to be the the owner of the return value (the child).\n        pybind11 then couples the lifetime of the parent to the child via a\n        reference relationship that ensures that the parent cannot be garbage\n        collected while Python is still using the child. More advanced\n        variations of this scheme are also possible using combinations of\n        return_value_policy::reference and the keep_alive call policy */\n    reference_internal\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline static constexpr int log2(size_t n, int k = 0) {\n    return (n <= 1) ? k : log2(n >> 1, k + 1);\n}\n\n// Returns the size as a multiple of sizeof(void *), rounded up.\ninline static constexpr size_t size_in_ptrs(size_t s) {\n    return 1 + ((s - 1) >> log2(sizeof(void *)));\n}\n\n/**\n * The space to allocate for simple layout instance holders (see below) in multiple of the size of\n * a pointer (e.g.  2 means 16 bytes on 64-bit architectures).  The default is the minimum required\n * to holder either a std::unique_ptr or std::shared_ptr (which is almost always\n * sizeof(std::shared_ptr<T>)).\n */\nconstexpr size_t instance_simple_holder_in_ptrs() {\n    static_assert(sizeof(std::shared_ptr<int>) >= sizeof(std::unique_ptr<int>),\n                  \"pybind assumes std::shared_ptrs are at least as big as std::unique_ptrs\");\n    return size_in_ptrs(sizeof(std::shared_ptr<int>));\n}\n\n// Forward declarations\nstruct type_info;\nstruct value_and_holder;\n\nstruct nonsimple_values_and_holders {\n    void **values_and_holders;\n    uint8_t *status;\n};\n\n/// The 'instance' type which needs to be standard layout (need to be able to use 'offsetof')\nstruct instance {\n    PyObject_HEAD\n    /// Storage for pointers and holder; see simple_layout, below, for a description\n    union {\n        void *simple_value_holder[1 + instance_simple_holder_in_ptrs()];\n        nonsimple_values_and_holders nonsimple;\n    };\n    /// Weak references\n    PyObject *weakrefs;\n    /// If true, the pointer is owned which means we're free to manage it with a holder.\n    bool owned : 1;\n    /**\n     * An instance has two possible value/holder layouts.\n     *\n     * Simple layout (when this flag is true), means the `simple_value_holder` is set with a\n     * pointer and the holder object governing that pointer, i.e. [val1*][holder].  This layout is\n     * applied whenever there is no python-side multiple inheritance of bound C++ types *and* the\n     * type's holder will fit in the default space (which is large enough to hold either a\n     * std::unique_ptr or std::shared_ptr).\n     *\n     * Non-simple layout applies when using custom holders that require more space than\n     * `shared_ptr` (which is typically the size of two pointers), or when multiple inheritance is\n     * used on the python side.  Non-simple layout allocates the required amount of memory to have\n     * multiple bound C++ classes as parents.  Under this layout, `nonsimple.values_and_holders` is\n     * set to a pointer to allocated space of the required space to hold a sequence of value\n     * pointers and holders followed `status`, a set of bit flags (1 byte each), i.e.\n     * [val1*][holder1][val2*][holder2]...[bb...]  where each [block] is rounded up to a multiple\n     * of `sizeof(void *)`.  `nonsimple.status` is, for convenience, a pointer to the beginning of\n     * the [bb...] block (but not independently allocated).\n     *\n     * Status bits indicate whether the associated holder is constructed (&\n     * status_holder_constructed) and whether the value pointer is registered (&\n     * status_instance_registered) in `registered_instances`.\n     */\n    bool simple_layout : 1;\n    /// For simple layout, tracks whether the holder has been constructed\n    bool simple_holder_constructed : 1;\n    /// For simple layout, tracks whether the instance is registered in `registered_instances`\n    bool simple_instance_registered : 1;\n    /// If true, get_internals().patients has an entry for this object\n    bool has_patients : 1;\n\n    /// Initializes all of the above type/values/holders data (but not the instance values\n    /// themselves)\n    void allocate_layout();\n\n    /// Destroys/deallocates all of the above\n    void deallocate_layout();\n\n    /// Returns the value_and_holder wrapper for the given type (or the first, if `find_type`\n    /// omitted).  Returns a default-constructed (with `.inst = nullptr`) object on failure if\n    /// `throw_if_missing` is false.\n    value_and_holder get_value_and_holder(const type_info *find_type = nullptr,\n                                          bool throw_if_missing = true);\n\n    /// Bit values for the non-simple status flags\n    static constexpr uint8_t status_holder_constructed = 1;\n    static constexpr uint8_t status_instance_registered = 2;\n};\n\nstatic_assert(std::is_standard_layout<instance>::value,\n              \"Internal error: `pybind11::detail::instance` is not standard layout!\");\n\n/// from __cpp_future__ import (convenient aliases from C++14/17)\n#if defined(PYBIND11_CPP14) && (!defined(_MSC_VER) || _MSC_VER >= 1910)\nusing std::conditional_t;\nusing std::enable_if_t;\nusing std::remove_cv_t;\nusing std::remove_reference_t;\n#else\ntemplate <bool B, typename T = void>\nusing enable_if_t = typename std::enable_if<B, T>::type;\ntemplate <bool B, typename T, typename F>\nusing conditional_t = typename std::conditional<B, T, F>::type;\ntemplate <typename T>\nusing remove_cv_t = typename std::remove_cv<T>::type;\ntemplate <typename T>\nusing remove_reference_t = typename std::remove_reference<T>::type;\n#endif\n\n#if defined(PYBIND11_CPP20)\nusing std::remove_cvref;\nusing std::remove_cvref_t;\n#else\ntemplate <class T>\nstruct remove_cvref {\n    using type = remove_cv_t<remove_reference_t<T>>;\n};\ntemplate <class T>\nusing remove_cvref_t = typename remove_cvref<T>::type;\n#endif\n\n/// Index sequences\n#if defined(PYBIND11_CPP14)\nusing std::index_sequence;\nusing std::make_index_sequence;\n#else\ntemplate <size_t...>\nstruct index_sequence {};\ntemplate <size_t N, size_t... S>\nstruct make_index_sequence_impl : make_index_sequence_impl<N - 1, N - 1, S...> {};\ntemplate <size_t... S>\nstruct make_index_sequence_impl<0, S...> {\n    using type = index_sequence<S...>;\n};\ntemplate <size_t N>\nusing make_index_sequence = typename make_index_sequence_impl<N>::type;\n#endif\n\n/// Make an index sequence of the indices of true arguments\ntemplate <typename ISeq, size_t, bool...>\nstruct select_indices_impl {\n    using type = ISeq;\n};\ntemplate <size_t... IPrev, size_t I, bool B, bool... Bs>\nstruct select_indices_impl<index_sequence<IPrev...>, I, B, Bs...>\n    : select_indices_impl<conditional_t<B, index_sequence<IPrev..., I>, index_sequence<IPrev...>>,\n                          I + 1,\n                          Bs...> {};\ntemplate <bool... Bs>\nusing select_indices = typename select_indices_impl<index_sequence<>, 0, Bs...>::type;\n\n/// Backports of std::bool_constant and std::negation to accommodate older compilers\ntemplate <bool B>\nusing bool_constant = std::integral_constant<bool, B>;\ntemplate <typename T>\nstruct negation : bool_constant<!T::value> {};\n\n// PGI/Intel cannot detect operator delete with the \"compatible\" void_t impl, so\n// using the new one (C++14 defect, so generally works on newer compilers, even\n// if not in C++17 mode)\n#if defined(__PGIC__) || defined(__INTEL_COMPILER)\ntemplate <typename...>\nusing void_t = void;\n#else\ntemplate <typename...>\nstruct void_t_impl {\n    using type = void;\n};\ntemplate <typename... Ts>\nusing void_t = typename void_t_impl<Ts...>::type;\n#endif\n\n/// Compile-time all/any/none of that check the boolean value of all template types\n#if defined(__cpp_fold_expressions) && !(defined(_MSC_VER) && (_MSC_VER < 1916))\ntemplate <class... Ts>\nusing all_of = bool_constant<(Ts::value && ...)>;\ntemplate <class... Ts>\nusing any_of = bool_constant<(Ts::value || ...)>;\n#elif !defined(_MSC_VER)\ntemplate <bool...>\nstruct bools {};\ntemplate <class... Ts>\nusing all_of = std::is_same<bools<Ts::value..., true>, bools<true, Ts::value...>>;\ntemplate <class... Ts>\nusing any_of = negation<all_of<negation<Ts>...>>;\n#else\n// MSVC has trouble with the above, but supports std::conjunction, which we can use instead (albeit\n// at a slight loss of compilation efficiency).\ntemplate <class... Ts>\nusing all_of = std::conjunction<Ts...>;\ntemplate <class... Ts>\nusing any_of = std::disjunction<Ts...>;\n#endif\ntemplate <class... Ts>\nusing none_of = negation<any_of<Ts...>>;\n\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_all_of = all_of<Predicates<T>...>;\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_any_of = any_of<Predicates<T>...>;\ntemplate <class T, template <class> class... Predicates>\nusing satisfies_none_of = none_of<Predicates<T>...>;\n\n/// Strip the class from a method type\ntemplate <typename T>\nstruct remove_class {};\ntemplate <typename C, typename R, typename... A>\nstruct remove_class<R (C::*)(A...)> {\n    using type = R(A...);\n};\ntemplate <typename C, typename R, typename... A>\nstruct remove_class<R (C::*)(A...) const> {\n    using type = R(A...);\n};\n\n/// Helper template to strip away type modifiers\ntemplate <typename T>\nstruct intrinsic_type {\n    using type = T;\n};\ntemplate <typename T>\nstruct intrinsic_type<const T> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T *> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T &> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nstruct intrinsic_type<T &&> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T, size_t N>\nstruct intrinsic_type<const T[N]> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T, size_t N>\nstruct intrinsic_type<T[N]> {\n    using type = typename intrinsic_type<T>::type;\n};\ntemplate <typename T>\nusing intrinsic_t = typename intrinsic_type<T>::type;\n\n/// Helper type to replace 'void' in some expressions\nstruct void_type {};\n\n/// Helper template which holds a list of types\ntemplate <typename...>\nstruct type_list {};\n\n/// Compile-time integer sum\n#ifdef __cpp_fold_expressions\ntemplate <typename... Ts>\nconstexpr size_t constexpr_sum(Ts... ns) {\n    return (0 + ... + size_t{ns});\n}\n#else\nconstexpr size_t constexpr_sum() { return 0; }\ntemplate <typename T, typename... Ts>\nconstexpr size_t constexpr_sum(T n, Ts... ns) {\n    return size_t{n} + constexpr_sum(ns...);\n}\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(constexpr_impl)\n/// Implementation details for constexpr functions\nconstexpr int first(int i) { return i; }\ntemplate <typename T, typename... Ts>\nconstexpr int first(int i, T v, Ts... vs) {\n    return v ? i : first(i + 1, vs...);\n}\n\nconstexpr int last(int /*i*/, int result) { return result; }\ntemplate <typename T, typename... Ts>\nconstexpr int last(int i, int result, T v, Ts... vs) {\n    return last(i + 1, v ? i : result, vs...);\n}\nPYBIND11_NAMESPACE_END(constexpr_impl)\n\n/// Return the index of the first type in Ts which satisfies Predicate<T>.\n/// Returns sizeof...(Ts) if none match.\ntemplate <template <typename> class Predicate, typename... Ts>\nconstexpr int constexpr_first() {\n    return constexpr_impl::first(0, Predicate<Ts>::value...);\n}\n\n/// Return the index of the last type in Ts which satisfies Predicate<T>, or -1 if none match.\ntemplate <template <typename> class Predicate, typename... Ts>\nconstexpr int constexpr_last() {\n    return constexpr_impl::last(0, -1, Predicate<Ts>::value...);\n}\n\n/// Return the Nth element from the parameter pack\ntemplate <size_t N, typename T, typename... Ts>\nstruct pack_element {\n    using type = typename pack_element<N - 1, Ts...>::type;\n};\ntemplate <typename T, typename... Ts>\nstruct pack_element<0, T, Ts...> {\n    using type = T;\n};\n\n/// Return the one and only type which matches the predicate, or Default if none match.\n/// If more than one type matches the predicate, fail at compile-time.\ntemplate <template <typename> class Predicate, typename Default, typename... Ts>\nstruct exactly_one {\n    static constexpr auto found = constexpr_sum(Predicate<Ts>::value...);\n    static_assert(found <= 1, \"Found more than one type matching the predicate\");\n\n    static constexpr auto index = found ? constexpr_first<Predicate, Ts...>() : 0;\n    using type = conditional_t<found, typename pack_element<index, Ts...>::type, Default>;\n};\ntemplate <template <typename> class P, typename Default>\nstruct exactly_one<P, Default> {\n    using type = Default;\n};\n\ntemplate <template <typename> class Predicate, typename Default, typename... Ts>\nusing exactly_one_t = typename exactly_one<Predicate, Default, Ts...>::type;\n\n/// Defer the evaluation of type T until types Us are instantiated\ntemplate <typename T, typename... /*Us*/>\nstruct deferred_type {\n    using type = T;\n};\ntemplate <typename T, typename... Us>\nusing deferred_t = typename deferred_type<T, Us...>::type;\n\n/// Like is_base_of, but requires a strict base (i.e. `is_strict_base_of<T, T>::value == false`,\n/// unlike `std::is_base_of`)\ntemplate <typename Base, typename Derived>\nusing is_strict_base_of\n    = bool_constant<std::is_base_of<Base, Derived>::value && !std::is_same<Base, Derived>::value>;\n\n/// Like is_base_of, but also requires that the base type is accessible (i.e. that a Derived\n/// pointer can be converted to a Base pointer) For unions, `is_base_of<T, T>::value` is False, so\n/// we need to check `is_same` as well.\ntemplate <typename Base, typename Derived>\nusing is_accessible_base_of\n    = bool_constant<(std::is_same<Base, Derived>::value || std::is_base_of<Base, Derived>::value)\n                    && std::is_convertible<Derived *, Base *>::value>;\n\ntemplate <template <typename...> class Base>\nstruct is_template_base_of_impl {\n    template <typename... Us>\n    static std::true_type check(Base<Us...> *);\n    static std::false_type check(...);\n};\n\n/// Check if a template is the base of a type. For example:\n/// `is_template_base_of<Base, T>` is true if `struct T : Base<U> {}` where U can be anything\ntemplate <template <typename...> class Base, typename T>\n#if !defined(_MSC_VER)\nusing is_template_base_of\n    = decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr));\n#else // MSVC2015 has trouble with decltype in template aliases\nstruct is_template_base_of\n    : decltype(is_template_base_of_impl<Base>::check((intrinsic_t<T> *) nullptr)) {\n};\n#endif\n\n/// Check if T is an instantiation of the template `Class`. For example:\n/// `is_instantiation<shared_ptr, T>` is true if `T == shared_ptr<U>` where U can be anything.\ntemplate <template <typename...> class Class, typename T>\nstruct is_instantiation : std::false_type {};\ntemplate <template <typename...> class Class, typename... Us>\nstruct is_instantiation<Class, Class<Us...>> : std::true_type {};\n\n/// Check if T is std::shared_ptr<U> where U can be anything\ntemplate <typename T>\nusing is_shared_ptr = is_instantiation<std::shared_ptr, T>;\n\n/// Check if T looks like an input iterator\ntemplate <typename T, typename = void>\nstruct is_input_iterator : std::false_type {};\ntemplate <typename T>\nstruct is_input_iterator<T,\n                         void_t<decltype(*std::declval<T &>()), decltype(++std::declval<T &>())>>\n    : std::true_type {};\n\ntemplate <typename T>\nusing is_function_pointer\n    = bool_constant<std::is_pointer<T>::value\n                    && std::is_function<typename std::remove_pointer<T>::type>::value>;\n\ntemplate <typename F>\nstruct strip_function_object {\n    // If you are encountering an\n    // 'error: name followed by \"::\" must be a class or namespace name'\n    // with the Intel compiler and a noexcept function here,\n    // try to use noexcept(true) instead of plain noexcept.\n    using type = typename remove_class<decltype(&F::operator())>::type;\n};\n\n// Extracts the function signature from a function, function pointer or lambda.\ntemplate <typename Function, typename F = remove_reference_t<Function>>\nusing function_signature_t = conditional_t<\n    std::is_function<F>::value,\n    F,\n    typename conditional_t<std::is_pointer<F>::value || std::is_member_pointer<F>::value,\n                           std::remove_pointer<F>,\n                           strip_function_object<F>>::type>;\n\n/// Returns true if the type looks like a lambda: that is, isn't a function, pointer or member\n/// pointer.  Note that this can catch all sorts of other things, too; this is intended to be used\n/// in a place where passing a lambda makes sense.\ntemplate <typename T>\nusing is_lambda = satisfies_none_of<remove_reference_t<T>,\n                                    std::is_function,\n                                    std::is_pointer,\n                                    std::is_member_pointer>;\n\n// [workaround(intel)] Internal error on fold expression\n/// Apply a function over each element of a parameter pack\n#if defined(__cpp_fold_expressions) && !defined(__INTEL_COMPILER)\n// Intel compiler produces an internal error on this fold expression (tested with ICC 19.0.2)\n#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN) (((PATTERN), void()), ...)\n#else\nusing expand_side_effects = bool[];\n#    define PYBIND11_EXPAND_SIDE_EFFECTS(PATTERN)                                                 \\\n        (void) pybind11::detail::expand_side_effects { ((PATTERN), void(), false)..., false }\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\n#if defined(_MSC_VER)\n#    pragma warning(push)\n#    pragma warning(disable : 4275)\n//     warning C4275: An exported class was derived from a class that wasn't exported.\n//     Can be ignored when derived from a STL class.\n#endif\n/// C++ bindings of builtin Python exceptions\nclass PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {\npublic:\n    using std::runtime_error::runtime_error;\n    /// Set the error using the Python C API\n    virtual void set_error() const = 0;\n};\n#if defined(_MSC_VER)\n#    pragma warning(pop)\n#endif\n\n#define PYBIND11_RUNTIME_EXCEPTION(name, type)                                                    \\\n    class PYBIND11_EXPORT_EXCEPTION name : public builtin_exception {                             \\\n    public:                                                                                       \\\n        using builtin_exception::builtin_exception;                                               \\\n        name() : name(\"\") {}                                                                      \\\n        void set_error() const override { PyErr_SetString(type, what()); }                        \\\n    };\n\nPYBIND11_RUNTIME_EXCEPTION(stop_iteration, PyExc_StopIteration)\nPYBIND11_RUNTIME_EXCEPTION(index_error, PyExc_IndexError)\nPYBIND11_RUNTIME_EXCEPTION(key_error, PyExc_KeyError)\nPYBIND11_RUNTIME_EXCEPTION(value_error, PyExc_ValueError)\nPYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError)\nPYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError)\nPYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError)\nPYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError)\nPYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or\n                                                           /// handle::call fail due to a type\n                                                           /// casting error\nPYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally\n\n[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) {\n    throw std::runtime_error(reason);\n}\n[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const std::string &reason) {\n    throw std::runtime_error(reason);\n}\n\ntemplate <typename T, typename SFINAE = void>\nstruct format_descriptor {};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Returns the index of the given type in the type char array below, and in the list in numpy.h\n// The order here is: bool; 8 ints ((signed,unsigned)x(8,16,32,64)bits); float,double,long double;\n// complex float,double,long double.  Note that the long double types only participate when long\n// double is actually longer than double (it isn't under MSVC).\n// NB: not only the string below but also complex.h and numpy.h rely on this order.\ntemplate <typename T, typename SFINAE = void>\nstruct is_fmt_numeric {\n    static constexpr bool value = false;\n};\ntemplate <typename T>\nstruct is_fmt_numeric<T, enable_if_t<std::is_arithmetic<T>::value>> {\n    static constexpr bool value = true;\n    static constexpr int index\n        = std::is_same<T, bool>::value\n              ? 0\n              : 1\n                    + (std::is_integral<T>::value\n                           ? detail::log2(sizeof(T)) * 2 + std::is_unsigned<T>::value\n                           : 8\n                                 + (std::is_same<T, double>::value        ? 1\n                                    : std::is_same<T, long double>::value ? 2\n                                                                          : 0));\n};\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>> {\n    static constexpr const char c = \"?bBhHiIqQfdg\"[detail::is_fmt_numeric<T>::index];\n    static constexpr const char value[2] = {c, '\\0'};\n    static std::string format() { return std::string(1, c); }\n};\n\n#if !defined(PYBIND11_CPP17)\n\ntemplate <typename T>\nconstexpr const char\n    format_descriptor<T, detail::enable_if_t<std::is_arithmetic<T>::value>>::value[2];\n\n#endif\n\n/// RAII wrapper that temporarily clears any Python error state\nstruct error_scope {\n    PyObject *type, *value, *trace;\n    error_scope() { PyErr_Fetch(&type, &value, &trace); }\n    ~error_scope() { PyErr_Restore(type, value, trace); }\n};\n\n/// Dummy destructor wrapper that can be used to expose classes with a private destructor\nstruct nodelete {\n    template <typename T>\n    void operator()(T *) {}\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename... Args>\nstruct overload_cast_impl {\n    // NOLINTNEXTLINE(modernize-use-equals-default):  MSVC 2015 needs this\n    constexpr overload_cast_impl() {}\n\n    template <typename Return>\n    constexpr auto operator()(Return (*pf)(Args...)) const noexcept -> decltype(pf) {\n        return pf;\n    }\n\n    template <typename Return, typename Class>\n    constexpr auto operator()(Return (Class::*pmf)(Args...), std::false_type = {}) const noexcept\n        -> decltype(pmf) {\n        return pmf;\n    }\n\n    template <typename Return, typename Class>\n    constexpr auto operator()(Return (Class::*pmf)(Args...) const, std::true_type) const noexcept\n        -> decltype(pmf) {\n        return pmf;\n    }\n};\nPYBIND11_NAMESPACE_END(detail)\n\n// overload_cast requires variable templates: C++14\n#if defined(PYBIND11_CPP14)\n#    define PYBIND11_OVERLOAD_CAST 1\n/// Syntax sugar for resolving overloaded function pointers:\n///  - regular: static_cast<Return (Class::*)(Arg0, Arg1, Arg2)>(&Class::func)\n///  - sweet:   overload_cast<Arg0, Arg1, Arg2>(&Class::func)\ntemplate <typename... Args>\nstatic constexpr detail::overload_cast_impl<Args...> overload_cast = {};\n// MSVC 2015 only accepts this particular initialization syntax for this variable template.\n#endif\n\n/// Const member function selector for overload_cast\n///  - regular: static_cast<Return (Class::*)(Arg) const>(&Class::func)\n///  - sweet:   overload_cast<Arg>(&Class::func, const_)\nstatic constexpr auto const_ = std::true_type{};\n\n#if !defined(PYBIND11_CPP14) // no overload_cast: providing something that static_assert-fails:\ntemplate <typename... Args>\nstruct overload_cast {\n    static_assert(detail::deferred_t<std::false_type, Args...>::value,\n                  \"pybind11::overload_cast<...> requires compiling in C++14 mode\");\n};\n#endif // overload_cast\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Adaptor for converting arbitrary container arguments into a vector; implicitly convertible from\n// any standard container (or C-style array) supporting std::begin/std::end, any singleton\n// arithmetic type (if T is arithmetic), or explicitly constructible from an iterator pair.\ntemplate <typename T>\nclass any_container {\n    std::vector<T> v;\n\npublic:\n    any_container() = default;\n\n    // Can construct from a pair of iterators\n    template <typename It, typename = enable_if_t<is_input_iterator<It>::value>>\n    any_container(It first, It last) : v(first, last) {}\n\n    // Implicit conversion constructor from any arbitrary container type\n    // with values convertible to T\n    template <typename Container,\n              typename = enable_if_t<\n                  std::is_convertible<decltype(*std::begin(std::declval<const Container &>())),\n                                      T>::value>>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    any_container(const Container &c) : any_container(std::begin(c), std::end(c)) {}\n\n    // initializer_list's aren't deducible, so don't get matched by the above template;\n    // we need this to explicitly allow implicit conversion from one:\n    template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>\n    any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) {}\n\n    // Avoid copying if given an rvalue vector of the correct type.\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    any_container(std::vector<T> &&v) : v(std::move(v)) {}\n\n    // Moves the vector out of an rvalue any_container\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::vector<T> &&() && { return std::move(v); }\n\n    // Dereferencing obtains a reference to the underlying vector\n    std::vector<T> &operator*() { return v; }\n    const std::vector<T> &operator*() const { return v; }\n\n    // -> lets you call methods on the underlying vector\n    std::vector<T> *operator->() { return &v; }\n    const std::vector<T> *operator->() const { return &v; }\n};\n\n// Forward-declaration; see detail/class.h\nstd::string get_fully_qualified_tp_name(PyTypeObject *);\n\ntemplate <typename T>\ninline static std::shared_ptr<T>\ntry_get_shared_from_this(std::enable_shared_from_this<T> *holder_value_ptr) {\n// Pre C++17, this code path exploits undefined behavior, but is known to work on many platforms.\n// Use at your own risk!\n// See also https://en.cppreference.com/w/cpp/memory/enable_shared_from_this, and in particular\n// the `std::shared_ptr<Good> gp1 = not_so_good.getptr();` and `try`-`catch` parts of the example.\n#if defined(__cpp_lib_enable_shared_from_this) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n    return holder_value_ptr->weak_from_this().lock();\n#else\n    try {\n        return holder_value_ptr->shared_from_this();\n    } catch (const std::bad_weak_ptr &) {\n        return nullptr;\n    }\n#endif\n}\n\n// For silencing \"unused\" compiler warnings in special situations.\ntemplate <typename... Args>\n#if defined(_MSC_VER) && _MSC_VER >= 1910 && _MSC_VER < 1920 // MSVC 2017\nconstexpr\n#endif\n    inline void\n    silence_unused_warnings(Args &&...) {\n}\n\n// MSVC warning C4100: Unreferenced formal parameter\n#if defined(_MSC_VER) && _MSC_VER <= 1916\n#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)                                         \\\n        detail::silence_unused_warnings(__VA_ARGS__)\n#else\n#    define PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(...)\n#endif\n\n// GCC -Wunused-but-set-parameter  All GCC versions (as of July 2021).\n#if defined(__GNUG__) && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)                       \\\n        detail::silence_unused_warnings(__VA_ARGS__)\n#else\n#    define PYBIND11_WORKAROUND_INCORRECT_GCC_UNUSED_BUT_SET_PARAMETER(...)\n#endif\n\n#if defined(_MSC_VER) // All versions (as of July 2021).\n\n// warning C4127: Conditional expression is constant\nconstexpr inline bool silence_msvc_c4127(bool cond) { return cond; }\n\n#    define PYBIND11_SILENCE_MSVC_C4127(...) ::pybind11::detail::silence_msvc_c4127(__VA_ARGS__)\n\n#else\n#    define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/descr.h",
    "content": "/*\n    pybind11/detail/descr.h: Helper type for concatenating type signatures at compile time\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if !defined(_MSC_VER)\n#    define PYBIND11_DESCR_CONSTEXPR static constexpr\n#else\n#    define PYBIND11_DESCR_CONSTEXPR const\n#endif\n\n/* Concatenate type signatures at compile time */\ntemplate <size_t N, typename... Ts>\nstruct descr {\n    char text[N + 1]{'\\0'};\n\n    constexpr descr() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    constexpr descr(char const (&s)[N + 1]) : descr(s, make_index_sequence<N>()) {}\n\n    template <size_t... Is>\n    constexpr descr(char const (&s)[N + 1], index_sequence<Is...>) : text{s[Is]..., '\\0'} {}\n\n    template <typename... Chars>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    constexpr descr(char c, Chars... cs) : text{c, static_cast<char>(cs)..., '\\0'} {}\n\n    static constexpr std::array<const std::type_info *, sizeof...(Ts) + 1> types() {\n        return {{&typeid(Ts)..., nullptr}};\n    }\n};\n\ntemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2, size_t... Is1, size_t... Is2>\nconstexpr descr<N1 + N2, Ts1..., Ts2...> plus_impl(const descr<N1, Ts1...> &a,\n                                                   const descr<N2, Ts2...> &b,\n                                                   index_sequence<Is1...>,\n                                                   index_sequence<Is2...>) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(b);\n    return {a.text[Is1]..., b.text[Is2]...};\n}\n\ntemplate <size_t N1, size_t N2, typename... Ts1, typename... Ts2>\nconstexpr descr<N1 + N2, Ts1..., Ts2...> operator+(const descr<N1, Ts1...> &a,\n                                                   const descr<N2, Ts2...> &b) {\n    return plus_impl(a, b, make_index_sequence<N1>(), make_index_sequence<N2>());\n}\n\ntemplate <size_t N>\nconstexpr descr<N - 1> const_name(char const (&text)[N]) {\n    return descr<N - 1>(text);\n}\nconstexpr descr<0> const_name(char const (&)[1]) { return {}; }\n\ntemplate <size_t Rem, size_t... Digits>\nstruct int_to_str : int_to_str<Rem / 10, Rem % 10, Digits...> {};\ntemplate <size_t... Digits>\nstruct int_to_str<0, Digits...> {\n    // WARNING: This only works with C++17 or higher.\n    static constexpr auto digits = descr<sizeof...(Digits)>(('0' + Digits)...);\n};\n\n// Ternary description (like std::conditional)\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<B, descr<N1 - 1>> const_name(char const (&text1)[N1], char const (&)[N2]) {\n    return const_name(text1);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<!B, descr<N2 - 1>> const_name(char const (&)[N1], char const (&text2)[N2]) {\n    return const_name(text2);\n}\n\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<B, T1> const_name(const T1 &d, const T2 &) {\n    return d;\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<!B, T2> const_name(const T1 &, const T2 &d) {\n    return d;\n}\n\ntemplate <size_t Size>\nauto constexpr const_name() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {\n    return int_to_str<Size / 10, Size % 10>::digits;\n}\n\ntemplate <typename Type>\nconstexpr descr<1, Type> const_name() {\n    return {'%'};\n}\n\n// If \"_\" is defined as a macro, py::detail::_ cannot be provided.\n// It is therefore best to use py::detail::const_name universally.\n// This block is for backward compatibility only.\n// (The const_name code is repeated to avoid introducing a \"_\" #define ourselves.)\n#ifndef _\n#    define PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\ntemplate <size_t N>\nconstexpr descr<N - 1> _(char const (&text)[N]) {\n    return const_name<N>(text);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<B, descr<N1 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {\n    return const_name<B, N1, N2>(text1, text2);\n}\ntemplate <bool B, size_t N1, size_t N2>\nconstexpr enable_if_t<!B, descr<N2 - 1>> _(char const (&text1)[N1], char const (&text2)[N2]) {\n    return const_name<B, N1, N2>(text1, text2);\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<B, T1> _(const T1 &d1, const T2 &d2) {\n    return const_name<B, T1, T2>(d1, d2);\n}\ntemplate <bool B, typename T1, typename T2>\nconstexpr enable_if_t<!B, T2> _(const T1 &d1, const T2 &d2) {\n    return const_name<B, T1, T2>(d1, d2);\n}\n\ntemplate <size_t Size>\nauto constexpr _() -> remove_cv_t<decltype(int_to_str<Size / 10, Size % 10>::digits)> {\n    return const_name<Size>();\n}\ntemplate <typename Type>\nconstexpr descr<1, Type> _() {\n    return const_name<Type>();\n}\n#endif // #ifndef _\n\nconstexpr descr<0> concat() { return {}; }\n\ntemplate <size_t N, typename... Ts>\nconstexpr descr<N, Ts...> concat(const descr<N, Ts...> &descr) {\n    return descr;\n}\n\ntemplate <size_t N, typename... Ts, typename... Args>\nconstexpr auto concat(const descr<N, Ts...> &d, const Args &...args)\n    -> decltype(std::declval<descr<N + 2, Ts...>>() + concat(args...)) {\n    return d + const_name(\", \") + concat(args...);\n}\n\ntemplate <size_t N, typename... Ts>\nconstexpr descr<N + 2, Ts...> type_descr(const descr<N, Ts...> &descr) {\n    return const_name(\"{\") + descr + const_name(\"}\");\n}\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/init.h",
    "content": "/*\n    pybind11/detail/init.h: init factory function implementation and support code.\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"class.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <>\nclass type_caster<value_and_holder> {\npublic:\n    bool load(handle h, bool) {\n        value = reinterpret_cast<value_and_holder *>(h.ptr());\n        return true;\n    }\n\n    template <typename>\n    using cast_op_type = value_and_holder &;\n    explicit operator value_and_holder &() { return *value; }\n    static constexpr auto name = const_name<value_and_holder>();\n\nprivate:\n    value_and_holder *value = nullptr;\n};\n\nPYBIND11_NAMESPACE_BEGIN(initimpl)\n\ninline void no_nullptr(void *ptr) {\n    if (!ptr) {\n        throw type_error(\"pybind11::init(): factory function returned nullptr\");\n    }\n}\n\n// Implementing functions for all forms of py::init<...> and py::init(...)\ntemplate <typename Class>\nusing Cpp = typename Class::type;\ntemplate <typename Class>\nusing Alias = typename Class::type_alias;\ntemplate <typename Class>\nusing Holder = typename Class::holder_type;\n\ntemplate <typename Class>\nusing is_alias_constructible = std::is_constructible<Alias<Class>, Cpp<Class> &&>;\n\n// Takes a Cpp pointer and returns true if it actually is a polymorphic Alias instance.\ntemplate <typename Class, enable_if_t<Class::has_alias, int> = 0>\nbool is_alias(Cpp<Class> *ptr) {\n    return dynamic_cast<Alias<Class> *>(ptr) != nullptr;\n}\n// Failing fallback version of the above for a no-alias class (always returns false)\ntemplate <typename /*Class*/>\nconstexpr bool is_alias(void *) {\n    return false;\n}\n\n// Constructs and returns a new object; if the given arguments don't map to a constructor, we fall\n// back to brace aggregate initiailization so that for aggregate initialization can be used with\n// py::init, e.g.  `py::init<int, int>` to initialize a `struct T { int a; int b; }`.  For\n// non-aggregate types, we need to use an ordinary T(...) constructor (invoking as `T{...}` usually\n// works, but will not do the expected thing when `T` has an `initializer_list<T>` constructor).\ntemplate <typename Class,\n          typename... Args,\n          detail::enable_if_t<std::is_constructible<Class, Args...>::value, int> = 0>\ninline Class *construct_or_initialize(Args &&...args) {\n    return new Class(std::forward<Args>(args)...);\n}\ntemplate <typename Class,\n          typename... Args,\n          detail::enable_if_t<!std::is_constructible<Class, Args...>::value, int> = 0>\ninline Class *construct_or_initialize(Args &&...args) {\n    return new Class{std::forward<Args>(args)...};\n}\n\n// Attempts to constructs an alias using a `Alias(Cpp &&)` constructor.  This allows types with\n// an alias to provide only a single Cpp factory function as long as the Alias can be\n// constructed from an rvalue reference of the base Cpp type.  This means that Alias classes\n// can, when appropriate, simply define a `Alias(Cpp &&)` constructor rather than needing to\n// inherit all the base class constructors.\ntemplate <typename Class>\nvoid construct_alias_from_cpp(std::true_type /*is_alias_constructible*/,\n                              value_and_holder &v_h,\n                              Cpp<Class> &&base) {\n    v_h.value_ptr() = new Alias<Class>(std::move(base));\n}\ntemplate <typename Class>\n[[noreturn]] void construct_alias_from_cpp(std::false_type /*!is_alias_constructible*/,\n                                           value_and_holder &,\n                                           Cpp<Class> &&) {\n    throw type_error(\"pybind11::init(): unable to convert returned instance to required \"\n                     \"alias class: no `Alias<Class>(Class &&)` constructor available\");\n}\n\n// Error-generating fallback for factories that don't match one of the below construction\n// mechanisms.\ntemplate <typename Class>\nvoid construct(...) {\n    static_assert(!std::is_same<Class, Class>::value /* always false */,\n                  \"pybind11::init(): init function must return a compatible pointer, \"\n                  \"holder, or value\");\n}\n\n// Pointer return v1: the factory function returns a class pointer for a registered class.\n// If we don't need an alias (because this class doesn't have one, or because the final type is\n// inherited on the Python side) we can simply take over ownership.  Otherwise we need to try to\n// construct an Alias from the returned base instance.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Cpp<Class> *ptr, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    no_nullptr(ptr);\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {\n        // We're going to try to construct an alias by moving the cpp type.  Whether or not\n        // that succeeds, we still need to destroy the original cpp pointer (either the\n        // moved away leftover, if the alias construction works, or the value itself if we\n        // throw an error), but we can't just call `delete ptr`: it might have a special\n        // deleter, or might be shared_from_this.  So we construct a holder around it as if\n        // it was a normal instance, then steal the holder away into a local variable; thus\n        // the holder and destruction happens when we leave the C++ scope, and the holder\n        // class gets to handle the destruction however it likes.\n        v_h.value_ptr() = ptr;\n        v_h.set_instance_registered(true);          // To prevent init_instance from registering it\n        v_h.type->init_instance(v_h.inst, nullptr); // Set up the holder\n        Holder<Class> temp_holder(std::move(v_h.holder<Holder<Class>>())); // Steal the holder\n        v_h.type->dealloc(v_h); // Destroys the moved-out holder remains, resets value ptr to null\n        v_h.set_instance_registered(false);\n\n        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(*ptr));\n    } else {\n        // Otherwise the type isn't inherited, so we don't need an Alias\n        v_h.value_ptr() = ptr;\n    }\n}\n\n// Pointer return v2: a factory that always returns an alias instance ptr.  We simply take over\n// ownership of the pointer.\ntemplate <typename Class, enable_if_t<Class::has_alias, int> = 0>\nvoid construct(value_and_holder &v_h, Alias<Class> *alias_ptr, bool) {\n    no_nullptr(alias_ptr);\n    v_h.value_ptr() = static_cast<Cpp<Class> *>(alias_ptr);\n}\n\n// Holder return: copy its pointer, and move or copy the returned holder into the new instance's\n// holder.  This also handles types like std::shared_ptr<T> and std::unique_ptr<T> where T is a\n// derived type (through those holder's implicit conversion from derived class holder\n// constructors).\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Holder<Class> holder, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    auto *ptr = holder_helper<Holder<Class>>::get(holder);\n    no_nullptr(ptr);\n    // If we need an alias, check that the held pointer is actually an alias instance\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias && !is_alias<Class>(ptr)) {\n        throw type_error(\"pybind11::init(): construction failed: returned holder-wrapped instance \"\n                         \"is not an alias instance\");\n    }\n\n    v_h.value_ptr() = ptr;\n    v_h.type->init_instance(v_h.inst, &holder);\n}\n\n// return-by-value version 1: returning a cpp class by value.  If the class has an alias and an\n// alias is required the alias must have an `Alias(Cpp &&)` constructor so that we can construct\n// the alias from the base when needed (i.e. because of Python-side inheritance).  When we don't\n// need it, we simply move-construct the cpp value into a new instance.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Cpp<Class> &&result, bool need_alias) {\n    PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(need_alias);\n    static_assert(std::is_move_constructible<Cpp<Class>>::value,\n                  \"pybind11::init() return-by-value factory function requires a movable class\");\n    if (PYBIND11_SILENCE_MSVC_C4127(Class::has_alias) && need_alias) {\n        construct_alias_from_cpp<Class>(is_alias_constructible<Class>{}, v_h, std::move(result));\n    } else {\n        v_h.value_ptr() = new Cpp<Class>(std::move(result));\n    }\n}\n\n// return-by-value version 2: returning a value of the alias type itself.  We move-construct an\n// Alias instance (even if no the python-side inheritance is involved).  The is intended for\n// cases where Alias initialization is always desired.\ntemplate <typename Class>\nvoid construct(value_and_holder &v_h, Alias<Class> &&result, bool) {\n    static_assert(\n        std::is_move_constructible<Alias<Class>>::value,\n        \"pybind11::init() return-by-alias-value factory function requires a movable alias class\");\n    v_h.value_ptr() = new Alias<Class>(std::move(result));\n}\n\n// Implementing class for py::init<...>()\ntemplate <typename... Args>\nstruct constructor {\n    template <typename Class, typename... Extra, enable_if_t<!Class::has_alias, int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr() = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && std::is_constructible<Cpp<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                if (Py_TYPE(v_h.inst) == v_h.type->type) {\n                    v_h.value_ptr()\n                        = construct_or_initialize<Cpp<Class>>(std::forward<Args>(args)...);\n                } else {\n                    v_h.value_ptr()\n                        = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n                }\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && !std::is_constructible<Cpp<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr()\n                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Implementing class for py::init_alias<...>()\ntemplate <typename... Args>\nstruct alias_constructor {\n    template <typename Class,\n              typename... Extra,\n              enable_if_t<Class::has_alias && std::is_constructible<Alias<Class>, Args...>::value,\n                          int> = 0>\n    static void execute(Class &cl, const Extra &...extra) {\n        cl.def(\n            \"__init__\",\n            [](value_and_holder &v_h, Args... args) {\n                v_h.value_ptr()\n                    = construct_or_initialize<Alias<Class>>(std::forward<Args>(args)...);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Implementation class for py::init(Func) and py::init(Func, AliasFunc)\ntemplate <typename CFunc,\n          typename AFunc = void_type (*)(),\n          typename = function_signature_t<CFunc>,\n          typename = function_signature_t<AFunc>>\nstruct factory;\n\n// Specialization for py::init(Func)\ntemplate <typename Func, typename Return, typename... Args>\nstruct factory<Func, void_type (*)(), Return(Args...)> {\n    remove_reference_t<Func> class_factory;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    factory(Func &&f) : class_factory(std::forward<Func>(f)) {}\n\n    // The given class either has no alias or has no separate alias factory;\n    // this always constructs the class itself.  If the class is registered with an alias\n    // type and an alias instance is needed (i.e. because the final type is a Python class\n    // inheriting from the C++ type) the returned value needs to either already be an alias\n    // instance, or the alias needs to be constructible from a `Class &&` argument.\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__init__\",\n            [func = std::move(class_factory)]\n#else\n        auto &func = class_factory;\n        cl.def(\n            \"__init__\",\n            [func]\n#endif\n            (value_and_holder &v_h, Args... args) {\n                construct<Class>(\n                    v_h, func(std::forward<Args>(args)...), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n// Specialization for py::init(Func, AliasFunc)\ntemplate <typename CFunc,\n          typename AFunc,\n          typename CReturn,\n          typename... CArgs,\n          typename AReturn,\n          typename... AArgs>\nstruct factory<CFunc, AFunc, CReturn(CArgs...), AReturn(AArgs...)> {\n    static_assert(sizeof...(CArgs) == sizeof...(AArgs),\n                  \"pybind11::init(class_factory, alias_factory): class and alias factories \"\n                  \"must have identical argument signatures\");\n    static_assert(all_of<std::is_same<CArgs, AArgs>...>::value,\n                  \"pybind11::init(class_factory, alias_factory): class and alias factories \"\n                  \"must have identical argument signatures\");\n\n    remove_reference_t<CFunc> class_factory;\n    remove_reference_t<AFunc> alias_factory;\n\n    factory(CFunc &&c, AFunc &&a)\n        : class_factory(std::forward<CFunc>(c)), alias_factory(std::forward<AFunc>(a)) {}\n\n    // The class factory is called when the `self` type passed to `__init__` is the direct\n    // class (i.e. not inherited), the alias factory when `self` is a Python-side subtype.\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n        static_assert(Class::has_alias,\n                      \"The two-argument version of `py::init()` can \"\n                      \"only be used if the class has an alias\");\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__init__\",\n            [class_func = std::move(class_factory), alias_func = std::move(alias_factory)]\n#else\n        auto &class_func = class_factory;\n        auto &alias_func = alias_factory;\n        cl.def(\n            \"__init__\",\n            [class_func, alias_func]\n#endif\n            (value_and_holder &v_h, CArgs... args) {\n                if (Py_TYPE(v_h.inst) == v_h.type->type) {\n                    // If the instance type equals the registered type we don't have inheritance,\n                    // so don't need the alias and can construct using the class function:\n                    construct<Class>(v_h, class_func(std::forward<CArgs>(args)...), false);\n                } else {\n                    construct<Class>(v_h, alias_func(std::forward<CArgs>(args)...), true);\n                }\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\n/// Set just the C++ state. Same as `__init__`.\ntemplate <typename Class, typename T>\nvoid setstate(value_and_holder &v_h, T &&result, bool need_alias) {\n    construct<Class>(v_h, std::forward<T>(result), need_alias);\n}\n\n/// Set both the C++ and Python states\ntemplate <typename Class,\n          typename T,\n          typename O,\n          enable_if_t<std::is_convertible<O, handle>::value, int> = 0>\nvoid setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias) {\n    construct<Class>(v_h, std::move(result.first), need_alias);\n    auto d = handle(result.second);\n    if (PyDict_Check(d.ptr()) && PyDict_Size(d.ptr()) == 0) {\n        // Skipping setattr below, to not force use of py::dynamic_attr() for Class unnecessarily.\n        // See PR #2972 for details.\n        return;\n    }\n    setattr((PyObject *) v_h.inst, \"__dict__\", d);\n}\n\n/// Implementation for py::pickle(GetState, SetState)\ntemplate <typename Get,\n          typename Set,\n          typename = function_signature_t<Get>,\n          typename = function_signature_t<Set>>\nstruct pickle_factory;\n\ntemplate <typename Get,\n          typename Set,\n          typename RetState,\n          typename Self,\n          typename NewInstance,\n          typename ArgState>\nstruct pickle_factory<Get, Set, RetState(Self), NewInstance(ArgState)> {\n    static_assert(std::is_same<intrinsic_t<RetState>, intrinsic_t<ArgState>>::value,\n                  \"The type returned by `__getstate__` must be the same \"\n                  \"as the argument accepted by `__setstate__`\");\n\n    remove_reference_t<Get> get;\n    remove_reference_t<Set> set;\n\n    pickle_factory(Get get, Set set) : get(std::forward<Get>(get)), set(std::forward<Set>(set)) {}\n\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) && {\n        cl.def(\"__getstate__\", std::move(get));\n\n#if defined(PYBIND11_CPP14)\n        cl.def(\n            \"__setstate__\",\n            [func = std::move(set)]\n#else\n        auto &func = set;\n        cl.def(\n            \"__setstate__\",\n            [func]\n#endif\n            (value_and_holder &v_h, ArgState state) {\n                setstate<Class>(\n                    v_h, func(std::forward<ArgState>(state)), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            is_new_style_constructor(),\n            extra...);\n    }\n};\n\nPYBIND11_NAMESPACE_END(initimpl)\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/internals.h",
    "content": "/*\n    pybind11/detail/internals.h: Internal data structure and related functions\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../pytypes.h\"\n\n#include <exception>\n\n/// Tracks the `internals` and `type_info` ABI version independent of the main library version.\n///\n/// Some portions of the code use an ABI that is conditional depending on this\n/// version number.  That allows ABI-breaking changes to be \"pre-implemented\".\n/// Once the default version number is incremented, the conditional logic that\n/// no longer applies can be removed.  Additionally, users that need not\n/// maintain ABI compatibility can increase the version number in order to take\n/// advantage of any functionality/efficiency improvements that depend on the\n/// newer ABI.\n///\n/// WARNING: If you choose to manually increase the ABI version, note that\n/// pybind11 may not be tested as thoroughly with a non-default ABI version, and\n/// further ABI-incompatible changes may be made before the ABI is officially\n/// changed to the new version.\n#ifndef PYBIND11_INTERNALS_VERSION\n#    define PYBIND11_INTERNALS_VERSION 4\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nusing ExceptionTranslator = void (*)(std::exception_ptr);\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Forward declarations\ninline PyTypeObject *make_static_property_type();\ninline PyTypeObject *make_default_metaclass();\ninline PyObject *make_object_base_type(PyTypeObject *metaclass);\n\n// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new\n// Thread Specific Storage (TSS) API.\n#if PY_VERSION_HEX >= 0x03070000\n// Avoid unnecessary allocation of `Py_tss_t`, since we cannot use\n// `Py_LIMITED_API` anyway.\n#    if PYBIND11_INTERNALS_VERSION > 4\n#        define PYBIND11_TLS_KEY_REF Py_tss_t &\n#        ifdef __GNUC__\n// Clang on macOS warns due to `Py_tss_NEEDS_INIT` not specifying an initializer\n// for every field.\n#            define PYBIND11_TLS_KEY_INIT(var)                                                    \\\n                _Pragma(\"GCC diagnostic push\")                                         /**/       \\\n                    _Pragma(\"GCC diagnostic ignored \\\"-Wmissing-field-initializers\\\"\") /**/       \\\n                    Py_tss_t var                                                                  \\\n                    = Py_tss_NEEDS_INIT;                                                          \\\n                _Pragma(\"GCC diagnostic pop\")\n#        else\n#            define PYBIND11_TLS_KEY_INIT(var) Py_tss_t var = Py_tss_NEEDS_INIT;\n#        endif\n#        define PYBIND11_TLS_KEY_CREATE(var) (PyThread_tss_create(&(var)) == 0)\n#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get(&(key))\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set(&(key), (value))\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set(&(key), nullptr)\n#        define PYBIND11_TLS_FREE(key) PyThread_tss_delete(&(key))\n#    else\n#        define PYBIND11_TLS_KEY_REF Py_tss_t *\n#        define PYBIND11_TLS_KEY_INIT(var) Py_tss_t *var = nullptr;\n#        define PYBIND11_TLS_KEY_CREATE(var)                                                      \\\n            (((var) = PyThread_tss_alloc()) != nullptr && (PyThread_tss_create((var)) == 0))\n#        define PYBIND11_TLS_GET_VALUE(key) PyThread_tss_get((key))\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_tss_set((key), (value))\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_tss_set((key), nullptr)\n#        define PYBIND11_TLS_FREE(key) PyThread_tss_free(key)\n#    endif\n#else\n// Usually an int but a long on Cygwin64 with Python 3.x\n#    define PYBIND11_TLS_KEY_REF decltype(PyThread_create_key())\n#    define PYBIND11_TLS_KEY_INIT(var) PYBIND11_TLS_KEY_REF var = 0;\n#    define PYBIND11_TLS_KEY_CREATE(var) (((var) = PyThread_create_key()) != -1)\n#    define PYBIND11_TLS_GET_VALUE(key) PyThread_get_key_value((key))\n#    if PY_MAJOR_VERSION < 3 || defined(PYPY_VERSION)\n// On CPython < 3.4 and on PyPy, `PyThread_set_key_value` strangely does not set\n// the value if it has already been set.  Instead, it must first be deleted and\n// then set again.\ninline void tls_replace_value(PYBIND11_TLS_KEY_REF key, void *value) {\n    PyThread_delete_key_value(key);\n    PyThread_set_key_value(key, value);\n}\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_delete_key_value(key)\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value)                                            \\\n            ::pybind11::detail::tls_replace_value((key), (value))\n#    else\n#        define PYBIND11_TLS_DELETE_VALUE(key) PyThread_set_key_value((key), nullptr)\n#        define PYBIND11_TLS_REPLACE_VALUE(key, value) PyThread_set_key_value((key), (value))\n#    endif\n#    define PYBIND11_TLS_FREE(key) (void) key\n#endif\n\n// Python loads modules by default with dlopen with the RTLD_LOCAL flag; under libc++ and possibly\n// other STLs, this means `typeid(A)` from one module won't equal `typeid(A)` from another module\n// even when `A` is the same, non-hidden-visibility type (e.g. from a common include).  Under\n// libstdc++, this doesn't happen: equality and the type_index hash are based on the type name,\n// which works.  If not under a known-good stl, provide our own name-based hash and equality\n// functions that use the type name.\n#if defined(__GLIBCXX__)\ninline bool same_type(const std::type_info &lhs, const std::type_info &rhs) { return lhs == rhs; }\nusing type_hash = std::hash<std::type_index>;\nusing type_equal_to = std::equal_to<std::type_index>;\n#else\ninline bool same_type(const std::type_info &lhs, const std::type_info &rhs) {\n    return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;\n}\n\nstruct type_hash {\n    size_t operator()(const std::type_index &t) const {\n        size_t hash = 5381;\n        const char *ptr = t.name();\n        while (auto c = static_cast<unsigned char>(*ptr++)) {\n            hash = (hash * 33) ^ c;\n        }\n        return hash;\n    }\n};\n\nstruct type_equal_to {\n    bool operator()(const std::type_index &lhs, const std::type_index &rhs) const {\n        return lhs.name() == rhs.name() || std::strcmp(lhs.name(), rhs.name()) == 0;\n    }\n};\n#endif\n\ntemplate <typename value_type>\nusing type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;\n\nstruct override_hash {\n    inline size_t operator()(const std::pair<const PyObject *, const char *> &v) const {\n        size_t value = std::hash<const void *>()(v.first);\n        value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value << 6) + (value >> 2);\n        return value;\n    }\n};\n\n/// Internal data structure used to track registered instances and types.\n/// Whenever binary incompatible changes are made to this structure,\n/// `PYBIND11_INTERNALS_VERSION` must be incremented.\nstruct internals {\n    // std::type_index -> pybind11's type information\n    type_map<type_info *> registered_types_cpp;\n    // PyTypeObject* -> base type_info(s)\n    std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;\n    std::unordered_multimap<const void *, instance *> registered_instances; // void * -> instance*\n    std::unordered_set<std::pair<const PyObject *, const char *>, override_hash>\n        inactive_override_cache;\n    type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;\n    std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;\n    std::forward_list<ExceptionTranslator> registered_exception_translators;\n    std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across\n                                                         // extensions\n#if PYBIND11_INTERNALS_VERSION == 4\n    std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;\n#endif\n    std::forward_list<std::string> static_strings; // Stores the std::strings backing\n                                                   // detail::c_str()\n    PyTypeObject *static_property_type;\n    PyTypeObject *default_metaclass;\n    PyObject *instance_base;\n#if defined(WITH_THREAD)\n    PYBIND11_TLS_KEY_INIT(tstate)\n#    if PYBIND11_INTERNALS_VERSION > 4\n    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n#    endif // PYBIND11_INTERNALS_VERSION > 4\n    PyInterpreterState *istate = nullptr;\n    ~internals() {\n#    if PYBIND11_INTERNALS_VERSION > 4\n        PYBIND11_TLS_FREE(loader_life_support_tls_key);\n#    endif // PYBIND11_INTERNALS_VERSION > 4\n\n        // This destructor is called *after* Py_Finalize() in finalize_interpreter().\n        // That *SHOULD BE* fine. The following details what happens when PyThread_tss_free is\n        // called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does\n        // nothing. PyThread_tss_free calls PyThread_tss_delete and PyMem_RawFree.\n        // PyThread_tss_delete just calls TlsFree (on Windows) or pthread_key_delete (on *NIX).\n        // Neither of those have anything to do with CPython internals. PyMem_RawFree *requires*\n        // that the `tstate` be allocated with the CPython allocator.\n        PYBIND11_TLS_FREE(tstate);\n    }\n#endif\n};\n\n/// Additional type information which does not fit into the PyTypeObject.\n/// Changes to this struct also require bumping `PYBIND11_INTERNALS_VERSION`.\nstruct type_info {\n    PyTypeObject *type;\n    const std::type_info *cpptype;\n    size_t type_size, type_align, holder_size_in_ptrs;\n    void *(*operator_new)(size_t);\n    void (*init_instance)(instance *, const void *);\n    void (*dealloc)(value_and_holder &v_h);\n    std::vector<PyObject *(*) (PyObject *, PyTypeObject *)> implicit_conversions;\n    std::vector<std::pair<const std::type_info *, void *(*) (void *)>> implicit_casts;\n    std::vector<bool (*)(PyObject *, void *&)> *direct_conversions;\n    buffer_info *(*get_buffer)(PyObject *, void *) = nullptr;\n    void *get_buffer_data = nullptr;\n    void *(*module_local_load)(PyObject *, const type_info *) = nullptr;\n    /* A simple type never occurs as a (direct or indirect) parent\n     * of a class that makes use of multiple inheritance.\n     * A type can be simple even if it has non-simple ancestors as long as it has no descendants.\n     */\n    bool simple_type : 1;\n    /* True if there is no multiple inheritance in this type's inheritance tree */\n    bool simple_ancestors : 1;\n    /* for base vs derived holder_type checks */\n    bool default_holder : 1;\n    /* true if this is a type registered with py::module_local */\n    bool module_local : 1;\n};\n\n/// On MSVC, debug and release builds are not ABI-compatible!\n#if defined(_MSC_VER) && defined(_DEBUG)\n#    define PYBIND11_BUILD_TYPE \"_debug\"\n#else\n#    define PYBIND11_BUILD_TYPE \"\"\n#endif\n\n/// Let's assume that different compilers are ABI-incompatible.\n/// A user can manually set this string if they know their\n/// compiler is compatible.\n#ifndef PYBIND11_COMPILER_TYPE\n#    if defined(_MSC_VER)\n#        define PYBIND11_COMPILER_TYPE \"_msvc\"\n#    elif defined(__INTEL_COMPILER)\n#        define PYBIND11_COMPILER_TYPE \"_icc\"\n#    elif defined(__clang__)\n#        define PYBIND11_COMPILER_TYPE \"_clang\"\n#    elif defined(__PGI)\n#        define PYBIND11_COMPILER_TYPE \"_pgi\"\n#    elif defined(__MINGW32__)\n#        define PYBIND11_COMPILER_TYPE \"_mingw\"\n#    elif defined(__CYGWIN__)\n#        define PYBIND11_COMPILER_TYPE \"_gcc_cygwin\"\n#    elif defined(__GNUC__)\n#        define PYBIND11_COMPILER_TYPE \"_gcc\"\n#    else\n#        define PYBIND11_COMPILER_TYPE \"_unknown\"\n#    endif\n#endif\n\n/// Also standard libs\n#ifndef PYBIND11_STDLIB\n#    if defined(_LIBCPP_VERSION)\n#        define PYBIND11_STDLIB \"_libcpp\"\n#    elif defined(__GLIBCXX__) || defined(__GLIBCPP__)\n#        define PYBIND11_STDLIB \"_libstdcpp\"\n#    else\n#        define PYBIND11_STDLIB \"\"\n#    endif\n#endif\n\n/// On Linux/OSX, changes in __GXX_ABI_VERSION__ indicate ABI incompatibility.\n#ifndef PYBIND11_BUILD_ABI\n#    if defined(__GXX_ABI_VERSION)\n#        define PYBIND11_BUILD_ABI \"_cxxabi\" PYBIND11_TOSTRING(__GXX_ABI_VERSION)\n#    else\n#        define PYBIND11_BUILD_ABI \"\"\n#    endif\n#endif\n\n#ifndef PYBIND11_INTERNALS_KIND\n#    if defined(WITH_THREAD)\n#        define PYBIND11_INTERNALS_KIND \"\"\n#    else\n#        define PYBIND11_INTERNALS_KIND \"_without_thread\"\n#    endif\n#endif\n\n#define PYBIND11_INTERNALS_ID                                                                     \\\n    \"__pybind11_internals_v\" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                        \\\n        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \\\n            PYBIND11_BUILD_TYPE \"__\"\n\n#define PYBIND11_MODULE_LOCAL_ID                                                                  \\\n    \"__pybind11_module_local_v\" PYBIND11_TOSTRING(PYBIND11_INTERNALS_VERSION)                     \\\n        PYBIND11_INTERNALS_KIND PYBIND11_COMPILER_TYPE PYBIND11_STDLIB PYBIND11_BUILD_ABI         \\\n            PYBIND11_BUILD_TYPE \"__\"\n\n/// Each module locally stores a pointer to the `internals` data. The data\n/// itself is shared among modules with the same `PYBIND11_INTERNALS_ID`.\ninline internals **&get_internals_pp() {\n    static internals **internals_pp = nullptr;\n    return internals_pp;\n}\n\n#if PY_VERSION_HEX >= 0x03030000\n// forward decl\ninline void translate_exception(std::exception_ptr);\n\ntemplate <class T,\n          enable_if_t<std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>\nbool handle_nested_exception(const T &exc, const std::exception_ptr &p) {\n    std::exception_ptr nested = exc.nested_ptr();\n    if (nested != nullptr && nested != p) {\n        translate_exception(nested);\n        return true;\n    }\n    return false;\n}\n\ntemplate <class T,\n          enable_if_t<!std::is_same<std::nested_exception, remove_cvref_t<T>>::value, int> = 0>\nbool handle_nested_exception(const T &exc, const std::exception_ptr &p) {\n    if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(exc))) {\n        return handle_nested_exception(*nep, p);\n    }\n    return false;\n}\n\n#else\n\ntemplate <class T>\nbool handle_nested_exception(const T &, std::exception_ptr &) {\n    return false;\n}\n#endif\n\ninline bool raise_err(PyObject *exc_type, const char *msg) {\n#if PY_VERSION_HEX >= 0x03030000\n    if (PyErr_Occurred()) {\n        raise_from(exc_type, msg);\n        return true;\n    }\n#endif\n    PyErr_SetString(exc_type, msg);\n    return false;\n}\n\ninline void translate_exception(std::exception_ptr p) {\n    if (!p) {\n        return;\n    }\n    try {\n        std::rethrow_exception(p);\n    } catch (error_already_set &e) {\n        handle_nested_exception(e, p);\n        e.restore();\n        return;\n    } catch (const builtin_exception &e) {\n        // Could not use template since it's an abstract class.\n        if (const auto *nep = dynamic_cast<const std::nested_exception *>(std::addressof(e))) {\n            handle_nested_exception(*nep, p);\n        }\n        e.set_error();\n        return;\n    } catch (const std::bad_alloc &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_MemoryError, e.what());\n        return;\n    } catch (const std::domain_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::invalid_argument &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::length_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::out_of_range &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_IndexError, e.what());\n        return;\n    } catch (const std::range_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_ValueError, e.what());\n        return;\n    } catch (const std::overflow_error &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_OverflowError, e.what());\n        return;\n    } catch (const std::exception &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_RuntimeError, e.what());\n        return;\n    } catch (const std::nested_exception &e) {\n        handle_nested_exception(e, p);\n        raise_err(PyExc_RuntimeError, \"Caught an unknown nested exception!\");\n        return;\n    } catch (...) {\n        raise_err(PyExc_RuntimeError, \"Caught an unknown exception!\");\n        return;\n    }\n}\n\n#if !defined(__GLIBCXX__)\ninline void translate_local_exception(std::exception_ptr p) {\n    try {\n        if (p) {\n            std::rethrow_exception(p);\n        }\n    } catch (error_already_set &e) {\n        e.restore();\n        return;\n    } catch (const builtin_exception &e) {\n        e.set_error();\n        return;\n    }\n}\n#endif\n\n/// Return a reference to the current `internals` data\nPYBIND11_NOINLINE internals &get_internals() {\n    auto **&internals_pp = get_internals_pp();\n    if (internals_pp && *internals_pp) {\n        return **internals_pp;\n    }\n\n    // Ensure that the GIL is held since we will need to make Python calls.\n    // Cannot use py::gil_scoped_acquire here since that constructor calls get_internals.\n    struct gil_scoped_acquire_local {\n        gil_scoped_acquire_local() : state(PyGILState_Ensure()) {}\n        ~gil_scoped_acquire_local() { PyGILState_Release(state); }\n        const PyGILState_STATE state;\n    } gil;\n\n    PYBIND11_STR_TYPE id(PYBIND11_INTERNALS_ID);\n    auto builtins = handle(PyEval_GetBuiltins());\n    if (builtins.contains(id) && isinstance<capsule>(builtins[id])) {\n        internals_pp = static_cast<internals **>(capsule(builtins[id]));\n\n        // We loaded builtins through python's builtins, which means that our `error_already_set`\n        // and `builtin_exception` may be different local classes than the ones set up in the\n        // initial exception translator, below, so add another for our local exception classes.\n        //\n        // libstdc++ doesn't require this (types there are identified only by name)\n        // libc++ with CPython doesn't require this (types are explicitly exported)\n        // libc++ with PyPy still need it, awaiting further investigation\n#if !defined(__GLIBCXX__)\n        (*internals_pp)->registered_exception_translators.push_front(&translate_local_exception);\n#endif\n    } else {\n        if (!internals_pp) {\n            internals_pp = new internals *();\n        }\n        auto *&internals_ptr = *internals_pp;\n        internals_ptr = new internals();\n#if defined(WITH_THREAD)\n\n#    if PY_VERSION_HEX < 0x03090000\n        PyEval_InitThreads();\n#    endif\n        PyThreadState *tstate = PyThreadState_Get();\n        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->tstate)) {\n            pybind11_fail(\"get_internals: could not successfully initialize the tstate TSS key!\");\n        }\n        PYBIND11_TLS_REPLACE_VALUE(internals_ptr->tstate, tstate);\n\n#    if PYBIND11_INTERNALS_VERSION > 4\n        if (!PYBIND11_TLS_KEY_CREATE(internals_ptr->loader_life_support_tls_key)) {\n            pybind11_fail(\"get_internals: could not successfully initialize the \"\n                          \"loader_life_support TSS key!\");\n        }\n#    endif\n        internals_ptr->istate = tstate->interp;\n#endif\n        builtins[id] = capsule(internals_pp);\n        internals_ptr->registered_exception_translators.push_front(&translate_exception);\n        internals_ptr->static_property_type = make_static_property_type();\n        internals_ptr->default_metaclass = make_default_metaclass();\n        internals_ptr->instance_base = make_object_base_type(internals_ptr->default_metaclass);\n    }\n    return **internals_pp;\n}\n\n// the internals struct (above) is shared between all the modules. local_internals are only\n// for a single module. Any changes made to internals may require an update to\n// PYBIND11_INTERNALS_VERSION, breaking backwards compatibility. local_internals is, by design,\n// restricted to a single module. Whether a module has local internals or not should not\n// impact any other modules, because the only things accessing the local internals is the\n// module that contains them.\nstruct local_internals {\n    type_map<type_info *> registered_types_cpp;\n    std::forward_list<ExceptionTranslator> registered_exception_translators;\n#if defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4\n\n    // For ABI compatibility, we can't store the loader_life_support TLS key in\n    // the `internals` struct directly.  Instead, we store it in `shared_data` and\n    // cache a copy in `local_internals`.  If we allocated a separate TLS key for\n    // each instance of `local_internals`, we could end up allocating hundreds of\n    // TLS keys if hundreds of different pybind11 modules are loaded (which is a\n    // plausible number).\n    PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n\n    // Holds the shared TLS key for the loader_life_support stack.\n    struct shared_loader_life_support_data {\n        PYBIND11_TLS_KEY_INIT(loader_life_support_tls_key)\n        shared_loader_life_support_data() {\n            if (!PYBIND11_TLS_KEY_CREATE(loader_life_support_tls_key)) {\n                pybind11_fail(\"local_internals: could not successfully initialize the \"\n                              \"loader_life_support TLS key!\");\n            }\n        }\n        // We can't help but leak the TLS key, because Python never unloads extension modules.\n    };\n\n    local_internals() {\n        auto &internals = get_internals();\n        // Get or create the `loader_life_support_stack_key`.\n        auto &ptr = internals.shared_data[\"_life_support\"];\n        if (!ptr) {\n            ptr = new shared_loader_life_support_data;\n        }\n        loader_life_support_tls_key\n            = static_cast<shared_loader_life_support_data *>(ptr)->loader_life_support_tls_key;\n    }\n#endif //  defined(WITH_THREAD) && PYBIND11_INTERNALS_VERSION == 4\n};\n\n/// Works like `get_internals`, but for things which are locally registered.\ninline local_internals &get_local_internals() {\n    static local_internals locals;\n    return locals;\n}\n\n/// Constructs a std::string with the given arguments, stores it in `internals`, and returns its\n/// `c_str()`.  Such strings objects have a long storage duration -- the internal strings are only\n/// cleared when the program exits or after interpreter shutdown (when embedding), and so are\n/// suitable for c-style strings needed by Python internals (such as PyTypeObject's tp_name).\ntemplate <typename... Args>\nconst char *c_str(Args &&...args) {\n    auto &strings = get_internals().static_strings;\n    strings.emplace_front(std::forward<Args>(args)...);\n    return strings.front().c_str();\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Returns a named pointer that is shared among all extension modules (using the same\n/// pybind11 version) running in the current interpreter. Names starting with underscores\n/// are reserved for internal usage. Returns `nullptr` if no matching entry was found.\nPYBIND11_NOINLINE void *get_shared_data(const std::string &name) {\n    auto &internals = detail::get_internals();\n    auto it = internals.shared_data.find(name);\n    return it != internals.shared_data.end() ? it->second : nullptr;\n}\n\n/// Set the shared data that can be later recovered by `get_shared_data()`.\nPYBIND11_NOINLINE void *set_shared_data(const std::string &name, void *data) {\n    detail::get_internals().shared_data[name] = data;\n    return data;\n}\n\n/// Returns a typed reference to a shared data entry (by using `get_shared_data()`) if\n/// such entry exists. Otherwise, a new object of default-constructible type `T` is\n/// added to the shared data under the given name and a reference to it is returned.\ntemplate <typename T>\nT &get_or_create_shared_data(const std::string &name) {\n    auto &internals = detail::get_internals();\n    auto it = internals.shared_data.find(name);\n    T *ptr = (T *) (it != internals.shared_data.end() ? it->second : nullptr);\n    if (!ptr) {\n        ptr = new T();\n        internals.shared_data[name] = ptr;\n    }\n    return *ptr;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/type_caster_base.h",
    "content": "/*\n    pybind11/detail/type_caster_base.h (originally first part of pybind11/cast.h)\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"../pytypes.h\"\n#include \"common.h\"\n#include \"descr.h\"\n#include \"internals.h\"\n#include \"typeid.h\"\n\n#include <cstdint>\n#include <iterator>\n#include <new>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <typeinfo>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// A life support system for temporary objects created by `type_caster::load()`.\n/// Adding a patient will keep it alive up until the enclosing function returns.\nclass loader_life_support {\nprivate:\n    loader_life_support *parent = nullptr;\n    std::unordered_set<PyObject *> keep_alive;\n\n#if defined(WITH_THREAD)\n    // Store stack pointer in thread-local storage.\n    static PYBIND11_TLS_KEY_REF get_stack_tls_key() {\n#    if PYBIND11_INTERNALS_VERSION == 4\n        return get_local_internals().loader_life_support_tls_key;\n#    else\n        return get_internals().loader_life_support_tls_key;\n#    endif\n    }\n    static loader_life_support *get_stack_top() {\n        return static_cast<loader_life_support *>(PYBIND11_TLS_GET_VALUE(get_stack_tls_key()));\n    }\n    static void set_stack_top(loader_life_support *value) {\n        PYBIND11_TLS_REPLACE_VALUE(get_stack_tls_key(), value);\n    }\n#else\n    // Use single global variable for stack.\n    static loader_life_support **get_stack_pp() {\n        static loader_life_support *global_stack = nullptr;\n        return global_stack;\n    }\n    static loader_life_support *get_stack_top() { return *get_stack_pp(); }\n    static void set_stack_top(loader_life_support *value) { *get_stack_pp() = value; }\n#endif\n\npublic:\n    /// A new patient frame is created when a function is entered\n    loader_life_support() : parent{get_stack_top()} { set_stack_top(this); }\n\n    /// ... and destroyed after it returns\n    ~loader_life_support() {\n        if (get_stack_top() != this) {\n            pybind11_fail(\"loader_life_support: internal error\");\n        }\n        set_stack_top(parent);\n        for (auto *item : keep_alive) {\n            Py_DECREF(item);\n        }\n    }\n\n    /// This can only be used inside a pybind11-bound function, either by `argument_loader`\n    /// at argument preparation time or by `py::cast()` at execution time.\n    PYBIND11_NOINLINE static void add_patient(handle h) {\n        loader_life_support *frame = get_stack_top();\n        if (!frame) {\n            // NOTE: It would be nice to include the stack frames here, as this indicates\n            // use of pybind11::cast<> outside the normal call framework, finding such\n            // a location is challenging. Developers could consider printing out\n            // stack frame addresses here using something like __builtin_frame_address(0)\n            throw cast_error(\"When called outside a bound function, py::cast() cannot \"\n                             \"do Python -> C++ conversions which require the creation \"\n                             \"of temporary values\");\n        }\n\n        if (frame->keep_alive.insert(h.ptr()).second) {\n            Py_INCREF(h.ptr());\n        }\n    }\n};\n\n// Gets the cache entry for the given type, creating it if necessary.  The return value is the pair\n// returned by emplace, i.e. an iterator for the entry and a bool set to `true` if the entry was\n// just created.\ninline std::pair<decltype(internals::registered_types_py)::iterator, bool>\nall_type_info_get_cache(PyTypeObject *type);\n\n// Populates a just-created cache entry.\nPYBIND11_NOINLINE void all_type_info_populate(PyTypeObject *t, std::vector<type_info *> &bases) {\n    std::vector<PyTypeObject *> check;\n    for (handle parent : reinterpret_borrow<tuple>(t->tp_bases)) {\n        check.push_back((PyTypeObject *) parent.ptr());\n    }\n\n    auto const &type_dict = get_internals().registered_types_py;\n    for (size_t i = 0; i < check.size(); i++) {\n        auto *type = check[i];\n        // Ignore Python2 old-style class super type:\n        if (!PyType_Check((PyObject *) type)) {\n            continue;\n        }\n\n        // Check `type` in the current set of registered python types:\n        auto it = type_dict.find(type);\n        if (it != type_dict.end()) {\n            // We found a cache entry for it, so it's either pybind-registered or has pre-computed\n            // pybind bases, but we have to make sure we haven't already seen the type(s) before:\n            // we want to follow Python/virtual C++ rules that there should only be one instance of\n            // a common base.\n            for (auto *tinfo : it->second) {\n                // NB: Could use a second set here, rather than doing a linear search, but since\n                // having a large number of immediate pybind11-registered types seems fairly\n                // unlikely, that probably isn't worthwhile.\n                bool found = false;\n                for (auto *known : bases) {\n                    if (known == tinfo) {\n                        found = true;\n                        break;\n                    }\n                }\n                if (!found) {\n                    bases.push_back(tinfo);\n                }\n            }\n        } else if (type->tp_bases) {\n            // It's some python type, so keep follow its bases classes to look for one or more\n            // registered types\n            if (i + 1 == check.size()) {\n                // When we're at the end, we can pop off the current element to avoid growing\n                // `check` when adding just one base (which is typical--i.e. when there is no\n                // multiple inheritance)\n                check.pop_back();\n                i--;\n            }\n            for (handle parent : reinterpret_borrow<tuple>(type->tp_bases)) {\n                check.push_back((PyTypeObject *) parent.ptr());\n            }\n        }\n    }\n}\n\n/**\n * Extracts vector of type_info pointers of pybind-registered roots of the given Python type.  Will\n * be just 1 pybind type for the Python type of a pybind-registered class, or for any Python-side\n * derived class that uses single inheritance.  Will contain as many types as required for a Python\n * class that uses multiple inheritance to inherit (directly or indirectly) from multiple\n * pybind-registered classes.  Will be empty if neither the type nor any base classes are\n * pybind-registered.\n *\n * The value is cached for the lifetime of the Python type.\n */\ninline const std::vector<detail::type_info *> &all_type_info(PyTypeObject *type) {\n    auto ins = all_type_info_get_cache(type);\n    if (ins.second) {\n        // New cache entry: populate it\n        all_type_info_populate(type, ins.first->second);\n    }\n\n    return ins.first->second;\n}\n\n/**\n * Gets a single pybind11 type info for a python type.  Returns nullptr if neither the type nor any\n * ancestors are pybind11-registered.  Throws an exception if there are multiple bases--use\n * `all_type_info` instead if you want to support multiple bases.\n */\nPYBIND11_NOINLINE detail::type_info *get_type_info(PyTypeObject *type) {\n    const auto &bases = all_type_info(type);\n    if (bases.empty()) {\n        return nullptr;\n    }\n    if (bases.size() > 1) {\n        pybind11_fail(\n            \"pybind11::detail::get_type_info: type has multiple pybind11-registered bases\");\n    }\n    return bases.front();\n}\n\ninline detail::type_info *get_local_type_info(const std::type_index &tp) {\n    auto &locals = get_local_internals().registered_types_cpp;\n    auto it = locals.find(tp);\n    if (it != locals.end()) {\n        return it->second;\n    }\n    return nullptr;\n}\n\ninline detail::type_info *get_global_type_info(const std::type_index &tp) {\n    auto &types = get_internals().registered_types_cpp;\n    auto it = types.find(tp);\n    if (it != types.end()) {\n        return it->second;\n    }\n    return nullptr;\n}\n\n/// Return the type info for a given C++ type; on lookup failure can either throw or return\n/// nullptr.\nPYBIND11_NOINLINE detail::type_info *get_type_info(const std::type_index &tp,\n                                                   bool throw_if_missing = false) {\n    if (auto *ltype = get_local_type_info(tp)) {\n        return ltype;\n    }\n    if (auto *gtype = get_global_type_info(tp)) {\n        return gtype;\n    }\n\n    if (throw_if_missing) {\n        std::string tname = tp.name();\n        detail::clean_type_id(tname);\n        pybind11_fail(\"pybind11::detail::get_type_info: unable to find type info for \\\"\" + tname\n                      + \"\\\"\");\n    }\n    return nullptr;\n}\n\nPYBIND11_NOINLINE handle get_type_handle(const std::type_info &tp, bool throw_if_missing) {\n    detail::type_info *type_info = get_type_info(tp, throw_if_missing);\n    return handle(type_info ? ((PyObject *) type_info->type) : nullptr);\n}\n\n// Searches the inheritance graph for a registered Python instance, using all_type_info().\nPYBIND11_NOINLINE handle find_registered_python_instance(void *src,\n                                                         const detail::type_info *tinfo) {\n    auto it_instances = get_internals().registered_instances.equal_range(src);\n    for (auto it_i = it_instances.first; it_i != it_instances.second; ++it_i) {\n        for (auto *instance_type : detail::all_type_info(Py_TYPE(it_i->second))) {\n            if (instance_type && same_type(*instance_type->cpptype, *tinfo->cpptype)) {\n                return handle((PyObject *) it_i->second).inc_ref();\n            }\n        }\n    }\n    return handle();\n}\n\nstruct value_and_holder {\n    instance *inst = nullptr;\n    size_t index = 0u;\n    const detail::type_info *type = nullptr;\n    void **vh = nullptr;\n\n    // Main constructor for a found value/holder:\n    value_and_holder(instance *i, const detail::type_info *type, size_t vpos, size_t index)\n        : inst{i}, index{index}, type{type}, vh{inst->simple_layout\n                                                    ? inst->simple_value_holder\n                                                    : &inst->nonsimple.values_and_holders[vpos]} {}\n\n    // Default constructor (used to signal a value-and-holder not found by get_value_and_holder())\n    value_and_holder() = default;\n\n    // Used for past-the-end iterator\n    explicit value_and_holder(size_t index) : index{index} {}\n\n    template <typename V = void>\n    V *&value_ptr() const {\n        return reinterpret_cast<V *&>(vh[0]);\n    }\n    // True if this `value_and_holder` has a non-null value pointer\n    explicit operator bool() const { return value_ptr() != nullptr; }\n\n    template <typename H>\n    H &holder() const {\n        return reinterpret_cast<H &>(vh[1]);\n    }\n    bool holder_constructed() const {\n        return inst->simple_layout\n                   ? inst->simple_holder_constructed\n                   : (inst->nonsimple.status[index] & instance::status_holder_constructed) != 0u;\n    }\n    // NOLINTNEXTLINE(readability-make-member-function-const)\n    void set_holder_constructed(bool v = true) {\n        if (inst->simple_layout) {\n            inst->simple_holder_constructed = v;\n        } else if (v) {\n            inst->nonsimple.status[index] |= instance::status_holder_constructed;\n        } else {\n            inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_holder_constructed;\n        }\n    }\n    bool instance_registered() const {\n        return inst->simple_layout\n                   ? inst->simple_instance_registered\n                   : ((inst->nonsimple.status[index] & instance::status_instance_registered) != 0);\n    }\n    // NOLINTNEXTLINE(readability-make-member-function-const)\n    void set_instance_registered(bool v = true) {\n        if (inst->simple_layout) {\n            inst->simple_instance_registered = v;\n        } else if (v) {\n            inst->nonsimple.status[index] |= instance::status_instance_registered;\n        } else {\n            inst->nonsimple.status[index] &= (std::uint8_t) ~instance::status_instance_registered;\n        }\n    }\n};\n\n// Container for accessing and iterating over an instance's values/holders\nstruct values_and_holders {\nprivate:\n    instance *inst;\n    using type_vec = std::vector<detail::type_info *>;\n    const type_vec &tinfo;\n\npublic:\n    explicit values_and_holders(instance *inst)\n        : inst{inst}, tinfo(all_type_info(Py_TYPE(inst))) {}\n\n    struct iterator {\n    private:\n        instance *inst = nullptr;\n        const type_vec *types = nullptr;\n        value_and_holder curr;\n        friend struct values_and_holders;\n        iterator(instance *inst, const type_vec *tinfo)\n            : inst{inst}, types{tinfo},\n              curr(inst /* instance */,\n                   types->empty() ? nullptr : (*types)[0] /* type info */,\n                   0, /* vpos: (non-simple types only): the first vptr comes first */\n                   0 /* index */) {}\n        // Past-the-end iterator:\n        explicit iterator(size_t end) : curr(end) {}\n\n    public:\n        bool operator==(const iterator &other) const { return curr.index == other.curr.index; }\n        bool operator!=(const iterator &other) const { return curr.index != other.curr.index; }\n        iterator &operator++() {\n            if (!inst->simple_layout) {\n                curr.vh += 1 + (*types)[curr.index]->holder_size_in_ptrs;\n            }\n            ++curr.index;\n            curr.type = curr.index < types->size() ? (*types)[curr.index] : nullptr;\n            return *this;\n        }\n        value_and_holder &operator*() { return curr; }\n        value_and_holder *operator->() { return &curr; }\n    };\n\n    iterator begin() { return iterator(inst, &tinfo); }\n    iterator end() { return iterator(tinfo.size()); }\n\n    iterator find(const type_info *find_type) {\n        auto it = begin(), endit = end();\n        while (it != endit && it->type != find_type) {\n            ++it;\n        }\n        return it;\n    }\n\n    size_t size() { return tinfo.size(); }\n};\n\n/**\n * Extracts C++ value and holder pointer references from an instance (which may contain multiple\n * values/holders for python-side multiple inheritance) that match the given type.  Throws an error\n * if the given type (or ValueType, if omitted) is not a pybind11 base of the given instance.  If\n * `find_type` is omitted (or explicitly specified as nullptr) the first value/holder are returned,\n * regardless of type (and the resulting .type will be nullptr).\n *\n * The returned object should be short-lived: in particular, it must not outlive the called-upon\n * instance.\n */\nPYBIND11_NOINLINE value_and_holder\ninstance::get_value_and_holder(const type_info *find_type /*= nullptr default in common.h*/,\n                               bool throw_if_missing /*= true in common.h*/) {\n    // Optimize common case:\n    if (!find_type || Py_TYPE(this) == find_type->type) {\n        return value_and_holder(this, find_type, 0, 0);\n    }\n\n    detail::values_and_holders vhs(this);\n    auto it = vhs.find(find_type);\n    if (it != vhs.end()) {\n        return *it;\n    }\n\n    if (!throw_if_missing) {\n        return value_and_holder();\n    }\n\n#if defined(NDEBUG)\n    pybind11_fail(\"pybind11::detail::instance::get_value_and_holder: \"\n                  \"type is not a pybind11 base of the given instance \"\n                  \"(compile in debug mode for type details)\");\n#else\n    pybind11_fail(\"pybind11::detail::instance::get_value_and_holder: `\"\n                  + get_fully_qualified_tp_name(find_type->type)\n                  + \"' is not a pybind11 base of the given `\"\n                  + get_fully_qualified_tp_name(Py_TYPE(this)) + \"' instance\");\n#endif\n}\n\nPYBIND11_NOINLINE void instance::allocate_layout() {\n    const auto &tinfo = all_type_info(Py_TYPE(this));\n\n    const size_t n_types = tinfo.size();\n\n    if (n_types == 0) {\n        pybind11_fail(\n            \"instance allocation failed: new instance has no pybind11-registered base types\");\n    }\n\n    simple_layout\n        = n_types == 1 && tinfo.front()->holder_size_in_ptrs <= instance_simple_holder_in_ptrs();\n\n    // Simple path: no python-side multiple inheritance, and a small-enough holder\n    if (simple_layout) {\n        simple_value_holder[0] = nullptr;\n        simple_holder_constructed = false;\n        simple_instance_registered = false;\n    } else { // multiple base types or a too-large holder\n        // Allocate space to hold: [v1*][h1][v2*][h2]...[bb...] where [vN*] is a value pointer,\n        // [hN] is the (uninitialized) holder instance for value N, and [bb...] is a set of bool\n        // values that tracks whether each associated holder has been initialized.  Each [block] is\n        // padded, if necessary, to an integer multiple of sizeof(void *).\n        size_t space = 0;\n        for (auto *t : tinfo) {\n            space += 1;                      // value pointer\n            space += t->holder_size_in_ptrs; // holder instance\n        }\n        size_t flags_at = space;\n        space += size_in_ptrs(n_types); // status bytes (holder_constructed and\n                                        // instance_registered)\n\n        // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values,\n        // in particular, need to be 0).  Use Python's memory allocation functions: in Python 3.6\n        // they default to using pymalloc, which is designed to be efficient for small allocations\n        // like the one we're doing here; in earlier versions (and for larger allocations) they are\n        // just wrappers around malloc.\n#if PY_VERSION_HEX >= 0x03050000\n        nonsimple.values_and_holders = (void **) PyMem_Calloc(space, sizeof(void *));\n        if (!nonsimple.values_and_holders) {\n            throw std::bad_alloc();\n        }\n#else\n        nonsimple.values_and_holders = (void **) PyMem_New(void *, space);\n        if (!nonsimple.values_and_holders)\n            throw std::bad_alloc();\n        std::memset(nonsimple.values_and_holders, 0, space * sizeof(void *));\n#endif\n        nonsimple.status\n            = reinterpret_cast<std::uint8_t *>(&nonsimple.values_and_holders[flags_at]);\n    }\n    owned = true;\n}\n\n// NOLINTNEXTLINE(readability-make-member-function-const)\nPYBIND11_NOINLINE void instance::deallocate_layout() {\n    if (!simple_layout) {\n        PyMem_Free(nonsimple.values_and_holders);\n    }\n}\n\nPYBIND11_NOINLINE bool isinstance_generic(handle obj, const std::type_info &tp) {\n    handle type = detail::get_type_handle(tp, false);\n    if (!type) {\n        return false;\n    }\n    return isinstance(obj, type);\n}\n\nPYBIND11_NOINLINE std::string error_string() {\n    if (!PyErr_Occurred()) {\n        PyErr_SetString(PyExc_RuntimeError, \"Unknown internal error occurred\");\n        return \"Unknown internal error occurred\";\n    }\n\n    error_scope scope; // Preserve error state\n\n    std::string errorString;\n    if (scope.type) {\n        errorString += handle(scope.type).attr(\"__name__\").cast<std::string>();\n        errorString += \": \";\n    }\n    if (scope.value) {\n        errorString += (std::string) str(scope.value);\n    }\n\n    PyErr_NormalizeException(&scope.type, &scope.value, &scope.trace);\n\n#if PY_MAJOR_VERSION >= 3\n    if (scope.trace != nullptr) {\n        PyException_SetTraceback(scope.value, scope.trace);\n    }\n#endif\n\n#if !defined(PYPY_VERSION)\n    if (scope.trace) {\n        auto *trace = (PyTracebackObject *) scope.trace;\n\n        /* Get the deepest trace possible */\n        while (trace->tb_next) {\n            trace = trace->tb_next;\n        }\n\n        PyFrameObject *frame = trace->tb_frame;\n        Py_XINCREF(frame);\n        errorString += \"\\n\\nAt:\\n\";\n        while (frame) {\n#    if PY_VERSION_HEX >= 0x030900B1\n            PyCodeObject *f_code = PyFrame_GetCode(frame);\n#    else\n            PyCodeObject *f_code = frame->f_code;\n            Py_INCREF(f_code);\n#    endif\n            int lineno = PyFrame_GetLineNumber(frame);\n            errorString += \"  \" + handle(f_code->co_filename).cast<std::string>() + \"(\"\n                           + std::to_string(lineno)\n                           + \"): \" + handle(f_code->co_name).cast<std::string>() + \"\\n\";\n            Py_DECREF(f_code);\n#    if PY_VERSION_HEX >= 0x030900B1\n            auto *b_frame = PyFrame_GetBack(frame);\n#    else\n            auto *b_frame = frame->f_back;\n            Py_XINCREF(b_frame);\n#    endif\n            Py_DECREF(frame);\n            frame = b_frame;\n        }\n    }\n#endif\n\n    return errorString;\n}\n\nPYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_info *type) {\n    auto &instances = get_internals().registered_instances;\n    auto range = instances.equal_range(ptr);\n    for (auto it = range.first; it != range.second; ++it) {\n        for (const auto &vh : values_and_holders(it->second)) {\n            if (vh.type == type) {\n                return handle((PyObject *) it->second);\n            }\n        }\n    }\n    return handle();\n}\n\ninline PyThreadState *get_thread_state_unchecked() {\n#if defined(PYPY_VERSION)\n    return PyThreadState_GET();\n#elif PY_VERSION_HEX < 0x03000000\n    return _PyThreadState_Current;\n#elif PY_VERSION_HEX < 0x03050000\n    return (PyThreadState *) _Py_atomic_load_relaxed(&_PyThreadState_Current);\n#elif PY_VERSION_HEX < 0x03050200\n    return (PyThreadState *) _PyThreadState_Current.value;\n#else\n    return _PyThreadState_UncheckedGet();\n#endif\n}\n\n// Forward declarations\nvoid keep_alive_impl(handle nurse, handle patient);\ninline PyObject *make_new_instance(PyTypeObject *type);\n\nclass type_caster_generic {\npublic:\n    PYBIND11_NOINLINE explicit type_caster_generic(const std::type_info &type_info)\n        : typeinfo(get_type_info(type_info)), cpptype(&type_info) {}\n\n    explicit type_caster_generic(const type_info *typeinfo)\n        : typeinfo(typeinfo), cpptype(typeinfo ? typeinfo->cpptype : nullptr) {}\n\n    bool load(handle src, bool convert) { return load_impl<type_caster_generic>(src, convert); }\n\n    PYBIND11_NOINLINE static handle cast(const void *_src,\n                                         return_value_policy policy,\n                                         handle parent,\n                                         const detail::type_info *tinfo,\n                                         void *(*copy_constructor)(const void *),\n                                         void *(*move_constructor)(const void *),\n                                         const void *existing_holder = nullptr) {\n        if (!tinfo) { // no type info: error will be set already\n            return handle();\n        }\n\n        void *src = const_cast<void *>(_src);\n        if (src == nullptr) {\n            return none().release();\n        }\n\n        if (handle registered_inst = find_registered_python_instance(src, tinfo)) {\n            return registered_inst;\n        }\n\n        auto inst = reinterpret_steal<object>(make_new_instance(tinfo->type));\n        auto *wrapper = reinterpret_cast<instance *>(inst.ptr());\n        wrapper->owned = false;\n        void *&valueptr = values_and_holders(wrapper).begin()->value_ptr();\n\n        switch (policy) {\n            case return_value_policy::automatic:\n            case return_value_policy::take_ownership:\n                valueptr = src;\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::automatic_reference:\n            case return_value_policy::reference:\n                valueptr = src;\n                wrapper->owned = false;\n                break;\n\n            case return_value_policy::copy:\n                if (copy_constructor) {\n                    valueptr = copy_constructor(src);\n                } else {\n#if defined(NDEBUG)\n                    throw cast_error(\"return_value_policy = copy, but type is \"\n                                     \"non-copyable! (compile in debug mode for details)\");\n#else\n                    std::string type_name(tinfo->cpptype->name());\n                    detail::clean_type_id(type_name);\n                    throw cast_error(\"return_value_policy = copy, but type \" + type_name\n                                     + \" is non-copyable!\");\n#endif\n                }\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::move:\n                if (move_constructor) {\n                    valueptr = move_constructor(src);\n                } else if (copy_constructor) {\n                    valueptr = copy_constructor(src);\n                } else {\n#if defined(NDEBUG)\n                    throw cast_error(\"return_value_policy = move, but type is neither \"\n                                     \"movable nor copyable! \"\n                                     \"(compile in debug mode for details)\");\n#else\n                    std::string type_name(tinfo->cpptype->name());\n                    detail::clean_type_id(type_name);\n                    throw cast_error(\"return_value_policy = move, but type \" + type_name\n                                     + \" is neither movable nor copyable!\");\n#endif\n                }\n                wrapper->owned = true;\n                break;\n\n            case return_value_policy::reference_internal:\n                valueptr = src;\n                wrapper->owned = false;\n                keep_alive_impl(inst, parent);\n                break;\n\n            default:\n                throw cast_error(\"unhandled return_value_policy: should not happen!\");\n        }\n\n        tinfo->init_instance(wrapper, existing_holder);\n\n        return inst.release();\n    }\n\n    // Base methods for generic caster; there are overridden in copyable_holder_caster\n    void load_value(value_and_holder &&v_h) {\n        auto *&vptr = v_h.value_ptr();\n        // Lazy allocation for unallocated values:\n        if (vptr == nullptr) {\n            const auto *type = v_h.type ? v_h.type : typeinfo;\n            if (type->operator_new) {\n                vptr = type->operator_new(type->type_size);\n            } else {\n#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n                if (type->type_align > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {\n                    vptr = ::operator new(type->type_size, std::align_val_t(type->type_align));\n                } else {\n                    vptr = ::operator new(type->type_size);\n                }\n#else\n                vptr = ::operator new(type->type_size);\n#endif\n            }\n        }\n        value = vptr;\n    }\n    bool try_implicit_casts(handle src, bool convert) {\n        for (const auto &cast : typeinfo->implicit_casts) {\n            type_caster_generic sub_caster(*cast.first);\n            if (sub_caster.load(src, convert)) {\n                value = cast.second(sub_caster.value);\n                return true;\n            }\n        }\n        return false;\n    }\n    bool try_direct_conversions(handle src) {\n        for (auto &converter : *typeinfo->direct_conversions) {\n            if (converter(src.ptr(), value)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    void check_holder_compat() {}\n\n    PYBIND11_NOINLINE static void *local_load(PyObject *src, const type_info *ti) {\n        auto caster = type_caster_generic(ti);\n        if (caster.load(src, false)) {\n            return caster.value;\n        }\n        return nullptr;\n    }\n\n    /// Try to load with foreign typeinfo, if available. Used when there is no\n    /// native typeinfo, or when the native one wasn't able to produce a value.\n    PYBIND11_NOINLINE bool try_load_foreign_module_local(handle src) {\n        constexpr auto *local_key = PYBIND11_MODULE_LOCAL_ID;\n        const auto pytype = type::handle_of(src);\n        if (!hasattr(pytype, local_key)) {\n            return false;\n        }\n\n        type_info *foreign_typeinfo = reinterpret_borrow<capsule>(getattr(pytype, local_key));\n        // Only consider this foreign loader if actually foreign and is a loader of the correct cpp\n        // type\n        if (foreign_typeinfo->module_local_load == &local_load\n            || (cpptype && !same_type(*cpptype, *foreign_typeinfo->cpptype))) {\n            return false;\n        }\n\n        if (auto *result = foreign_typeinfo->module_local_load(src.ptr(), foreign_typeinfo)) {\n            value = result;\n            return true;\n        }\n        return false;\n    }\n\n    // Implementation of `load`; this takes the type of `this` so that it can dispatch the relevant\n    // bits of code between here and copyable_holder_caster where the two classes need different\n    // logic (without having to resort to virtual inheritance).\n    template <typename ThisT>\n    PYBIND11_NOINLINE bool load_impl(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (!typeinfo) {\n            return try_load_foreign_module_local(src);\n        }\n\n        auto &this_ = static_cast<ThisT &>(*this);\n        this_.check_holder_compat();\n\n        PyTypeObject *srctype = Py_TYPE(src.ptr());\n\n        // Case 1: If src is an exact type match for the target type then we can reinterpret_cast\n        // the instance's value pointer to the target type:\n        if (srctype == typeinfo->type) {\n            this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());\n            return true;\n        }\n        // Case 2: We have a derived class\n        if (PyType_IsSubtype(srctype, typeinfo->type)) {\n            const auto &bases = all_type_info(srctype);\n            bool no_cpp_mi = typeinfo->simple_type;\n\n            // Case 2a: the python type is a Python-inherited derived class that inherits from just\n            // one simple (no MI) pybind11 class, or is an exact match, so the C++ instance is of\n            // the right type and we can use reinterpret_cast.\n            // (This is essentially the same as case 2b, but because not using multiple inheritance\n            // is extremely common, we handle it specially to avoid the loop iterator and type\n            // pointer lookup overhead)\n            if (bases.size() == 1 && (no_cpp_mi || bases.front()->type == typeinfo->type)) {\n                this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder());\n                return true;\n            }\n            // Case 2b: the python type inherits from multiple C++ bases.  Check the bases to see\n            // if we can find an exact match (or, for a simple C++ type, an inherited match); if\n            // so, we can safely reinterpret_cast to the relevant pointer.\n            if (bases.size() > 1) {\n                for (auto *base : bases) {\n                    if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type)\n                                  : base->type == typeinfo->type) {\n                        this_.load_value(\n                            reinterpret_cast<instance *>(src.ptr())->get_value_and_holder(base));\n                        return true;\n                    }\n                }\n            }\n\n            // Case 2c: C++ multiple inheritance is involved and we couldn't find an exact type\n            // match in the registered bases, above, so try implicit casting (needed for proper C++\n            // casting when MI is involved).\n            if (this_.try_implicit_casts(src, convert)) {\n                return true;\n            }\n        }\n\n        // Perform an implicit conversion\n        if (convert) {\n            for (const auto &converter : typeinfo->implicit_conversions) {\n                auto temp = reinterpret_steal<object>(converter(src.ptr(), typeinfo->type));\n                if (load_impl<ThisT>(temp, false)) {\n                    loader_life_support::add_patient(temp);\n                    return true;\n                }\n            }\n            if (this_.try_direct_conversions(src)) {\n                return true;\n            }\n        }\n\n        // Failed to match local typeinfo. Try again with global.\n        if (typeinfo->module_local) {\n            if (auto *gtype = get_global_type_info(*typeinfo->cpptype)) {\n                typeinfo = gtype;\n                return load(src, false);\n            }\n        }\n\n        // Global typeinfo has precedence over foreign module_local\n        if (try_load_foreign_module_local(src)) {\n            return true;\n        }\n\n        // Custom converters didn't take None, now we convert None to nullptr.\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            value = nullptr;\n            return true;\n        }\n\n        return false;\n    }\n\n    // Called to do type lookup and wrap the pointer and type in a pair when a dynamic_cast\n    // isn't needed or can't be used.  If the type is unknown, sets the error and returns a pair\n    // with .second = nullptr.  (p.first = nullptr is not an error: it becomes None).\n    PYBIND11_NOINLINE static std::pair<const void *, const type_info *>\n    src_and_type(const void *src,\n                 const std::type_info &cast_type,\n                 const std::type_info *rtti_type = nullptr) {\n        if (auto *tpi = get_type_info(cast_type)) {\n            return {src, const_cast<const type_info *>(tpi)};\n        }\n\n        // Not found, set error:\n        std::string tname = rtti_type ? rtti_type->name() : cast_type.name();\n        detail::clean_type_id(tname);\n        std::string msg = \"Unregistered type : \" + tname;\n        PyErr_SetString(PyExc_TypeError, msg.c_str());\n        return {nullptr, nullptr};\n    }\n\n    const type_info *typeinfo = nullptr;\n    const std::type_info *cpptype = nullptr;\n    void *value = nullptr;\n};\n\n/**\n * Determine suitable casting operator for pointer-or-lvalue-casting type casters.  The type caster\n * needs to provide `operator T*()` and `operator T&()` operators.\n *\n * If the type supports moving the value away via an `operator T&&() &&` method, it should use\n * `movable_cast_op_type` instead.\n */\ntemplate <typename T>\nusing cast_op_type = conditional_t<std::is_pointer<remove_reference_t<T>>::value,\n                                   typename std::add_pointer<intrinsic_t<T>>::type,\n                                   typename std::add_lvalue_reference<intrinsic_t<T>>::type>;\n\n/**\n * Determine suitable casting operator for a type caster with a movable value.  Such a type caster\n * needs to provide `operator T*()`, `operator T&()`, and `operator T&&() &&`.  The latter will be\n * called in appropriate contexts where the value can be moved rather than copied.\n *\n * These operator are automatically provided when using the PYBIND11_TYPE_CASTER macro.\n */\ntemplate <typename T>\nusing movable_cast_op_type\n    = conditional_t<std::is_pointer<typename std::remove_reference<T>::type>::value,\n                    typename std::add_pointer<intrinsic_t<T>>::type,\n                    conditional_t<std::is_rvalue_reference<T>::value,\n                                  typename std::add_rvalue_reference<intrinsic_t<T>>::type,\n                                  typename std::add_lvalue_reference<intrinsic_t<T>>::type>>;\n\n// std::is_copy_constructible isn't quite enough: it lets std::vector<T> (and similar) through when\n// T is non-copyable, but code containing such a copy constructor fails to actually compile.\ntemplate <typename T, typename SFINAE = void>\nstruct is_copy_constructible : std::is_copy_constructible<T> {};\n\n// Specialization for types that appear to be copy constructible but also look like stl containers\n// (we specifically check for: has `value_type` and `reference` with `reference = value_type&`): if\n// so, copy constructability depends on whether the value_type is copy constructible.\ntemplate <typename Container>\nstruct is_copy_constructible<\n    Container,\n    enable_if_t<\n        all_of<std::is_copy_constructible<Container>,\n               std::is_same<typename Container::value_type &, typename Container::reference>,\n               // Avoid infinite recursion\n               negation<std::is_same<Container, typename Container::value_type>>>::value>>\n    : is_copy_constructible<typename Container::value_type> {};\n\n// Likewise for std::pair\n// (after C++17 it is mandatory that the copy constructor not exist when the two types aren't\n// themselves copy constructible, but this can not be relied upon when T1 or T2 are themselves\n// containers).\ntemplate <typename T1, typename T2>\nstruct is_copy_constructible<std::pair<T1, T2>>\n    : all_of<is_copy_constructible<T1>, is_copy_constructible<T2>> {};\n\n// The same problems arise with std::is_copy_assignable, so we use the same workaround.\ntemplate <typename T, typename SFINAE = void>\nstruct is_copy_assignable : std::is_copy_assignable<T> {};\ntemplate <typename Container>\nstruct is_copy_assignable<Container,\n                          enable_if_t<all_of<std::is_copy_assignable<Container>,\n                                             std::is_same<typename Container::value_type &,\n                                                          typename Container::reference>>::value>>\n    : is_copy_assignable<typename Container::value_type> {};\ntemplate <typename T1, typename T2>\nstruct is_copy_assignable<std::pair<T1, T2>>\n    : all_of<is_copy_assignable<T1>, is_copy_assignable<T2>> {};\n\nPYBIND11_NAMESPACE_END(detail)\n\n// polymorphic_type_hook<itype>::get(src, tinfo) determines whether the object pointed\n// to by `src` actually is an instance of some class derived from `itype`.\n// If so, it sets `tinfo` to point to the std::type_info representing that derived\n// type, and returns a pointer to the start of the most-derived object of that type\n// (in which `src` is a subobject; this will be the same address as `src` in most\n// single inheritance cases). If not, or if `src` is nullptr, it simply returns `src`\n// and leaves `tinfo` at its default value of nullptr.\n//\n// The default polymorphic_type_hook just returns src. A specialization for polymorphic\n// types determines the runtime type of the passed object and adjusts the this-pointer\n// appropriately via dynamic_cast<void*>. This is what enables a C++ Animal* to appear\n// to Python as a Dog (if Dog inherits from Animal, Animal is polymorphic, Dog is\n// registered with pybind11, and this Animal is in fact a Dog).\n//\n// You may specialize polymorphic_type_hook yourself for types that want to appear\n// polymorphic to Python but do not use C++ RTTI. (This is a not uncommon pattern\n// in performance-sensitive applications, used most notably in LLVM.)\n//\n// polymorphic_type_hook_base allows users to specialize polymorphic_type_hook with\n// std::enable_if. User provided specializations will always have higher priority than\n// the default implementation and specialization provided in polymorphic_type_hook_base.\ntemplate <typename itype, typename SFINAE = void>\nstruct polymorphic_type_hook_base {\n    static const void *get(const itype *src, const std::type_info *&) { return src; }\n};\ntemplate <typename itype>\nstruct polymorphic_type_hook_base<itype, detail::enable_if_t<std::is_polymorphic<itype>::value>> {\n    static const void *get(const itype *src, const std::type_info *&type) {\n        type = src ? &typeid(*src) : nullptr;\n        return dynamic_cast<const void *>(src);\n    }\n};\ntemplate <typename itype, typename SFINAE = void>\nstruct polymorphic_type_hook : public polymorphic_type_hook_base<itype> {};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Generic type caster for objects stored on the heap\ntemplate <typename type>\nclass type_caster_base : public type_caster_generic {\n    using itype = intrinsic_t<type>;\n\npublic:\n    static constexpr auto name = const_name<type>();\n\n    type_caster_base() : type_caster_base(typeid(type)) {}\n    explicit type_caster_base(const std::type_info &info) : type_caster_generic(info) {}\n\n    static handle cast(const itype &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n\n    static handle cast(itype &&src, return_value_policy, handle parent) {\n        return cast(&src, return_value_policy::move, parent);\n    }\n\n    // Returns a (pointer, type_info) pair taking care of necessary type lookup for a\n    // polymorphic type (using RTTI by default, but can be overridden by specializing\n    // polymorphic_type_hook). If the instance isn't derived, returns the base version.\n    static std::pair<const void *, const type_info *> src_and_type(const itype *src) {\n        const auto &cast_type = typeid(itype);\n        const std::type_info *instance_type = nullptr;\n        const void *vsrc = polymorphic_type_hook<itype>::get(src, instance_type);\n        if (instance_type && !same_type(cast_type, *instance_type)) {\n            // This is a base pointer to a derived type. If the derived type is registered\n            // with pybind11, we want to make the full derived object available.\n            // In the typical case where itype is polymorphic, we get the correct\n            // derived pointer (which may be != base pointer) by a dynamic_cast to\n            // most derived type. If itype is not polymorphic, we won't get here\n            // except via a user-provided specialization of polymorphic_type_hook,\n            // and the user has promised that no this-pointer adjustment is\n            // required in that case, so it's OK to use static_cast.\n            if (const auto *tpi = get_type_info(*instance_type)) {\n                return {vsrc, tpi};\n            }\n        }\n        // Otherwise we have either a nullptr, an `itype` pointer, or an unknown derived pointer,\n        // so don't do a cast\n        return type_caster_generic::src_and_type(src, cast_type, instance_type);\n    }\n\n    static handle cast(const itype *src, return_value_policy policy, handle parent) {\n        auto st = src_and_type(src);\n        return type_caster_generic::cast(st.first,\n                                         policy,\n                                         parent,\n                                         st.second,\n                                         make_copy_constructor(src),\n                                         make_move_constructor(src));\n    }\n\n    static handle cast_holder(const itype *src, const void *holder) {\n        auto st = src_and_type(src);\n        return type_caster_generic::cast(st.first,\n                                         return_value_policy::take_ownership,\n                                         {},\n                                         st.second,\n                                         nullptr,\n                                         nullptr,\n                                         holder);\n    }\n\n    template <typename T>\n    using cast_op_type = detail::cast_op_type<T>;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator itype *() { return (type *) value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator itype &() {\n        if (!value) {\n            throw reference_cast_error();\n        }\n        return *((itype *) value);\n    }\n\nprotected:\n    using Constructor = void *(*) (const void *);\n\n    /* Only enabled when the types are {copy,move}-constructible *and* when the type\n       does not have a private operator new implementation. A comma operator is used in the\n       decltype argument to apply SFINAE to the public copy/move constructors.*/\n    template <typename T, typename = enable_if_t<is_copy_constructible<T>::value>>\n    static auto make_copy_constructor(const T *)\n        -> decltype(new T(std::declval<const T>()), Constructor{}) {\n        return [](const void *arg) -> void * { return new T(*reinterpret_cast<const T *>(arg)); };\n    }\n\n    template <typename T, typename = enable_if_t<std::is_move_constructible<T>::value>>\n    static auto make_move_constructor(const T *)\n        -> decltype(new T(std::declval<T &&>()), Constructor{}) {\n        return [](const void *arg) -> void * {\n            return new T(std::move(*const_cast<T *>(reinterpret_cast<const T *>(arg))));\n        };\n    }\n\n    static Constructor make_copy_constructor(...) { return nullptr; }\n    static Constructor make_move_constructor(...) { return nullptr; }\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/detail/typeid.h",
    "content": "/*\n    pybind11/detail/typeid.h: Compiler-independent access to type identifiers\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include <cstdio>\n#include <cstdlib>\n\n#if defined(__GNUG__)\n#    include <cxxabi.h>\n#endif\n\n#include \"common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n/// Erase all occurrences of a substring\ninline void erase_all(std::string &string, const std::string &search) {\n    for (size_t pos = 0;;) {\n        pos = string.find(search, pos);\n        if (pos == std::string::npos) {\n            break;\n        }\n        string.erase(pos, search.length());\n    }\n}\n\nPYBIND11_NOINLINE void clean_type_id(std::string &name) {\n#if defined(__GNUG__)\n    int status = 0;\n    std::unique_ptr<char, void (*)(void *)> res{\n        abi::__cxa_demangle(name.c_str(), nullptr, nullptr, &status), std::free};\n    if (status == 0) {\n        name = res.get();\n    }\n#else\n    detail::erase_all(name, \"class \");\n    detail::erase_all(name, \"struct \");\n    detail::erase_all(name, \"enum \");\n#endif\n    detail::erase_all(name, \"pybind11::\");\n}\nPYBIND11_NAMESPACE_END(detail)\n\n/// Return a string representation of a C++ type\ntemplate <typename T>\nstatic std::string type_id() {\n    std::string name(typeid(T).name());\n    detail::clean_type_id(name);\n    return name;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/eigen.h",
    "content": "/*\n    pybind11/eigen.h: Transparent conversion for dense and sparse Eigen matrices\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n/* HINT: To suppress warnings originating from the Eigen headers, use -isystem.\n   See also:\n       https://stackoverflow.com/questions/2579576/i-dir-vs-isystem-dir\n       https://stackoverflow.com/questions/1741816/isystem-for-ms-visual-studio-c-compiler\n*/\n\n#include \"numpy.h\"\n\n// The C4127 suppression was introduced for Eigen 3.4.0. In theory we could\n// make it version specific, or even remove it later, but considering that\n// 1. C4127 is generally far more distracting than useful for modern template code, and\n// 2. we definitely want to ignore any MSVC warnings originating from Eigen code,\n// it is probably best to keep this around indefinitely.\n#if defined(_MSC_VER)\n#    pragma warning(push)\n#    pragma warning(disable : 4127) // C4127: conditional expression is constant\n#endif\n\n#include <Eigen/Core>\n#include <Eigen/SparseCore>\n\n#if defined(_MSC_VER)\n#    pragma warning(pop)\n#endif\n\n// Eigen prior to 3.2.7 doesn't have proper move constructors--but worse, some classes get implicit\n// move constructors that break things.  We could detect this an explicitly copy, but an extra copy\n// of matrices seems highly undesirable.\nstatic_assert(EIGEN_VERSION_AT_LEAST(3, 2, 7),\n              \"Eigen support in pybind11 requires Eigen >= 3.2.7\");\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n// Provide a convenience alias for easier pass-by-ref usage with fully dynamic strides:\nusing EigenDStride = Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>;\ntemplate <typename MatrixType>\nusing EigenDRef = Eigen::Ref<MatrixType, 0, EigenDStride>;\ntemplate <typename MatrixType>\nusing EigenDMap = Eigen::Map<MatrixType, 0, EigenDStride>;\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if EIGEN_VERSION_AT_LEAST(3, 3, 0)\nusing EigenIndex = Eigen::Index;\ntemplate <typename Scalar, int Flags, typename StorageIndex>\nusing EigenMapSparseMatrix = Eigen::Map<Eigen::SparseMatrix<Scalar, Flags, StorageIndex>>;\n#else\nusing EigenIndex = EIGEN_DEFAULT_DENSE_INDEX_TYPE;\ntemplate <typename Scalar, int Flags, typename StorageIndex>\nusing EigenMapSparseMatrix = Eigen::MappedSparseMatrix<Scalar, Flags, StorageIndex>;\n#endif\n\n// Matches Eigen::Map, Eigen::Ref, blocks, etc:\ntemplate <typename T>\nusing is_eigen_dense_map = all_of<is_template_base_of<Eigen::DenseBase, T>,\n                                  std::is_base_of<Eigen::MapBase<T, Eigen::ReadOnlyAccessors>, T>>;\ntemplate <typename T>\nusing is_eigen_mutable_map = std::is_base_of<Eigen::MapBase<T, Eigen::WriteAccessors>, T>;\ntemplate <typename T>\nusing is_eigen_dense_plain\n    = all_of<negation<is_eigen_dense_map<T>>, is_template_base_of<Eigen::PlainObjectBase, T>>;\ntemplate <typename T>\nusing is_eigen_sparse = is_template_base_of<Eigen::SparseMatrixBase, T>;\n// Test for objects inheriting from EigenBase<Derived> that aren't captured by the above.  This\n// basically covers anything that can be assigned to a dense matrix but that don't have a typical\n// matrix data layout that can be copied from their .data().  For example, DiagonalMatrix and\n// SelfAdjointView fall into this category.\ntemplate <typename T>\nusing is_eigen_other\n    = all_of<is_template_base_of<Eigen::EigenBase, T>,\n             negation<any_of<is_eigen_dense_map<T>, is_eigen_dense_plain<T>, is_eigen_sparse<T>>>>;\n\n// Captures numpy/eigen conformability status (returned by EigenProps::conformable()):\ntemplate <bool EigenRowMajor>\nstruct EigenConformable {\n    bool conformable = false;\n    EigenIndex rows = 0, cols = 0;\n    EigenDStride stride{0, 0};    // Only valid if negativestrides is false!\n    bool negativestrides = false; // If true, do not use stride!\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    EigenConformable(bool fits = false) : conformable{fits} {}\n    // Matrix type:\n    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex rstride, EigenIndex cstride)\n        : conformable{true}, rows{r}, cols{c},\n          // TODO: when Eigen bug #747 is fixed, remove the tests for non-negativity.\n          // http://eigen.tuxfamily.org/bz/show_bug.cgi?id=747\n          stride{EigenRowMajor ? (rstride > 0 ? rstride : 0)\n                               : (cstride > 0 ? cstride : 0) /* outer stride */,\n                 EigenRowMajor ? (cstride > 0 ? cstride : 0)\n                               : (rstride > 0 ? rstride : 0) /* inner stride */},\n          negativestrides{rstride < 0 || cstride < 0} {}\n    // Vector type:\n    EigenConformable(EigenIndex r, EigenIndex c, EigenIndex stride)\n        : EigenConformable(r, c, r == 1 ? c * stride : stride, c == 1 ? r : r * stride) {}\n\n    template <typename props>\n    bool stride_compatible() const {\n        // To have compatible strides, we need (on both dimensions) one of fully dynamic strides,\n        // matching strides, or a dimension size of 1 (in which case the stride value is\n        // irrelevant)\n        return !negativestrides\n               && (props::inner_stride == Eigen::Dynamic || props::inner_stride == stride.inner()\n                   || (EigenRowMajor ? cols : rows) == 1)\n               && (props::outer_stride == Eigen::Dynamic || props::outer_stride == stride.outer()\n                   || (EigenRowMajor ? rows : cols) == 1);\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator bool() const { return conformable; }\n};\n\ntemplate <typename Type>\nstruct eigen_extract_stride {\n    using type = Type;\n};\ntemplate <typename PlainObjectType, int MapOptions, typename StrideType>\nstruct eigen_extract_stride<Eigen::Map<PlainObjectType, MapOptions, StrideType>> {\n    using type = StrideType;\n};\ntemplate <typename PlainObjectType, int Options, typename StrideType>\nstruct eigen_extract_stride<Eigen::Ref<PlainObjectType, Options, StrideType>> {\n    using type = StrideType;\n};\n\n// Helper struct for extracting information from an Eigen type\ntemplate <typename Type_>\nstruct EigenProps {\n    using Type = Type_;\n    using Scalar = typename Type::Scalar;\n    using StrideType = typename eigen_extract_stride<Type>::type;\n    static constexpr EigenIndex rows = Type::RowsAtCompileTime, cols = Type::ColsAtCompileTime,\n                                size = Type::SizeAtCompileTime;\n    static constexpr bool row_major = Type::IsRowMajor,\n                          vector\n                          = Type::IsVectorAtCompileTime, // At least one dimension has fixed size 1\n        fixed_rows = rows != Eigen::Dynamic, fixed_cols = cols != Eigen::Dynamic,\n                          fixed = size != Eigen::Dynamic, // Fully-fixed size\n        dynamic = !fixed_rows && !fixed_cols;             // Fully-dynamic size\n\n    template <EigenIndex i, EigenIndex ifzero>\n    using if_zero = std::integral_constant<EigenIndex, i == 0 ? ifzero : i>;\n    static constexpr EigenIndex inner_stride\n        = if_zero<StrideType::InnerStrideAtCompileTime, 1>::value,\n        outer_stride = if_zero < StrideType::OuterStrideAtCompileTime,\n        vector      ? size\n        : row_major ? cols\n                    : rows > ::value;\n    static constexpr bool dynamic_stride\n        = inner_stride == Eigen::Dynamic && outer_stride == Eigen::Dynamic;\n    static constexpr bool requires_row_major\n        = !dynamic_stride && !vector && (row_major ? inner_stride : outer_stride) == 1;\n    static constexpr bool requires_col_major\n        = !dynamic_stride && !vector && (row_major ? outer_stride : inner_stride) == 1;\n\n    // Takes an input array and determines whether we can make it fit into the Eigen type.  If\n    // the array is a vector, we attempt to fit it into either an Eigen 1xN or Nx1 vector\n    // (preferring the latter if it will fit in either, i.e. for a fully dynamic matrix type).\n    static EigenConformable<row_major> conformable(const array &a) {\n        const auto dims = a.ndim();\n        if (dims < 1 || dims > 2) {\n            return false;\n        }\n\n        if (dims == 2) { // Matrix type: require exact match (or dynamic)\n\n            EigenIndex np_rows = a.shape(0), np_cols = a.shape(1),\n                       np_rstride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar)),\n                       np_cstride = a.strides(1) / static_cast<ssize_t>(sizeof(Scalar));\n            if ((PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && np_rows != rows)\n                || (PYBIND11_SILENCE_MSVC_C4127(fixed_cols) && np_cols != cols)) {\n                return false;\n            }\n\n            return {np_rows, np_cols, np_rstride, np_cstride};\n        }\n\n        // Otherwise we're storing an n-vector.  Only one of the strides will be used, but\n        // whichever is used, we want the (single) numpy stride value.\n        const EigenIndex n = a.shape(0),\n                         stride = a.strides(0) / static_cast<ssize_t>(sizeof(Scalar));\n\n        if (vector) { // Eigen type is a compile-time vector\n            if (PYBIND11_SILENCE_MSVC_C4127(fixed) && size != n) {\n                return false; // Vector size mismatch\n            }\n            return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};\n        }\n        if (fixed) {\n            // The type has a fixed size, but is not a vector: abort\n            return false;\n        }\n        if (fixed_cols) {\n            // Since this isn't a vector, cols must be != 1.  We allow this only if it exactly\n            // equals the number of elements (rows is Dynamic, and so 1 row is allowed).\n            if (cols != n) {\n                return false;\n            }\n            return {1, n, stride};\n        } // Otherwise it's either fully dynamic, or column dynamic; both become a column vector\n        if (PYBIND11_SILENCE_MSVC_C4127(fixed_rows) && rows != n) {\n            return false;\n        }\n        return {n, 1, stride};\n    }\n\n    static constexpr bool show_writeable\n        = is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;\n    static constexpr bool show_order = is_eigen_dense_map<Type>::value;\n    static constexpr bool show_c_contiguous = show_order && requires_row_major;\n    static constexpr bool show_f_contiguous\n        = !show_c_contiguous && show_order && requires_col_major;\n\n    static constexpr auto descriptor\n        = const_name(\"numpy.ndarray[\") + npy_format_descriptor<Scalar>::name + const_name(\"[\")\n          + const_name<fixed_rows>(const_name<(size_t) rows>(), const_name(\"m\")) + const_name(\", \")\n          + const_name<fixed_cols>(const_name<(size_t) cols>(), const_name(\"n\")) + const_name(\"]\")\n          +\n          // For a reference type (e.g. Ref<MatrixXd>) we have other constraints that might need to\n          // be satisfied: writeable=True (for a mutable reference), and, depending on the map's\n          // stride options, possibly f_contiguous or c_contiguous.  We include them in the\n          // descriptor output to provide some hint as to why a TypeError is occurring (otherwise\n          // it can be confusing to see that a function accepts a 'numpy.ndarray[float64[3,2]]' and\n          // an error message that you *gave* a numpy.ndarray of the right type and dimensions.\n          const_name<show_writeable>(\", flags.writeable\", \"\")\n          + const_name<show_c_contiguous>(\", flags.c_contiguous\", \"\")\n          + const_name<show_f_contiguous>(\", flags.f_contiguous\", \"\") + const_name(\"]\");\n};\n\n// Casts an Eigen type to numpy array.  If given a base, the numpy array references the src data,\n// otherwise it'll make a copy.  writeable lets you turn off the writeable flag for the array.\ntemplate <typename props>\nhandle\neigen_array_cast(typename props::Type const &src, handle base = handle(), bool writeable = true) {\n    constexpr ssize_t elem_size = sizeof(typename props::Scalar);\n    array a;\n    if (props::vector) {\n        a = array({src.size()}, {elem_size * src.innerStride()}, src.data(), base);\n    } else {\n        a = array({src.rows(), src.cols()},\n                  {elem_size * src.rowStride(), elem_size * src.colStride()},\n                  src.data(),\n                  base);\n    }\n\n    if (!writeable) {\n        array_proxy(a.ptr())->flags &= ~detail::npy_api::NPY_ARRAY_WRITEABLE_;\n    }\n\n    return a.release();\n}\n\n// Takes an lvalue ref to some Eigen type and a (python) base object, creating a numpy array that\n// reference the Eigen object's data with `base` as the python-registered base class (if omitted,\n// the base will be set to None, and lifetime management is up to the caller).  The numpy array is\n// non-writeable if the given type is const.\ntemplate <typename props, typename Type>\nhandle eigen_ref_array(Type &src, handle parent = none()) {\n    // none here is to get past array's should-we-copy detection, which currently always\n    // copies when there is no base.  Setting the base to None should be harmless.\n    return eigen_array_cast<props>(src, parent, !std::is_const<Type>::value);\n}\n\n// Takes a pointer to some dense, plain Eigen type, builds a capsule around it, then returns a\n// numpy array that references the encapsulated data with a python-side reference to the capsule to\n// tie its destruction to that of any dependent python objects.  Const-ness is determined by\n// whether or not the Type of the pointer given is const.\ntemplate <typename props, typename Type, typename = enable_if_t<is_eigen_dense_plain<Type>::value>>\nhandle eigen_encapsulate(Type *src) {\n    capsule base(src, [](void *o) { delete static_cast<Type *>(o); });\n    return eigen_ref_array<props>(*src, base);\n}\n\n// Type caster for regular, dense matrix types (e.g. MatrixXd), but not maps/refs/etc. of dense\n// types.\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_dense_plain<Type>::value>> {\n    using Scalar = typename Type::Scalar;\n    using props = EigenProps<Type>;\n\n    bool load(handle src, bool convert) {\n        // If we're in no-convert mode, only load if given an array of the correct type\n        if (!convert && !isinstance<array_t<Scalar>>(src)) {\n            return false;\n        }\n\n        // Coerce into an array, but don't do type conversion yet; the copy below handles it.\n        auto buf = array::ensure(src);\n\n        if (!buf) {\n            return false;\n        }\n\n        auto dims = buf.ndim();\n        if (dims < 1 || dims > 2) {\n            return false;\n        }\n\n        auto fits = props::conformable(buf);\n        if (!fits) {\n            return false;\n        }\n\n        // Allocate the new type, then build a numpy reference into it\n        value = Type(fits.rows, fits.cols);\n        auto ref = reinterpret_steal<array>(eigen_ref_array<props>(value));\n        if (dims == 1) {\n            ref = ref.squeeze();\n        } else if (ref.ndim() == 1) {\n            buf = buf.squeeze();\n        }\n\n        int result = detail::npy_api::get().PyArray_CopyInto_(ref.ptr(), buf.ptr());\n\n        if (result < 0) { // Copy failed!\n            PyErr_Clear();\n            return false;\n        }\n\n        return true;\n    }\n\nprivate:\n    // Cast implementation\n    template <typename CType>\n    static handle cast_impl(CType *src, return_value_policy policy, handle parent) {\n        switch (policy) {\n            case return_value_policy::take_ownership:\n            case return_value_policy::automatic:\n                return eigen_encapsulate<props>(src);\n            case return_value_policy::move:\n                return eigen_encapsulate<props>(new CType(std::move(*src)));\n            case return_value_policy::copy:\n                return eigen_array_cast<props>(*src);\n            case return_value_policy::reference:\n            case return_value_policy::automatic_reference:\n                return eigen_ref_array<props>(*src);\n            case return_value_policy::reference_internal:\n                return eigen_ref_array<props>(*src, parent);\n            default:\n                throw cast_error(\"unhandled return_value_policy: should not happen!\");\n        };\n    }\n\npublic:\n    // Normal returned non-reference, non-const value:\n    static handle cast(Type &&src, return_value_policy /* policy */, handle parent) {\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n    // If you return a non-reference const, we mark the numpy array readonly:\n    static handle cast(const Type &&src, return_value_policy /* policy */, handle parent) {\n        return cast_impl(&src, return_value_policy::move, parent);\n    }\n    // lvalue reference return; default (automatic) becomes copy\n    static handle cast(Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast_impl(&src, policy, parent);\n    }\n    // const lvalue reference return; default (automatic) becomes copy\n    static handle cast(const Type &src, return_value_policy policy, handle parent) {\n        if (policy == return_value_policy::automatic\n            || policy == return_value_policy::automatic_reference) {\n            policy = return_value_policy::copy;\n        }\n        return cast(&src, policy, parent);\n    }\n    // non-const pointer return\n    static handle cast(Type *src, return_value_policy policy, handle parent) {\n        return cast_impl(src, policy, parent);\n    }\n    // const pointer return\n    static handle cast(const Type *src, return_value_policy policy, handle parent) {\n        return cast_impl(src, policy, parent);\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type *() { return &value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &() { return value; }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &&() && { return std::move(value); }\n    template <typename T>\n    using cast_op_type = movable_cast_op_type<T>;\n\nprivate:\n    Type value;\n};\n\n// Base class for casting reference/map/block/etc. objects back to python.\ntemplate <typename MapType>\nstruct eigen_map_caster {\nprivate:\n    using props = EigenProps<MapType>;\n\npublic:\n    // Directly referencing a ref/map's data is a bit dangerous (whatever the map/ref points to has\n    // to stay around), but we'll allow it under the assumption that you know what you're doing\n    // (and have an appropriate keep_alive in place).  We return a numpy array pointing directly at\n    // the ref's data (The numpy array ends up read-only if the ref was to a const matrix type.)\n    // Note that this means you need to ensure you don't destroy the object in some other way (e.g.\n    // with an appropriate keep_alive, or with a reference to a statically allocated matrix).\n    static handle cast(const MapType &src, return_value_policy policy, handle parent) {\n        switch (policy) {\n            case return_value_policy::copy:\n                return eigen_array_cast<props>(src);\n            case return_value_policy::reference_internal:\n                return eigen_array_cast<props>(src, parent, is_eigen_mutable_map<MapType>::value);\n            case return_value_policy::reference:\n            case return_value_policy::automatic:\n            case return_value_policy::automatic_reference:\n                return eigen_array_cast<props>(src, none(), is_eigen_mutable_map<MapType>::value);\n            default:\n                // move, take_ownership don't make any sense for a ref/map:\n                pybind11_fail(\"Invalid return_value_policy for Eigen Map/Ref/Block type\");\n        }\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return\n    // types but not bound arguments).  We still provide them (with an explicitly delete) so that\n    // you end up here if you try anyway.\n    bool load(handle, bool) = delete;\n    operator MapType() = delete;\n    template <typename>\n    using cast_op_type = MapType;\n};\n\n// We can return any map-like object (but can only load Refs, specialized next):\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_dense_map<Type>::value>> : eigen_map_caster<Type> {};\n\n// Loader for Ref<...> arguments.  See the documentation for info on how to make this work without\n// copying (it requires some extra effort in many cases).\ntemplate <typename PlainObjectType, typename StrideType>\nstruct type_caster<\n    Eigen::Ref<PlainObjectType, 0, StrideType>,\n    enable_if_t<is_eigen_dense_map<Eigen::Ref<PlainObjectType, 0, StrideType>>::value>>\n    : public eigen_map_caster<Eigen::Ref<PlainObjectType, 0, StrideType>> {\nprivate:\n    using Type = Eigen::Ref<PlainObjectType, 0, StrideType>;\n    using props = EigenProps<Type>;\n    using Scalar = typename props::Scalar;\n    using MapType = Eigen::Map<PlainObjectType, 0, StrideType>;\n    using Array\n        = array_t<Scalar,\n                  array::forcecast\n                      | ((props::row_major ? props::inner_stride : props::outer_stride) == 1\n                             ? array::c_style\n                         : (props::row_major ? props::outer_stride : props::inner_stride) == 1\n                             ? array::f_style\n                             : 0)>;\n    static constexpr bool need_writeable = is_eigen_mutable_map<Type>::value;\n    // Delay construction (these have no default constructor)\n    std::unique_ptr<MapType> map;\n    std::unique_ptr<Type> ref;\n    // Our array.  When possible, this is just a numpy array pointing to the source data, but\n    // sometimes we can't avoid copying (e.g. input is not a numpy array at all, has an\n    // incompatible layout, or is an array of a type that needs to be converted).  Using a numpy\n    // temporary (rather than an Eigen temporary) saves an extra copy when we need both type\n    // conversion and storage order conversion.  (Note that we refuse to use this temporary copy\n    // when loading an argument for a Ref<M> with M non-const, i.e. a read-write reference).\n    Array copy_or_ref;\n\npublic:\n    bool load(handle src, bool convert) {\n        // First check whether what we have is already an array of the right type.  If not, we\n        // can't avoid a copy (because the copy is also going to do type conversion).\n        bool need_copy = !isinstance<Array>(src);\n\n        EigenConformable<props::row_major> fits;\n        if (!need_copy) {\n            // We don't need a converting copy, but we also need to check whether the strides are\n            // compatible with the Ref's stride requirements\n            auto aref = reinterpret_borrow<Array>(src);\n\n            if (aref && (!need_writeable || aref.writeable())) {\n                fits = props::conformable(aref);\n                if (!fits) {\n                    return false; // Incompatible dimensions\n                }\n                if (!fits.template stride_compatible<props>()) {\n                    need_copy = true;\n                } else {\n                    copy_or_ref = std::move(aref);\n                }\n            } else {\n                need_copy = true;\n            }\n        }\n\n        if (need_copy) {\n            // We need to copy: If we need a mutable reference, or we're not supposed to convert\n            // (either because we're in the no-convert overload pass, or because we're explicitly\n            // instructed not to copy (via `py::arg().noconvert()`) we have to fail loading.\n            if (!convert || need_writeable) {\n                return false;\n            }\n\n            Array copy = Array::ensure(src);\n            if (!copy) {\n                return false;\n            }\n            fits = props::conformable(copy);\n            if (!fits || !fits.template stride_compatible<props>()) {\n                return false;\n            }\n            copy_or_ref = std::move(copy);\n            loader_life_support::add_patient(copy_or_ref);\n        }\n\n        ref.reset();\n        map.reset(new MapType(data(copy_or_ref),\n                              fits.rows,\n                              fits.cols,\n                              make_stride(fits.stride.outer(), fits.stride.inner())));\n        ref.reset(new Type(*map));\n\n        return true;\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type *() { return ref.get(); }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator Type &() { return *ref; }\n    template <typename _T>\n    using cast_op_type = pybind11::detail::cast_op_type<_T>;\n\nprivate:\n    template <typename T = Type, enable_if_t<is_eigen_mutable_map<T>::value, int> = 0>\n    Scalar *data(Array &a) {\n        return a.mutable_data();\n    }\n\n    template <typename T = Type, enable_if_t<!is_eigen_mutable_map<T>::value, int> = 0>\n    const Scalar *data(Array &a) {\n        return a.data();\n    }\n\n    // Attempt to figure out a constructor of `Stride` that will work.\n    // If both strides are fixed, use a default constructor:\n    template <typename S>\n    using stride_ctor_default = bool_constant<S::InnerStrideAtCompileTime != Eigen::Dynamic\n                                              && S::OuterStrideAtCompileTime != Eigen::Dynamic\n                                              && std::is_default_constructible<S>::value>;\n    // Otherwise, if there is a two-index constructor, assume it is (outer,inner) like\n    // Eigen::Stride, and use it:\n    template <typename S>\n    using stride_ctor_dual\n        = bool_constant<!stride_ctor_default<S>::value\n                        && std::is_constructible<S, EigenIndex, EigenIndex>::value>;\n    // Otherwise, if there is a one-index constructor, and just one of the strides is dynamic, use\n    // it (passing whichever stride is dynamic).\n    template <typename S>\n    using stride_ctor_outer\n        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value\n                        && S::OuterStrideAtCompileTime == Eigen::Dynamic\n                        && S::InnerStrideAtCompileTime != Eigen::Dynamic\n                        && std::is_constructible<S, EigenIndex>::value>;\n    template <typename S>\n    using stride_ctor_inner\n        = bool_constant<!any_of<stride_ctor_default<S>, stride_ctor_dual<S>>::value\n                        && S::InnerStrideAtCompileTime == Eigen::Dynamic\n                        && S::OuterStrideAtCompileTime != Eigen::Dynamic\n                        && std::is_constructible<S, EigenIndex>::value>;\n\n    template <typename S = StrideType, enable_if_t<stride_ctor_default<S>::value, int> = 0>\n    static S make_stride(EigenIndex, EigenIndex) {\n        return S();\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_dual<S>::value, int> = 0>\n    static S make_stride(EigenIndex outer, EigenIndex inner) {\n        return S(outer, inner);\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_outer<S>::value, int> = 0>\n    static S make_stride(EigenIndex outer, EigenIndex) {\n        return S(outer);\n    }\n    template <typename S = StrideType, enable_if_t<stride_ctor_inner<S>::value, int> = 0>\n    static S make_stride(EigenIndex, EigenIndex inner) {\n        return S(inner);\n    }\n};\n\n// type_caster for special matrix types (e.g. DiagonalMatrix), which are EigenBase, but not\n// EigenDense (i.e. they don't have a data(), at least not with the usual matrix layout).\n// load() is not supported, but we can cast them into the python domain by first copying to a\n// regular Eigen::Matrix, then casting that.\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_other<Type>::value>> {\nprotected:\n    using Matrix\n        = Eigen::Matrix<typename Type::Scalar, Type::RowsAtCompileTime, Type::ColsAtCompileTime>;\n    using props = EigenProps<Matrix>;\n\npublic:\n    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {\n        handle h = eigen_encapsulate<props>(new Matrix(src));\n        return h;\n    }\n    static handle cast(const Type *src, return_value_policy policy, handle parent) {\n        return cast(*src, policy, parent);\n    }\n\n    static constexpr auto name = props::descriptor;\n\n    // Explicitly delete these: support python -> C++ conversion on these (i.e. these can be return\n    // types but not bound arguments).  We still provide them (with an explicitly delete) so that\n    // you end up here if you try anyway.\n    bool load(handle, bool) = delete;\n    operator Type() = delete;\n    template <typename>\n    using cast_op_type = Type;\n};\n\ntemplate <typename Type>\nstruct type_caster<Type, enable_if_t<is_eigen_sparse<Type>::value>> {\n    using Scalar = typename Type::Scalar;\n    using StorageIndex = remove_reference_t<decltype(*std::declval<Type>().outerIndexPtr())>;\n    using Index = typename Type::Index;\n    static constexpr bool rowMajor = Type::IsRowMajor;\n\n    bool load(handle src, bool) {\n        if (!src) {\n            return false;\n        }\n\n        auto obj = reinterpret_borrow<object>(src);\n        object sparse_module = module_::import(\"scipy.sparse\");\n        object matrix_type = sparse_module.attr(rowMajor ? \"csr_matrix\" : \"csc_matrix\");\n\n        if (!type::handle_of(obj).is(matrix_type)) {\n            try {\n                obj = matrix_type(obj);\n            } catch (const error_already_set &) {\n                return false;\n            }\n        }\n\n        auto values = array_t<Scalar>((object) obj.attr(\"data\"));\n        auto innerIndices = array_t<StorageIndex>((object) obj.attr(\"indices\"));\n        auto outerIndices = array_t<StorageIndex>((object) obj.attr(\"indptr\"));\n        auto shape = pybind11::tuple((pybind11::object) obj.attr(\"shape\"));\n        auto nnz = obj.attr(\"nnz\").cast<Index>();\n\n        if (!values || !innerIndices || !outerIndices) {\n            return false;\n        }\n\n        value = EigenMapSparseMatrix<Scalar,\n                                     Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),\n                                     StorageIndex>(shape[0].cast<Index>(),\n                                                   shape[1].cast<Index>(),\n                                                   nnz,\n                                                   outerIndices.mutable_data(),\n                                                   innerIndices.mutable_data(),\n                                                   values.mutable_data());\n\n        return true;\n    }\n\n    static handle cast(const Type &src, return_value_policy /* policy */, handle /* parent */) {\n        const_cast<Type &>(src).makeCompressed();\n\n        object matrix_type\n            = module_::import(\"scipy.sparse\").attr(rowMajor ? \"csr_matrix\" : \"csc_matrix\");\n\n        array data(src.nonZeros(), src.valuePtr());\n        array outerIndices((rowMajor ? src.rows() : src.cols()) + 1, src.outerIndexPtr());\n        array innerIndices(src.nonZeros(), src.innerIndexPtr());\n\n        return matrix_type(std::make_tuple(data, innerIndices, outerIndices),\n                           std::make_pair(src.rows(), src.cols()))\n            .release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name<(Type::IsRowMajor) != 0>(\"scipy.sparse.csr_matrix[\",\n                                                             \"scipy.sparse.csc_matrix[\")\n                             + npy_format_descriptor<Scalar>::name + const_name(\"]\"));\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/embed.h",
    "content": "/*\n    pybind11/embed.h: Support for embedding the interpreter\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"eval.h\"\n\n#include <memory>\n#include <vector>\n\n#if defined(PYPY_VERSION)\n#    error Embedding the interpreter is not supported with PyPy\n#endif\n\n#if PY_MAJOR_VERSION >= 3\n#    define PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                   \\\n        extern \"C\" PyObject *pybind11_init_impl_##name();                                         \\\n        extern \"C\" PyObject *pybind11_init_impl_##name() { return pybind11_init_wrapper_##name(); }\n#else\n#    define PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                   \\\n        extern \"C\" void pybind11_init_impl_##name();                                              \\\n        extern \"C\" void pybind11_init_impl_##name() { pybind11_init_wrapper_##name(); }\n#endif\n\n/** \\rst\n    Add a new module to the table of builtins for the interpreter. Must be\n    defined in global scope. The first macro parameter is the name of the\n    module (without quotes). The second parameter is the variable which will\n    be used as the interface to add functions and classes to the module.\n\n    .. code-block:: cpp\n\n        PYBIND11_EMBEDDED_MODULE(example, m) {\n            // ... initialize functions and classes here\n            m.def(\"foo\", []() {\n                return \"Hello, World!\";\n            });\n        }\n \\endrst */\n#define PYBIND11_EMBEDDED_MODULE(name, variable)                                                  \\\n    static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name);           \\\n    static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &);                     \\\n    static PyObject PYBIND11_CONCAT(*pybind11_init_wrapper_, name)() {                            \\\n        auto m = ::pybind11::module_::create_extension_module(                                    \\\n            PYBIND11_TOSTRING(name), nullptr, &PYBIND11_CONCAT(pybind11_module_def_, name));      \\\n        try {                                                                                     \\\n            PYBIND11_CONCAT(pybind11_init_, name)(m);                                             \\\n            return m.ptr();                                                                       \\\n        }                                                                                         \\\n        PYBIND11_CATCH_INIT_EXCEPTIONS                                                            \\\n    }                                                                                             \\\n    PYBIND11_EMBEDDED_MODULE_IMPL(name)                                                           \\\n    ::pybind11::detail::embedded_module PYBIND11_CONCAT(pybind11_module_, name)(                  \\\n        PYBIND11_TOSTRING(name), PYBIND11_CONCAT(pybind11_init_impl_, name));                     \\\n    void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_                                \\\n                                               & variable) // NOLINT(bugprone-macro-parentheses)\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Python 2.7/3.x compatible version of `PyImport_AppendInittab` and error checks.\nstruct embedded_module {\n#if PY_MAJOR_VERSION >= 3\n    using init_t = PyObject *(*) ();\n#else\n    using init_t = void (*)();\n#endif\n    embedded_module(const char *name, init_t init) {\n        if (Py_IsInitialized() != 0) {\n            pybind11_fail(\"Can't add new modules after the interpreter has been initialized\");\n        }\n\n        auto result = PyImport_AppendInittab(name, init);\n        if (result == -1) {\n            pybind11_fail(\"Insufficient memory to add a new module\");\n        }\n    }\n};\n\nstruct wide_char_arg_deleter {\n    void operator()(wchar_t *ptr) const {\n#if PY_VERSION_HEX >= 0x030500f0\n        // API docs: https://docs.python.org/3/c-api/sys.html#c.Py_DecodeLocale\n        PyMem_RawFree(ptr);\n#else\n        delete[] ptr;\n#endif\n    }\n};\n\ninline wchar_t *widen_chars(const char *safe_arg) {\n#if PY_VERSION_HEX >= 0x030500f0\n    wchar_t *widened_arg = Py_DecodeLocale(safe_arg, nullptr);\n#else\n    wchar_t *widened_arg = nullptr;\n\n// warning C4996: 'mbstowcs': This function or variable may be unsafe.\n#    if defined(_MSC_VER)\n#        pragma warning(push)\n#        pragma warning(disable : 4996)\n#    endif\n\n#    if defined(HAVE_BROKEN_MBSTOWCS) && HAVE_BROKEN_MBSTOWCS\n    size_t count = std::strlen(safe_arg);\n#    else\n    size_t count = std::mbstowcs(nullptr, safe_arg, 0);\n#    endif\n    if (count != static_cast<size_t>(-1)) {\n        widened_arg = new wchar_t[count + 1];\n        std::mbstowcs(widened_arg, safe_arg, count + 1);\n    }\n\n#    if defined(_MSC_VER)\n#        pragma warning(pop)\n#    endif\n\n#endif\n    return widened_arg;\n}\n\n/// Python 2.x/3.x-compatible version of `PySys_SetArgv`\ninline void set_interpreter_argv(int argc, const char *const *argv, bool add_program_dir_to_path) {\n    // Before it was special-cased in python 3.8, passing an empty or null argv\n    // caused a segfault, so we have to reimplement the special case ourselves.\n    bool special_case = (argv == nullptr || argc <= 0);\n\n    const char *const empty_argv[]{\"\\0\"};\n    const char *const *safe_argv = special_case ? empty_argv : argv;\n    if (special_case) {\n        argc = 1;\n    }\n\n    auto argv_size = static_cast<size_t>(argc);\n#if PY_MAJOR_VERSION >= 3\n    // SetArgv* on python 3 takes wchar_t, so we have to convert.\n    std::unique_ptr<wchar_t *[]> widened_argv(new wchar_t *[argv_size]);\n    std::vector<std::unique_ptr<wchar_t[], wide_char_arg_deleter>> widened_argv_entries;\n    widened_argv_entries.reserve(argv_size);\n    for (size_t ii = 0; ii < argv_size; ++ii) {\n        widened_argv_entries.emplace_back(widen_chars(safe_argv[ii]));\n        if (!widened_argv_entries.back()) {\n            // A null here indicates a character-encoding failure or the python\n            // interpreter out of memory. Give up.\n            return;\n        }\n        widened_argv[ii] = widened_argv_entries.back().get();\n    }\n\n    auto *pysys_argv = widened_argv.get();\n#else\n    // python 2.x\n    std::vector<std::string> strings{safe_argv, safe_argv + argv_size};\n    std::vector<char *> char_strings{argv_size};\n    for (std::size_t i = 0; i < argv_size; ++i)\n        char_strings[i] = &strings[i][0];\n    char **pysys_argv = char_strings.data();\n#endif\n\n    PySys_SetArgvEx(argc, pysys_argv, static_cast<int>(add_program_dir_to_path));\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    Initialize the Python interpreter. No other pybind11 or CPython API functions can be\n    called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The\n    optional `init_signal_handlers` parameter can be used to skip the registration of\n    signal handlers (see the `Python documentation`_ for details). Calling this function\n    again after the interpreter has already been initialized is a fatal error.\n\n    If initializing the Python interpreter fails, then the program is terminated.  (This\n    is controlled by the CPython runtime and is an exception to pybind11's normal behavior\n    of throwing exceptions on errors.)\n\n    The remaining optional parameters, `argc`, `argv`, and `add_program_dir_to_path` are\n    used to populate ``sys.argv`` and ``sys.path``.\n    See the |PySys_SetArgvEx documentation|_ for details.\n\n    .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx\n    .. |PySys_SetArgvEx documentation| replace:: ``PySys_SetArgvEx`` documentation\n    .. _PySys_SetArgvEx documentation: https://docs.python.org/3/c-api/init.html#c.PySys_SetArgvEx\n \\endrst */\ninline void initialize_interpreter(bool init_signal_handlers = true,\n                                   int argc = 0,\n                                   const char *const *argv = nullptr,\n                                   bool add_program_dir_to_path = true) {\n    if (Py_IsInitialized() != 0) {\n        pybind11_fail(\"The interpreter is already running\");\n    }\n\n    Py_InitializeEx(init_signal_handlers ? 1 : 0);\n\n    detail::set_interpreter_argv(argc, argv, add_program_dir_to_path);\n}\n\n/** \\rst\n    Shut down the Python interpreter. No pybind11 or CPython API functions can be called\n    after this. In addition, pybind11 objects must not outlive the interpreter:\n\n    .. code-block:: cpp\n\n        { // BAD\n            py::initialize_interpreter();\n            auto hello = py::str(\"Hello, World!\");\n            py::finalize_interpreter();\n        } // <-- BOOM, hello's destructor is called after interpreter shutdown\n\n        { // GOOD\n            py::initialize_interpreter();\n            { // scoped\n                auto hello = py::str(\"Hello, World!\");\n            } // <-- OK, hello is cleaned up properly\n            py::finalize_interpreter();\n        }\n\n        { // BETTER\n            py::scoped_interpreter guard{};\n            auto hello = py::str(\"Hello, World!\");\n        }\n\n    .. warning::\n\n        The interpreter can be restarted by calling `initialize_interpreter` again.\n        Modules created using pybind11 can be safely re-initialized. However, Python\n        itself cannot completely unload binary extension modules and there are several\n        caveats with regard to interpreter restarting. All the details can be found\n        in the CPython documentation. In short, not all interpreter memory may be\n        freed, either due to reference cycles or user-created global data.\n\n \\endrst */\ninline void finalize_interpreter() {\n    handle builtins(PyEval_GetBuiltins());\n    const char *id = PYBIND11_INTERNALS_ID;\n\n    // Get the internals pointer (without creating it if it doesn't exist).  It's possible for the\n    // internals to be created during Py_Finalize() (e.g. if a py::capsule calls `get_internals()`\n    // during destruction), so we get the pointer-pointer here and check it after Py_Finalize().\n    detail::internals **internals_ptr_ptr = detail::get_internals_pp();\n    // It could also be stashed in builtins, so look there too:\n    if (builtins.contains(id) && isinstance<capsule>(builtins[id])) {\n        internals_ptr_ptr = capsule(builtins[id]);\n    }\n    // Local internals contains data managed by the current interpreter, so we must clear them to\n    // avoid undefined behaviors when initializing another interpreter\n    detail::get_local_internals().registered_types_cpp.clear();\n    detail::get_local_internals().registered_exception_translators.clear();\n\n    Py_Finalize();\n\n    if (internals_ptr_ptr) {\n        delete *internals_ptr_ptr;\n        *internals_ptr_ptr = nullptr;\n    }\n}\n\n/** \\rst\n    Scope guard version of `initialize_interpreter` and `finalize_interpreter`.\n    This a move-only guard and only a single instance can exist.\n\n    See `initialize_interpreter` for a discussion of its constructor arguments.\n\n    .. code-block:: cpp\n\n        #include <pybind11/embed.h>\n\n        int main() {\n            py::scoped_interpreter guard{};\n            py::print(Hello, World!);\n        } // <-- interpreter shutdown\n \\endrst */\nclass scoped_interpreter {\npublic:\n    explicit scoped_interpreter(bool init_signal_handlers = true,\n                                int argc = 0,\n                                const char *const *argv = nullptr,\n                                bool add_program_dir_to_path = true) {\n        initialize_interpreter(init_signal_handlers, argc, argv, add_program_dir_to_path);\n    }\n\n    scoped_interpreter(const scoped_interpreter &) = delete;\n    scoped_interpreter(scoped_interpreter &&other) noexcept { other.is_valid = false; }\n    scoped_interpreter &operator=(const scoped_interpreter &) = delete;\n    scoped_interpreter &operator=(scoped_interpreter &&) = delete;\n\n    ~scoped_interpreter() {\n        if (is_valid) {\n            finalize_interpreter();\n        }\n    }\n\nprivate:\n    bool is_valid = true;\n};\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/eval.h",
    "content": "/*\n    pybind11/eval.h: Support for evaluating Python expressions and statements\n    from strings and files\n\n    Copyright (c) 2016 Klemens Morgenstern <klemens.morgenstern@ed-chemnitz.de> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <utility>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline void ensure_builtins_in_globals(object &global) {\n#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000\n    // Running exec and eval on Python 2 and 3 adds `builtins` module under\n    // `__builtins__` key to globals if not yet present.\n    // Python 3.8 made PyRun_String behave similarly. Let's also do that for\n    // older versions, for consistency. This was missing from PyPy3.8 7.3.7.\n    if (!global.contains(\"__builtins__\"))\n        global[\"__builtins__\"] = module_::import(PYBIND11_BUILTINS_MODULE);\n#else\n    (void) global;\n#endif\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\nenum eval_mode {\n    /// Evaluate a string containing an isolated expression\n    eval_expr,\n\n    /// Evaluate a string containing a single statement. Returns \\c none\n    eval_single_statement,\n\n    /// Evaluate a string containing a sequence of statement. Returns \\c none\n    eval_statements\n};\n\ntemplate <eval_mode mode = eval_expr>\nobject eval(const str &expr, object global = globals(), object local = object()) {\n    if (!local) {\n        local = global;\n    }\n\n    detail::ensure_builtins_in_globals(global);\n\n    /* PyRun_String does not accept a PyObject / encoding specifier,\n       this seems to be the only alternative */\n    std::string buffer = \"# -*- coding: utf-8 -*-\\n\" + (std::string) expr;\n\n    int start = 0;\n    switch (mode) {\n        case eval_expr:\n            start = Py_eval_input;\n            break;\n        case eval_single_statement:\n            start = Py_single_input;\n            break;\n        case eval_statements:\n            start = Py_file_input;\n            break;\n        default:\n            pybind11_fail(\"invalid evaluation mode\");\n    }\n\n    PyObject *result = PyRun_String(buffer.c_str(), start, global.ptr(), local.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ntemplate <eval_mode mode = eval_expr, size_t N>\nobject eval(const char (&s)[N], object global = globals(), object local = object()) {\n    /* Support raw string literals by removing common leading whitespace */\n    auto expr = (s[0] == '\\n') ? str(module_::import(\"textwrap\").attr(\"dedent\")(s)) : str(s);\n    return eval<mode>(expr, std::move(global), std::move(local));\n}\n\ninline void exec(const str &expr, object global = globals(), object local = object()) {\n    eval<eval_statements>(expr, std::move(global), std::move(local));\n}\n\ntemplate <size_t N>\nvoid exec(const char (&s)[N], object global = globals(), object local = object()) {\n    eval<eval_statements>(s, std::move(global), std::move(local));\n}\n\n#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str, object, object) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str, object) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str) {\n    pybind11_fail(\"eval_file not supported in PyPy3. Use eval\");\n}\n#else\ntemplate <eval_mode mode = eval_statements>\nobject eval_file(str fname, object global = globals(), object local = object()) {\n    if (!local) {\n        local = global;\n    }\n\n    detail::ensure_builtins_in_globals(global);\n\n    int start = 0;\n    switch (mode) {\n        case eval_expr:\n            start = Py_eval_input;\n            break;\n        case eval_single_statement:\n            start = Py_single_input;\n            break;\n        case eval_statements:\n            start = Py_file_input;\n            break;\n        default:\n            pybind11_fail(\"invalid evaluation mode\");\n    }\n\n    int closeFile = 1;\n    std::string fname_str = (std::string) fname;\n#    if PY_VERSION_HEX >= 0x03040000\n    FILE *f = _Py_fopen_obj(fname.ptr(), \"r\");\n#    elif PY_VERSION_HEX >= 0x03000000\n    FILE *f = _Py_fopen(fname.ptr(), \"r\");\n#    else\n    /* No unicode support in open() :( */\n    auto fobj = reinterpret_steal<object>(\n        PyFile_FromString(const_cast<char *>(fname_str.c_str()), const_cast<char *>(\"r\")));\n    FILE *f = nullptr;\n    if (fobj)\n        f = PyFile_AsFile(fobj.ptr());\n    closeFile = 0;\n#    endif\n    if (!f) {\n        PyErr_Clear();\n        pybind11_fail(\"File \\\"\" + fname_str + \"\\\" could not be opened!\");\n    }\n\n    // In Python2, this should be encoded by getfilesystemencoding.\n    // We don't boher setting it since Python2 is past EOL anyway.\n    // See PR#3233\n#    if PY_VERSION_HEX >= 0x03000000\n    if (!global.contains(\"__file__\")) {\n        global[\"__file__\"] = std::move(fname);\n    }\n#    endif\n\n#    if PY_VERSION_HEX < 0x03000000 && defined(PYPY_VERSION)\n    PyObject *result = PyRun_File(f, fname_str.c_str(), start, global.ptr(), local.ptr());\n    (void) closeFile;\n#    else\n    PyObject *result\n        = PyRun_FileEx(f, fname_str.c_str(), start, global.ptr(), local.ptr(), closeFile);\n#    endif\n\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n#endif\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/functional.h",
    "content": "/*\n    pybind11/functional.h: std::function<> support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <functional>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <typename Return, typename... Args>\nstruct type_caster<std::function<Return(Args...)>> {\n    using type = std::function<Return(Args...)>;\n    using retval_type = conditional_t<std::is_same<Return, void>::value, void_type, Return>;\n    using function_type = Return (*)(Args...);\n\npublic:\n    bool load(handle src, bool convert) {\n        if (src.is_none()) {\n            // Defer accepting None to other overloads (if we aren't in convert mode):\n            if (!convert) {\n                return false;\n            }\n            return true;\n        }\n\n        if (!isinstance<function>(src)) {\n            return false;\n        }\n\n        auto func = reinterpret_borrow<function>(src);\n\n        /*\n           When passing a C++ function as an argument to another C++\n           function via Python, every function call would normally involve\n           a full C++ -> Python -> C++ roundtrip, which can be prohibitive.\n           Here, we try to at least detect the case where the function is\n           stateless (i.e. function pointer or lambda function without\n           captured variables), in which case the roundtrip can be avoided.\n         */\n        if (auto cfunc = func.cpp_function()) {\n            auto *cfunc_self = PyCFunction_GET_SELF(cfunc.ptr());\n            if (isinstance<capsule>(cfunc_self)) {\n                auto c = reinterpret_borrow<capsule>(cfunc_self);\n                auto *rec = (function_record *) c;\n\n                while (rec != nullptr) {\n                    if (rec->is_stateless\n                        && same_type(typeid(function_type),\n                                     *reinterpret_cast<const std::type_info *>(rec->data[1]))) {\n                        struct capture {\n                            function_type f;\n                        };\n                        value = ((capture *) &rec->data)->f;\n                        return true;\n                    }\n                    rec = rec->next;\n                }\n            }\n            // PYPY segfaults here when passing builtin function like sum.\n            // Raising an fail exception here works to prevent the segfault, but only on gcc.\n            // See PR #1413 for full details\n        }\n\n        // ensure GIL is held during functor destruction\n        struct func_handle {\n            function f;\n#if !(defined(_MSC_VER) && _MSC_VER == 1916 && defined(PYBIND11_CPP17))\n            // This triggers a syntax error under very special conditions (very weird indeed).\n            explicit\n#endif\n                func_handle(function &&f_) noexcept\n                : f(std::move(f_)) {\n            }\n            func_handle(const func_handle &f_) { operator=(f_); }\n            func_handle &operator=(const func_handle &f_) {\n                gil_scoped_acquire acq;\n                f = f_.f;\n                return *this;\n            }\n            ~func_handle() {\n                gil_scoped_acquire acq;\n                function kill_f(std::move(f));\n            }\n        };\n\n        // to emulate 'move initialization capture' in C++11\n        struct func_wrapper {\n            func_handle hfunc;\n            explicit func_wrapper(func_handle &&hf) noexcept : hfunc(std::move(hf)) {}\n            Return operator()(Args... args) const {\n                gil_scoped_acquire acq;\n                object retval(hfunc.f(std::forward<Args>(args)...));\n                /* Visual studio 2015 parser issue: need parentheses around this expression */\n                return (retval.template cast<Return>());\n            }\n        };\n\n        value = func_wrapper(func_handle(std::move(func)));\n        return true;\n    }\n\n    template <typename Func>\n    static handle cast(Func &&f_, return_value_policy policy, handle /* parent */) {\n        if (!f_) {\n            return none().inc_ref();\n        }\n\n        auto result = f_.template target<function_type>();\n        if (result) {\n            return cpp_function(*result, policy).release();\n        }\n        return cpp_function(std::forward<Func>(f_), policy).release();\n    }\n\n    PYBIND11_TYPE_CASTER(type,\n                         const_name(\"Callable[[\") + concat(make_caster<Args>::name...)\n                             + const_name(\"], \") + make_caster<retval_type>::name\n                             + const_name(\"]\"));\n};\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/gil.h",
    "content": "/*\n    pybind11/gil.h: RAII helpers for managing the GIL\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"detail/internals.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// forward declarations\nPyThreadState *get_thread_state_unchecked();\n\nPYBIND11_NAMESPACE_END(detail)\n\n#if defined(WITH_THREAD) && !defined(PYPY_VERSION)\n\n/* The functions below essentially reproduce the PyGILState_* API using a RAII\n * pattern, but there are a few important differences:\n *\n * 1. When acquiring the GIL from an non-main thread during the finalization\n *    phase, the GILState API blindly terminates the calling thread, which\n *    is often not what is wanted. This API does not do this.\n *\n * 2. The gil_scoped_release function can optionally cut the relationship\n *    of a PyThreadState and its associated thread, which allows moving it to\n *    another thread (this is a fairly rare/advanced use case).\n *\n * 3. The reference count of an acquired thread state can be controlled. This\n *    can be handy to prevent cases where callbacks issued from an external\n *    thread would otherwise constantly construct and destroy thread state data\n *    structures.\n *\n * See the Python bindings of NanoGUI (http://github.com/wjakob/nanogui) for an\n * example which uses features 2 and 3 to migrate the Python thread of\n * execution to another thread (to run the event loop on the original thread,\n * in this case).\n */\n\nclass gil_scoped_acquire {\npublic:\n    PYBIND11_NOINLINE gil_scoped_acquire() {\n        auto &internals = detail::get_internals();\n        tstate = (PyThreadState *) PYBIND11_TLS_GET_VALUE(internals.tstate);\n\n        if (!tstate) {\n            /* Check if the GIL was acquired using the PyGILState_* API instead (e.g. if\n               calling from a Python thread). Since we use a different key, this ensures\n               we don't create a new thread state and deadlock in PyEval_AcquireThread\n               below. Note we don't save this state with internals.tstate, since we don't\n               create it we would fail to clear it (its reference count should be > 0). */\n            tstate = PyGILState_GetThisThreadState();\n        }\n\n        if (!tstate) {\n            tstate = PyThreadState_New(internals.istate);\n#    if !defined(NDEBUG)\n            if (!tstate) {\n                pybind11_fail(\"scoped_acquire: could not create thread state!\");\n            }\n#    endif\n            tstate->gilstate_counter = 0;\n            PYBIND11_TLS_REPLACE_VALUE(internals.tstate, tstate);\n        } else {\n            release = detail::get_thread_state_unchecked() != tstate;\n        }\n\n        if (release) {\n            PyEval_AcquireThread(tstate);\n        }\n\n        inc_ref();\n    }\n\n    void inc_ref() { ++tstate->gilstate_counter; }\n\n    PYBIND11_NOINLINE void dec_ref() {\n        --tstate->gilstate_counter;\n#    if !defined(NDEBUG)\n        if (detail::get_thread_state_unchecked() != tstate) {\n            pybind11_fail(\"scoped_acquire::dec_ref(): thread state must be current!\");\n        }\n        if (tstate->gilstate_counter < 0) {\n            pybind11_fail(\"scoped_acquire::dec_ref(): reference count underflow!\");\n        }\n#    endif\n        if (tstate->gilstate_counter == 0) {\n#    if !defined(NDEBUG)\n            if (!release) {\n                pybind11_fail(\"scoped_acquire::dec_ref(): internal error!\");\n            }\n#    endif\n            PyThreadState_Clear(tstate);\n            if (active) {\n                PyThreadState_DeleteCurrent();\n            }\n            PYBIND11_TLS_DELETE_VALUE(detail::get_internals().tstate);\n            release = false;\n        }\n    }\n\n    /// This method will disable the PyThreadState_DeleteCurrent call and the\n    /// GIL won't be acquired. This method should be used if the interpreter\n    /// could be shutting down when this is called, as thread deletion is not\n    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and\n    /// protect subsequent code.\n    PYBIND11_NOINLINE void disarm() { active = false; }\n\n    PYBIND11_NOINLINE ~gil_scoped_acquire() {\n        dec_ref();\n        if (release) {\n            PyEval_SaveThread();\n        }\n    }\n\nprivate:\n    PyThreadState *tstate = nullptr;\n    bool release = true;\n    bool active = true;\n};\n\nclass gil_scoped_release {\npublic:\n    explicit gil_scoped_release(bool disassoc = false) : disassoc(disassoc) {\n        // `get_internals()` must be called here unconditionally in order to initialize\n        // `internals.tstate` for subsequent `gil_scoped_acquire` calls. Otherwise, an\n        // initialization race could occur as multiple threads try `gil_scoped_acquire`.\n        auto &internals = detail::get_internals();\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        tstate = PyEval_SaveThread();\n        if (disassoc) {\n            // Python >= 3.7 can remove this, it's an int before 3.7\n            // NOLINTNEXTLINE(readability-qualified-auto)\n            auto key = internals.tstate;\n            PYBIND11_TLS_DELETE_VALUE(key);\n        }\n    }\n\n    /// This method will disable the PyThreadState_DeleteCurrent call and the\n    /// GIL won't be acquired. This method should be used if the interpreter\n    /// could be shutting down when this is called, as thread deletion is not\n    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and\n    /// protect subsequent code.\n    PYBIND11_NOINLINE void disarm() { active = false; }\n\n    ~gil_scoped_release() {\n        if (!tstate) {\n            return;\n        }\n        // `PyEval_RestoreThread()` should not be called if runtime is finalizing\n        if (active) {\n            PyEval_RestoreThread(tstate);\n        }\n        if (disassoc) {\n            // Python >= 3.7 can remove this, it's an int before 3.7\n            // NOLINTNEXTLINE(readability-qualified-auto)\n            auto key = detail::get_internals().tstate;\n            PYBIND11_TLS_REPLACE_VALUE(key, tstate);\n        }\n    }\n\nprivate:\n    PyThreadState *tstate;\n    bool disassoc;\n    bool active = true;\n};\n#elif defined(PYPY_VERSION)\nclass gil_scoped_acquire {\n    PyGILState_STATE state;\n\npublic:\n    gil_scoped_acquire() { state = PyGILState_Ensure(); }\n    ~gil_scoped_acquire() { PyGILState_Release(state); }\n    void disarm() {}\n};\n\nclass gil_scoped_release {\n    PyThreadState *state;\n\npublic:\n    gil_scoped_release() { state = PyEval_SaveThread(); }\n    ~gil_scoped_release() { PyEval_RestoreThread(state); }\n    void disarm() {}\n};\n#else\nclass gil_scoped_acquire {\n    void disarm() {}\n};\nclass gil_scoped_release {\n    void disarm() {}\n};\n#endif\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/iostream.h",
    "content": "/*\n    pybind11/iostream.h -- Tools to assist with redirecting cout and cerr to Python\n\n    Copyright (c) 2017 Henry F. Schreiner\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n\n    WARNING: The implementation in this file is NOT thread safe. Multiple\n    threads writing to a redirected ostream concurrently cause data races\n    and potentially buffer overflows. Therefore it is currently a requirement\n    that all (possibly) concurrent redirected ostream writes are protected by\n    a mutex.\n    #HelpAppreciated: Work on iostream.h thread safety.\n    For more background see the discussions under\n    https://github.com/pybind/pybind11/pull/2982 and\n    https://github.com/pybind/pybind11/pull/2995.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\n#include <algorithm>\n#include <cstring>\n#include <iostream>\n#include <iterator>\n#include <memory>\n#include <ostream>\n#include <streambuf>\n#include <string>\n#include <utility>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Buffer that writes to Python instead of C++\nclass pythonbuf : public std::streambuf {\nprivate:\n    using traits_type = std::streambuf::traits_type;\n\n    const size_t buf_size;\n    std::unique_ptr<char[]> d_buffer;\n    object pywrite;\n    object pyflush;\n\n    int overflow(int c) override {\n        if (!traits_type::eq_int_type(c, traits_type::eof())) {\n            *pptr() = traits_type::to_char_type(c);\n            pbump(1);\n        }\n        return sync() == 0 ? traits_type::not_eof(c) : traits_type::eof();\n    }\n\n    // Computes how many bytes at the end of the buffer are part of an\n    // incomplete sequence of UTF-8 bytes.\n    // Precondition: pbase() < pptr()\n    size_t utf8_remainder() const {\n        const auto rbase = std::reverse_iterator<char *>(pbase());\n        const auto rpptr = std::reverse_iterator<char *>(pptr());\n        auto is_ascii = [](char c) { return (static_cast<unsigned char>(c) & 0x80) == 0x00; };\n        auto is_leading = [](char c) { return (static_cast<unsigned char>(c) & 0xC0) == 0xC0; };\n        auto is_leading_2b = [](char c) { return static_cast<unsigned char>(c) <= 0xDF; };\n        auto is_leading_3b = [](char c) { return static_cast<unsigned char>(c) <= 0xEF; };\n        // If the last character is ASCII, there are no incomplete code points\n        if (is_ascii(*rpptr)) {\n            return 0;\n        }\n        // Otherwise, work back from the end of the buffer and find the first\n        // UTF-8 leading byte\n        const auto rpend = rbase - rpptr >= 3 ? rpptr + 3 : rbase;\n        const auto leading = std::find_if(rpptr, rpend, is_leading);\n        if (leading == rbase) {\n            return 0;\n        }\n        const auto dist = static_cast<size_t>(leading - rpptr);\n        size_t remainder = 0;\n\n        if (dist == 0) {\n            remainder = 1; // 1-byte code point is impossible\n        } else if (dist == 1) {\n            remainder = is_leading_2b(*leading) ? 0 : dist + 1;\n        } else if (dist == 2) {\n            remainder = is_leading_3b(*leading) ? 0 : dist + 1;\n        }\n        // else if (dist >= 3), at least 4 bytes before encountering an UTF-8\n        // leading byte, either no remainder or invalid UTF-8.\n        // Invalid UTF-8 will cause an exception later when converting\n        // to a Python string, so that's not handled here.\n        return remainder;\n    }\n\n    // This function must be non-virtual to be called in a destructor.\n    int _sync() {\n        if (pbase() != pptr()) { // If buffer is not empty\n            gil_scoped_acquire tmp;\n            // This subtraction cannot be negative, so dropping the sign.\n            auto size = static_cast<size_t>(pptr() - pbase());\n            size_t remainder = utf8_remainder();\n\n            if (size > remainder) {\n                str line(pbase(), size - remainder);\n                pywrite(line);\n                pyflush();\n            }\n\n            // Copy the remainder at the end of the buffer to the beginning:\n            if (remainder > 0) {\n                std::memmove(pbase(), pptr() - remainder, remainder);\n            }\n            setp(pbase(), epptr());\n            pbump(static_cast<int>(remainder));\n        }\n        return 0;\n    }\n\n    int sync() override { return _sync(); }\n\npublic:\n    explicit pythonbuf(const object &pyostream, size_t buffer_size = 1024)\n        : buf_size(buffer_size), d_buffer(new char[buf_size]), pywrite(pyostream.attr(\"write\")),\n          pyflush(pyostream.attr(\"flush\")) {\n        setp(d_buffer.get(), d_buffer.get() + buf_size - 1);\n    }\n\n    pythonbuf(pythonbuf &&) = default;\n\n    /// Sync before destroy\n    ~pythonbuf() override { _sync(); }\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    This a move-only guard that redirects output.\n\n    .. code-block:: cpp\n\n        #include <pybind11/iostream.h>\n\n        ...\n\n        {\n            py::scoped_ostream_redirect output;\n            std::cout << \"Hello, World!\"; // Python stdout\n        } // <-- return std::cout to normal\n\n    You can explicitly pass the c++ stream and the python object,\n    for example to guard stderr instead.\n\n    .. code-block:: cpp\n\n        {\n            py::scoped_ostream_redirect output{\n                std::cerr, py::module::import(\"sys\").attr(\"stderr\")};\n            std::cout << \"Hello, World!\";\n        }\n \\endrst */\nclass scoped_ostream_redirect {\nprotected:\n    std::streambuf *old;\n    std::ostream &costream;\n    detail::pythonbuf buffer;\n\npublic:\n    explicit scoped_ostream_redirect(std::ostream &costream = std::cout,\n                                     const object &pyostream\n                                     = module_::import(\"sys\").attr(\"stdout\"))\n        : costream(costream), buffer(pyostream) {\n        old = costream.rdbuf(&buffer);\n    }\n\n    ~scoped_ostream_redirect() { costream.rdbuf(old); }\n\n    scoped_ostream_redirect(const scoped_ostream_redirect &) = delete;\n    scoped_ostream_redirect(scoped_ostream_redirect &&other) = default;\n    scoped_ostream_redirect &operator=(const scoped_ostream_redirect &) = delete;\n    scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete;\n};\n\n/** \\rst\n    Like `scoped_ostream_redirect`, but redirects cerr by default. This class\n    is provided primary to make ``py::call_guard`` easier to make.\n\n    .. code-block:: cpp\n\n     m.def(\"noisy_func\", &noisy_func,\n           py::call_guard<scoped_ostream_redirect,\n                          scoped_estream_redirect>());\n\n\\endrst */\nclass scoped_estream_redirect : public scoped_ostream_redirect {\npublic:\n    explicit scoped_estream_redirect(std::ostream &costream = std::cerr,\n                                     const object &pyostream\n                                     = module_::import(\"sys\").attr(\"stderr\"))\n        : scoped_ostream_redirect(costream, pyostream) {}\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Class to redirect output as a context manager. C++ backend.\nclass OstreamRedirect {\n    bool do_stdout_;\n    bool do_stderr_;\n    std::unique_ptr<scoped_ostream_redirect> redirect_stdout;\n    std::unique_ptr<scoped_estream_redirect> redirect_stderr;\n\npublic:\n    explicit OstreamRedirect(bool do_stdout = true, bool do_stderr = true)\n        : do_stdout_(do_stdout), do_stderr_(do_stderr) {}\n\n    void enter() {\n        if (do_stdout_) {\n            redirect_stdout.reset(new scoped_ostream_redirect());\n        }\n        if (do_stderr_) {\n            redirect_stderr.reset(new scoped_estream_redirect());\n        }\n    }\n\n    void exit() {\n        redirect_stdout.reset();\n        redirect_stderr.reset();\n    }\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    This is a helper function to add a C++ redirect context manager to Python\n    instead of using a C++ guard. To use it, add the following to your binding code:\n\n    .. code-block:: cpp\n\n        #include <pybind11/iostream.h>\n\n        ...\n\n        py::add_ostream_redirect(m, \"ostream_redirect\");\n\n    You now have a Python context manager that redirects your output:\n\n    .. code-block:: python\n\n        with m.ostream_redirect():\n            m.print_to_cout_function()\n\n    This manager can optionally be told which streams to operate on:\n\n    .. code-block:: python\n\n        with m.ostream_redirect(stdout=true, stderr=true):\n            m.noisy_function_with_error_printing()\n\n \\endrst */\ninline class_<detail::OstreamRedirect>\nadd_ostream_redirect(module_ m, const std::string &name = \"ostream_redirect\") {\n    return class_<detail::OstreamRedirect>(std::move(m), name.c_str(), module_local())\n        .def(init<bool, bool>(), arg(\"stdout\") = true, arg(\"stderr\") = true)\n        .def(\"__enter__\", &detail::OstreamRedirect::enter)\n        .def(\"__exit__\", [](detail::OstreamRedirect &self_, const args &) { self_.exit(); });\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/numpy.h",
    "content": "/*\n    pybind11/numpy.h: Basic NumPy support, vectorize() wrapper\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"complex.h\"\n\n#include <algorithm>\n#include <array>\n#include <cstdint>\n#include <cstdlib>\n#include <cstring>\n#include <functional>\n#include <numeric>\n#include <sstream>\n#include <string>\n#include <type_traits>\n#include <typeindex>\n#include <utility>\n#include <vector>\n\n/* This will be true on all flat address space platforms and allows us to reduce the\n   whole npy_intp / ssize_t / Py_intptr_t business down to just ssize_t for all size\n   and dimension types (e.g. shape, strides, indexing), instead of inflicting this\n   upon the library user. */\nstatic_assert(sizeof(::pybind11::ssize_t) == sizeof(Py_intptr_t), \"ssize_t != Py_intptr_t\");\nstatic_assert(std::is_signed<Py_intptr_t>::value, \"Py_intptr_t must be signed\");\n// We now can reinterpret_cast between py::ssize_t and Py_intptr_t (MSVC + PyPy cares)\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nclass array; // Forward declaration\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ntemplate <>\nstruct handle_type_name<array> {\n    static constexpr auto name = const_name(\"numpy.ndarray\");\n};\n\ntemplate <typename type, typename SFINAE = void>\nstruct npy_format_descriptor;\n\nstruct PyArrayDescr_Proxy {\n    PyObject_HEAD\n    PyObject *typeobj;\n    char kind;\n    char type;\n    char byteorder;\n    char flags;\n    int type_num;\n    int elsize;\n    int alignment;\n    char *subarray;\n    PyObject *fields;\n    PyObject *names;\n};\n\nstruct PyArray_Proxy {\n    PyObject_HEAD\n    char *data;\n    int nd;\n    ssize_t *dimensions;\n    ssize_t *strides;\n    PyObject *base;\n    PyObject *descr;\n    int flags;\n};\n\nstruct PyVoidScalarObject_Proxy {\n    PyObject_VAR_HEAD char *obval;\n    PyArrayDescr_Proxy *descr;\n    int flags;\n    PyObject *base;\n};\n\nstruct numpy_type_info {\n    PyObject *dtype_ptr;\n    std::string format_str;\n};\n\nstruct numpy_internals {\n    std::unordered_map<std::type_index, numpy_type_info> registered_dtypes;\n\n    numpy_type_info *get_type_info(const std::type_info &tinfo, bool throw_if_missing = true) {\n        auto it = registered_dtypes.find(std::type_index(tinfo));\n        if (it != registered_dtypes.end()) {\n            return &(it->second);\n        }\n        if (throw_if_missing) {\n            pybind11_fail(std::string(\"NumPy type info missing for \") + tinfo.name());\n        }\n        return nullptr;\n    }\n\n    template <typename T>\n    numpy_type_info *get_type_info(bool throw_if_missing = true) {\n        return get_type_info(typeid(typename std::remove_cv<T>::type), throw_if_missing);\n    }\n};\n\nPYBIND11_NOINLINE void load_numpy_internals(numpy_internals *&ptr) {\n    ptr = &get_or_create_shared_data<numpy_internals>(\"_numpy_internals\");\n}\n\ninline numpy_internals &get_numpy_internals() {\n    static numpy_internals *ptr = nullptr;\n    if (!ptr) {\n        load_numpy_internals(ptr);\n    }\n    return *ptr;\n}\n\ntemplate <typename T>\nstruct same_size {\n    template <typename U>\n    using as = bool_constant<sizeof(T) == sizeof(U)>;\n};\n\ntemplate <typename Concrete>\nconstexpr int platform_lookup() {\n    return -1;\n}\n\n// Lookup a type according to its size, and return a value corresponding to the NumPy typenum.\ntemplate <typename Concrete, typename T, typename... Ts, typename... Ints>\nconstexpr int platform_lookup(int I, Ints... Is) {\n    return sizeof(Concrete) == sizeof(T) ? I : platform_lookup<Concrete, Ts...>(Is...);\n}\n\nstruct npy_api {\n    enum constants {\n        NPY_ARRAY_C_CONTIGUOUS_ = 0x0001,\n        NPY_ARRAY_F_CONTIGUOUS_ = 0x0002,\n        NPY_ARRAY_OWNDATA_ = 0x0004,\n        NPY_ARRAY_FORCECAST_ = 0x0010,\n        NPY_ARRAY_ENSUREARRAY_ = 0x0040,\n        NPY_ARRAY_ALIGNED_ = 0x0100,\n        NPY_ARRAY_WRITEABLE_ = 0x0400,\n        NPY_BOOL_ = 0,\n        NPY_BYTE_,\n        NPY_UBYTE_,\n        NPY_SHORT_,\n        NPY_USHORT_,\n        NPY_INT_,\n        NPY_UINT_,\n        NPY_LONG_,\n        NPY_ULONG_,\n        NPY_LONGLONG_,\n        NPY_ULONGLONG_,\n        NPY_FLOAT_,\n        NPY_DOUBLE_,\n        NPY_LONGDOUBLE_,\n        NPY_CFLOAT_,\n        NPY_CDOUBLE_,\n        NPY_CLONGDOUBLE_,\n        NPY_OBJECT_ = 17,\n        NPY_STRING_,\n        NPY_UNICODE_,\n        NPY_VOID_,\n        // Platform-dependent normalization\n        NPY_INT8_ = NPY_BYTE_,\n        NPY_UINT8_ = NPY_UBYTE_,\n        NPY_INT16_ = NPY_SHORT_,\n        NPY_UINT16_ = NPY_USHORT_,\n        // `npy_common.h` defines the integer aliases. In order, it checks:\n        // NPY_BITSOF_LONG, NPY_BITSOF_LONGLONG, NPY_BITSOF_INT, NPY_BITSOF_SHORT, NPY_BITSOF_CHAR\n        // and assigns the alias to the first matching size, so we should check in this order.\n        NPY_INT32_\n        = platform_lookup<std::int32_t, long, int, short>(NPY_LONG_, NPY_INT_, NPY_SHORT_),\n        NPY_UINT32_ = platform_lookup<std::uint32_t, unsigned long, unsigned int, unsigned short>(\n            NPY_ULONG_, NPY_UINT_, NPY_USHORT_),\n        NPY_INT64_\n        = platform_lookup<std::int64_t, long, long long, int>(NPY_LONG_, NPY_LONGLONG_, NPY_INT_),\n        NPY_UINT64_\n        = platform_lookup<std::uint64_t, unsigned long, unsigned long long, unsigned int>(\n            NPY_ULONG_, NPY_ULONGLONG_, NPY_UINT_),\n    };\n\n    struct PyArray_Dims {\n        Py_intptr_t *ptr;\n        int len;\n    };\n\n    static npy_api &get() {\n        static npy_api api = lookup();\n        return api;\n    }\n\n    bool PyArray_Check_(PyObject *obj) const {\n        return PyObject_TypeCheck(obj, PyArray_Type_) != 0;\n    }\n    bool PyArrayDescr_Check_(PyObject *obj) const {\n        return PyObject_TypeCheck(obj, PyArrayDescr_Type_) != 0;\n    }\n\n    unsigned int (*PyArray_GetNDArrayCFeatureVersion_)();\n    PyObject *(*PyArray_DescrFromType_)(int);\n    PyObject *(*PyArray_NewFromDescr_)(PyTypeObject *,\n                                       PyObject *,\n                                       int,\n                                       Py_intptr_t const *,\n                                       Py_intptr_t const *,\n                                       void *,\n                                       int,\n                                       PyObject *);\n    // Unused. Not removed because that affects ABI of the class.\n    PyObject *(*PyArray_DescrNewFromType_)(int);\n    int (*PyArray_CopyInto_)(PyObject *, PyObject *);\n    PyObject *(*PyArray_NewCopy_)(PyObject *, int);\n    PyTypeObject *PyArray_Type_;\n    PyTypeObject *PyVoidArrType_Type_;\n    PyTypeObject *PyArrayDescr_Type_;\n    PyObject *(*PyArray_DescrFromScalar_)(PyObject *);\n    PyObject *(*PyArray_FromAny_)(PyObject *, PyObject *, int, int, int, PyObject *);\n    int (*PyArray_DescrConverter_)(PyObject *, PyObject **);\n    bool (*PyArray_EquivTypes_)(PyObject *, PyObject *);\n    int (*PyArray_GetArrayParamsFromObject_)(PyObject *,\n                                             PyObject *,\n                                             unsigned char,\n                                             PyObject **,\n                                             int *,\n                                             Py_intptr_t *,\n                                             PyObject **,\n                                             PyObject *);\n    PyObject *(*PyArray_Squeeze_)(PyObject *);\n    // Unused. Not removed because that affects ABI of the class.\n    int (*PyArray_SetBaseObject_)(PyObject *, PyObject *);\n    PyObject *(*PyArray_Resize_)(PyObject *, PyArray_Dims *, int, int);\n    PyObject *(*PyArray_Newshape_)(PyObject *, PyArray_Dims *, int);\n    PyObject *(*PyArray_View_)(PyObject *, PyObject *, PyObject *);\n\nprivate:\n    enum functions {\n        API_PyArray_GetNDArrayCFeatureVersion = 211,\n        API_PyArray_Type = 2,\n        API_PyArrayDescr_Type = 3,\n        API_PyVoidArrType_Type = 39,\n        API_PyArray_DescrFromType = 45,\n        API_PyArray_DescrFromScalar = 57,\n        API_PyArray_FromAny = 69,\n        API_PyArray_Resize = 80,\n        API_PyArray_CopyInto = 82,\n        API_PyArray_NewCopy = 85,\n        API_PyArray_NewFromDescr = 94,\n        API_PyArray_DescrNewFromType = 96,\n        API_PyArray_Newshape = 135,\n        API_PyArray_Squeeze = 136,\n        API_PyArray_View = 137,\n        API_PyArray_DescrConverter = 174,\n        API_PyArray_EquivTypes = 182,\n        API_PyArray_GetArrayParamsFromObject = 278,\n        API_PyArray_SetBaseObject = 282\n    };\n\n    static npy_api lookup() {\n        module_ m = module_::import(\"numpy.core.multiarray\");\n        auto c = m.attr(\"_ARRAY_API\");\n#if PY_MAJOR_VERSION >= 3\n        void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);\n#else\n        void **api_ptr = (void **) PyCObject_AsVoidPtr(c.ptr());\n#endif\n        npy_api api;\n#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];\n        DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);\n        if (api.PyArray_GetNDArrayCFeatureVersion_() < 0x7) {\n            pybind11_fail(\"pybind11 numpy support requires numpy >= 1.7.0\");\n        }\n        DECL_NPY_API(PyArray_Type);\n        DECL_NPY_API(PyVoidArrType_Type);\n        DECL_NPY_API(PyArrayDescr_Type);\n        DECL_NPY_API(PyArray_DescrFromType);\n        DECL_NPY_API(PyArray_DescrFromScalar);\n        DECL_NPY_API(PyArray_FromAny);\n        DECL_NPY_API(PyArray_Resize);\n        DECL_NPY_API(PyArray_CopyInto);\n        DECL_NPY_API(PyArray_NewCopy);\n        DECL_NPY_API(PyArray_NewFromDescr);\n        DECL_NPY_API(PyArray_DescrNewFromType);\n        DECL_NPY_API(PyArray_Newshape);\n        DECL_NPY_API(PyArray_Squeeze);\n        DECL_NPY_API(PyArray_View);\n        DECL_NPY_API(PyArray_DescrConverter);\n        DECL_NPY_API(PyArray_EquivTypes);\n        DECL_NPY_API(PyArray_GetArrayParamsFromObject);\n        DECL_NPY_API(PyArray_SetBaseObject);\n\n#undef DECL_NPY_API\n        return api;\n    }\n};\n\ninline PyArray_Proxy *array_proxy(void *ptr) { return reinterpret_cast<PyArray_Proxy *>(ptr); }\n\ninline const PyArray_Proxy *array_proxy(const void *ptr) {\n    return reinterpret_cast<const PyArray_Proxy *>(ptr);\n}\n\ninline PyArrayDescr_Proxy *array_descriptor_proxy(PyObject *ptr) {\n    return reinterpret_cast<PyArrayDescr_Proxy *>(ptr);\n}\n\ninline const PyArrayDescr_Proxy *array_descriptor_proxy(const PyObject *ptr) {\n    return reinterpret_cast<const PyArrayDescr_Proxy *>(ptr);\n}\n\ninline bool check_flags(const void *ptr, int flag) {\n    return (flag == (array_proxy(ptr)->flags & flag));\n}\n\ntemplate <typename T>\nstruct is_std_array : std::false_type {};\ntemplate <typename T, size_t N>\nstruct is_std_array<std::array<T, N>> : std::true_type {};\ntemplate <typename T>\nstruct is_complex : std::false_type {};\ntemplate <typename T>\nstruct is_complex<std::complex<T>> : std::true_type {};\n\ntemplate <typename T>\nstruct array_info_scalar {\n    using type = T;\n    static constexpr bool is_array = false;\n    static constexpr bool is_empty = false;\n    static constexpr auto extents = const_name(\"\");\n    static void append_extents(list & /* shape */) {}\n};\n// Computes underlying type and a comma-separated list of extents for array\n// types (any mix of std::array and built-in arrays). An array of char is\n// treated as scalar because it gets special handling.\ntemplate <typename T>\nstruct array_info : array_info_scalar<T> {};\ntemplate <typename T, size_t N>\nstruct array_info<std::array<T, N>> {\n    using type = typename array_info<T>::type;\n    static constexpr bool is_array = true;\n    static constexpr bool is_empty = (N == 0) || array_info<T>::is_empty;\n    static constexpr size_t extent = N;\n\n    // appends the extents to shape\n    static void append_extents(list &shape) {\n        shape.append(N);\n        array_info<T>::append_extents(shape);\n    }\n\n    static constexpr auto extents = const_name<array_info<T>::is_array>(\n        concat(const_name<N>(), array_info<T>::extents), const_name<N>());\n};\n// For numpy we have special handling for arrays of characters, so we don't include\n// the size in the array extents.\ntemplate <size_t N>\nstruct array_info<char[N]> : array_info_scalar<char[N]> {};\ntemplate <size_t N>\nstruct array_info<std::array<char, N>> : array_info_scalar<std::array<char, N>> {};\ntemplate <typename T, size_t N>\nstruct array_info<T[N]> : array_info<std::array<T, N>> {};\ntemplate <typename T>\nusing remove_all_extents_t = typename array_info<T>::type;\n\ntemplate <typename T>\nusing is_pod_struct\n    = all_of<std::is_standard_layout<T>, // since we're accessing directly in memory\n                                         // we need a standard layout type\n#if defined(__GLIBCXX__)                                                                          \\\n    && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623              \\\n        || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)\n             // libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after\n             // 5) don't implement is_trivially_copyable, so approximate it\n             std::is_trivially_destructible<T>,\n             satisfies_any_of<T, std::has_trivial_copy_constructor, std::has_trivial_copy_assign>,\n#else\n             std::is_trivially_copyable<T>,\n#endif\n             satisfies_none_of<T,\n                               std::is_reference,\n                               std::is_array,\n                               is_std_array,\n                               std::is_arithmetic,\n                               is_complex,\n                               std::is_enum>>;\n\n// Replacement for std::is_pod (deprecated in C++20)\ntemplate <typename T>\nusing is_pod = all_of<std::is_standard_layout<T>, std::is_trivial<T>>;\n\ntemplate <ssize_t Dim = 0, typename Strides>\nssize_t byte_offset_unsafe(const Strides &) {\n    return 0;\n}\ntemplate <ssize_t Dim = 0, typename Strides, typename... Ix>\nssize_t byte_offset_unsafe(const Strides &strides, ssize_t i, Ix... index) {\n    return i * strides[Dim] + byte_offset_unsafe<Dim + 1>(strides, index...);\n}\n\n/**\n * Proxy class providing unsafe, unchecked const access to array data.  This is constructed through\n * the `unchecked<T, N>()` method of `array` or the `unchecked<N>()` method of `array_t<T>`. `Dims`\n * will be -1 for dimensions determined at runtime.\n */\ntemplate <typename T, ssize_t Dims>\nclass unchecked_reference {\nprotected:\n    static constexpr bool Dynamic = Dims < 0;\n    const unsigned char *data_;\n    // Storing the shape & strides in local variables (i.e. these arrays) allows the compiler to\n    // make large performance gains on big, nested loops, but requires compile-time dimensions\n    conditional_t<Dynamic, const ssize_t *, std::array<ssize_t, (size_t) Dims>> shape_, strides_;\n    const ssize_t dims_;\n\n    friend class pybind11::array;\n    // Constructor for compile-time dimensions:\n    template <bool Dyn = Dynamic>\n    unchecked_reference(const void *data,\n                        const ssize_t *shape,\n                        const ssize_t *strides,\n                        enable_if_t<!Dyn, ssize_t>)\n        : data_{reinterpret_cast<const unsigned char *>(data)}, dims_{Dims} {\n        for (size_t i = 0; i < (size_t) dims_; i++) {\n            shape_[i] = shape[i];\n            strides_[i] = strides[i];\n        }\n    }\n    // Constructor for runtime dimensions:\n    template <bool Dyn = Dynamic>\n    unchecked_reference(const void *data,\n                        const ssize_t *shape,\n                        const ssize_t *strides,\n                        enable_if_t<Dyn, ssize_t> dims)\n        : data_{reinterpret_cast<const unsigned char *>(data)}, shape_{shape}, strides_{strides},\n          dims_{dims} {}\n\npublic:\n    /**\n     * Unchecked const reference access to data at the given indices.  For a compile-time known\n     * number of dimensions, this requires the correct number of arguments; for run-time\n     * dimensionality, this is not checked (and so is up to the caller to use safely).\n     */\n    template <typename... Ix>\n    const T &operator()(Ix... index) const {\n        static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,\n                      \"Invalid number of indices for unchecked array reference\");\n        return *reinterpret_cast<const T *>(data_\n                                            + byte_offset_unsafe(strides_, ssize_t(index)...));\n    }\n    /**\n     * Unchecked const reference access to data; this operator only participates if the reference\n     * is to a 1-dimensional array.  When present, this is exactly equivalent to `obj(index)`.\n     */\n    template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>\n    const T &operator[](ssize_t index) const {\n        return operator()(index);\n    }\n\n    /// Pointer access to the data at the given indices.\n    template <typename... Ix>\n    const T *data(Ix... ix) const {\n        return &operator()(ssize_t(ix)...);\n    }\n\n    /// Returns the item size, i.e. sizeof(T)\n    constexpr static ssize_t itemsize() { return sizeof(T); }\n\n    /// Returns the shape (i.e. size) of dimension `dim`\n    ssize_t shape(ssize_t dim) const { return shape_[(size_t) dim]; }\n\n    /// Returns the number of dimensions of the array\n    ssize_t ndim() const { return dims_; }\n\n    /// Returns the total number of elements in the referenced array, i.e. the product of the\n    /// shapes\n    template <bool Dyn = Dynamic>\n    enable_if_t<!Dyn, ssize_t> size() const {\n        return std::accumulate(\n            shape_.begin(), shape_.end(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n    template <bool Dyn = Dynamic>\n    enable_if_t<Dyn, ssize_t> size() const {\n        return std::accumulate(shape_, shape_ + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n\n    /// Returns the total number of bytes used by the referenced data.  Note that the actual span\n    /// in memory may be larger if the referenced array has non-contiguous strides (e.g. for a\n    /// slice).\n    ssize_t nbytes() const { return size() * itemsize(); }\n};\n\ntemplate <typename T, ssize_t Dims>\nclass unchecked_mutable_reference : public unchecked_reference<T, Dims> {\n    friend class pybind11::array;\n    using ConstBase = unchecked_reference<T, Dims>;\n    using ConstBase::ConstBase;\n    using ConstBase::Dynamic;\n\npublic:\n    // Bring in const-qualified versions from base class\n    using ConstBase::operator();\n    using ConstBase::operator[];\n\n    /// Mutable, unchecked access to data at the given indices.\n    template <typename... Ix>\n    T &operator()(Ix... index) {\n        static_assert(ssize_t{sizeof...(Ix)} == Dims || Dynamic,\n                      \"Invalid number of indices for unchecked array reference\");\n        return const_cast<T &>(ConstBase::operator()(index...));\n    }\n    /**\n     * Mutable, unchecked access data at the given index; this operator only participates if the\n     * reference is to a 1-dimensional array (or has runtime dimensions).  When present, this is\n     * exactly equivalent to `obj(index)`.\n     */\n    template <ssize_t D = Dims, typename = enable_if_t<D == 1 || Dynamic>>\n    T &operator[](ssize_t index) {\n        return operator()(index);\n    }\n\n    /// Mutable pointer access to the data at the given indices.\n    template <typename... Ix>\n    T *mutable_data(Ix... ix) {\n        return &operator()(ssize_t(ix)...);\n    }\n};\n\ntemplate <typename T, ssize_t Dim>\nstruct type_caster<unchecked_reference<T, Dim>> {\n    static_assert(Dim == 0 && Dim > 0 /* always fail */,\n                  \"unchecked array proxy object is not castable\");\n};\ntemplate <typename T, ssize_t Dim>\nstruct type_caster<unchecked_mutable_reference<T, Dim>>\n    : type_caster<unchecked_reference<T, Dim>> {};\n\nPYBIND11_NAMESPACE_END(detail)\n\nclass dtype : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(dtype, object, detail::npy_api::get().PyArrayDescr_Check_);\n\n    explicit dtype(const buffer_info &info) {\n        dtype descr(_dtype_from_pep3118()(PYBIND11_STR_TYPE(info.format)));\n        // If info.itemsize == 0, use the value calculated from the format string\n        m_ptr = descr.strip_padding(info.itemsize != 0 ? info.itemsize : descr.itemsize())\n                    .release()\n                    .ptr();\n    }\n\n    explicit dtype(const std::string &format) {\n        m_ptr = from_args(pybind11::str(format)).release().ptr();\n    }\n\n    explicit dtype(const char *format) : dtype(std::string(format)) {}\n\n    dtype(list names, list formats, list offsets, ssize_t itemsize) {\n        dict args;\n        args[\"names\"] = std::move(names);\n        args[\"formats\"] = std::move(formats);\n        args[\"offsets\"] = std::move(offsets);\n        args[\"itemsize\"] = pybind11::int_(itemsize);\n        m_ptr = from_args(std::move(args)).release().ptr();\n    }\n\n    /// This is essentially the same as calling numpy.dtype(args) in Python.\n    static dtype from_args(object args) {\n        PyObject *ptr = nullptr;\n        if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<dtype>(ptr);\n    }\n\n    /// Return dtype associated with a C++ type.\n    template <typename T>\n    static dtype of() {\n        return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::dtype();\n    }\n\n    /// Size of the data type in bytes.\n    ssize_t itemsize() const { return detail::array_descriptor_proxy(m_ptr)->elsize; }\n\n    /// Returns true for structured data types.\n    bool has_fields() const { return detail::array_descriptor_proxy(m_ptr)->names != nullptr; }\n\n    /// Single-character code for dtype's kind.\n    /// For example, floating point types are 'f' and integral types are 'i'.\n    char kind() const { return detail::array_descriptor_proxy(m_ptr)->kind; }\n\n    /// Single-character for dtype's type.\n    /// For example, ``float`` is 'f', ``double`` 'd', ``int`` 'i', and ``long`` 'l'.\n    char char_() const {\n        // Note: The signature, `dtype::char_` follows the naming of NumPy's\n        // public Python API (i.e., ``dtype.char``), rather than its internal\n        // C API (``PyArray_Descr::type``).\n        return detail::array_descriptor_proxy(m_ptr)->type;\n    }\n\nprivate:\n    static object _dtype_from_pep3118() {\n        static PyObject *obj = module_::import(\"numpy.core._internal\")\n                                   .attr(\"_dtype_from_pep3118\")\n                                   .cast<object>()\n                                   .release()\n                                   .ptr();\n        return reinterpret_borrow<object>(obj);\n    }\n\n    dtype strip_padding(ssize_t itemsize) {\n        // Recursively strip all void fields with empty names that are generated for\n        // padding fields (as of NumPy v1.11).\n        if (!has_fields()) {\n            return *this;\n        }\n\n        struct field_descr {\n            PYBIND11_STR_TYPE name;\n            object format;\n            pybind11::int_ offset;\n        };\n        std::vector<field_descr> field_descriptors;\n\n        for (auto field : attr(\"fields\").attr(\"items\")()) {\n            auto spec = field.cast<tuple>();\n            auto name = spec[0].cast<pybind11::str>();\n            auto format = spec[1].cast<tuple>()[0].cast<dtype>();\n            auto offset = spec[1].cast<tuple>()[1].cast<pybind11::int_>();\n            if ((len(name) == 0u) && format.kind() == 'V') {\n                continue;\n            }\n            field_descriptors.push_back(\n                {(PYBIND11_STR_TYPE) name, format.strip_padding(format.itemsize()), offset});\n        }\n\n        std::sort(field_descriptors.begin(),\n                  field_descriptors.end(),\n                  [](const field_descr &a, const field_descr &b) {\n                      return a.offset.cast<int>() < b.offset.cast<int>();\n                  });\n\n        list names, formats, offsets;\n        for (auto &descr : field_descriptors) {\n            names.append(descr.name);\n            formats.append(descr.format);\n            offsets.append(descr.offset);\n        }\n        return dtype(std::move(names), std::move(formats), std::move(offsets), itemsize);\n    }\n};\n\nclass array : public buffer {\npublic:\n    PYBIND11_OBJECT_CVT(array, buffer, detail::npy_api::get().PyArray_Check_, raw_array)\n\n    enum {\n        c_style = detail::npy_api::NPY_ARRAY_C_CONTIGUOUS_,\n        f_style = detail::npy_api::NPY_ARRAY_F_CONTIGUOUS_,\n        forcecast = detail::npy_api::NPY_ARRAY_FORCECAST_\n    };\n\n    array() : array(0, static_cast<const double *>(nullptr)) {}\n\n    using ShapeContainer = detail::any_container<ssize_t>;\n    using StridesContainer = detail::any_container<ssize_t>;\n\n    // Constructs an array taking shape/strides from arbitrary container types\n    array(const pybind11::dtype &dt,\n          ShapeContainer shape,\n          StridesContainer strides,\n          const void *ptr = nullptr,\n          handle base = handle()) {\n\n        if (strides->empty()) {\n            *strides = detail::c_strides(*shape, dt.itemsize());\n        }\n\n        auto ndim = shape->size();\n        if (ndim != strides->size()) {\n            pybind11_fail(\"NumPy: shape ndim doesn't match strides ndim\");\n        }\n        auto descr = dt;\n\n        int flags = 0;\n        if (base && ptr) {\n            if (isinstance<array>(base)) {\n                /* Copy flags from base (except ownership bit) */\n                flags = reinterpret_borrow<array>(base).flags()\n                        & ~detail::npy_api::NPY_ARRAY_OWNDATA_;\n            } else {\n                /* Writable by default, easy to downgrade later on if needed */\n                flags = detail::npy_api::NPY_ARRAY_WRITEABLE_;\n            }\n        }\n\n        auto &api = detail::npy_api::get();\n        auto tmp = reinterpret_steal<object>(api.PyArray_NewFromDescr_(\n            api.PyArray_Type_,\n            descr.release().ptr(),\n            (int) ndim,\n            // Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)\n            reinterpret_cast<Py_intptr_t *>(shape->data()),\n            reinterpret_cast<Py_intptr_t *>(strides->data()),\n            const_cast<void *>(ptr),\n            flags,\n            nullptr));\n        if (!tmp) {\n            throw error_already_set();\n        }\n        if (ptr) {\n            if (base) {\n                api.PyArray_SetBaseObject_(tmp.ptr(), base.inc_ref().ptr());\n            } else {\n                tmp = reinterpret_steal<object>(\n                    api.PyArray_NewCopy_(tmp.ptr(), -1 /* any order */));\n            }\n        }\n        m_ptr = tmp.release().ptr();\n    }\n\n    array(const pybind11::dtype &dt,\n          ShapeContainer shape,\n          const void *ptr = nullptr,\n          handle base = handle())\n        : array(dt, std::move(shape), {}, ptr, base) {}\n\n    template <typename T,\n              typename\n              = detail::enable_if_t<std::is_integral<T>::value && !std::is_same<bool, T>::value>>\n    array(const pybind11::dtype &dt, T count, const void *ptr = nullptr, handle base = handle())\n        : array(dt, {{count}}, ptr, base) {}\n\n    template <typename T>\n    array(ShapeContainer shape, StridesContainer strides, const T *ptr, handle base = handle())\n        : array(pybind11::dtype::of<T>(), std::move(shape), std::move(strides), ptr, base) {}\n\n    template <typename T>\n    array(ShapeContainer shape, const T *ptr, handle base = handle())\n        : array(std::move(shape), {}, ptr, base) {}\n\n    template <typename T>\n    explicit array(ssize_t count, const T *ptr, handle base = handle())\n        : array({count}, {}, ptr, base) {}\n\n    explicit array(const buffer_info &info, handle base = handle())\n        : array(pybind11::dtype(info), info.shape, info.strides, info.ptr, base) {}\n\n    /// Array descriptor (dtype)\n    pybind11::dtype dtype() const {\n        return reinterpret_borrow<pybind11::dtype>(detail::array_proxy(m_ptr)->descr);\n    }\n\n    /// Total number of elements\n    ssize_t size() const {\n        return std::accumulate(shape(), shape() + ndim(), (ssize_t) 1, std::multiplies<ssize_t>());\n    }\n\n    /// Byte size of a single element\n    ssize_t itemsize() const {\n        return detail::array_descriptor_proxy(detail::array_proxy(m_ptr)->descr)->elsize;\n    }\n\n    /// Total number of bytes\n    ssize_t nbytes() const { return size() * itemsize(); }\n\n    /// Number of dimensions\n    ssize_t ndim() const { return detail::array_proxy(m_ptr)->nd; }\n\n    /// Base object\n    object base() const { return reinterpret_borrow<object>(detail::array_proxy(m_ptr)->base); }\n\n    /// Dimensions of the array\n    const ssize_t *shape() const { return detail::array_proxy(m_ptr)->dimensions; }\n\n    /// Dimension along a given axis\n    ssize_t shape(ssize_t dim) const {\n        if (dim >= ndim()) {\n            fail_dim_check(dim, \"invalid axis\");\n        }\n        return shape()[dim];\n    }\n\n    /// Strides of the array\n    const ssize_t *strides() const { return detail::array_proxy(m_ptr)->strides; }\n\n    /// Stride along a given axis\n    ssize_t strides(ssize_t dim) const {\n        if (dim >= ndim()) {\n            fail_dim_check(dim, \"invalid axis\");\n        }\n        return strides()[dim];\n    }\n\n    /// Return the NumPy array flags\n    int flags() const { return detail::array_proxy(m_ptr)->flags; }\n\n    /// If set, the array is writeable (otherwise the buffer is read-only)\n    bool writeable() const {\n        return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_WRITEABLE_);\n    }\n\n    /// If set, the array owns the data (will be freed when the array is deleted)\n    bool owndata() const {\n        return detail::check_flags(m_ptr, detail::npy_api::NPY_ARRAY_OWNDATA_);\n    }\n\n    /// Pointer to the contained data. If index is not provided, points to the\n    /// beginning of the buffer. May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    const void *data(Ix... index) const {\n        return static_cast<const void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));\n    }\n\n    /// Mutable pointer to the contained data. If index is not provided, points to the\n    /// beginning of the buffer. May throw if the index would lead to out of bounds access.\n    /// May throw if the array is not writeable.\n    template <typename... Ix>\n    void *mutable_data(Ix... index) {\n        check_writeable();\n        return static_cast<void *>(detail::array_proxy(m_ptr)->data + offset_at(index...));\n    }\n\n    /// Byte offset from beginning of the array to a given index (full or partial).\n    /// May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    ssize_t offset_at(Ix... index) const {\n        if ((ssize_t) sizeof...(index) > ndim()) {\n            fail_dim_check(sizeof...(index), \"too many indices for an array\");\n        }\n        return byte_offset(ssize_t(index)...);\n    }\n\n    ssize_t offset_at() const { return 0; }\n\n    /// Item count from beginning of the array to a given index (full or partial).\n    /// May throw if the index would lead to out of bounds access.\n    template <typename... Ix>\n    ssize_t index_at(Ix... index) const {\n        return offset_at(index...) / itemsize();\n    }\n\n    /**\n     * Returns a proxy object that provides access to the array's data without bounds or\n     * dimensionality checking.  Will throw if the array is missing the `writeable` flag.  Use with\n     * care: the array must not be destroyed or reshaped for the duration of the returned object,\n     * and the caller must take care not to access invalid dimensions or dimension indices.\n     */\n    template <typename T, ssize_t Dims = -1>\n    detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {\n        if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {\n            throw std::domain_error(\"array has incorrect number of dimensions: \"\n                                    + std::to_string(ndim()) + \"; expected \"\n                                    + std::to_string(Dims));\n        }\n        return detail::unchecked_mutable_reference<T, Dims>(\n            mutable_data(), shape(), strides(), ndim());\n    }\n\n    /**\n     * Returns a proxy object that provides const access to the array's data without bounds or\n     * dimensionality checking.  Unlike `mutable_unchecked()`, this does not require that the\n     * underlying array have the `writable` flag.  Use with care: the array must not be destroyed\n     * or reshaped for the duration of the returned object, and the caller must take care not to\n     * access invalid dimensions or dimension indices.\n     */\n    template <typename T, ssize_t Dims = -1>\n    detail::unchecked_reference<T, Dims> unchecked() const & {\n        if (PYBIND11_SILENCE_MSVC_C4127(Dims >= 0) && ndim() != Dims) {\n            throw std::domain_error(\"array has incorrect number of dimensions: \"\n                                    + std::to_string(ndim()) + \"; expected \"\n                                    + std::to_string(Dims));\n        }\n        return detail::unchecked_reference<T, Dims>(data(), shape(), strides(), ndim());\n    }\n\n    /// Return a new view with all of the dimensions of length 1 removed\n    array squeeze() {\n        auto &api = detail::npy_api::get();\n        return reinterpret_steal<array>(api.PyArray_Squeeze_(m_ptr));\n    }\n\n    /// Resize array to given shape\n    /// If refcheck is true and more that one reference exist to this array\n    /// then resize will succeed only if it makes a reshape, i.e. original size doesn't change\n    void resize(ShapeContainer new_shape, bool refcheck = true) {\n        detail::npy_api::PyArray_Dims d\n            = {// Use reinterpret_cast for PyPy on Windows (remove if fixed, checked on 7.3.1)\n               reinterpret_cast<Py_intptr_t *>(new_shape->data()),\n               int(new_shape->size())};\n        // try to resize, set ordering param to -1 cause it's not used anyway\n        auto new_array = reinterpret_steal<object>(\n            detail::npy_api::get().PyArray_Resize_(m_ptr, &d, int(refcheck), -1));\n        if (!new_array) {\n            throw error_already_set();\n        }\n        if (isinstance<array>(new_array)) {\n            *this = std::move(new_array);\n        }\n    }\n\n    /// Optional `order` parameter omitted, to be added as needed.\n    array reshape(ShapeContainer new_shape) {\n        detail::npy_api::PyArray_Dims d\n            = {reinterpret_cast<Py_intptr_t *>(new_shape->data()), int(new_shape->size())};\n        auto new_array\n            = reinterpret_steal<array>(detail::npy_api::get().PyArray_Newshape_(m_ptr, &d, 0));\n        if (!new_array) {\n            throw error_already_set();\n        }\n        return new_array;\n    }\n\n    /// Create a view of an array in a different data type.\n    /// This function may fundamentally reinterpret the data in the array.\n    /// It is the responsibility of the caller to ensure that this is safe.\n    /// Only supports the `dtype` argument, the `type` argument is omitted,\n    /// to be added as needed.\n    array view(const std::string &dtype) {\n        auto &api = detail::npy_api::get();\n        auto new_view = reinterpret_steal<array>(api.PyArray_View_(\n            m_ptr, dtype::from_args(pybind11::str(dtype)).release().ptr(), nullptr));\n        if (!new_view) {\n            throw error_already_set();\n        }\n        return new_view;\n    }\n\n    /// Ensure that the argument is a NumPy array\n    /// In case of an error, nullptr is returned and the Python error is cleared.\n    static array ensure(handle h, int ExtraFlags = 0) {\n        auto result = reinterpret_steal<array>(raw_array(h.ptr(), ExtraFlags));\n        if (!result) {\n            PyErr_Clear();\n        }\n        return result;\n    }\n\nprotected:\n    template <typename, typename>\n    friend struct detail::npy_format_descriptor;\n\n    void fail_dim_check(ssize_t dim, const std::string &msg) const {\n        throw index_error(msg + \": \" + std::to_string(dim) + \" (ndim = \" + std::to_string(ndim())\n                          + \")\");\n    }\n\n    template <typename... Ix>\n    ssize_t byte_offset(Ix... index) const {\n        check_dimensions(index...);\n        return detail::byte_offset_unsafe(strides(), ssize_t(index)...);\n    }\n\n    void check_writeable() const {\n        if (!writeable()) {\n            throw std::domain_error(\"array is not writeable\");\n        }\n    }\n\n    template <typename... Ix>\n    void check_dimensions(Ix... index) const {\n        check_dimensions_impl(ssize_t(0), shape(), ssize_t(index)...);\n    }\n\n    void check_dimensions_impl(ssize_t, const ssize_t *) const {}\n\n    template <typename... Ix>\n    void check_dimensions_impl(ssize_t axis, const ssize_t *shape, ssize_t i, Ix... index) const {\n        if (i >= *shape) {\n            throw index_error(std::string(\"index \") + std::to_string(i)\n                              + \" is out of bounds for axis \" + std::to_string(axis)\n                              + \" with size \" + std::to_string(*shape));\n        }\n        check_dimensions_impl(axis + 1, shape + 1, index...);\n    }\n\n    /// Create array from any object -- always returns a new reference\n    static PyObject *raw_array(PyObject *ptr, int ExtraFlags = 0) {\n        if (ptr == nullptr) {\n            PyErr_SetString(PyExc_ValueError, \"cannot create a pybind11::array from a nullptr\");\n            return nullptr;\n        }\n        return detail::npy_api::get().PyArray_FromAny_(\n            ptr, nullptr, 0, 0, detail::npy_api::NPY_ARRAY_ENSUREARRAY_ | ExtraFlags, nullptr);\n    }\n};\n\ntemplate <typename T, int ExtraFlags = array::forcecast>\nclass array_t : public array {\nprivate:\n    struct private_ctor {};\n    // Delegating constructor needed when both moving and accessing in the same constructor\n    array_t(private_ctor,\n            ShapeContainer &&shape,\n            StridesContainer &&strides,\n            const T *ptr,\n            handle base)\n        : array(std::move(shape), std::move(strides), ptr, base) {}\n\npublic:\n    static_assert(!detail::array_info<T>::is_array, \"Array types cannot be used with array_t\");\n\n    using value_type = T;\n\n    array_t() : array(0, static_cast<const T *>(nullptr)) {}\n    array_t(handle h, borrowed_t) : array(h, borrowed_t{}) {}\n    array_t(handle h, stolen_t) : array(h, stolen_t{}) {}\n\n    PYBIND11_DEPRECATED(\"Use array_t<T>::ensure() instead\")\n    array_t(handle h, bool is_borrowed) : array(raw_array_t(h.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            PyErr_Clear();\n        }\n        if (!is_borrowed) {\n            Py_XDECREF(h.ptr());\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    array_t(const object &o) : array(raw_array_t(o.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    explicit array_t(const buffer_info &info, handle base = handle()) : array(info, base) {}\n\n    array_t(ShapeContainer shape,\n            StridesContainer strides,\n            const T *ptr = nullptr,\n            handle base = handle())\n        : array(std::move(shape), std::move(strides), ptr, base) {}\n\n    explicit array_t(ShapeContainer shape, const T *ptr = nullptr, handle base = handle())\n        : array_t(private_ctor{},\n                  std::move(shape),\n                  (ExtraFlags & f_style) != 0 ? detail::f_strides(*shape, itemsize())\n                                              : detail::c_strides(*shape, itemsize()),\n                  ptr,\n                  base) {}\n\n    explicit array_t(ssize_t count, const T *ptr = nullptr, handle base = handle())\n        : array({count}, {}, ptr, base) {}\n\n    constexpr ssize_t itemsize() const { return sizeof(T); }\n\n    template <typename... Ix>\n    ssize_t index_at(Ix... index) const {\n        return offset_at(index...) / itemsize();\n    }\n\n    template <typename... Ix>\n    const T *data(Ix... index) const {\n        return static_cast<const T *>(array::data(index...));\n    }\n\n    template <typename... Ix>\n    T *mutable_data(Ix... index) {\n        return static_cast<T *>(array::mutable_data(index...));\n    }\n\n    // Reference to element at a given index\n    template <typename... Ix>\n    const T &at(Ix... index) const {\n        if ((ssize_t) sizeof...(index) != ndim()) {\n            fail_dim_check(sizeof...(index), \"index dimension mismatch\");\n        }\n        return *(static_cast<const T *>(array::data())\n                 + byte_offset(ssize_t(index)...) / itemsize());\n    }\n\n    // Mutable reference to element at a given index\n    template <typename... Ix>\n    T &mutable_at(Ix... index) {\n        if ((ssize_t) sizeof...(index) != ndim()) {\n            fail_dim_check(sizeof...(index), \"index dimension mismatch\");\n        }\n        return *(static_cast<T *>(array::mutable_data())\n                 + byte_offset(ssize_t(index)...) / itemsize());\n    }\n\n    /**\n     * Returns a proxy object that provides access to the array's data without bounds or\n     * dimensionality checking.  Will throw if the array is missing the `writeable` flag.  Use with\n     * care: the array must not be destroyed or reshaped for the duration of the returned object,\n     * and the caller must take care not to access invalid dimensions or dimension indices.\n     */\n    template <ssize_t Dims = -1>\n    detail::unchecked_mutable_reference<T, Dims> mutable_unchecked() & {\n        return array::mutable_unchecked<T, Dims>();\n    }\n\n    /**\n     * Returns a proxy object that provides const access to the array's data without bounds or\n     * dimensionality checking.  Unlike `unchecked()`, this does not require that the underlying\n     * array have the `writable` flag.  Use with care: the array must not be destroyed or reshaped\n     * for the duration of the returned object, and the caller must take care not to access invalid\n     * dimensions or dimension indices.\n     */\n    template <ssize_t Dims = -1>\n    detail::unchecked_reference<T, Dims> unchecked() const & {\n        return array::unchecked<T, Dims>();\n    }\n\n    /// Ensure that the argument is a NumPy array of the correct dtype (and if not, try to convert\n    /// it).  In case of an error, nullptr is returned and the Python error is cleared.\n    static array_t ensure(handle h) {\n        auto result = reinterpret_steal<array_t>(raw_array_t(h.ptr()));\n        if (!result) {\n            PyErr_Clear();\n        }\n        return result;\n    }\n\n    static bool check_(handle h) {\n        const auto &api = detail::npy_api::get();\n        return api.PyArray_Check_(h.ptr())\n               && api.PyArray_EquivTypes_(detail::array_proxy(h.ptr())->descr,\n                                          dtype::of<T>().ptr())\n               && detail::check_flags(h.ptr(), ExtraFlags & (array::c_style | array::f_style));\n    }\n\nprotected:\n    /// Create array from any object -- always returns a new reference\n    static PyObject *raw_array_t(PyObject *ptr) {\n        if (ptr == nullptr) {\n            PyErr_SetString(PyExc_ValueError, \"cannot create a pybind11::array_t from a nullptr\");\n            return nullptr;\n        }\n        return detail::npy_api::get().PyArray_FromAny_(ptr,\n                                                       dtype::of<T>().release().ptr(),\n                                                       0,\n                                                       0,\n                                                       detail::npy_api::NPY_ARRAY_ENSUREARRAY_\n                                                           | ExtraFlags,\n                                                       nullptr);\n    }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {\n    static std::string format() {\n        return detail::npy_format_descriptor<typename std::remove_cv<T>::type>::format();\n    }\n};\n\ntemplate <size_t N>\nstruct format_descriptor<char[N]> {\n    static std::string format() { return std::to_string(N) + \"s\"; }\n};\ntemplate <size_t N>\nstruct format_descriptor<std::array<char, N>> {\n    static std::string format() { return std::to_string(N) + \"s\"; }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<std::is_enum<T>::value>> {\n    static std::string format() {\n        return format_descriptor<\n            typename std::remove_cv<typename std::underlying_type<T>::type>::type>::format();\n    }\n};\n\ntemplate <typename T>\nstruct format_descriptor<T, detail::enable_if_t<detail::array_info<T>::is_array>> {\n    static std::string format() {\n        using namespace detail;\n        static constexpr auto extents = const_name(\"(\") + array_info<T>::extents + const_name(\")\");\n        return extents.text + format_descriptor<remove_all_extents_t<T>>::format();\n    }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename T, int ExtraFlags>\nstruct pyobject_caster<array_t<T, ExtraFlags>> {\n    using type = array_t<T, ExtraFlags>;\n\n    bool load(handle src, bool convert) {\n        if (!convert && !type::check_(src)) {\n            return false;\n        }\n        value = type::ensure(src);\n        return static_cast<bool>(value);\n    }\n\n    static handle cast(const handle &src, return_value_policy /* policy */, handle /* parent */) {\n        return src.inc_ref();\n    }\n    PYBIND11_TYPE_CASTER(type, handle_type_name<type>::name);\n};\n\ntemplate <typename T>\nstruct compare_buffer_info<T, detail::enable_if_t<detail::is_pod_struct<T>::value>> {\n    static bool compare(const buffer_info &b) {\n        return npy_api::get().PyArray_EquivTypes_(dtype::of<T>().ptr(), dtype(b).ptr());\n    }\n};\n\ntemplate <typename T, typename = void>\nstruct npy_format_descriptor_name;\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<std::is_integral<T>::value>> {\n    static constexpr auto name = const_name<std::is_same<T, bool>::value>(\n        const_name(\"bool\"),\n        const_name<std::is_signed<T>::value>(\"numpy.int\", \"numpy.uint\")\n            + const_name<sizeof(T) * 8>());\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<std::is_floating_point<T>::value>> {\n    static constexpr auto name = const_name < std::is_same<T, float>::value\n                                 || std::is_same<T, const float>::value\n                                 || std::is_same<T, double>::value\n                                 || std::is_same<T, const double>::value\n                                        > (const_name(\"numpy.float\") + const_name<sizeof(T) * 8>(),\n                                           const_name(\"numpy.longdouble\"));\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor_name<T, enable_if_t<is_complex<T>::value>> {\n    static constexpr auto name = const_name < std::is_same<typename T::value_type, float>::value\n                                 || std::is_same<typename T::value_type, const float>::value\n                                 || std::is_same<typename T::value_type, double>::value\n                                 || std::is_same<typename T::value_type, const double>::value\n                                        > (const_name(\"numpy.complex\")\n                                               + const_name<sizeof(typename T::value_type) * 16>(),\n                                           const_name(\"numpy.longcomplex\"));\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor<\n    T,\n    enable_if_t<satisfies_any_of<T, std::is_arithmetic, is_complex>::value>>\n    : npy_format_descriptor_name<T> {\nprivate:\n    // NB: the order here must match the one in common.h\n    constexpr static const int values[15] = {npy_api::NPY_BOOL_,\n                                             npy_api::NPY_BYTE_,\n                                             npy_api::NPY_UBYTE_,\n                                             npy_api::NPY_INT16_,\n                                             npy_api::NPY_UINT16_,\n                                             npy_api::NPY_INT32_,\n                                             npy_api::NPY_UINT32_,\n                                             npy_api::NPY_INT64_,\n                                             npy_api::NPY_UINT64_,\n                                             npy_api::NPY_FLOAT_,\n                                             npy_api::NPY_DOUBLE_,\n                                             npy_api::NPY_LONGDOUBLE_,\n                                             npy_api::NPY_CFLOAT_,\n                                             npy_api::NPY_CDOUBLE_,\n                                             npy_api::NPY_CLONGDOUBLE_};\n\npublic:\n    static constexpr int value = values[detail::is_fmt_numeric<T>::index];\n\n    static pybind11::dtype dtype() {\n        if (auto *ptr = npy_api::get().PyArray_DescrFromType_(value)) {\n            return reinterpret_steal<pybind11::dtype>(ptr);\n        }\n        pybind11_fail(\"Unsupported buffer format!\");\n    }\n};\n\n#define PYBIND11_DECL_CHAR_FMT                                                                    \\\n    static constexpr auto name = const_name(\"S\") + const_name<N>();                               \\\n    static pybind11::dtype dtype() {                                                              \\\n        return pybind11::dtype(std::string(\"S\") + std::to_string(N));                             \\\n    }\ntemplate <size_t N>\nstruct npy_format_descriptor<char[N]> {\n    PYBIND11_DECL_CHAR_FMT\n};\ntemplate <size_t N>\nstruct npy_format_descriptor<std::array<char, N>> {\n    PYBIND11_DECL_CHAR_FMT\n};\n#undef PYBIND11_DECL_CHAR_FMT\n\ntemplate <typename T>\nstruct npy_format_descriptor<T, enable_if_t<array_info<T>::is_array>> {\nprivate:\n    using base_descr = npy_format_descriptor<typename array_info<T>::type>;\n\npublic:\n    static_assert(!array_info<T>::is_empty, \"Zero-sized arrays are not supported\");\n\n    static constexpr auto name\n        = const_name(\"(\") + array_info<T>::extents + const_name(\")\") + base_descr::name;\n    static pybind11::dtype dtype() {\n        list shape;\n        array_info<T>::append_extents(shape);\n        return pybind11::dtype::from_args(pybind11::make_tuple(base_descr::dtype(), shape));\n    }\n};\n\ntemplate <typename T>\nstruct npy_format_descriptor<T, enable_if_t<std::is_enum<T>::value>> {\nprivate:\n    using base_descr = npy_format_descriptor<typename std::underlying_type<T>::type>;\n\npublic:\n    static constexpr auto name = base_descr::name;\n    static pybind11::dtype dtype() { return base_descr::dtype(); }\n};\n\nstruct field_descriptor {\n    const char *name;\n    ssize_t offset;\n    ssize_t size;\n    std::string format;\n    dtype descr;\n};\n\nPYBIND11_NOINLINE void register_structured_dtype(any_container<field_descriptor> fields,\n                                                 const std::type_info &tinfo,\n                                                 ssize_t itemsize,\n                                                 bool (*direct_converter)(PyObject *, void *&)) {\n\n    auto &numpy_internals = get_numpy_internals();\n    if (numpy_internals.get_type_info(tinfo, false)) {\n        pybind11_fail(\"NumPy: dtype is already registered\");\n    }\n\n    // Use ordered fields because order matters as of NumPy 1.14:\n    // https://docs.scipy.org/doc/numpy/release.html#multiple-field-indexing-assignment-of-structured-arrays\n    std::vector<field_descriptor> ordered_fields(std::move(fields));\n    std::sort(\n        ordered_fields.begin(),\n        ordered_fields.end(),\n        [](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });\n\n    list names, formats, offsets;\n    for (auto &field : ordered_fields) {\n        if (!field.descr) {\n            pybind11_fail(std::string(\"NumPy: unsupported field dtype: `\") + field.name + \"` @ \"\n                          + tinfo.name());\n        }\n        names.append(PYBIND11_STR_TYPE(field.name));\n        formats.append(field.descr);\n        offsets.append(pybind11::int_(field.offset));\n    }\n    auto *dtype_ptr\n        = pybind11::dtype(std::move(names), std::move(formats), std::move(offsets), itemsize)\n              .release()\n              .ptr();\n\n    // There is an existing bug in NumPy (as of v1.11): trailing bytes are\n    // not encoded explicitly into the format string. This will supposedly\n    // get fixed in v1.12; for further details, see these:\n    // - https://github.com/numpy/numpy/issues/7797\n    // - https://github.com/numpy/numpy/pull/7798\n    // Because of this, we won't use numpy's logic to generate buffer format\n    // strings and will just do it ourselves.\n    ssize_t offset = 0;\n    std::ostringstream oss;\n    // mark the structure as unaligned with '^', because numpy and C++ don't\n    // always agree about alignment (particularly for complex), and we're\n    // explicitly listing all our padding. This depends on none of the fields\n    // overriding the endianness. Putting the ^ in front of individual fields\n    // isn't guaranteed to work due to https://github.com/numpy/numpy/issues/9049\n    oss << \"^T{\";\n    for (auto &field : ordered_fields) {\n        if (field.offset > offset) {\n            oss << (field.offset - offset) << 'x';\n        }\n        oss << field.format << ':' << field.name << ':';\n        offset = field.offset + field.size;\n    }\n    if (itemsize > offset) {\n        oss << (itemsize - offset) << 'x';\n    }\n    oss << '}';\n    auto format_str = oss.str();\n\n    // Sanity check: verify that NumPy properly parses our buffer format string\n    auto &api = npy_api::get();\n    auto arr = array(buffer_info(nullptr, itemsize, format_str, 1));\n    if (!api.PyArray_EquivTypes_(dtype_ptr, arr.dtype().ptr())) {\n        pybind11_fail(\"NumPy: invalid buffer descriptor!\");\n    }\n\n    auto tindex = std::type_index(tinfo);\n    numpy_internals.registered_dtypes[tindex] = {dtype_ptr, format_str};\n    get_internals().direct_conversions[tindex].push_back(direct_converter);\n}\n\ntemplate <typename T, typename SFINAE>\nstruct npy_format_descriptor {\n    static_assert(is_pod_struct<T>::value,\n                  \"Attempt to use a non-POD or unimplemented POD type as a numpy dtype\");\n\n    static constexpr auto name = make_caster<T>::name;\n\n    static pybind11::dtype dtype() { return reinterpret_borrow<pybind11::dtype>(dtype_ptr()); }\n\n    static std::string format() {\n        static auto format_str = get_numpy_internals().get_type_info<T>(true)->format_str;\n        return format_str;\n    }\n\n    static void register_dtype(any_container<field_descriptor> fields) {\n        register_structured_dtype(std::move(fields),\n                                  typeid(typename std::remove_cv<T>::type),\n                                  sizeof(T),\n                                  &direct_converter);\n    }\n\nprivate:\n    static PyObject *dtype_ptr() {\n        static PyObject *ptr = get_numpy_internals().get_type_info<T>(true)->dtype_ptr;\n        return ptr;\n    }\n\n    static bool direct_converter(PyObject *obj, void *&value) {\n        auto &api = npy_api::get();\n        if (!PyObject_TypeCheck(obj, api.PyVoidArrType_Type_)) {\n            return false;\n        }\n        if (auto descr = reinterpret_steal<object>(api.PyArray_DescrFromScalar_(obj))) {\n            if (api.PyArray_EquivTypes_(dtype_ptr(), descr.ptr())) {\n                value = ((PyVoidScalarObject_Proxy *) obj)->obval;\n                return true;\n            }\n        }\n        return false;\n    }\n};\n\n#ifdef __CLION_IDE__ // replace heavy macro with dummy code for the IDE (doesn't affect code)\n#    define PYBIND11_NUMPY_DTYPE(Type, ...) ((void) 0)\n#    define PYBIND11_NUMPY_DTYPE_EX(Type, ...) ((void) 0)\n#else\n\n#    define PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, Name)                                          \\\n        ::pybind11::detail::field_descriptor {                                                    \\\n            Name, offsetof(T, Field), sizeof(decltype(std::declval<T>().Field)),                  \\\n                ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(),       \\\n                ::pybind11::detail::npy_format_descriptor<                                        \\\n                    decltype(std::declval<T>().Field)>::dtype()                                   \\\n        }\n\n// Extract name, offset and format descriptor for a struct field\n#    define PYBIND11_FIELD_DESCRIPTOR(T, Field) PYBIND11_FIELD_DESCRIPTOR_EX(T, Field, #    Field)\n\n// The main idea of this macro is borrowed from https://github.com/swansontec/map-macro\n// (C) William Swanson, Paul Fultz\n#    define PYBIND11_EVAL0(...) __VA_ARGS__\n#    define PYBIND11_EVAL1(...) PYBIND11_EVAL0(PYBIND11_EVAL0(PYBIND11_EVAL0(__VA_ARGS__)))\n#    define PYBIND11_EVAL2(...) PYBIND11_EVAL1(PYBIND11_EVAL1(PYBIND11_EVAL1(__VA_ARGS__)))\n#    define PYBIND11_EVAL3(...) PYBIND11_EVAL2(PYBIND11_EVAL2(PYBIND11_EVAL2(__VA_ARGS__)))\n#    define PYBIND11_EVAL4(...) PYBIND11_EVAL3(PYBIND11_EVAL3(PYBIND11_EVAL3(__VA_ARGS__)))\n#    define PYBIND11_EVAL(...) PYBIND11_EVAL4(PYBIND11_EVAL4(PYBIND11_EVAL4(__VA_ARGS__)))\n#    define PYBIND11_MAP_END(...)\n#    define PYBIND11_MAP_OUT\n#    define PYBIND11_MAP_COMMA ,\n#    define PYBIND11_MAP_GET_END() 0, PYBIND11_MAP_END\n#    define PYBIND11_MAP_NEXT0(test, next, ...) next PYBIND11_MAP_OUT\n#    define PYBIND11_MAP_NEXT1(test, next) PYBIND11_MAP_NEXT0(test, next, 0)\n#    define PYBIND11_MAP_NEXT(test, next) PYBIND11_MAP_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    if defined(_MSC_VER)                                                                         \\\n        && !defined(__clang__) // MSVC is not as eager to expand macros, hence this workaround\n#        define PYBIND11_MAP_LIST_NEXT1(test, next)                                               \\\n            PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))\n#    else\n#        define PYBIND11_MAP_LIST_NEXT1(test, next)                                               \\\n            PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)\n#    endif\n#    define PYBIND11_MAP_LIST_NEXT(test, next)                                                    \\\n        PYBIND11_MAP_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    define PYBIND11_MAP_LIST0(f, t, x, peek, ...)                                                \\\n        f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST1)(f, t, peek, __VA_ARGS__)\n#    define PYBIND11_MAP_LIST1(f, t, x, peek, ...)                                                \\\n        f(t, x) PYBIND11_MAP_LIST_NEXT(peek, PYBIND11_MAP_LIST0)(f, t, peek, __VA_ARGS__)\n// PYBIND11_MAP_LIST(f, t, a1, a2, ...) expands to f(t, a1), f(t, a2), ...\n#    define PYBIND11_MAP_LIST(f, t, ...)                                                          \\\n        PYBIND11_EVAL(PYBIND11_MAP_LIST1(f, t, __VA_ARGS__, (), 0))\n\n#    define PYBIND11_NUMPY_DTYPE(Type, ...)                                                       \\\n        ::pybind11::detail::npy_format_descriptor<Type>::register_dtype(                          \\\n            ::std::vector<::pybind11::detail::field_descriptor>{                                  \\\n                PYBIND11_MAP_LIST(PYBIND11_FIELD_DESCRIPTOR, Type, __VA_ARGS__)})\n\n#    if defined(_MSC_VER) && !defined(__clang__)\n#        define PYBIND11_MAP2_LIST_NEXT1(test, next)                                              \\\n            PYBIND11_EVAL0(PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0))\n#    else\n#        define PYBIND11_MAP2_LIST_NEXT1(test, next)                                              \\\n            PYBIND11_MAP_NEXT0(test, PYBIND11_MAP_COMMA next, 0)\n#    endif\n#    define PYBIND11_MAP2_LIST_NEXT(test, next)                                                   \\\n        PYBIND11_MAP2_LIST_NEXT1(PYBIND11_MAP_GET_END test, next)\n#    define PYBIND11_MAP2_LIST0(f, t, x1, x2, peek, ...)                                          \\\n        f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST1)(f, t, peek, __VA_ARGS__)\n#    define PYBIND11_MAP2_LIST1(f, t, x1, x2, peek, ...)                                          \\\n        f(t, x1, x2) PYBIND11_MAP2_LIST_NEXT(peek, PYBIND11_MAP2_LIST0)(f, t, peek, __VA_ARGS__)\n// PYBIND11_MAP2_LIST(f, t, a1, a2, ...) expands to f(t, a1, a2), f(t, a3, a4), ...\n#    define PYBIND11_MAP2_LIST(f, t, ...)                                                         \\\n        PYBIND11_EVAL(PYBIND11_MAP2_LIST1(f, t, __VA_ARGS__, (), 0))\n\n#    define PYBIND11_NUMPY_DTYPE_EX(Type, ...)                                                    \\\n        ::pybind11::detail::npy_format_descriptor<Type>::register_dtype(                          \\\n            ::std::vector<::pybind11::detail::field_descriptor>{                                  \\\n                PYBIND11_MAP2_LIST(PYBIND11_FIELD_DESCRIPTOR_EX, Type, __VA_ARGS__)})\n\n#endif // __CLION_IDE__\n\nclass common_iterator {\npublic:\n    using container_type = std::vector<ssize_t>;\n    using value_type = container_type::value_type;\n    using size_type = container_type::size_type;\n\n    common_iterator() : m_strides() {}\n\n    common_iterator(void *ptr, const container_type &strides, const container_type &shape)\n        : p_ptr(reinterpret_cast<char *>(ptr)), m_strides(strides.size()) {\n        m_strides.back() = static_cast<value_type>(strides.back());\n        for (size_type i = m_strides.size() - 1; i != 0; --i) {\n            size_type j = i - 1;\n            auto s = static_cast<value_type>(shape[i]);\n            m_strides[j] = strides[j] + m_strides[i] - strides[i] * s;\n        }\n    }\n\n    void increment(size_type dim) { p_ptr += m_strides[dim]; }\n\n    void *data() const { return p_ptr; }\n\nprivate:\n    char *p_ptr{0};\n    container_type m_strides;\n};\n\ntemplate <size_t N>\nclass multi_array_iterator {\npublic:\n    using container_type = std::vector<ssize_t>;\n\n    multi_array_iterator(const std::array<buffer_info, N> &buffers, const container_type &shape)\n        : m_shape(shape.size()), m_index(shape.size(), 0), m_common_iterator() {\n\n        // Manual copy to avoid conversion warning if using std::copy\n        for (size_t i = 0; i < shape.size(); ++i) {\n            m_shape[i] = shape[i];\n        }\n\n        container_type strides(shape.size());\n        for (size_t i = 0; i < N; ++i) {\n            init_common_iterator(buffers[i], shape, m_common_iterator[i], strides);\n        }\n    }\n\n    multi_array_iterator &operator++() {\n        for (size_t j = m_index.size(); j != 0; --j) {\n            size_t i = j - 1;\n            if (++m_index[i] != m_shape[i]) {\n                increment_common_iterator(i);\n                break;\n            }\n            m_index[i] = 0;\n        }\n        return *this;\n    }\n\n    template <size_t K, class T = void>\n    T *data() const {\n        return reinterpret_cast<T *>(m_common_iterator[K].data());\n    }\n\nprivate:\n    using common_iter = common_iterator;\n\n    void init_common_iterator(const buffer_info &buffer,\n                              const container_type &shape,\n                              common_iter &iterator,\n                              container_type &strides) {\n        auto buffer_shape_iter = buffer.shape.rbegin();\n        auto buffer_strides_iter = buffer.strides.rbegin();\n        auto shape_iter = shape.rbegin();\n        auto strides_iter = strides.rbegin();\n\n        while (buffer_shape_iter != buffer.shape.rend()) {\n            if (*shape_iter == *buffer_shape_iter) {\n                *strides_iter = *buffer_strides_iter;\n            } else {\n                *strides_iter = 0;\n            }\n\n            ++buffer_shape_iter;\n            ++buffer_strides_iter;\n            ++shape_iter;\n            ++strides_iter;\n        }\n\n        std::fill(strides_iter, strides.rend(), 0);\n        iterator = common_iter(buffer.ptr, strides, shape);\n    }\n\n    void increment_common_iterator(size_t dim) {\n        for (auto &iter : m_common_iterator) {\n            iter.increment(dim);\n        }\n    }\n\n    container_type m_shape;\n    container_type m_index;\n    std::array<common_iter, N> m_common_iterator;\n};\n\nenum class broadcast_trivial { non_trivial, c_trivial, f_trivial };\n\n// Populates the shape and number of dimensions for the set of buffers.  Returns a\n// broadcast_trivial enum value indicating whether the broadcast is \"trivial\"--that is, has each\n// buffer being either a singleton or a full-size, C-contiguous (`c_trivial`) or Fortran-contiguous\n// (`f_trivial`) storage buffer; returns `non_trivial` otherwise.\ntemplate <size_t N>\nbroadcast_trivial\nbroadcast(const std::array<buffer_info, N> &buffers, ssize_t &ndim, std::vector<ssize_t> &shape) {\n    ndim = std::accumulate(\n        buffers.begin(), buffers.end(), ssize_t(0), [](ssize_t res, const buffer_info &buf) {\n            return std::max(res, buf.ndim);\n        });\n\n    shape.clear();\n    shape.resize((size_t) ndim, 1);\n\n    // Figure out the output size, and make sure all input arrays conform (i.e. are either size 1\n    // or the full size).\n    for (size_t i = 0; i < N; ++i) {\n        auto res_iter = shape.rbegin();\n        auto end = buffers[i].shape.rend();\n        for (auto shape_iter = buffers[i].shape.rbegin(); shape_iter != end;\n             ++shape_iter, ++res_iter) {\n            const auto &dim_size_in = *shape_iter;\n            auto &dim_size_out = *res_iter;\n\n            // Each input dimension can either be 1 or `n`, but `n` values must match across\n            // buffers\n            if (dim_size_out == 1) {\n                dim_size_out = dim_size_in;\n            } else if (dim_size_in != 1 && dim_size_in != dim_size_out) {\n                pybind11_fail(\"pybind11::vectorize: incompatible size/dimension of inputs!\");\n            }\n        }\n    }\n\n    bool trivial_broadcast_c = true;\n    bool trivial_broadcast_f = true;\n    for (size_t i = 0; i < N && (trivial_broadcast_c || trivial_broadcast_f); ++i) {\n        if (buffers[i].size == 1) {\n            continue;\n        }\n\n        // Require the same number of dimensions:\n        if (buffers[i].ndim != ndim) {\n            return broadcast_trivial::non_trivial;\n        }\n\n        // Require all dimensions be full-size:\n        if (!std::equal(buffers[i].shape.cbegin(), buffers[i].shape.cend(), shape.cbegin())) {\n            return broadcast_trivial::non_trivial;\n        }\n\n        // Check for C contiguity (but only if previous inputs were also C contiguous)\n        if (trivial_broadcast_c) {\n            ssize_t expect_stride = buffers[i].itemsize;\n            auto end = buffers[i].shape.crend();\n            for (auto shape_iter = buffers[i].shape.crbegin(),\n                      stride_iter = buffers[i].strides.crbegin();\n                 trivial_broadcast_c && shape_iter != end;\n                 ++shape_iter, ++stride_iter) {\n                if (expect_stride == *stride_iter) {\n                    expect_stride *= *shape_iter;\n                } else {\n                    trivial_broadcast_c = false;\n                }\n            }\n        }\n\n        // Check for Fortran contiguity (if previous inputs were also F contiguous)\n        if (trivial_broadcast_f) {\n            ssize_t expect_stride = buffers[i].itemsize;\n            auto end = buffers[i].shape.cend();\n            for (auto shape_iter = buffers[i].shape.cbegin(),\n                      stride_iter = buffers[i].strides.cbegin();\n                 trivial_broadcast_f && shape_iter != end;\n                 ++shape_iter, ++stride_iter) {\n                if (expect_stride == *stride_iter) {\n                    expect_stride *= *shape_iter;\n                } else {\n                    trivial_broadcast_f = false;\n                }\n            }\n        }\n    }\n\n    return trivial_broadcast_c   ? broadcast_trivial::c_trivial\n           : trivial_broadcast_f ? broadcast_trivial::f_trivial\n                                 : broadcast_trivial::non_trivial;\n}\n\ntemplate <typename T>\nstruct vectorize_arg {\n    static_assert(!std::is_rvalue_reference<T>::value,\n                  \"Functions with rvalue reference arguments cannot be vectorized\");\n    // The wrapped function gets called with this type:\n    using call_type = remove_reference_t<T>;\n    // Is this a vectorized argument?\n    static constexpr bool vectorize\n        = satisfies_any_of<call_type, std::is_arithmetic, is_complex, is_pod>::value\n          && satisfies_none_of<call_type,\n                               std::is_pointer,\n                               std::is_array,\n                               is_std_array,\n                               std::is_enum>::value\n          && (!std::is_reference<T>::value\n              || (std::is_lvalue_reference<T>::value && std::is_const<call_type>::value));\n    // Accept this type: an array for vectorized types, otherwise the type as-is:\n    using type = conditional_t<vectorize, array_t<remove_cv_t<call_type>, array::forcecast>, T>;\n};\n\n// py::vectorize when a return type is present\ntemplate <typename Func, typename Return, typename... Args>\nstruct vectorize_returned_array {\n    using Type = array_t<Return>;\n\n    static Type create(broadcast_trivial trivial, const std::vector<ssize_t> &shape) {\n        if (trivial == broadcast_trivial::f_trivial) {\n            return array_t<Return, array::f_style>(shape);\n        }\n        return array_t<Return>(shape);\n    }\n\n    static Return *mutable_data(Type &array) { return array.mutable_data(); }\n\n    static Return call(Func &f, Args &...args) { return f(args...); }\n\n    static void call(Return *out, size_t i, Func &f, Args &...args) { out[i] = f(args...); }\n};\n\n// py::vectorize when a return type is not present\ntemplate <typename Func, typename... Args>\nstruct vectorize_returned_array<Func, void, Args...> {\n    using Type = none;\n\n    static Type create(broadcast_trivial, const std::vector<ssize_t> &) { return none(); }\n\n    static void *mutable_data(Type &) { return nullptr; }\n\n    static detail::void_type call(Func &f, Args &...args) {\n        f(args...);\n        return {};\n    }\n\n    static void call(void *, size_t, Func &f, Args &...args) { f(args...); }\n};\n\ntemplate <typename Func, typename Return, typename... Args>\nstruct vectorize_helper {\n\n// NVCC for some reason breaks if NVectorized is private\n#ifdef __CUDACC__\npublic:\n#else\nprivate:\n#endif\n\n    static constexpr size_t N = sizeof...(Args);\n    static constexpr size_t NVectorized = constexpr_sum(vectorize_arg<Args>::vectorize...);\n    static_assert(\n        NVectorized >= 1,\n        \"pybind11::vectorize(...) requires a function with at least one vectorizable argument\");\n\npublic:\n    template <typename T,\n              // SFINAE to prevent shadowing the copy constructor.\n              typename = detail::enable_if_t<\n                  !std::is_same<vectorize_helper, typename std::decay<T>::type>::value>>\n    explicit vectorize_helper(T &&f) : f(std::forward<T>(f)) {}\n\n    object operator()(typename vectorize_arg<Args>::type... args) {\n        return run(args...,\n                   make_index_sequence<N>(),\n                   select_indices<vectorize_arg<Args>::vectorize...>(),\n                   make_index_sequence<NVectorized>());\n    }\n\nprivate:\n    remove_reference_t<Func> f;\n\n    // Internal compiler error in MSVC 19.16.27025.1 (Visual Studio 2017 15.9.4), when compiling\n    // with \"/permissive-\" flag when arg_call_types is manually inlined.\n    using arg_call_types = std::tuple<typename vectorize_arg<Args>::call_type...>;\n    template <size_t Index>\n    using param_n_t = typename std::tuple_element<Index, arg_call_types>::type;\n\n    using returned_array = vectorize_returned_array<Func, Return, Args...>;\n\n    // Runs a vectorized function given arguments tuple and three index sequences:\n    //     - Index is the full set of 0 ... (N-1) argument indices;\n    //     - VIndex is the subset of argument indices with vectorized parameters, letting us access\n    //       vectorized arguments (anything not in this sequence is passed through)\n    //     - BIndex is a incremental sequence (beginning at 0) of the same size as VIndex, so that\n    //       we can store vectorized buffer_infos in an array (argument VIndex has its buffer at\n    //       index BIndex in the array).\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    object run(typename vectorize_arg<Args>::type &...args,\n               index_sequence<Index...> i_seq,\n               index_sequence<VIndex...> vi_seq,\n               index_sequence<BIndex...> bi_seq) {\n\n        // Pointers to values the function was called with; the vectorized ones set here will start\n        // out as array_t<T> pointers, but they will be changed them to T pointers before we make\n        // call the wrapped function.  Non-vectorized pointers are left as-is.\n        std::array<void *, N> params{{&args...}};\n\n        // The array of `buffer_info`s of vectorized arguments:\n        std::array<buffer_info, NVectorized> buffers{\n            {reinterpret_cast<array *>(params[VIndex])->request()...}};\n\n        /* Determine dimensions parameters of output array */\n        ssize_t nd = 0;\n        std::vector<ssize_t> shape(0);\n        auto trivial = broadcast(buffers, nd, shape);\n        auto ndim = (size_t) nd;\n\n        size_t size\n            = std::accumulate(shape.begin(), shape.end(), (size_t) 1, std::multiplies<size_t>());\n\n        // If all arguments are 0-dimension arrays (i.e. single values) return a plain value (i.e.\n        // not wrapped in an array).\n        if (size == 1 && ndim == 0) {\n            PYBIND11_EXPAND_SIDE_EFFECTS(params[VIndex] = buffers[BIndex].ptr);\n            return cast(\n                returned_array::call(f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...));\n        }\n\n        auto result = returned_array::create(trivial, shape);\n\n        if (size == 0) {\n            return std::move(result);\n        }\n\n        /* Call the function */\n        auto *mutable_data = returned_array::mutable_data(result);\n        if (trivial == broadcast_trivial::non_trivial) {\n            apply_broadcast(buffers, params, mutable_data, size, shape, i_seq, vi_seq, bi_seq);\n        } else {\n            apply_trivial(buffers, params, mutable_data, size, i_seq, vi_seq, bi_seq);\n        }\n\n        return std::move(result);\n    }\n\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    void apply_trivial(std::array<buffer_info, NVectorized> &buffers,\n                       std::array<void *, N> &params,\n                       Return *out,\n                       size_t size,\n                       index_sequence<Index...>,\n                       index_sequence<VIndex...>,\n                       index_sequence<BIndex...>) {\n\n        // Initialize an array of mutable byte references and sizes with references set to the\n        // appropriate pointer in `params`; as we iterate, we'll increment each pointer by its size\n        // (except for singletons, which get an increment of 0).\n        std::array<std::pair<unsigned char *&, const size_t>, NVectorized> vecparams{\n            {std::pair<unsigned char *&, const size_t>(\n                reinterpret_cast<unsigned char *&>(params[VIndex] = buffers[BIndex].ptr),\n                buffers[BIndex].size == 1 ? 0 : sizeof(param_n_t<VIndex>))...}};\n\n        for (size_t i = 0; i < size; ++i) {\n            returned_array::call(\n                out, i, f, *reinterpret_cast<param_n_t<Index> *>(params[Index])...);\n            for (auto &x : vecparams) {\n                x.first += x.second;\n            }\n        }\n    }\n\n    template <size_t... Index, size_t... VIndex, size_t... BIndex>\n    void apply_broadcast(std::array<buffer_info, NVectorized> &buffers,\n                         std::array<void *, N> &params,\n                         Return *out,\n                         size_t size,\n                         const std::vector<ssize_t> &output_shape,\n                         index_sequence<Index...>,\n                         index_sequence<VIndex...>,\n                         index_sequence<BIndex...>) {\n\n        multi_array_iterator<NVectorized> input_iter(buffers, output_shape);\n\n        for (size_t i = 0; i < size; ++i, ++input_iter) {\n            PYBIND11_EXPAND_SIDE_EFFECTS((params[VIndex] = input_iter.template data<BIndex>()));\n            returned_array::call(\n                out, i, f, *reinterpret_cast<param_n_t<Index> *>(std::get<Index>(params))...);\n        }\n    }\n};\n\ntemplate <typename Func, typename Return, typename... Args>\nvectorize_helper<Func, Return, Args...> vectorize_extractor(const Func &f, Return (*)(Args...)) {\n    return detail::vectorize_helper<Func, Return, Args...>(f);\n}\n\ntemplate <typename T, int Flags>\nstruct handle_type_name<array_t<T, Flags>> {\n    static constexpr auto name\n        = const_name(\"numpy.ndarray[\") + npy_format_descriptor<T>::name + const_name(\"]\");\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n// Vanilla pointer vectorizer:\ntemplate <typename Return, typename... Args>\ndetail::vectorize_helper<Return (*)(Args...), Return, Args...> vectorize(Return (*f)(Args...)) {\n    return detail::vectorize_helper<Return (*)(Args...), Return, Args...>(f);\n}\n\n// lambda vectorizer:\ntemplate <typename Func, detail::enable_if_t<detail::is_lambda<Func>::value, int> = 0>\nauto vectorize(Func &&f)\n    -> decltype(detail::vectorize_extractor(std::forward<Func>(f),\n                                            (detail::function_signature_t<Func> *) nullptr)) {\n    return detail::vectorize_extractor(std::forward<Func>(f),\n                                       (detail::function_signature_t<Func> *) nullptr);\n}\n\n// Vectorize a class method (non-const):\ntemplate <typename Return,\n          typename Class,\n          typename... Args,\n          typename Helper = detail::vectorize_helper<\n              decltype(std::mem_fn(std::declval<Return (Class::*)(Args...)>())),\n              Return,\n              Class *,\n              Args...>>\nHelper vectorize(Return (Class::*f)(Args...)) {\n    return Helper(std::mem_fn(f));\n}\n\n// Vectorize a class method (const):\ntemplate <typename Return,\n          typename Class,\n          typename... Args,\n          typename Helper = detail::vectorize_helper<\n              decltype(std::mem_fn(std::declval<Return (Class::*)(Args...) const>())),\n              Return,\n              const Class *,\n              Args...>>\nHelper vectorize(Return (Class::*f)(Args...) const) {\n    return Helper(std::mem_fn(f));\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/operators.h",
    "content": "/*\n    pybind11/operator.h: Metatemplates for operator overloading\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Enumeration with all supported operator types\nenum op_id : int {\n    op_add,\n    op_sub,\n    op_mul,\n    op_div,\n    op_mod,\n    op_divmod,\n    op_pow,\n    op_lshift,\n    op_rshift,\n    op_and,\n    op_xor,\n    op_or,\n    op_neg,\n    op_pos,\n    op_abs,\n    op_invert,\n    op_int,\n    op_long,\n    op_float,\n    op_str,\n    op_cmp,\n    op_gt,\n    op_ge,\n    op_lt,\n    op_le,\n    op_eq,\n    op_ne,\n    op_iadd,\n    op_isub,\n    op_imul,\n    op_idiv,\n    op_imod,\n    op_ilshift,\n    op_irshift,\n    op_iand,\n    op_ixor,\n    op_ior,\n    op_complex,\n    op_bool,\n    op_nonzero,\n    op_repr,\n    op_truediv,\n    op_itruediv,\n    op_hash\n};\n\nenum op_type : int {\n    op_l, /* base type on left */\n    op_r, /* base type on right */\n    op_u  /* unary operator */\n};\n\nstruct self_t {};\nstatic const self_t self = self_t();\n\n/// Type for an unused type slot\nstruct undefined_t {};\n\n/// Don't warn about an unused variable\ninline self_t __self() { return self; }\n\n/// base template of operator implementations\ntemplate <op_id, op_type, typename B, typename L, typename R>\nstruct op_impl {};\n\n/// Operator implementation generator\ntemplate <op_id id, op_type ot, typename L, typename R>\nstruct op_ {\n    template <typename Class, typename... Extra>\n    void execute(Class &cl, const Extra &...extra) const {\n        using Base = typename Class::type;\n        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;\n        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;\n        using op = op_impl<id, ot, Base, L_type, R_type>;\n        cl.def(op::name(), &op::execute, is_operator(), extra...);\n#if PY_MAJOR_VERSION < 3\n        if (PYBIND11_SILENCE_MSVC_C4127(id == op_truediv)\n            || PYBIND11_SILENCE_MSVC_C4127(id == op_itruediv))\n            cl.def(id == op_itruediv ? \"__idiv__\"\n                   : ot == op_l      ? \"__div__\"\n                                     : \"__rdiv__\",\n                   &op::execute,\n                   is_operator(),\n                   extra...);\n#endif\n    }\n    template <typename Class, typename... Extra>\n    void execute_cast(Class &cl, const Extra &...extra) const {\n        using Base = typename Class::type;\n        using L_type = conditional_t<std::is_same<L, self_t>::value, Base, L>;\n        using R_type = conditional_t<std::is_same<R, self_t>::value, Base, R>;\n        using op = op_impl<id, ot, Base, L_type, R_type>;\n        cl.def(op::name(), &op::execute_cast, is_operator(), extra...);\n#if PY_MAJOR_VERSION < 3\n        if (id == op_truediv || id == op_itruediv)\n            cl.def(id == op_itruediv ? \"__idiv__\"\n                   : ot == op_l      ? \"__div__\"\n                                     : \"__rdiv__\",\n                   &op::execute,\n                   is_operator(),\n                   extra...);\n#endif\n    }\n};\n\n#define PYBIND11_BINARY_OPERATOR(id, rid, op, expr)                                               \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_l, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(const L &l, const R &r) -> decltype(expr) { return (expr); }          \\\n        static B execute_cast(const L &l, const R &r) { return B(expr); }                         \\\n    };                                                                                            \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_r, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #rid \"__\"; }                                      \\\n        static auto execute(const R &r, const L &l) -> decltype(expr) { return (expr); }          \\\n        static B execute_cast(const R &r, const L &l) { return B(expr); }                         \\\n    };                                                                                            \\\n    inline op_<op_##id, op_l, self_t, self_t> op(const self_t &, const self_t &) {                \\\n        return op_<op_##id, op_l, self_t, self_t>();                                              \\\n    }                                                                                             \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \\\n        return op_<op_##id, op_l, self_t, T>();                                                   \\\n    }                                                                                             \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_r, T, self_t> op(const T &, const self_t &) {                                 \\\n        return op_<op_##id, op_r, T, self_t>();                                                   \\\n    }\n\n#define PYBIND11_INPLACE_OPERATOR(id, op, expr)                                                   \\\n    template <typename B, typename L, typename R>                                                 \\\n    struct op_impl<op_##id, op_l, B, L, R> {                                                      \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(L &l, const R &r) -> decltype(expr) { return expr; }                  \\\n        static B execute_cast(L &l, const R &r) { return B(expr); }                               \\\n    };                                                                                            \\\n    template <typename T>                                                                         \\\n    op_<op_##id, op_l, self_t, T> op(const self_t &, const T &) {                                 \\\n        return op_<op_##id, op_l, self_t, T>();                                                   \\\n    }\n\n#define PYBIND11_UNARY_OPERATOR(id, op, expr)                                                     \\\n    template <typename B, typename L>                                                             \\\n    struct op_impl<op_##id, op_u, B, L, undefined_t> {                                            \\\n        static char const *name() { return \"__\" #id \"__\"; }                                       \\\n        static auto execute(const L &l) -> decltype(expr) { return expr; }                        \\\n        static B execute_cast(const L &l) { return B(expr); }                                     \\\n    };                                                                                            \\\n    inline op_<op_##id, op_u, self_t, undefined_t> op(const self_t &) {                           \\\n        return op_<op_##id, op_u, self_t, undefined_t>();                                         \\\n    }\n\nPYBIND11_BINARY_OPERATOR(sub, rsub, operator-, l - r)\nPYBIND11_BINARY_OPERATOR(add, radd, operator+, l + r)\nPYBIND11_BINARY_OPERATOR(mul, rmul, operator*, l *r)\nPYBIND11_BINARY_OPERATOR(truediv, rtruediv, operator/, l / r)\nPYBIND11_BINARY_OPERATOR(mod, rmod, operator%, l % r)\nPYBIND11_BINARY_OPERATOR(lshift, rlshift, operator<<, l << r)\nPYBIND11_BINARY_OPERATOR(rshift, rrshift, operator>>, l >> r)\nPYBIND11_BINARY_OPERATOR(and, rand, operator&, l &r)\nPYBIND11_BINARY_OPERATOR(xor, rxor, operator^, l ^ r)\nPYBIND11_BINARY_OPERATOR(eq, eq, operator==, l == r)\nPYBIND11_BINARY_OPERATOR(ne, ne, operator!=, l != r)\nPYBIND11_BINARY_OPERATOR(or, ror, operator|, l | r)\nPYBIND11_BINARY_OPERATOR(gt, lt, operator>, l > r)\nPYBIND11_BINARY_OPERATOR(ge, le, operator>=, l >= r)\nPYBIND11_BINARY_OPERATOR(lt, gt, operator<, l < r)\nPYBIND11_BINARY_OPERATOR(le, ge, operator<=, l <= r)\n// PYBIND11_BINARY_OPERATOR(pow,       rpow,         pow,          std::pow(l,  r))\nPYBIND11_INPLACE_OPERATOR(iadd, operator+=, l += r)\nPYBIND11_INPLACE_OPERATOR(isub, operator-=, l -= r)\nPYBIND11_INPLACE_OPERATOR(imul, operator*=, l *= r)\nPYBIND11_INPLACE_OPERATOR(itruediv, operator/=, l /= r)\nPYBIND11_INPLACE_OPERATOR(imod, operator%=, l %= r)\nPYBIND11_INPLACE_OPERATOR(ilshift, operator<<=, l <<= r)\nPYBIND11_INPLACE_OPERATOR(irshift, operator>>=, l >>= r)\nPYBIND11_INPLACE_OPERATOR(iand, operator&=, l &= r)\nPYBIND11_INPLACE_OPERATOR(ixor, operator^=, l ^= r)\nPYBIND11_INPLACE_OPERATOR(ior, operator|=, l |= r)\nPYBIND11_UNARY_OPERATOR(neg, operator-, -l)\nPYBIND11_UNARY_OPERATOR(pos, operator+, +l)\n// WARNING: This usage of `abs` should only be done for existing STL overloads.\n// Adding overloads directly in to the `std::` namespace is advised against:\n// https://en.cppreference.com/w/cpp/language/extending_std\nPYBIND11_UNARY_OPERATOR(abs, abs, std::abs(l))\nPYBIND11_UNARY_OPERATOR(hash, hash, std::hash<L>()(l))\nPYBIND11_UNARY_OPERATOR(invert, operator~, (~l))\nPYBIND11_UNARY_OPERATOR(bool, operator!, !!l)\nPYBIND11_UNARY_OPERATOR(int, int_, (int) l)\nPYBIND11_UNARY_OPERATOR(float, float_, (double) l)\n\n#undef PYBIND11_BINARY_OPERATOR\n#undef PYBIND11_INPLACE_OPERATOR\n#undef PYBIND11_UNARY_OPERATOR\nPYBIND11_NAMESPACE_END(detail)\n\nusing detail::self;\n// Add named operators so that they are accessible via `py::`.\nusing detail::hash;\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/options.h",
    "content": "/*\n    pybind11/options.h: global settings that are configurable at runtime.\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nclass options {\npublic:\n    // Default RAII constructor, which leaves settings as they currently are.\n    options() : previous_state(global_state()) {}\n\n    // Class is non-copyable.\n    options(const options &) = delete;\n    options &operator=(const options &) = delete;\n\n    // Destructor, which restores settings that were in effect before.\n    ~options() { global_state() = previous_state; }\n\n    // Setter methods (affect the global state):\n\n    options &disable_user_defined_docstrings() & {\n        global_state().show_user_defined_docstrings = false;\n        return *this;\n    }\n\n    options &enable_user_defined_docstrings() & {\n        global_state().show_user_defined_docstrings = true;\n        return *this;\n    }\n\n    options &disable_function_signatures() & {\n        global_state().show_function_signatures = false;\n        return *this;\n    }\n\n    options &enable_function_signatures() & {\n        global_state().show_function_signatures = true;\n        return *this;\n    }\n\n    options& disable_enum_members_docstring() & { global_state().show_enum_members_docstring = false; return *this; }\n\n    options& enable_enum_members_docstring() & { global_state().show_enum_members_docstring = true; return *this; }\n\n    // Getter methods (return the global state):\n\n    static bool show_user_defined_docstrings() {\n        return global_state().show_user_defined_docstrings;\n    }\n\n    static bool show_function_signatures() { return global_state().show_function_signatures; }\n\n    static bool show_enum_members_docstring() { return global_state().show_enum_members_docstring; }\n\n    // This type is not meant to be allocated on the heap.\n    void *operator new(size_t) = delete;\n\nprivate:\n    struct state {\n        bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.\n        bool show_function_signatures = true;     //< Include auto-generated function signatures\n                                                  //  in docstrings.\n        bool show_enum_members_docstring = true;  //< Include auto-generated member list in enum\n                                                  //  docstrings.\n    };\n\n    static state &global_state() {\n        static state instance;\n        return instance;\n    }\n\n    state previous_state;\n};\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/pybind11.h",
    "content": "/*\n    pybind11/pybind11.h: Main header file of the C++11 python\n    binding generator library\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/class.h\"\n#include \"detail/init.h\"\n#include \"attr.h\"\n#include \"gil.h\"\n#include \"options.h\"\n\n#include <cstdlib>\n#include <cstring>\n#include <memory>\n#include <new>\n#include <string>\n#include <utility>\n#include <vector>\n\n#if defined(__cpp_lib_launder) && !(defined(_MSC_VER) && (_MSC_VER < 1914))\n#    define PYBIND11_STD_LAUNDER std::launder\n#    define PYBIND11_HAS_STD_LAUNDER 1\n#else\n#    define PYBIND11_STD_LAUNDER\n#    define PYBIND11_HAS_STD_LAUNDER 0\n#endif\n#if defined(__GNUG__) && !defined(__clang__)\n#    include <cxxabi.h>\n#endif\n\n/* https://stackoverflow.com/questions/46798456/handling-gccs-noexcept-type-warning\n   This warning is about ABI compatibility, not code health.\n   It is only actually needed in a couple places, but apparently GCC 7 \"generates this warning if\n   and only if the first template instantiation ... involves noexcept\" [stackoverflow], therefore\n   it could get triggered from seemingly random places, depending on user code.\n   No other GCC version generates this warning.\n */\n#if defined(__GNUC__) && __GNUC__ == 7\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wnoexcept-type\"\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n// Apply all the extensions translators from a list\n// Return true if one of the translators completed without raising an exception\n// itself. Return of false indicates that if there are other translators\n// available, they should be tried.\ninline bool apply_exception_translators(std::forward_list<ExceptionTranslator> &translators) {\n    auto last_exception = std::current_exception();\n\n    for (auto &translator : translators) {\n        try {\n            translator(last_exception);\n            return true;\n        } catch (...) {\n            last_exception = std::current_exception();\n        }\n    }\n    return false;\n}\n\n#if defined(_MSC_VER)\n#    define PYBIND11_COMPAT_STRDUP _strdup\n#else\n#    define PYBIND11_COMPAT_STRDUP strdup\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Wraps an arbitrary C++ function/method/lambda function/.. into a callable Python object\nclass cpp_function : public function {\npublic:\n    cpp_function() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(std::nullptr_t) {}\n\n    /// Construct a cpp_function from a vanilla function pointer\n    template <typename Return, typename... Args, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (*f)(Args...), const Extra &...extra) {\n        initialize(f, f, extra...);\n    }\n\n    /// Construct a cpp_function from a lambda function (possibly with internal state)\n    template <typename Func,\n              typename... Extra,\n              typename = detail::enable_if_t<detail::is_lambda<Func>::value>>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Func &&f, const Extra &...extra) {\n        initialize(\n            std::forward<Func>(f), (detail::function_signature_t<Func> *) nullptr, extra...);\n    }\n\n    /// Construct a cpp_function from a class method (non-const, no ref-qualifier)\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...), const Extra &...extra) {\n        initialize(\n            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n            (Return(*)(Class *, Arg...)) nullptr,\n            extra...);\n    }\n\n    /// Construct a cpp_function from a class method (non-const, lvalue ref-qualifier)\n    /// A copy of the overload for non-const functions without explicit ref-qualifier\n    /// but with an added `&`.\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) &, const Extra &...extra) {\n        initialize(\n            [f](Class *c, Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n            (Return(*)(Class *, Arg...)) nullptr,\n            extra...);\n    }\n\n    /// Construct a cpp_function from a class method (const, no ref-qualifier)\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) const, const Extra &...extra) {\n        initialize([f](const Class *c,\n                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n                   (Return(*)(const Class *, Arg...)) nullptr,\n                   extra...);\n    }\n\n    /// Construct a cpp_function from a class method (const, lvalue ref-qualifier)\n    /// A copy of the overload for const functions without explicit ref-qualifier\n    /// but with an added `&`.\n    template <typename Return, typename Class, typename... Arg, typename... Extra>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    cpp_function(Return (Class::*f)(Arg...) const &, const Extra &...extra) {\n        initialize([f](const Class *c,\n                       Arg... args) -> Return { return (c->*f)(std::forward<Arg>(args)...); },\n                   (Return(*)(const Class *, Arg...)) nullptr,\n                   extra...);\n    }\n\n    /// Return the function name\n    object name() const { return attr(\"__name__\"); }\n\nprotected:\n    struct InitializingFunctionRecordDeleter {\n        // `destruct(function_record, false)`: `initialize_generic` copies strings and\n        // takes care of cleaning up in case of exceptions. So pass `false` to `free_strings`.\n        void operator()(detail::function_record *rec) { destruct(rec, false); }\n    };\n    using unique_function_record\n        = std::unique_ptr<detail::function_record, InitializingFunctionRecordDeleter>;\n\n    /// Space optimization: don't inline this frequently instantiated fragment\n    PYBIND11_NOINLINE unique_function_record make_function_record() {\n        return unique_function_record(new detail::function_record());\n    }\n\n    /// Special internal constructor for functors, lambda functions, etc.\n    template <typename Func, typename Return, typename... Args, typename... Extra>\n    void initialize(Func &&f, Return (*)(Args...), const Extra &...extra) {\n        using namespace detail;\n        struct capture {\n            remove_reference_t<Func> f;\n        };\n\n        /* Store the function including any extra state it might have (e.g. a lambda capture\n         * object) */\n        // The unique_ptr makes sure nothing is leaked in case of an exception.\n        auto unique_rec = make_function_record();\n        auto *rec = unique_rec.get();\n\n        /* Store the capture object directly in the function record if there is enough space */\n        if (PYBIND11_SILENCE_MSVC_C4127(sizeof(capture) <= sizeof(rec->data))) {\n            /* Without these pragmas, GCC warns that there might not be\n               enough space to use the placement new operator. However, the\n               'if' statement above ensures that this is the case. */\n#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wplacement-new\"\n#endif\n            new ((capture *) &rec->data) capture{std::forward<Func>(f)};\n#if defined(__GNUG__) && __GNUC__ >= 6 && !defined(__clang__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wstrict-aliasing\"\n#endif\n            // UB without std::launder, but without breaking ABI and/or\n            // a significant refactoring it's \"impossible\" to solve.\n            if (!std::is_trivially_destructible<capture>::value) {\n                rec->free_data = [](function_record *r) {\n                    auto data = PYBIND11_STD_LAUNDER((capture *) &r->data);\n                    (void) data;\n                    data->~capture();\n                };\n            }\n#if defined(__GNUG__) && !PYBIND11_HAS_STD_LAUNDER && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n        } else {\n            rec->data[0] = new capture{std::forward<Func>(f)};\n            rec->free_data = [](function_record *r) { delete ((capture *) r->data[0]); };\n        }\n\n        /* Type casters for the function arguments and return value */\n        using cast_in = argument_loader<Args...>;\n        using cast_out\n            = make_caster<conditional_t<std::is_void<Return>::value, void_type, Return>>;\n\n        static_assert(\n            expected_num_args<Extra...>(\n                sizeof...(Args), cast_in::args_pos >= 0, cast_in::has_kwargs),\n            \"The number of argument annotations does not match the number of function arguments\");\n\n        /* Dispatch code which converts function arguments and performs the actual function call */\n        rec->impl = [](function_call &call) -> handle {\n            cast_in args_converter;\n\n            /* Try to cast the function arguments into the C++ domain */\n            if (!args_converter.load_args(call)) {\n                return PYBIND11_TRY_NEXT_OVERLOAD;\n            }\n\n            /* Invoke call policy pre-call hook */\n            process_attributes<Extra...>::precall(call);\n\n            /* Get a pointer to the capture object */\n            const auto *data = (sizeof(capture) <= sizeof(call.func.data) ? &call.func.data\n                                                                          : call.func.data[0]);\n            auto *cap = const_cast<capture *>(reinterpret_cast<const capture *>(data));\n\n            /* Override policy for rvalues -- usually to enforce rvp::move on an rvalue */\n            return_value_policy policy\n                = return_value_policy_override<Return>::policy(call.func.policy);\n\n            /* Function scope guard -- defaults to the compile-to-nothing `void_type` */\n            using Guard = extract_guard_t<Extra...>;\n\n            /* Perform the function call */\n            handle result\n                = cast_out::cast(std::move(args_converter).template call<Return, Guard>(cap->f),\n                                 policy,\n                                 call.parent);\n\n            /* Invoke call policy post-call hook */\n            process_attributes<Extra...>::postcall(call, result);\n\n            return result;\n        };\n\n        rec->nargs_pos = cast_in::args_pos >= 0\n                             ? static_cast<std::uint16_t>(cast_in::args_pos)\n                             : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if\n                                                                      // we have a kw_only\n        rec->has_args = cast_in::args_pos >= 0;\n        rec->has_kwargs = cast_in::has_kwargs;\n\n        /* Process any user-provided function attributes */\n        process_attributes<Extra...>::init(extra..., rec);\n\n        {\n            constexpr bool has_kw_only_args = any_of<std::is_same<kw_only, Extra>...>::value,\n                           has_pos_only_args = any_of<std::is_same<pos_only, Extra>...>::value,\n                           has_arg_annotations = any_of<is_keyword<Extra>...>::value;\n            static_assert(has_arg_annotations || !has_kw_only_args,\n                          \"py::kw_only requires the use of argument annotations\");\n            static_assert(has_arg_annotations || !has_pos_only_args,\n                          \"py::pos_only requires the use of argument annotations (for docstrings \"\n                          \"and aligning the annotations to the argument)\");\n\n            static_assert(constexpr_sum(is_kw_only<Extra>::value...) <= 1,\n                          \"py::kw_only may be specified only once\");\n            static_assert(constexpr_sum(is_pos_only<Extra>::value...) <= 1,\n                          \"py::pos_only may be specified only once\");\n            constexpr auto kw_only_pos = constexpr_first<is_kw_only, Extra...>();\n            constexpr auto pos_only_pos = constexpr_first<is_pos_only, Extra...>();\n            static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos,\n                          \"py::pos_only must come before py::kw_only\");\n        }\n\n        /* Generate a readable signature describing the function's arguments and return\n           value types */\n        static constexpr auto signature\n            = const_name(\"(\") + cast_in::arg_names + const_name(\") -> \") + cast_out::name;\n        PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();\n\n        /* Register the function with Python from generic (non-templated) code */\n        // Pass on the ownership over the `unique_rec` to `initialize_generic`. `rec` stays valid.\n        initialize_generic(std::move(unique_rec), signature.text, types.data(), sizeof...(Args));\n\n        /* Stash some additional information used by an important optimization in 'functional.h' */\n        using FunctionType = Return (*)(Args...);\n        constexpr bool is_function_ptr\n            = std::is_convertible<Func, FunctionType>::value && sizeof(capture) == sizeof(void *);\n        if (is_function_ptr) {\n            rec->is_stateless = true;\n            rec->data[1]\n                = const_cast<void *>(reinterpret_cast<const void *>(&typeid(FunctionType)));\n        }\n    }\n\n    // Utility class that keeps track of all duplicated strings, and cleans them up in its\n    // destructor, unless they are released. Basically a RAII-solution to deal with exceptions\n    // along the way.\n    class strdup_guard {\n    public:\n        ~strdup_guard() {\n            for (auto *s : strings) {\n                std::free(s);\n            }\n        }\n        char *operator()(const char *s) {\n            auto *t = PYBIND11_COMPAT_STRDUP(s);\n            strings.push_back(t);\n            return t;\n        }\n        void release() { strings.clear(); }\n\n    private:\n        std::vector<char *> strings;\n    };\n\n    /// Register a function call with Python (generic non-templated code goes here)\n    void initialize_generic(unique_function_record &&unique_rec,\n                            const char *text,\n                            const std::type_info *const *types,\n                            size_t args) {\n        // Do NOT receive `unique_rec` by value. If this function fails to move out the unique_ptr,\n        // we do not want this to destruct the pointer. `initialize` (the caller) still relies on\n        // the pointee being alive after this call. Only move out if a `capsule` is going to keep\n        // it alive.\n        auto *rec = unique_rec.get();\n\n        // Keep track of strdup'ed strings, and clean them up as long as the function's capsule\n        // has not taken ownership yet (when `unique_rec.release()` is called).\n        // Note: This cannot easily be fixed by a `unique_ptr` with custom deleter, because the\n        // strings are only referenced before strdup'ing. So only *after* the following block could\n        // `destruct` safely be called, but even then, `repr` could still throw in the middle of\n        // copying all strings.\n        strdup_guard guarded_strdup;\n\n        /* Create copies of all referenced C-style strings */\n        rec->name = guarded_strdup(rec->name ? rec->name : \"\");\n        if (rec->doc) {\n            rec->doc = guarded_strdup(rec->doc);\n        }\n        for (auto &a : rec->args) {\n            if (a.name) {\n                a.name = guarded_strdup(a.name);\n            }\n            if (a.descr) {\n                a.descr = guarded_strdup(a.descr);\n            } else if (a.value) {\n                a.descr = guarded_strdup(repr(a.value).cast<std::string>().c_str());\n            }\n        }\n\n        rec->is_constructor = (std::strcmp(rec->name, \"__init__\") == 0)\n                              || (std::strcmp(rec->name, \"__setstate__\") == 0);\n\n#if !defined(NDEBUG) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)\n        if (rec->is_constructor && !rec->is_new_style_constructor) {\n            const auto class_name\n                = detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());\n            const auto func_name = std::string(rec->name);\n            PyErr_WarnEx(PyExc_FutureWarning,\n                         (\"pybind11-bound class '\" + class_name\n                          + \"' is using an old-style \"\n                            \"placement-new '\"\n                          + func_name\n                          + \"' which has been deprecated. See \"\n                            \"the upgrade guide in pybind11's docs. This message is only visible \"\n                            \"when compiled in debug mode.\")\n                             .c_str(),\n                         0);\n        }\n#endif\n\n        /* Generate a proper function signature */\n        std::string signature;\n        size_t type_index = 0, arg_index = 0;\n        bool is_starred = false;\n        for (const auto *pc = text; *pc != '\\0'; ++pc) {\n            const auto c = *pc;\n\n            if (c == '{') {\n                // Write arg name for everything except *args and **kwargs.\n                is_starred = *(pc + 1) == '*';\n                if (is_starred) {\n                    continue;\n                }\n                // Separator for keyword-only arguments, placed before the kw\n                // arguments start (unless we are already putting an *args)\n                if (!rec->has_args && arg_index == rec->nargs_pos) {\n                    signature += \"*, \";\n                }\n                if (arg_index < rec->args.size() && rec->args[arg_index].name) {\n                    signature += rec->args[arg_index].name;\n                } else if (arg_index == 0 && rec->is_method) {\n                    signature += \"self\";\n                } else {\n                    signature += \"arg\" + std::to_string(arg_index - (rec->is_method ? 1 : 0));\n                }\n                signature += \": \";\n            } else if (c == '}') {\n                // Write default value if available.\n                if (!is_starred && arg_index < rec->args.size() && rec->args[arg_index].descr) {\n                    signature += \" = \";\n                    signature += rec->args[arg_index].descr;\n                }\n                // Separator for positional-only arguments (placed after the\n                // argument, rather than before like *\n                if (rec->nargs_pos_only > 0 && (arg_index + 1) == rec->nargs_pos_only) {\n                    signature += \", /\";\n                }\n                if (!is_starred) {\n                    arg_index++;\n                }\n            } else if (c == '%') {\n                const std::type_info *t = types[type_index++];\n                if (!t) {\n                    pybind11_fail(\"Internal error while parsing type signature (1)\");\n                }\n                if (auto *tinfo = detail::get_type_info(*t)) {\n                    handle th((PyObject *) tinfo->type);\n                    signature += th.attr(\"__module__\").cast<std::string>() + \".\" +\n                                 // Python 3.3+, but we backport it to earlier versions\n                                 th.attr(\"__qualname__\").cast<std::string>();\n                } else if (rec->is_new_style_constructor && arg_index == 0) {\n                    // A new-style `__init__` takes `self` as `value_and_holder`.\n                    // Rewrite it to the proper class type.\n                    signature += rec->scope.attr(\"__module__\").cast<std::string>() + \".\"\n                                 + rec->scope.attr(\"__qualname__\").cast<std::string>();\n                } else {\n                    std::string tname(t->name());\n                    detail::clean_type_id(tname);\n                    signature += tname;\n                }\n            } else {\n                signature += c;\n            }\n        }\n\n        if (arg_index != args - rec->has_args - rec->has_kwargs || types[type_index] != nullptr) {\n            pybind11_fail(\"Internal error while parsing type signature (2)\");\n        }\n\n#if PY_MAJOR_VERSION < 3\n        if (std::strcmp(rec->name, \"__next__\") == 0) {\n            std::free(rec->name);\n            rec->name = guarded_strdup(\"next\");\n        } else if (std::strcmp(rec->name, \"__bool__\") == 0) {\n            std::free(rec->name);\n            rec->name = guarded_strdup(\"__nonzero__\");\n        }\n#endif\n        rec->signature = guarded_strdup(signature.c_str());\n        rec->args.shrink_to_fit();\n        rec->nargs = (std::uint16_t) args;\n\n        if (rec->sibling && PYBIND11_INSTANCE_METHOD_CHECK(rec->sibling.ptr())) {\n            rec->sibling = PYBIND11_INSTANCE_METHOD_GET_FUNCTION(rec->sibling.ptr());\n        }\n\n        detail::function_record *chain = nullptr, *chain_start = rec;\n        if (rec->sibling) {\n            if (PyCFunction_Check(rec->sibling.ptr())) {\n                auto *self = PyCFunction_GET_SELF(rec->sibling.ptr());\n                capsule rec_capsule = isinstance<capsule>(self) ? reinterpret_borrow<capsule>(self)\n                                                                : capsule(self);\n                chain = (detail::function_record *) rec_capsule;\n                /* Never append a method to an overload chain of a parent class;\n                   instead, hide the parent's overloads in this case */\n                if (!chain->scope.is(rec->scope)) {\n                    chain = nullptr;\n                }\n            }\n            // Don't trigger for things like the default __init__, which are wrapper_descriptors\n            // that we are intentionally replacing\n            else if (!rec->sibling.is_none() && rec->name[0] != '_') {\n                pybind11_fail(\"Cannot overload existing non-function object \\\"\"\n                              + std::string(rec->name) + \"\\\" with a function of the same name\");\n            }\n        }\n\n        if (!chain) {\n            /* No existing overload was found, create a new function object */\n            rec->def = new PyMethodDef();\n            std::memset(rec->def, 0, sizeof(PyMethodDef));\n            rec->def->ml_name = rec->name;\n            rec->def->ml_meth\n                = reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(dispatcher));\n            rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;\n\n            capsule rec_capsule(unique_rec.release(),\n                                [](void *ptr) { destruct((detail::function_record *) ptr); });\n            guarded_strdup.release();\n\n            object scope_module;\n            if (rec->scope) {\n                if (hasattr(rec->scope, \"__module__\")) {\n                    scope_module = rec->scope.attr(\"__module__\");\n                } else if (hasattr(rec->scope, \"__name__\")) {\n                    scope_module = rec->scope.attr(\"__name__\");\n                }\n            }\n\n            m_ptr = PyCFunction_NewEx(rec->def, rec_capsule.ptr(), scope_module.ptr());\n            if (!m_ptr) {\n                pybind11_fail(\"cpp_function::cpp_function(): Could not allocate function object\");\n            }\n        } else {\n            /* Append at the beginning or end of the overload chain */\n            m_ptr = rec->sibling.ptr();\n            inc_ref();\n            if (chain->is_method != rec->is_method) {\n                pybind11_fail(\n                    \"overloading a method with both static and instance methods is not supported; \"\n#if defined(NDEBUG)\n                    \"compile in debug mode for more details\"\n#else\n                    \"error while attempting to bind \"\n                    + std::string(rec->is_method ? \"instance\" : \"static\") + \" method \"\n                    + std::string(pybind11::str(rec->scope.attr(\"__name__\"))) + \".\"\n                    + std::string(rec->name) + signature\n#endif\n                );\n            }\n\n            if (rec->prepend) {\n                // Beginning of chain; we need to replace the capsule's current head-of-the-chain\n                // pointer with this one, then make this one point to the previous head of the\n                // chain.\n                chain_start = rec;\n                rec->next = chain;\n                auto rec_capsule\n                    = reinterpret_borrow<capsule>(((PyCFunctionObject *) m_ptr)->m_self);\n                rec_capsule.set_pointer(unique_rec.release());\n                guarded_strdup.release();\n            } else {\n                // Or end of chain (normal behavior)\n                chain_start = chain;\n                while (chain->next) {\n                    chain = chain->next;\n                }\n                chain->next = unique_rec.release();\n                guarded_strdup.release();\n            }\n        }\n\n        std::string signatures;\n        int index = 0;\n        /* Create a nice pydoc rec including all signatures and\n           docstrings of the functions in the overload chain */\n        if (chain && options::show_function_signatures()) {\n            // First a generic signature\n            signatures += rec->name;\n            signatures += \"(*args, **kwargs)\\n\";\n            signatures += \"Overloaded function.\\n\\n\";\n        }\n        // Then specific overload signatures\n        bool first_user_def = true;\n        for (auto *it = chain_start; it != nullptr; it = it->next) {\n            if (options::show_function_signatures()) {\n                if (index > 0) {\n                    signatures += \"\\n\";\n                }\n                if (chain) {\n                    signatures += std::to_string(++index) + \". \";\n                }\n                signatures += rec->name;\n                signatures += it->signature;\n                signatures += \"\\n\";\n            }\n            if (it->doc && it->doc[0] != '\\0' && options::show_user_defined_docstrings()) {\n                // If we're appending another docstring, and aren't printing function signatures,\n                // we need to append a newline first:\n                if (!options::show_function_signatures()) {\n                    if (first_user_def) {\n                        first_user_def = false;\n                    } else {\n                        signatures += \"\\n\";\n                    }\n                }\n                if (options::show_function_signatures()) {\n                    signatures += \"\\n\";\n                }\n                signatures += it->doc;\n                if (options::show_function_signatures()) {\n                    signatures += \"\\n\";\n                }\n            }\n        }\n\n        /* Install docstring */\n        auto *func = (PyCFunctionObject *) m_ptr;\n        std::free(const_cast<char *>(func->m_ml->ml_doc));\n        // Install docstring if it's non-empty (when at least one option is enabled)\n        func->m_ml->ml_doc\n            = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());\n\n        if (rec->is_method) {\n            m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr());\n            if (!m_ptr) {\n                pybind11_fail(\n                    \"cpp_function::cpp_function(): Could not allocate instance method object\");\n            }\n            Py_DECREF(func);\n        }\n    }\n\n    /// When a cpp_function is GCed, release any memory allocated by pybind11\n    static void destruct(detail::function_record *rec, bool free_strings = true) {\n// If on Python 3.9, check the interpreter \"MICRO\" (patch) version.\n// If this is running on 3.9.0, we have to work around a bug.\n#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9\n        static bool is_zero = Py_GetVersion()[4] == '0';\n#endif\n\n        while (rec) {\n            detail::function_record *next = rec->next;\n            if (rec->free_data) {\n                rec->free_data(rec);\n            }\n            // During initialization, these strings might not have been copied yet,\n            // so they cannot be freed. Once the function has been created, they can.\n            // Check `make_function_record` for more details.\n            if (free_strings) {\n                std::free((char *) rec->name);\n                std::free((char *) rec->doc);\n                std::free((char *) rec->signature);\n                for (auto &arg : rec->args) {\n                    std::free(const_cast<char *>(arg.name));\n                    std::free(const_cast<char *>(arg.descr));\n                }\n            }\n            for (auto &arg : rec->args) {\n                arg.value.dec_ref();\n            }\n            if (rec->def) {\n                std::free(const_cast<char *>(rec->def->ml_doc));\n// Python 3.9.0 decref's these in the wrong order; rec->def\n// If loaded on 3.9.0, let these leak (use Python 3.9.1 at runtime to fix)\n// See https://github.com/python/cpython/pull/22670\n#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9\n                if (!is_zero) {\n                    delete rec->def;\n                }\n#else\n                delete rec->def;\n#endif\n            }\n            delete rec;\n            rec = next;\n        }\n    }\n\n    /// Main dispatch logic for calls to functions bound using pybind11\n    static PyObject *dispatcher(PyObject *self, PyObject *args_in, PyObject *kwargs_in) {\n        using namespace detail;\n\n        /* Iterator over the list of potentially admissible overloads */\n        const function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr),\n                              *it = overloads;\n\n        /* Need to know how many arguments + keyword arguments there are to pick the right\n           overload */\n        const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in);\n\n        handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,\n               result = PYBIND11_TRY_NEXT_OVERLOAD;\n\n        auto self_value_and_holder = value_and_holder();\n        if (overloads->is_constructor) {\n            if (!parent\n                || !PyObject_TypeCheck(parent.ptr(), (PyTypeObject *) overloads->scope.ptr())) {\n                PyErr_SetString(\n                    PyExc_TypeError,\n                    \"__init__(self, ...) called with invalid or missing `self` argument\");\n                return nullptr;\n            }\n\n            auto *const tinfo = get_type_info((PyTypeObject *) overloads->scope.ptr());\n            auto *const pi = reinterpret_cast<instance *>(parent.ptr());\n            self_value_and_holder = pi->get_value_and_holder(tinfo, true);\n\n            // If this value is already registered it must mean __init__ is invoked multiple times;\n            // we really can't support that in C++, so just ignore the second __init__.\n            if (self_value_and_holder.instance_registered()) {\n                return none().release().ptr();\n            }\n        }\n\n        try {\n            // We do this in two passes: in the first pass, we load arguments with `convert=false`;\n            // in the second, we allow conversion (except for arguments with an explicit\n            // py::arg().noconvert()).  This lets us prefer calls without conversion, with\n            // conversion as a fallback.\n            std::vector<function_call> second_pass;\n\n            // However, if there are no overloads, we can just skip the no-convert pass entirely\n            const bool overloaded = it != nullptr && it->next != nullptr;\n\n            for (; it != nullptr; it = it->next) {\n\n                /* For each overload:\n                   1. Copy all positional arguments we were given, also checking to make sure that\n                      named positional arguments weren't *also* specified via kwarg.\n                   2. If we weren't given enough, try to make up the omitted ones by checking\n                      whether they were provided by a kwarg matching the `py::arg(\"name\")` name. If\n                      so, use it (and remove it from kwargs); if not, see if the function binding\n                      provided a default that we can use.\n                   3. Ensure that either all keyword arguments were \"consumed\", or that the\n                   function takes a kwargs argument to accept unconsumed kwargs.\n                   4. Any positional arguments still left get put into a tuple (for args), and any\n                      leftover kwargs get put into a dict.\n                   5. Pack everything into a vector; if we have py::args or py::kwargs, they are an\n                      extra tuple or dict at the end of the positional arguments.\n                   6. Call the function call dispatcher (function_record::impl)\n\n                   If one of these fail, move on to the next overload and keep trying until we get\n                   a result other than PYBIND11_TRY_NEXT_OVERLOAD.\n                 */\n\n                const function_record &func = *it;\n                size_t num_args = func.nargs; // Number of positional arguments that we need\n                if (func.has_args) {\n                    --num_args; // (but don't count py::args\n                }\n                if (func.has_kwargs) {\n                    --num_args; //  or py::kwargs)\n                }\n                size_t pos_args = func.nargs_pos;\n\n                if (!func.has_args && n_args_in > pos_args) {\n                    continue; // Too many positional arguments for this overload\n                }\n\n                if (n_args_in < pos_args && func.args.size() < pos_args) {\n                    continue; // Not enough positional arguments given, and not enough defaults to\n                              // fill in the blanks\n                }\n\n                function_call call(func, parent);\n\n                // Protect std::min with parentheses\n                size_t args_to_copy = (std::min)(pos_args, n_args_in);\n                size_t args_copied = 0;\n\n                // 0. Inject new-style `self` argument\n                if (func.is_new_style_constructor) {\n                    // The `value` may have been preallocated by an old-style `__init__`\n                    // if it was a preceding candidate for overload resolution.\n                    if (self_value_and_holder) {\n                        self_value_and_holder.type->dealloc(self_value_and_holder);\n                    }\n\n                    call.init_self = PyTuple_GET_ITEM(args_in, 0);\n                    call.args.emplace_back(reinterpret_cast<PyObject *>(&self_value_and_holder));\n                    call.args_convert.push_back(false);\n                    ++args_copied;\n                }\n\n                // 1. Copy any position arguments given.\n                bool bad_arg = false;\n                for (; args_copied < args_to_copy; ++args_copied) {\n                    const argument_record *arg_rec\n                        = args_copied < func.args.size() ? &func.args[args_copied] : nullptr;\n                    if (kwargs_in && arg_rec && arg_rec->name\n                        && dict_getitemstring(kwargs_in, arg_rec->name)) {\n                        bad_arg = true;\n                        break;\n                    }\n\n                    handle arg(PyTuple_GET_ITEM(args_in, args_copied));\n                    if (arg_rec && !arg_rec->none && arg.is_none()) {\n                        bad_arg = true;\n                        break;\n                    }\n                    call.args.push_back(arg);\n                    call.args_convert.push_back(arg_rec ? arg_rec->convert : true);\n                }\n                if (bad_arg) {\n                    continue; // Maybe it was meant for another overload (issue #688)\n                }\n\n                // Keep track of how many position args we copied out in case we need to come back\n                // to copy the rest into a py::args argument.\n                size_t positional_args_copied = args_copied;\n\n                // We'll need to copy this if we steal some kwargs for defaults\n                dict kwargs = reinterpret_borrow<dict>(kwargs_in);\n\n                // 1.5. Fill in any missing pos_only args from defaults if they exist\n                if (args_copied < func.nargs_pos_only) {\n                    for (; args_copied < func.nargs_pos_only; ++args_copied) {\n                        const auto &arg_rec = func.args[args_copied];\n                        handle value;\n\n                        if (arg_rec.value) {\n                            value = arg_rec.value;\n                        }\n                        if (value) {\n                            call.args.push_back(value);\n                            call.args_convert.push_back(arg_rec.convert);\n                        } else {\n                            break;\n                        }\n                    }\n\n                    if (args_copied < func.nargs_pos_only) {\n                        continue; // Not enough defaults to fill the positional arguments\n                    }\n                }\n\n                // 2. Check kwargs and, failing that, defaults that may help complete the list\n                if (args_copied < num_args) {\n                    bool copied_kwargs = false;\n\n                    for (; args_copied < num_args; ++args_copied) {\n                        const auto &arg_rec = func.args[args_copied];\n\n                        handle value;\n                        if (kwargs_in && arg_rec.name) {\n                            value = dict_getitemstring(kwargs.ptr(), arg_rec.name);\n                        }\n\n                        if (value) {\n                            // Consume a kwargs value\n                            if (!copied_kwargs) {\n                                kwargs = reinterpret_steal<dict>(PyDict_Copy(kwargs.ptr()));\n                                copied_kwargs = true;\n                            }\n                            if (PyDict_DelItemString(kwargs.ptr(), arg_rec.name) == -1) {\n                                throw error_already_set();\n                            }\n                        } else if (arg_rec.value) {\n                            value = arg_rec.value;\n                        }\n\n                        if (!arg_rec.none && value.is_none()) {\n                            break;\n                        }\n\n                        if (value) {\n                            // If we're at the py::args index then first insert a stub for it to be\n                            // replaced later\n                            if (func.has_args && call.args.size() == func.nargs_pos) {\n                                call.args.push_back(none());\n                            }\n\n                            call.args.push_back(value);\n                            call.args_convert.push_back(arg_rec.convert);\n                        } else {\n                            break;\n                        }\n                    }\n\n                    if (args_copied < num_args) {\n                        continue; // Not enough arguments, defaults, or kwargs to fill the\n                                  // positional arguments\n                    }\n                }\n\n                // 3. Check everything was consumed (unless we have a kwargs arg)\n                if (kwargs && !kwargs.empty() && !func.has_kwargs) {\n                    continue; // Unconsumed kwargs, but no py::kwargs argument to accept them\n                }\n\n                // 4a. If we have a py::args argument, create a new tuple with leftovers\n                if (func.has_args) {\n                    tuple extra_args;\n                    if (args_to_copy == 0) {\n                        // We didn't copy out any position arguments from the args_in tuple, so we\n                        // can reuse it directly without copying:\n                        extra_args = reinterpret_borrow<tuple>(args_in);\n                    } else if (positional_args_copied >= n_args_in) {\n                        extra_args = tuple(0);\n                    } else {\n                        size_t args_size = n_args_in - positional_args_copied;\n                        extra_args = tuple(args_size);\n                        for (size_t i = 0; i < args_size; ++i) {\n                            extra_args[i] = PyTuple_GET_ITEM(args_in, positional_args_copied + i);\n                        }\n                    }\n                    if (call.args.size() <= func.nargs_pos) {\n                        call.args.push_back(extra_args);\n                    } else {\n                        call.args[func.nargs_pos] = extra_args;\n                    }\n                    call.args_convert.push_back(false);\n                    call.args_ref = std::move(extra_args);\n                }\n\n                // 4b. If we have a py::kwargs, pass on any remaining kwargs\n                if (func.has_kwargs) {\n                    if (!kwargs.ptr()) {\n                        kwargs = dict(); // If we didn't get one, send an empty one\n                    }\n                    call.args.push_back(kwargs);\n                    call.args_convert.push_back(false);\n                    call.kwargs_ref = std::move(kwargs);\n                }\n\n// 5. Put everything in a vector.  Not technically step 5, we've been building it\n// in `call.args` all along.\n#if !defined(NDEBUG)\n                if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {\n                    pybind11_fail(\"Internal error: function call dispatcher inserted wrong number \"\n                                  \"of arguments!\");\n                }\n#endif\n\n                std::vector<bool> second_pass_convert;\n                if (overloaded) {\n                    // We're in the first no-convert pass, so swap out the conversion flags for a\n                    // set of all-false flags.  If the call fails, we'll swap the flags back in for\n                    // the conversion-allowed call below.\n                    second_pass_convert.resize(func.nargs, false);\n                    call.args_convert.swap(second_pass_convert);\n                }\n\n                // 6. Call the function.\n                try {\n                    loader_life_support guard{};\n                    result = func.impl(call);\n                } catch (reference_cast_error &) {\n                    result = PYBIND11_TRY_NEXT_OVERLOAD;\n                }\n\n                if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {\n                    break;\n                }\n\n                if (overloaded) {\n                    // The (overloaded) call failed; if the call has at least one argument that\n                    // permits conversion (i.e. it hasn't been explicitly specified `.noconvert()`)\n                    // then add this call to the list of second pass overloads to try.\n                    for (size_t i = func.is_method ? 1 : 0; i < pos_args; i++) {\n                        if (second_pass_convert[i]) {\n                            // Found one: swap the converting flags back in and store the call for\n                            // the second pass.\n                            call.args_convert.swap(second_pass_convert);\n                            second_pass.push_back(std::move(call));\n                            break;\n                        }\n                    }\n                }\n            }\n\n            if (overloaded && !second_pass.empty() && result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {\n                // The no-conversion pass finished without success, try again with conversion\n                // allowed\n                for (auto &call : second_pass) {\n                    try {\n                        loader_life_support guard{};\n                        result = call.func.impl(call);\n                    } catch (reference_cast_error &) {\n                        result = PYBIND11_TRY_NEXT_OVERLOAD;\n                    }\n\n                    if (result.ptr() != PYBIND11_TRY_NEXT_OVERLOAD) {\n                        // The error reporting logic below expects 'it' to be valid, as it would be\n                        // if we'd encountered this failure in the first-pass loop.\n                        if (!result) {\n                            it = &call.func;\n                        }\n                        break;\n                    }\n                }\n            }\n        } catch (error_already_set &e) {\n            e.restore();\n            return nullptr;\n#ifdef __GLIBCXX__\n        } catch (abi::__forced_unwind &) {\n            throw;\n#endif\n        } catch (...) {\n            /* When an exception is caught, give each registered exception\n               translator a chance to translate it to a Python exception. First\n               all module-local translators will be tried in reverse order of\n               registration. If none of the module-locale translators handle\n               the exception (or there are no module-locale translators) then\n               the global translators will be tried, also in reverse order of\n               registration.\n\n               A translator may choose to do one of the following:\n\n                - catch the exception and call PyErr_SetString or PyErr_SetObject\n                  to set a standard (or custom) Python exception, or\n                - do nothing and let the exception fall through to the next translator, or\n                - delegate translation to the next translator by throwing a new type of exception.\n             */\n\n            auto &local_exception_translators\n                = get_local_internals().registered_exception_translators;\n            if (detail::apply_exception_translators(local_exception_translators)) {\n                return nullptr;\n            }\n            auto &exception_translators = get_internals().registered_exception_translators;\n            if (detail::apply_exception_translators(exception_translators)) {\n                return nullptr;\n            }\n\n            PyErr_SetString(PyExc_SystemError,\n                            \"Exception escaped from default exception translator!\");\n            return nullptr;\n        }\n\n        auto append_note_if_missing_header_is_suspected = [](std::string &msg) {\n            if (msg.find(\"std::\") != std::string::npos) {\n                msg += \"\\n\\n\"\n                       \"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\\n\"\n                       \"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\\n\"\n                       \"conversions are optional and require extra headers to be included\\n\"\n                       \"when compiling your pybind11 module.\";\n            }\n        };\n\n        if (result.ptr() == PYBIND11_TRY_NEXT_OVERLOAD) {\n            if (overloads->is_operator) {\n                return handle(Py_NotImplemented).inc_ref().ptr();\n            }\n\n            std::string msg = std::string(overloads->name) + \"(): incompatible \"\n                              + std::string(overloads->is_constructor ? \"constructor\" : \"function\")\n                              + \" arguments. The following argument types are supported:\\n\";\n\n            int ctr = 0;\n            for (const function_record *it2 = overloads; it2 != nullptr; it2 = it2->next) {\n                msg += \"    \" + std::to_string(++ctr) + \". \";\n\n                bool wrote_sig = false;\n                if (overloads->is_constructor) {\n                    // For a constructor, rewrite `(self: Object, arg0, ...) -> NoneType` as\n                    // `Object(arg0, ...)`\n                    std::string sig = it2->signature;\n                    size_t start = sig.find('(') + 7; // skip \"(self: \"\n                    if (start < sig.size()) {\n                        // End at the , for the next argument\n                        size_t end = sig.find(\", \"), next = end + 2;\n                        size_t ret = sig.rfind(\" -> \");\n                        // Or the ), if there is no comma:\n                        if (end >= sig.size()) {\n                            next = end = sig.find(')');\n                        }\n                        if (start < end && next < sig.size()) {\n                            msg.append(sig, start, end - start);\n                            msg += '(';\n                            msg.append(sig, next, ret - next);\n                            wrote_sig = true;\n                        }\n                    }\n                }\n                if (!wrote_sig) {\n                    msg += it2->signature;\n                }\n\n                msg += \"\\n\";\n            }\n            msg += \"\\nInvoked with: \";\n            auto args_ = reinterpret_borrow<tuple>(args_in);\n            bool some_args = false;\n            for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {\n                if (!some_args) {\n                    some_args = true;\n                } else {\n                    msg += \", \";\n                }\n                try {\n                    msg += pybind11::repr(args_[ti]);\n                } catch (const error_already_set &) {\n                    msg += \"<repr raised Error>\";\n                }\n            }\n            if (kwargs_in) {\n                auto kwargs = reinterpret_borrow<dict>(kwargs_in);\n                if (!kwargs.empty()) {\n                    if (some_args) {\n                        msg += \"; \";\n                    }\n                    msg += \"kwargs: \";\n                    bool first = true;\n                    for (auto kwarg : kwargs) {\n                        if (first) {\n                            first = false;\n                        } else {\n                            msg += \", \";\n                        }\n                        msg += pybind11::str(\"{}=\").format(kwarg.first);\n                        try {\n                            msg += pybind11::repr(kwarg.second);\n                        } catch (const error_already_set &) {\n                            msg += \"<repr raised Error>\";\n                        }\n                    }\n                }\n            }\n\n            append_note_if_missing_header_is_suspected(msg);\n#if PY_VERSION_HEX >= 0x03030000\n            // Attach additional error info to the exception if supported\n            if (PyErr_Occurred()) {\n                // #HelpAppreciated: unit test coverage for this branch.\n                raise_from(PyExc_TypeError, msg.c_str());\n                return nullptr;\n            }\n#endif\n            PyErr_SetString(PyExc_TypeError, msg.c_str());\n            return nullptr;\n        }\n        if (!result) {\n            std::string msg = \"Unable to convert function return value to a \"\n                              \"Python type! The signature was\\n\\t\";\n            msg += it->signature;\n            append_note_if_missing_header_is_suspected(msg);\n#if PY_VERSION_HEX >= 0x03030000\n            // Attach additional error info to the exception if supported\n            if (PyErr_Occurred()) {\n                raise_from(PyExc_TypeError, msg.c_str());\n                return nullptr;\n            }\n#endif\n            PyErr_SetString(PyExc_TypeError, msg.c_str());\n            return nullptr;\n        }\n        if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {\n            auto *pi = reinterpret_cast<instance *>(parent.ptr());\n            self_value_and_holder.type->init_instance(pi, nullptr);\n        }\n        return result.ptr();\n    }\n};\n\n/// Wrapper for Python extension modules\nclass module_ : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(module_, object, PyModule_Check)\n\n    /// Create a new top-level Python module with the given name and docstring\n    PYBIND11_DEPRECATED(\"Use PYBIND11_MODULE or module_::create_extension_module instead\")\n    explicit module_(const char *name, const char *doc = nullptr) {\n#if PY_MAJOR_VERSION >= 3\n        *this = create_extension_module(name, doc, new PyModuleDef());\n#else\n        *this = create_extension_module(name, doc, nullptr);\n#endif\n    }\n\n    /** \\rst\n        Create Python binding for a new function within the module scope. ``Func``\n        can be a plain C++ function, a function pointer, or a lambda function. For\n        details on the ``Extra&& ... extra`` argument, see section :ref:`extras`.\n    \\endrst */\n    template <typename Func, typename... Extra>\n    module_ &def(const char *name_, Func &&f, const Extra &...extra) {\n        cpp_function func(std::forward<Func>(f),\n                          name(name_),\n                          scope(*this),\n                          sibling(getattr(*this, name_, none())),\n                          extra...);\n        // NB: allow overwriting here because cpp_function sets up a chain with the intention of\n        // overwriting (and has already checked internally that it isn't overwriting\n        // non-functions).\n        add_object(name_, func, true /* overwrite */);\n        return *this;\n    }\n\n    /** \\rst\n        Create and return a new Python submodule with the given name and docstring.\n        This also works recursively, i.e.\n\n        .. code-block:: cpp\n\n            py::module_ m(\"example\", \"pybind11 example plugin\");\n            py::module_ m2 = m.def_submodule(\"sub\", \"A submodule of 'example'\");\n            py::module_ m3 = m2.def_submodule(\"subsub\", \"A submodule of 'example.sub'\");\n    \\endrst */\n    module_ def_submodule(const char *name, const char *doc = nullptr) {\n        std::string full_name\n            = std::string(PyModule_GetName(m_ptr)) + std::string(\".\") + std::string(name);\n        auto result = reinterpret_borrow<module_>(PyImport_AddModule(full_name.c_str()));\n        if (doc && options::show_user_defined_docstrings()) {\n            result.attr(\"__doc__\") = pybind11::str(doc);\n        }\n        attr(name) = result;\n        return result;\n    }\n\n    /// Import and return a module or throws `error_already_set`.\n    static module_ import(const char *name) {\n        PyObject *obj = PyImport_ImportModule(name);\n        if (!obj) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<module_>(obj);\n    }\n\n    /// Reload the module or throws `error_already_set`.\n    void reload() {\n        PyObject *obj = PyImport_ReloadModule(ptr());\n        if (!obj) {\n            throw error_already_set();\n        }\n        *this = reinterpret_steal<module_>(obj);\n    }\n\n    /** \\rst\n        Adds an object to the module using the given name.  Throws if an object with the given name\n        already exists.\n\n        ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11\n        has established will, in most cases, break things.\n    \\endrst */\n    PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) {\n        if (!overwrite && hasattr(*this, name)) {\n            pybind11_fail(\n                \"Error during initialization: multiple incompatible definitions with name \\\"\"\n                + std::string(name) + \"\\\"\");\n        }\n\n        PyModule_AddObject(ptr(), name, obj.inc_ref().ptr() /* steals a reference */);\n    }\n\n#if PY_MAJOR_VERSION >= 3\n    using module_def = PyModuleDef;\n#else\n    struct module_def {};\n#endif\n\n    /** \\rst\n        Create a new top-level module that can be used as the main module of a C extension.\n\n        For Python 3, ``def`` should point to a statically allocated module_def.\n        For Python 2, ``def`` can be a nullptr and is completely ignored.\n    \\endrst */\n    static module_ create_extension_module(const char *name, const char *doc, module_def *def) {\n#if PY_MAJOR_VERSION >= 3\n        // module_def is PyModuleDef\n        // Placement new (not an allocation).\n        def = new (def)\n            PyModuleDef{/* m_base */ PyModuleDef_HEAD_INIT,\n                        /* m_name */ name,\n                        /* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,\n                        /* m_size */ -1,\n                        /* m_methods */ nullptr,\n                        /* m_slots */ nullptr,\n                        /* m_traverse */ nullptr,\n                        /* m_clear */ nullptr,\n                        /* m_free */ nullptr};\n        auto *m = PyModule_Create(def);\n#else\n        // Ignore module_def *def; only necessary for Python 3\n        (void) def;\n        auto m = Py_InitModule3(\n            name, nullptr, options::show_user_defined_docstrings() ? doc : nullptr);\n#endif\n        if (m == nullptr) {\n            if (PyErr_Occurred()) {\n                throw error_already_set();\n            }\n            pybind11_fail(\"Internal error in module_::create_extension_module()\");\n        }\n        // TODO: Should be reinterpret_steal for Python 3, but Python also steals it again when\n        // returned from PyInit_...\n        //       For Python 2, reinterpret_borrow is correct.\n        return reinterpret_borrow<module_>(m);\n    }\n};\n\n// When inside a namespace (or anywhere as long as it's not the first item on a line),\n// C++20 allows \"module\" to be used. This is provided for backward compatibility, and for\n// simplicity, if someone wants to use py::module for example, that is perfectly safe.\nusing module = module_;\n\n/// \\ingroup python_builtins\n/// Return a dictionary representing the global variables in the current execution frame,\n/// or ``__main__.__dict__`` if there is no frame (usually when the interpreter is embedded).\ninline dict globals() {\n    PyObject *p = PyEval_GetGlobals();\n    return reinterpret_borrow<dict>(p ? p : module_::import(\"__main__\").attr(\"__dict__\").ptr());\n}\n\n#if PY_VERSION_HEX >= 0x03030000\ntemplate <typename... Args, typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>>\nPYBIND11_DEPRECATED(\"make_simple_namespace should be replaced with \"\n                    \"py::module_::import(\\\"types\\\").attr(\\\"SimpleNamespace\\\") \")\nobject make_simple_namespace(Args &&...args_) {\n    return module_::import(\"types\").attr(\"SimpleNamespace\")(std::forward<Args>(args_)...);\n}\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n/// Generic support for creating new Python heap types\nclass generic_type : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(generic_type, object, PyType_Check)\nprotected:\n    void initialize(const type_record &rec) {\n        if (rec.scope && hasattr(rec.scope, \"__dict__\")\n            && rec.scope.attr(\"__dict__\").contains(rec.name)) {\n            pybind11_fail(\"generic_type: cannot initialize type \\\"\" + std::string(rec.name)\n                          + \"\\\": an object with that name is already defined\");\n        }\n\n        if ((rec.module_local ? get_local_type_info(*rec.type) : get_global_type_info(*rec.type))\n            != nullptr) {\n            pybind11_fail(\"generic_type: type \\\"\" + std::string(rec.name)\n                          + \"\\\" is already registered!\");\n        }\n\n        m_ptr = make_new_python_type(rec);\n\n        /* Register supplemental type information in C++ dict */\n        auto *tinfo = new detail::type_info();\n        tinfo->type = (PyTypeObject *) m_ptr;\n        tinfo->cpptype = rec.type;\n        tinfo->type_size = rec.type_size;\n        tinfo->type_align = rec.type_align;\n        tinfo->operator_new = rec.operator_new;\n        tinfo->holder_size_in_ptrs = size_in_ptrs(rec.holder_size);\n        tinfo->init_instance = rec.init_instance;\n        tinfo->dealloc = rec.dealloc;\n        tinfo->simple_type = true;\n        tinfo->simple_ancestors = true;\n        tinfo->default_holder = rec.default_holder;\n        tinfo->module_local = rec.module_local;\n\n        auto &internals = get_internals();\n        auto tindex = std::type_index(*rec.type);\n        tinfo->direct_conversions = &internals.direct_conversions[tindex];\n        if (rec.module_local) {\n            get_local_internals().registered_types_cpp[tindex] = tinfo;\n        } else {\n            internals.registered_types_cpp[tindex] = tinfo;\n        }\n        internals.registered_types_py[(PyTypeObject *) m_ptr] = {tinfo};\n\n        if (rec.bases.size() > 1 || rec.multiple_inheritance) {\n            mark_parents_nonsimple(tinfo->type);\n            tinfo->simple_ancestors = false;\n        } else if (rec.bases.size() == 1) {\n            auto *parent_tinfo = get_type_info((PyTypeObject *) rec.bases[0].ptr());\n            assert(parent_tinfo != nullptr);\n            bool parent_simple_ancestors = parent_tinfo->simple_ancestors;\n            tinfo->simple_ancestors = parent_simple_ancestors;\n            // The parent can no longer be a simple type if it has MI and has a child\n            parent_tinfo->simple_type = parent_tinfo->simple_type && parent_simple_ancestors;\n        }\n\n        if (rec.module_local) {\n            // Stash the local typeinfo and loader so that external modules can access it.\n            tinfo->module_local_load = &type_caster_generic::local_load;\n            setattr(m_ptr, PYBIND11_MODULE_LOCAL_ID, capsule(tinfo));\n        }\n    }\n\n    /// Helper function which tags all parents of a type using mult. inheritance\n    void mark_parents_nonsimple(PyTypeObject *value) {\n        auto t = reinterpret_borrow<tuple>(value->tp_bases);\n        for (handle h : t) {\n            auto *tinfo2 = get_type_info((PyTypeObject *) h.ptr());\n            if (tinfo2) {\n                tinfo2->simple_type = false;\n            }\n            mark_parents_nonsimple((PyTypeObject *) h.ptr());\n        }\n    }\n\n    void install_buffer_funcs(buffer_info *(*get_buffer)(PyObject *, void *),\n                              void *get_buffer_data) {\n        auto *type = (PyHeapTypeObject *) m_ptr;\n        auto *tinfo = detail::get_type_info(&type->ht_type);\n\n        if (!type->ht_type.tp_as_buffer) {\n            pybind11_fail(\"To be able to register buffer protocol support for the type '\"\n                          + get_fully_qualified_tp_name(tinfo->type)\n                          + \"' the associated class<>(..) invocation must \"\n                            \"include the pybind11::buffer_protocol() annotation!\");\n        }\n\n        tinfo->get_buffer = get_buffer;\n        tinfo->get_buffer_data = get_buffer_data;\n    }\n\n    // rec_func must be set for either fget or fset.\n    void def_property_static_impl(const char *name,\n                                  handle fget,\n                                  handle fset,\n                                  detail::function_record *rec_func) {\n        const auto is_static = (rec_func != nullptr) && !(rec_func->is_method && rec_func->scope);\n        const auto has_doc = (rec_func != nullptr) && (rec_func->doc != nullptr)\n                             && pybind11::options::show_user_defined_docstrings();\n        auto property = handle(\n            (PyObject *) (is_static ? get_internals().static_property_type : &PyProperty_Type));\n        attr(name) = property(fget.ptr() ? fget : none(),\n                              fset.ptr() ? fset : none(),\n                              /*deleter*/ none(),\n                              pybind11::str(has_doc ? rec_func->doc : \"\"));\n    }\n};\n\n/// Set the pointer to operator new if it exists. The cast is needed because it can be overloaded.\ntemplate <typename T,\n          typename = void_t<decltype(static_cast<void *(*) (size_t)>(T::operator new))>>\nvoid set_operator_new(type_record *r) {\n    r->operator_new = &T::operator new;\n}\n\ntemplate <typename>\nvoid set_operator_new(...) {}\n\ntemplate <typename T, typename SFINAE = void>\nstruct has_operator_delete : std::false_type {};\ntemplate <typename T>\nstruct has_operator_delete<T, void_t<decltype(static_cast<void (*)(void *)>(T::operator delete))>>\n    : std::true_type {};\ntemplate <typename T, typename SFINAE = void>\nstruct has_operator_delete_size : std::false_type {};\ntemplate <typename T>\nstruct has_operator_delete_size<\n    T,\n    void_t<decltype(static_cast<void (*)(void *, size_t)>(T::operator delete))>> : std::true_type {\n};\n/// Call class-specific delete if it exists or global otherwise. Can also be an overload set.\ntemplate <typename T, enable_if_t<has_operator_delete<T>::value, int> = 0>\nvoid call_operator_delete(T *p, size_t, size_t) {\n    T::operator delete(p);\n}\ntemplate <\n    typename T,\n    enable_if_t<!has_operator_delete<T>::value && has_operator_delete_size<T>::value, int> = 0>\nvoid call_operator_delete(T *p, size_t s, size_t) {\n    T::operator delete(p, s);\n}\n\ninline void call_operator_delete(void *p, size_t s, size_t a) {\n    (void) s;\n    (void) a;\n#if defined(__cpp_aligned_new) && (!defined(_MSC_VER) || _MSC_VER >= 1912)\n    if (a > __STDCPP_DEFAULT_NEW_ALIGNMENT__) {\n#    ifdef __cpp_sized_deallocation\n        ::operator delete(p, s, std::align_val_t(a));\n#    else\n        ::operator delete(p, std::align_val_t(a));\n#    endif\n        return;\n    }\n#endif\n#ifdef __cpp_sized_deallocation\n    ::operator delete(p, s);\n#else\n    ::operator delete(p);\n#endif\n}\n\ninline void add_class_method(object &cls, const char *name_, const cpp_function &cf) {\n    cls.attr(cf.name()) = cf;\n    if (std::strcmp(name_, \"__eq__\") == 0 && !cls.attr(\"__dict__\").contains(\"__hash__\")) {\n        cls.attr(\"__hash__\") = none();\n    }\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Given a pointer to a member function, cast it to its `Derived` version.\n/// Forward everything else unchanged.\ntemplate <typename /*Derived*/, typename F>\nauto method_adaptor(F &&f) -> decltype(std::forward<F>(f)) {\n    return std::forward<F>(f);\n}\n\ntemplate <typename Derived, typename Return, typename Class, typename... Args>\nauto method_adaptor(Return (Class::*pmf)(Args...)) -> Return (Derived::*)(Args...) {\n    static_assert(\n        detail::is_accessible_base_of<Class, Derived>::value,\n        \"Cannot bind an inaccessible base class method; use a lambda definition instead\");\n    return pmf;\n}\n\ntemplate <typename Derived, typename Return, typename Class, typename... Args>\nauto method_adaptor(Return (Class::*pmf)(Args...) const) -> Return (Derived::*)(Args...) const {\n    static_assert(\n        detail::is_accessible_base_of<Class, Derived>::value,\n        \"Cannot bind an inaccessible base class method; use a lambda definition instead\");\n    return pmf;\n}\n\ntemplate <typename type_, typename... options>\nclass class_ : public detail::generic_type {\n    template <typename T>\n    using is_holder = detail::is_holder_type<type_, T>;\n    template <typename T>\n    using is_subtype = detail::is_strict_base_of<type_, T>;\n    template <typename T>\n    using is_base = detail::is_strict_base_of<T, type_>;\n    // struct instead of using here to help MSVC:\n    template <typename T>\n    struct is_valid_class_option : detail::any_of<is_holder<T>, is_subtype<T>, is_base<T>> {};\n\npublic:\n    using type = type_;\n    using type_alias = detail::exactly_one_t<is_subtype, void, options...>;\n    constexpr static bool has_alias = !std::is_void<type_alias>::value;\n    using holder_type = detail::exactly_one_t<is_holder, std::unique_ptr<type>, options...>;\n\n    static_assert(detail::all_of<is_valid_class_option<options>...>::value,\n                  \"Unknown/invalid class_ template parameters provided\");\n\n    static_assert(!has_alias || std::is_polymorphic<type>::value,\n                  \"Cannot use an alias class with a non-polymorphic type\");\n\n    PYBIND11_OBJECT(class_, generic_type, PyType_Check)\n\n    template <typename... Extra>\n    class_(handle scope, const char *name, const Extra &...extra) {\n        using namespace detail;\n\n        // MI can only be specified via class_ template options, not constructor parameters\n        static_assert(\n            none_of<is_pyobject<Extra>...>::value || // no base class arguments, or:\n                (constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base\n                 constexpr_sum(is_base<options>::value...) == 0 &&   // no template option bases\n                 // no multiple_inheritance attr\n                 none_of<std::is_same<multiple_inheritance, Extra>...>::value),\n            \"Error: multiple inheritance bases must be specified via class_ template options\");\n\n        type_record record;\n        record.scope = scope;\n        record.name = name;\n        record.type = &typeid(type);\n        record.type_size = sizeof(conditional_t<has_alias, type_alias, type>);\n        record.type_align = alignof(conditional_t<has_alias, type_alias, type> &);\n        record.holder_size = sizeof(holder_type);\n        record.init_instance = init_instance;\n        record.dealloc = dealloc;\n        record.default_holder = detail::is_instantiation<std::unique_ptr, holder_type>::value;\n\n        set_operator_new<type>(&record);\n\n        /* Register base classes specified via template arguments to class_, if any */\n        PYBIND11_EXPAND_SIDE_EFFECTS(add_base<options>(record));\n\n        /* Process optional arguments, if any */\n        process_attributes<Extra...>::init(extra..., &record);\n\n        generic_type::initialize(record);\n\n        if (has_alias) {\n            auto &instances = record.module_local ? get_local_internals().registered_types_cpp\n                                                  : get_internals().registered_types_cpp;\n            instances[std::type_index(typeid(type_alias))]\n                = instances[std::type_index(typeid(type))];\n        }\n    }\n\n    template <typename Base, detail::enable_if_t<is_base<Base>::value, int> = 0>\n    static void add_base(detail::type_record &rec) {\n        rec.add_base(typeid(Base), [](void *src) -> void * {\n            return static_cast<Base *>(reinterpret_cast<type *>(src));\n        });\n    }\n\n    template <typename Base, detail::enable_if_t<!is_base<Base>::value, int> = 0>\n    static void add_base(detail::type_record &) {}\n\n    template <typename Func, typename... Extra>\n    class_ &def(const char *name_, Func &&f, const Extra &...extra) {\n        cpp_function cf(method_adaptor<type>(std::forward<Func>(f)),\n                        name(name_),\n                        is_method(*this),\n                        sibling(getattr(*this, name_, none())),\n                        extra...);\n        add_class_method(*this, name_, cf);\n        return *this;\n    }\n\n    template <typename Func, typename... Extra>\n    class_ &def_static(const char *name_, Func &&f, const Extra &...extra) {\n        static_assert(!std::is_member_function_pointer<Func>::value,\n                      \"def_static(...) called with a non-static member function pointer\");\n        cpp_function cf(std::forward<Func>(f),\n                        name(name_),\n                        scope(*this),\n                        sibling(getattr(*this, name_, none())),\n                        extra...);\n        attr(cf.name()) = staticmethod(cf);\n        return *this;\n    }\n\n    template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>\n    class_ &def(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {\n        op.execute(*this, extra...);\n        return *this;\n    }\n\n    template <detail::op_id id, detail::op_type ot, typename L, typename R, typename... Extra>\n    class_ &def_cast(const detail::op_<id, ot, L, R> &op, const Extra &...extra) {\n        op.execute_cast(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(const detail::initimpl::constructor<Args...> &init, const Extra &...extra) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);\n        init.execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(const detail::initimpl::alias_constructor<Args...> &init, const Extra &...extra) {\n        PYBIND11_WORKAROUND_INCORRECT_MSVC_C4100(init);\n        init.execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(detail::initimpl::factory<Args...> &&init, const Extra &...extra) {\n        std::move(init).execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename... Args, typename... Extra>\n    class_ &def(detail::initimpl::pickle_factory<Args...> &&pf, const Extra &...extra) {\n        std::move(pf).execute(*this, extra...);\n        return *this;\n    }\n\n    template <typename Func>\n    class_ &def_buffer(Func &&func) {\n        struct capture {\n            Func func;\n        };\n        auto *ptr = new capture{std::forward<Func>(func)};\n        install_buffer_funcs(\n            [](PyObject *obj, void *ptr) -> buffer_info * {\n                detail::make_caster<type> caster;\n                if (!caster.load(obj, false)) {\n                    return nullptr;\n                }\n                return new buffer_info(((capture *) ptr)->func(caster));\n            },\n            ptr);\n        weakref(m_ptr, cpp_function([ptr](handle wr) {\n                    delete ptr;\n                    wr.dec_ref();\n                }))\n            .release();\n        return *this;\n    }\n\n    template <typename Return, typename Class, typename... Args>\n    class_ &def_buffer(Return (Class::*func)(Args...)) {\n        return def_buffer([func](type &obj) { return (obj.*func)(); });\n    }\n\n    template <typename Return, typename Class, typename... Args>\n    class_ &def_buffer(Return (Class::*func)(Args...) const) {\n        return def_buffer([func](const type &obj) { return (obj.*func)(); });\n    }\n\n    template <typename C, typename D, typename... Extra>\n    class_ &def_readwrite(const char *name, D C::*pm, const Extra &...extra) {\n        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,\n                      \"def_readwrite() requires a class member (or base class member)\");\n        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this)),\n            fset([pm](type &c, const D &value) { c.*pm = value; }, is_method(*this));\n        def_property(name, fget, fset, return_value_policy::reference_internal, extra...);\n        return *this;\n    }\n\n    template <typename C, typename D, typename... Extra>\n    class_ &def_readonly(const char *name, const D C::*pm, const Extra &...extra) {\n        static_assert(std::is_same<C, type>::value || std::is_base_of<C, type>::value,\n                      \"def_readonly() requires a class member (or base class member)\");\n        cpp_function fget([pm](const type &c) -> const D & { return c.*pm; }, is_method(*this));\n        def_property_readonly(name, fget, return_value_policy::reference_internal, extra...);\n        return *this;\n    }\n\n    template <typename D, typename... Extra>\n    class_ &def_readwrite_static(const char *name, D *pm, const Extra &...extra) {\n        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this)),\n            fset([pm](const object &, const D &value) { *pm = value; }, scope(*this));\n        def_property_static(name, fget, fset, return_value_policy::reference, extra...);\n        return *this;\n    }\n\n    template <typename D, typename... Extra>\n    class_ &def_readonly_static(const char *name, const D *pm, const Extra &...extra) {\n        cpp_function fget([pm](const object &) -> const D & { return *pm; }, scope(*this));\n        def_property_readonly_static(name, fget, return_value_policy::reference, extra...);\n        return *this;\n    }\n\n    /// Uses return_value_policy::reference_internal by default\n    template <typename Getter, typename... Extra>\n    class_ &def_property_readonly(const char *name, const Getter &fget, const Extra &...extra) {\n        return def_property_readonly(name,\n                                     cpp_function(method_adaptor<type>(fget)),\n                                     return_value_policy::reference_internal,\n                                     extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &\n    def_property_readonly(const char *name, const cpp_function &fget, const Extra &...extra) {\n        return def_property(name, fget, nullptr, extra...);\n    }\n\n    /// Uses return_value_policy::reference by default\n    template <typename Getter, typename... Extra>\n    class_ &\n    def_property_readonly_static(const char *name, const Getter &fget, const Extra &...extra) {\n        return def_property_readonly_static(\n            name, cpp_function(fget), return_value_policy::reference, extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property_readonly_static(const char *name,\n                                         const cpp_function &fget,\n                                         const Extra &...extra) {\n        return def_property_static(name, fget, nullptr, extra...);\n    }\n\n    /// Uses return_value_policy::reference_internal by default\n    template <typename Getter, typename Setter, typename... Extra>\n    class_ &\n    def_property(const char *name, const Getter &fget, const Setter &fset, const Extra &...extra) {\n        return def_property(name, fget, cpp_function(method_adaptor<type>(fset)), extra...);\n    }\n    template <typename Getter, typename... Extra>\n    class_ &def_property(const char *name,\n                         const Getter &fget,\n                         const cpp_function &fset,\n                         const Extra &...extra) {\n        return def_property(name,\n                            cpp_function(method_adaptor<type>(fget)),\n                            fset,\n                            return_value_policy::reference_internal,\n                            extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property(const char *name,\n                         const cpp_function &fget,\n                         const cpp_function &fset,\n                         const Extra &...extra) {\n        return def_property_static(name, fget, fset, is_method(*this), extra...);\n    }\n\n    /// Uses return_value_policy::reference by default\n    template <typename Getter, typename... Extra>\n    class_ &def_property_static(const char *name,\n                                const Getter &fget,\n                                const cpp_function &fset,\n                                const Extra &...extra) {\n        return def_property_static(\n            name, cpp_function(fget), fset, return_value_policy::reference, extra...);\n    }\n\n    /// Uses cpp_function's return_value_policy by default\n    template <typename... Extra>\n    class_ &def_property_static(const char *name,\n                                const cpp_function &fget,\n                                const cpp_function &fset,\n                                const Extra &...extra) {\n        static_assert(0 == detail::constexpr_sum(std::is_base_of<arg, Extra>::value...),\n                      \"Argument annotations are not allowed for properties\");\n        auto rec_fget = get_function_record(fget), rec_fset = get_function_record(fset);\n        auto *rec_active = rec_fget;\n        if (rec_fget) {\n            char *doc_prev = rec_fget->doc; /* 'extra' field may include a property-specific\n                                               documentation string */\n            detail::process_attributes<Extra...>::init(extra..., rec_fget);\n            if (rec_fget->doc && rec_fget->doc != doc_prev) {\n                std::free(doc_prev);\n                rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);\n            }\n        }\n        if (rec_fset) {\n            char *doc_prev = rec_fset->doc;\n            detail::process_attributes<Extra...>::init(extra..., rec_fset);\n            if (rec_fset->doc && rec_fset->doc != doc_prev) {\n                std::free(doc_prev);\n                rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc);\n            }\n            if (!rec_active) {\n                rec_active = rec_fset;\n            }\n        }\n        def_property_static_impl(name, fget, fset, rec_active);\n        return *this;\n    }\n\nprivate:\n    /// Initialize holder object, variant 1: object derives from enable_shared_from_this\n    template <typename T>\n    static void init_holder(detail::instance *inst,\n                            detail::value_and_holder &v_h,\n                            const holder_type * /* unused */,\n                            const std::enable_shared_from_this<T> * /* dummy */) {\n\n        auto sh = std::dynamic_pointer_cast<typename holder_type::element_type>(\n            detail::try_get_shared_from_this(v_h.value_ptr<type>()));\n        if (sh) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(std::move(sh));\n            v_h.set_holder_constructed();\n        }\n\n        if (!v_h.holder_constructed() && inst->owned) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());\n            v_h.set_holder_constructed();\n        }\n    }\n\n    static void init_holder_from_existing(const detail::value_and_holder &v_h,\n                                          const holder_type *holder_ptr,\n                                          std::true_type /*is_copy_constructible*/) {\n        new (std::addressof(v_h.holder<holder_type>()))\n            holder_type(*reinterpret_cast<const holder_type *>(holder_ptr));\n    }\n\n    static void init_holder_from_existing(const detail::value_and_holder &v_h,\n                                          const holder_type *holder_ptr,\n                                          std::false_type /*is_copy_constructible*/) {\n        new (std::addressof(v_h.holder<holder_type>()))\n            holder_type(std::move(*const_cast<holder_type *>(holder_ptr)));\n    }\n\n    /// Initialize holder object, variant 2: try to construct from existing holder object, if\n    /// possible\n    static void init_holder(detail::instance *inst,\n                            detail::value_and_holder &v_h,\n                            const holder_type *holder_ptr,\n                            const void * /* dummy -- not enable_shared_from_this<T>) */) {\n        if (holder_ptr) {\n            init_holder_from_existing(v_h, holder_ptr, std::is_copy_constructible<holder_type>());\n            v_h.set_holder_constructed();\n        } else if (inst->owned || detail::always_construct_holder<holder_type>::value) {\n            new (std::addressof(v_h.holder<holder_type>())) holder_type(v_h.value_ptr<type>());\n            v_h.set_holder_constructed();\n        }\n    }\n\n    /// Performs instance initialization including constructing a holder and registering the known\n    /// instance.  Should be called as soon as the `type` value_ptr is set for an instance.  Takes\n    /// an optional pointer to an existing holder to use; if not specified and the instance is\n    /// `.owned`, a new holder will be constructed to manage the value pointer.\n    static void init_instance(detail::instance *inst, const void *holder_ptr) {\n        auto v_h = inst->get_value_and_holder(detail::get_type_info(typeid(type)));\n        if (!v_h.instance_registered()) {\n            register_instance(inst, v_h.value_ptr(), v_h.type);\n            v_h.set_instance_registered();\n        }\n        init_holder(inst, v_h, (const holder_type *) holder_ptr, v_h.value_ptr<type>());\n    }\n\n    /// Deallocates an instance; via holder, if constructed; otherwise via operator delete.\n    static void dealloc(detail::value_and_holder &v_h) {\n        // We could be deallocating because we are cleaning up after a Python exception.\n        // If so, the Python error indicator will be set. We need to clear that before\n        // running the destructor, in case the destructor code calls more Python.\n        // If we don't, the Python API will exit with an exception, and pybind11 will\n        // throw error_already_set from the C++ destructor which is forbidden and triggers\n        // std::terminate().\n        error_scope scope;\n        if (v_h.holder_constructed()) {\n            v_h.holder<holder_type>().~holder_type();\n            v_h.set_holder_constructed(false);\n        } else {\n            detail::call_operator_delete(\n                v_h.value_ptr<type>(), v_h.type->type_size, v_h.type->type_align);\n        }\n        v_h.value_ptr() = nullptr;\n    }\n\n    static detail::function_record *get_function_record(handle h) {\n        h = detail::get_function(h);\n        return h ? (detail::function_record *) reinterpret_borrow<capsule>(\n                   PyCFunction_GET_SELF(h.ptr()))\n                 : nullptr;\n    }\n};\n\n/// Binds an existing constructor taking arguments Args...\ntemplate <typename... Args>\ndetail::initimpl::constructor<Args...> init() {\n    return {};\n}\n/// Like `init<Args...>()`, but the instance is always constructed through the alias class (even\n/// when not inheriting on the Python side).\ntemplate <typename... Args>\ndetail::initimpl::alias_constructor<Args...> init_alias() {\n    return {};\n}\n\n/// Binds a factory function as a constructor\ntemplate <typename Func, typename Ret = detail::initimpl::factory<Func>>\nRet init(Func &&f) {\n    return {std::forward<Func>(f)};\n}\n\n/// Dual-argument factory function: the first function is called when no alias is needed, the\n/// second when an alias is needed (i.e. due to python-side inheritance).  Arguments must be\n/// identical.\ntemplate <typename CFunc, typename AFunc, typename Ret = detail::initimpl::factory<CFunc, AFunc>>\nRet init(CFunc &&c, AFunc &&a) {\n    return {std::forward<CFunc>(c), std::forward<AFunc>(a)};\n}\n\n/// Binds pickling functions `__getstate__` and `__setstate__` and ensures that the type\n/// returned by `__getstate__` is the same as the argument accepted by `__setstate__`.\ntemplate <typename GetState, typename SetState>\ndetail::initimpl::pickle_factory<GetState, SetState> pickle(GetState &&g, SetState &&s) {\n    return {std::forward<GetState>(g), std::forward<SetState>(s)};\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\ninline str enum_name(handle arg) {\n    dict entries = arg.get_type().attr(\"__entries\");\n    for (auto kv : entries) {\n        if (handle(kv.second[int_(0)]).equal(arg)) {\n            return pybind11::str(kv.first);\n        }\n    }\n    return \"???\";\n}\n\nstruct enum_base {\n    enum_base(const handle &base, const handle &parent) : m_base(base), m_parent(parent) {}\n\n    PYBIND11_NOINLINE void init(bool is_arithmetic, bool is_convertible) {\n        m_base.attr(\"__entries\") = dict();\n        auto property = handle((PyObject *) &PyProperty_Type);\n        auto static_property = handle((PyObject *) get_internals().static_property_type);\n\n        m_base.attr(\"__repr__\") = cpp_function(\n            [](const object &arg) -> str {\n                handle type = type::handle_of(arg);\n                object type_name = type.attr(\"__name__\");\n                return pybind11::str(\"<{}.{}: {}>\").format(type_name, enum_name(arg), int_(arg));\n            },\n            name(\"__repr__\"),\n            is_method(m_base));\n\n        m_base.attr(\"name\") = property(cpp_function(&enum_name, name(\"name\"), is_method(m_base)));\n\n        m_base.attr(\"__str__\") = cpp_function(\n            [](handle arg) -> str {\n                object type_name = type::handle_of(arg).attr(\"__name__\");\n                return pybind11::str(\"{}.{}\").format(type_name, enum_name(arg));\n            },\n            name(\"name\"),\n            is_method(m_base));\n\n        if (options::show_enum_members_docstring()) {\n            m_base.attr(\"__doc__\") = static_property(\n                cpp_function(\n                    [](handle arg) -> std::string {\n                        std::string docstring;\n                        dict entries = arg.attr(\"__entries\");\n                        if (((PyTypeObject *) arg.ptr())->tp_doc) {\n                            docstring += std::string(((PyTypeObject *) arg.ptr())->tp_doc) + \"\\n\\n\";\n                        }\n                        docstring += \"Members:\";\n                        for (auto kv : entries) {\n                            auto key = std::string(pybind11::str(kv.first));\n                            auto comment = kv.second[int_(1)];\n                            docstring += \"\\n\\n  \" + key;\n                            if (!comment.is_none()) {\n                                docstring += \" : \" + (std::string) pybind11::str(comment);\n                            }\n                        }\n                        return docstring;\n                    },\n                    name(\"__doc__\")),\n                none(),\n                none(),\n                \"\");\n        }\n\n        m_base.attr(\"__members__\") = static_property(cpp_function(\n                                                         [](handle arg) -> dict {\n                                                             dict entries = arg.attr(\"__entries\"),\n                                                                  m;\n                                                             for (auto kv : entries) {\n                                                                 m[kv.first] = kv.second[int_(0)];\n                                                             }\n                                                             return m;\n                                                         },\n                                                         name(\"__members__\")),\n                                                     none(),\n                                                     none(),\n                                                     \"\");\n\n#define PYBIND11_ENUM_OP_STRICT(op, expr, strict_behavior)                                        \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a, const object &b) {                                                    \\\n            if (!type::handle_of(a).is(type::handle_of(b)))                                       \\\n                strict_behavior; /* NOLINT(bugprone-macro-parentheses) */                         \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n#define PYBIND11_ENUM_OP_CONV(op, expr)                                                           \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a_, const object &b_) {                                                  \\\n            int_ a(a_), b(b_);                                                                    \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n#define PYBIND11_ENUM_OP_CONV_LHS(op, expr)                                                       \\\n    m_base.attr(op) = cpp_function(                                                               \\\n        [](const object &a_, const object &b) {                                                   \\\n            int_ a(a_);                                                                           \\\n            return expr;                                                                          \\\n        },                                                                                        \\\n        name(op),                                                                                 \\\n        is_method(m_base),                                                                        \\\n        arg(\"other\"))\n\n        if (is_convertible) {\n            PYBIND11_ENUM_OP_CONV_LHS(\"__eq__\", !b.is_none() && a.equal(b));\n            PYBIND11_ENUM_OP_CONV_LHS(\"__ne__\", b.is_none() || !a.equal(b));\n\n            if (is_arithmetic) {\n                PYBIND11_ENUM_OP_CONV(\"__lt__\", a < b);\n                PYBIND11_ENUM_OP_CONV(\"__gt__\", a > b);\n                PYBIND11_ENUM_OP_CONV(\"__le__\", a <= b);\n                PYBIND11_ENUM_OP_CONV(\"__ge__\", a >= b);\n                PYBIND11_ENUM_OP_CONV(\"__and__\", a & b);\n                PYBIND11_ENUM_OP_CONV(\"__rand__\", a & b);\n                PYBIND11_ENUM_OP_CONV(\"__or__\", a | b);\n                PYBIND11_ENUM_OP_CONV(\"__ror__\", a | b);\n                PYBIND11_ENUM_OP_CONV(\"__xor__\", a ^ b);\n                PYBIND11_ENUM_OP_CONV(\"__rxor__\", a ^ b);\n                m_base.attr(\"__invert__\")\n                    = cpp_function([](const object &arg) { return ~(int_(arg)); },\n                                   name(\"__invert__\"),\n                                   is_method(m_base));\n            }\n        } else {\n            PYBIND11_ENUM_OP_STRICT(\"__eq__\", int_(a).equal(int_(b)), return false);\n            PYBIND11_ENUM_OP_STRICT(\"__ne__\", !int_(a).equal(int_(b)), return true);\n\n            if (is_arithmetic) {\n#define PYBIND11_THROW throw type_error(\"Expected an enumeration of matching type!\");\n                PYBIND11_ENUM_OP_STRICT(\"__lt__\", int_(a) < int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__gt__\", int_(a) > int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__le__\", int_(a) <= int_(b), PYBIND11_THROW);\n                PYBIND11_ENUM_OP_STRICT(\"__ge__\", int_(a) >= int_(b), PYBIND11_THROW);\n#undef PYBIND11_THROW\n            }\n        }\n\n#undef PYBIND11_ENUM_OP_CONV_LHS\n#undef PYBIND11_ENUM_OP_CONV\n#undef PYBIND11_ENUM_OP_STRICT\n\n        m_base.attr(\"__getstate__\") = cpp_function(\n            [](const object &arg) { return int_(arg); }, name(\"__getstate__\"), is_method(m_base));\n\n        m_base.attr(\"__hash__\") = cpp_function(\n            [](const object &arg) { return int_(arg); }, name(\"__hash__\"), is_method(m_base));\n    }\n\n    PYBIND11_NOINLINE void value(char const *name_, object value, const char *doc = nullptr) {\n        dict entries = m_base.attr(\"__entries\");\n        str name(name_);\n        if (entries.contains(name)) {\n            std::string type_name = (std::string) str(m_base.attr(\"__name__\"));\n            throw value_error(type_name + \": element \\\"\" + std::string(name_)\n                              + \"\\\" already exists!\");\n        }\n\n        entries[name] = std::make_pair(value, doc);\n        m_base.attr(name) = value;\n    }\n\n    PYBIND11_NOINLINE void export_values() {\n        dict entries = m_base.attr(\"__entries\");\n        for (auto kv : entries) {\n            m_parent.attr(kv.first) = kv.second[int_(0)];\n        }\n    }\n\n    handle m_base;\n    handle m_parent;\n};\n\ntemplate <bool is_signed, size_t length>\nstruct equivalent_integer {};\ntemplate <>\nstruct equivalent_integer<true, 1> {\n    using type = int8_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 1> {\n    using type = uint8_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 2> {\n    using type = int16_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 2> {\n    using type = uint16_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 4> {\n    using type = int32_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 4> {\n    using type = uint32_t;\n};\ntemplate <>\nstruct equivalent_integer<true, 8> {\n    using type = int64_t;\n};\ntemplate <>\nstruct equivalent_integer<false, 8> {\n    using type = uint64_t;\n};\n\ntemplate <typename IntLike>\nusing equivalent_integer_t =\n    typename equivalent_integer<std::is_signed<IntLike>::value, sizeof(IntLike)>::type;\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Binds C++ enumerations and enumeration classes to Python\ntemplate <typename Type>\nclass enum_ : public class_<Type> {\npublic:\n    using Base = class_<Type>;\n    using Base::attr;\n    using Base::def;\n    using Base::def_property_readonly;\n    using Base::def_property_readonly_static;\n    using Underlying = typename std::underlying_type<Type>::type;\n    // Scalar is the integer representation of underlying type\n    using Scalar = detail::conditional_t<detail::any_of<detail::is_std_char_type<Underlying>,\n                                                        std::is_same<Underlying, bool>>::value,\n                                         detail::equivalent_integer_t<Underlying>,\n                                         Underlying>;\n\n    template <typename... Extra>\n    enum_(const handle &scope, const char *name, const Extra &...extra)\n        : class_<Type>(scope, name, extra...), m_base(*this, scope) {\n        constexpr bool is_arithmetic = detail::any_of<std::is_same<arithmetic, Extra>...>::value;\n        constexpr bool is_convertible = std::is_convertible<Type, Underlying>::value;\n        m_base.init(is_arithmetic, is_convertible);\n\n        def(init([](Scalar i) { return static_cast<Type>(i); }), arg(\"value\"));\n        def_property_readonly(\"value\", [](Type value) { return (Scalar) value; });\n        def(\"__int__\", [](Type value) { return (Scalar) value; });\n        def(\"__index__\", [](Type value) { return (Scalar) value; });\n#if PY_MAJOR_VERSION < 3\n        def(\"__long__\", [](Type value) { return (Scalar) value; });\n#endif\n        attr(\"__setstate__\") = cpp_function(\n            [](detail::value_and_holder &v_h, Scalar arg) {\n                detail::initimpl::setstate<Base>(\n                    v_h, static_cast<Type>(arg), Py_TYPE(v_h.inst) != v_h.type->type);\n            },\n            detail::is_new_style_constructor(),\n            pybind11::name(\"__setstate__\"),\n            is_method(*this),\n            arg(\"state\"));\n    }\n\n    /// Export enumeration entries into the parent scope\n    enum_ &export_values() {\n        m_base.export_values();\n        return *this;\n    }\n\n    /// Add an enumeration entry\n    enum_ &value(char const *name, Type value, const char *doc = nullptr) {\n        m_base.value(name, pybind11::cast(value, return_value_policy::copy), doc);\n        return *this;\n    }\n\nprivate:\n    detail::enum_base m_base;\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\nPYBIND11_NOINLINE void keep_alive_impl(handle nurse, handle patient) {\n    if (!nurse || !patient) {\n        pybind11_fail(\"Could not activate keep_alive!\");\n    }\n\n    if (patient.is_none() || nurse.is_none()) {\n        return; /* Nothing to keep alive or nothing to be kept alive by */\n    }\n\n    auto tinfo = all_type_info(Py_TYPE(nurse.ptr()));\n    if (!tinfo.empty()) {\n        /* It's a pybind-registered type, so we can store the patient in the\n         * internal list. */\n        add_patient(nurse.ptr(), patient.ptr());\n    } else {\n        /* Fall back to clever approach based on weak references taken from\n         * Boost.Python. This is not used for pybind-registered types because\n         * the objects can be destroyed out-of-order in a GC pass. */\n        cpp_function disable_lifesupport([patient](handle weakref) {\n            patient.dec_ref();\n            weakref.dec_ref();\n        });\n\n        weakref wr(nurse, disable_lifesupport);\n\n        patient.inc_ref(); /* reference patient and leak the weak reference */\n        (void) wr.release();\n    }\n}\n\nPYBIND11_NOINLINE void\nkeep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret) {\n    auto get_arg = [&](size_t n) {\n        if (n == 0) {\n            return ret;\n        }\n        if (n == 1 && call.init_self) {\n            return call.init_self;\n        }\n        if (n <= call.args.size()) {\n            return call.args[n - 1];\n        }\n        return handle();\n    };\n\n    keep_alive_impl(get_arg(Nurse), get_arg(Patient));\n}\n\ninline std::pair<decltype(internals::registered_types_py)::iterator, bool>\nall_type_info_get_cache(PyTypeObject *type) {\n    auto res = get_internals()\n                   .registered_types_py\n#ifdef __cpp_lib_unordered_map_try_emplace\n                   .try_emplace(type);\n#else\n                   .emplace(type, std::vector<detail::type_info *>());\n#endif\n    if (res.second) {\n        // New cache entry created; set up a weak reference to automatically remove it if the type\n        // gets destroyed:\n        weakref((PyObject *) type, cpp_function([type](handle wr) {\n                    get_internals().registered_types_py.erase(type);\n\n                    // TODO consolidate the erasure code in pybind11_meta_dealloc() in class.h\n                    auto &cache = get_internals().inactive_override_cache;\n                    for (auto it = cache.begin(), last = cache.end(); it != last;) {\n                        if (it->first == reinterpret_cast<PyObject *>(type)) {\n                            it = cache.erase(it);\n                        } else {\n                            ++it;\n                        }\n                    }\n\n                    wr.dec_ref();\n                }))\n            .release();\n    }\n\n    return res;\n}\n\n/* There are a large number of apparently unused template arguments because\n * each combination requires a separate py::class_ registration.\n */\ntemplate <typename Access,\n          return_value_policy Policy,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType,\n          typename... Extra>\nstruct iterator_state {\n    Iterator it;\n    Sentinel end;\n    bool first_or_done;\n};\n\n// Note: these helpers take the iterator by non-const reference because some\n// iterators in the wild can't be dereferenced when const. The & after Iterator\n// is required for MSVC < 16.9. SFINAE cannot be reused for result_type due to\n// bugs in ICC, NVCC, and PGI compilers. See PR #3293.\ntemplate <typename Iterator, typename SFINAE = decltype(*std::declval<Iterator &>())>\nstruct iterator_access {\n    using result_type = decltype(*std::declval<Iterator &>());\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    result_type operator()(Iterator &it) const { return *it; }\n};\n\ntemplate <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).first)>\nclass iterator_key_access {\nprivate:\n    using pair_type = decltype(*std::declval<Iterator &>());\n\npublic:\n    /* If either the pair itself or the element of the pair is a reference, we\n     * want to return a reference, otherwise a value. When the decltype\n     * expression is parenthesized it is based on the value category of the\n     * expression; otherwise it is the declared type of the pair member.\n     * The use of declval<pair_type> in the second branch rather than directly\n     * using *std::declval<Iterator &>() is a workaround for nvcc\n     * (it's not used in the first branch because going via decltype and back\n     * through declval does not perfectly preserve references).\n     */\n    using result_type\n        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,\n                        decltype(((*std::declval<Iterator &>()).first)),\n                        decltype(std::declval<pair_type>().first)>;\n    result_type operator()(Iterator &it) const { return (*it).first; }\n};\n\ntemplate <typename Iterator, typename SFINAE = decltype((*std::declval<Iterator &>()).second)>\nclass iterator_value_access {\nprivate:\n    using pair_type = decltype(*std::declval<Iterator &>());\n\npublic:\n    using result_type\n        = conditional_t<std::is_reference<decltype(*std::declval<Iterator &>())>::value,\n                        decltype(((*std::declval<Iterator &>()).second)),\n                        decltype(std::declval<pair_type>().second)>;\n    result_type operator()(Iterator &it) const { return (*it).second; }\n};\n\ntemplate <typename Access,\n          return_value_policy Policy,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType,\n          typename... Extra>\niterator make_iterator_impl(Iterator first, Sentinel last, Extra &&...extra) {\n    using state = detail::iterator_state<Access, Policy, Iterator, Sentinel, ValueType, Extra...>;\n    // TODO: state captures only the types of Extra, not the values\n\n    if (!detail::get_type_info(typeid(state), false)) {\n        class_<state>(handle(), \"iterator\", pybind11::module_local())\n            .def(\"__iter__\", [](state &s) -> state & { return s; })\n            .def(\n                \"__next__\",\n                [](state &s) -> ValueType {\n                    if (!s.first_or_done) {\n                        ++s.it;\n                    } else {\n                        s.first_or_done = false;\n                    }\n                    if (s.it == s.end) {\n                        s.first_or_done = true;\n                        throw stop_iteration();\n                    }\n                    return Access()(s.it);\n                    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n                },\n                std::forward<Extra>(extra)...,\n                Policy);\n    }\n\n    return cast(state{first, last, true});\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/// Makes a python iterator from a first and past-the-end C++ InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType = typename detail::iterator_access<Iterator>::result_type,\n          typename... Extra>\niterator make_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      ValueType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes a python iterator over the keys (`.first`) of a iterator over pairs from a\n/// first and past-the-end InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename KeyType = typename detail::iterator_key_access<Iterator>::result_type,\n          typename... Extra>\niterator make_key_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_key_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      KeyType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes a python iterator over the values (`.second`) of a iterator over pairs from a\n/// first and past-the-end InputIterator.\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Iterator,\n          typename Sentinel,\n          typename ValueType = typename detail::iterator_value_access<Iterator>::result_type,\n          typename... Extra>\niterator make_value_iterator(Iterator first, Sentinel last, Extra &&...extra) {\n    return detail::make_iterator_impl<detail::iterator_value_access<Iterator>,\n                                      Policy,\n                                      Iterator,\n                                      Sentinel,\n                                      ValueType,\n                                      Extra...>(first, last, std::forward<Extra>(extra)...);\n}\n\n/// Makes an iterator over values of an stl container or other container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_iterator(Type &value, Extra &&...extra) {\n    return make_iterator<Policy>(std::begin(value), std::end(value), extra...);\n}\n\n/// Makes an iterator over the keys (`.first`) of a stl map-like container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_key_iterator(Type &value, Extra &&...extra) {\n    return make_key_iterator<Policy>(std::begin(value), std::end(value), extra...);\n}\n\n/// Makes an iterator over the values (`.second`) of a stl map-like container supporting\n/// `std::begin()`/`std::end()`\ntemplate <return_value_policy Policy = return_value_policy::reference_internal,\n          typename Type,\n          typename... Extra>\niterator make_value_iterator(Type &value, Extra &&...extra) {\n    return make_value_iterator<Policy>(std::begin(value), std::end(value), extra...);\n}\n\ntemplate <typename InputType, typename OutputType>\nvoid implicitly_convertible() {\n    struct set_flag {\n        bool &flag;\n        explicit set_flag(bool &flag_) : flag(flag_) { flag_ = true; }\n        ~set_flag() { flag = false; }\n    };\n    auto implicit_caster = [](PyObject *obj, PyTypeObject *type) -> PyObject * {\n        static bool currently_used = false;\n        if (currently_used) { // implicit conversions are non-reentrant\n            return nullptr;\n        }\n        set_flag flag_helper(currently_used);\n        if (!detail::make_caster<InputType>().load(obj, false)) {\n            return nullptr;\n        }\n        tuple args(1);\n        args[0] = obj;\n        PyObject *result = PyObject_Call((PyObject *) type, args.ptr(), nullptr);\n        if (result == nullptr) {\n            PyErr_Clear();\n        }\n        return result;\n    };\n\n    if (auto *tinfo = detail::get_type_info(typeid(OutputType))) {\n        tinfo->implicit_conversions.push_back(implicit_caster);\n    } else {\n        pybind11_fail(\"implicitly_convertible: Unable to find type \" + type_id<OutputType>());\n    }\n}\n\ninline void register_exception_translator(ExceptionTranslator &&translator) {\n    detail::get_internals().registered_exception_translators.push_front(\n        std::forward<ExceptionTranslator>(translator));\n}\n\n/**\n * Add a new module-local exception translator. Locally registered functions\n * will be tried before any globally registered exception translators, which\n * will only be invoked if the module-local handlers do not deal with\n * the exception.\n */\ninline void register_local_exception_translator(ExceptionTranslator &&translator) {\n    detail::get_local_internals().registered_exception_translators.push_front(\n        std::forward<ExceptionTranslator>(translator));\n}\n\n/**\n * Wrapper to generate a new Python exception type.\n *\n * This should only be used with PyErr_SetString for now.\n * It is not (yet) possible to use as a py::base.\n * Template type argument is reserved for future use.\n */\ntemplate <typename type>\nclass exception : public object {\npublic:\n    exception() = default;\n    exception(handle scope, const char *name, handle base = PyExc_Exception) {\n        std::string full_name\n            = scope.attr(\"__name__\").cast<std::string>() + std::string(\".\") + name;\n        m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), NULL);\n        if (hasattr(scope, \"__dict__\") && scope.attr(\"__dict__\").contains(name)) {\n            pybind11_fail(\"Error during initialization: multiple incompatible \"\n                          \"definitions with name \\\"\"\n                          + std::string(name) + \"\\\"\");\n        }\n        scope.attr(name) = *this;\n    }\n\n    // Sets the current python exception to this exception object with the given message\n    void operator()(const char *message) { PyErr_SetString(m_ptr, message); }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Returns a reference to a function-local static exception object used in the simple\n// register_exception approach below.  (It would be simpler to have the static local variable\n// directly in register_exception, but that makes clang <3.5 segfault - issue #1349).\ntemplate <typename CppException>\nexception<CppException> &get_exception_object() {\n    static exception<CppException> ex;\n    return ex;\n}\n\n// Helper function for register_exception and register_local_exception\ntemplate <typename CppException>\nexception<CppException> &\nregister_exception_impl(handle scope, const char *name, handle base, bool isLocal) {\n    auto &ex = detail::get_exception_object<CppException>();\n    if (!ex) {\n        ex = exception<CppException>(scope, name, base);\n    }\n\n    auto register_func\n        = isLocal ? &register_local_exception_translator : &register_exception_translator;\n\n    register_func([](std::exception_ptr p) {\n        if (!p) {\n            return;\n        }\n        try {\n            std::rethrow_exception(p);\n        } catch (const CppException &e) {\n            detail::get_exception_object<CppException>()(e.what());\n        }\n    });\n    return ex;\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n/**\n * Registers a Python exception in `m` of the given `name` and installs a translator to\n * translate the C++ exception to the created Python exception using the what() method.\n * This is intended for simple exception translations; for more complex translation, register the\n * exception object and translator directly.\n */\ntemplate <typename CppException>\nexception<CppException> &\nregister_exception(handle scope, const char *name, handle base = PyExc_Exception) {\n    return detail::register_exception_impl<CppException>(scope, name, base, false /* isLocal */);\n}\n\n/**\n * Registers a Python exception in `m` of the given `name` and installs a translator to\n * translate the C++ exception to the created Python exception using the what() method.\n * This translator will only be used for exceptions that are thrown in this module and will be\n * tried before global exception translators, including those registered with register_exception.\n * This is intended for simple exception translations; for more complex translation, register the\n * exception object and translator directly.\n */\ntemplate <typename CppException>\nexception<CppException> &\nregister_local_exception(handle scope, const char *name, handle base = PyExc_Exception) {\n    return detail::register_exception_impl<CppException>(scope, name, base, true /* isLocal */);\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\nPYBIND11_NOINLINE void print(const tuple &args, const dict &kwargs) {\n    auto strings = tuple(args.size());\n    for (size_t i = 0; i < args.size(); ++i) {\n        strings[i] = str(args[i]);\n    }\n    auto sep = kwargs.contains(\"sep\") ? kwargs[\"sep\"] : cast(\" \");\n    auto line = sep.attr(\"join\")(strings);\n\n    object file;\n    if (kwargs.contains(\"file\")) {\n        file = kwargs[\"file\"].cast<object>();\n    } else {\n        try {\n            file = module_::import(\"sys\").attr(\"stdout\");\n        } catch (const error_already_set &) {\n            /* If print() is called from code that is executed as\n               part of garbage collection during interpreter shutdown,\n               importing 'sys' can fail. Give up rather than crashing the\n               interpreter in this case. */\n            return;\n        }\n    }\n\n    auto write = file.attr(\"write\");\n    write(line);\n    write(kwargs.contains(\"end\") ? kwargs[\"end\"] : cast(\"\\n\"));\n\n    if (kwargs.contains(\"flush\") && kwargs[\"flush\"].cast<bool>()) {\n        file.attr(\"flush\")();\n    }\n}\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <return_value_policy policy = return_value_policy::automatic_reference, typename... Args>\nvoid print(Args &&...args) {\n    auto c = detail::collect_arguments<policy>(std::forward<Args>(args)...);\n    detail::print(c.args(), c.kwargs());\n}\n\nerror_already_set::~error_already_set() {\n    if (m_type) {\n        gil_scoped_acquire gil;\n        error_scope scope;\n        m_type.release().dec_ref();\n        m_value.release().dec_ref();\n        m_trace.release().dec_ref();\n    }\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ninline function\nget_type_override(const void *this_ptr, const type_info *this_type, const char *name) {\n    handle self = get_object_handle(this_ptr, this_type);\n    if (!self) {\n        return function();\n    }\n    handle type = type::handle_of(self);\n    auto key = std::make_pair(type.ptr(), name);\n\n    /* Cache functions that aren't overridden in Python to avoid\n       many costly Python dictionary lookups below */\n    auto &cache = get_internals().inactive_override_cache;\n    if (cache.find(key) != cache.end()) {\n        return function();\n    }\n\n    function override = getattr(self, name, function());\n    if (override.is_cpp_function()) {\n        cache.insert(key);\n        return function();\n    }\n\n    /* Don't call dispatch code if invoked from overridden function.\n       Unfortunately this doesn't work on PyPy. */\n#if !defined(PYPY_VERSION)\n#    if PY_VERSION_HEX >= 0x03090000\n    PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());\n    if (frame != nullptr) {\n        PyCodeObject *f_code = PyFrame_GetCode(frame);\n        // f_code is guaranteed to not be NULL\n        if ((std::string) str(f_code->co_name) == name && f_code->co_argcount > 0) {\n            PyObject *locals = PyEval_GetLocals();\n            if (locals != nullptr) {\n                PyObject *co_varnames = PyObject_GetAttrString((PyObject *) f_code, \"co_varnames\");\n                PyObject *self_arg = PyTuple_GET_ITEM(co_varnames, 0);\n                Py_DECREF(co_varnames);\n                PyObject *self_caller = dict_getitem(locals, self_arg);\n                if (self_caller == self.ptr()) {\n                    Py_DECREF(f_code);\n                    Py_DECREF(frame);\n                    return function();\n                }\n            }\n        }\n        Py_DECREF(f_code);\n        Py_DECREF(frame);\n    }\n#    else\n    PyFrameObject *frame = PyThreadState_Get()->frame;\n    if (frame != nullptr && (std::string) str(frame->f_code->co_name) == name\n        && frame->f_code->co_argcount > 0) {\n        PyFrame_FastToLocals(frame);\n        PyObject *self_caller\n            = dict_getitem(frame->f_locals, PyTuple_GET_ITEM(frame->f_code->co_varnames, 0));\n        if (self_caller == self.ptr()) {\n            return function();\n        }\n    }\n#    endif\n\n#else\n    /* PyPy currently doesn't provide a detailed cpyext emulation of\n       frame objects, so we have to emulate this using Python. This\n       is going to be slow..*/\n    dict d;\n    d[\"self\"] = self;\n    d[\"name\"] = pybind11::str(name);\n    PyObject *result\n        = PyRun_String(\"import inspect\\n\"\n                       \"frame = inspect.currentframe()\\n\"\n                       \"if frame is not None:\\n\"\n                       \"    frame = frame.f_back\\n\"\n                       \"    if frame is not None and str(frame.f_code.co_name) == name and \"\n                       \"frame.f_code.co_argcount > 0:\\n\"\n                       \"        self_caller = frame.f_locals[frame.f_code.co_varnames[0]]\\n\"\n                       \"        if self_caller == self:\\n\"\n                       \"            self = None\\n\",\n                       Py_file_input,\n                       d.ptr(),\n                       d.ptr());\n    if (result == nullptr)\n        throw error_already_set();\n    Py_DECREF(result);\n    if (d[\"self\"].is_none())\n        return function();\n#endif\n\n    return override;\n}\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n  Try to retrieve a python method by the provided name from the instance pointed to by the\n  this_ptr.\n\n  :this_ptr: The pointer to the object the overridden method should be retrieved for. This should\n             be the first non-trampoline class encountered in the inheritance chain.\n  :name: The name of the overridden Python method to retrieve.\n  :return: The Python method by this name from the object or an empty function wrapper.\n \\endrst */\ntemplate <class T>\nfunction get_override(const T *this_ptr, const char *name) {\n    auto *tinfo = detail::get_type_info(typeid(T));\n    return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();\n}\n\n#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...)                                        \\\n    do {                                                                                          \\\n        pybind11::gil_scoped_acquire gil;                                                         \\\n        pybind11::function override                                                               \\\n            = pybind11::get_override(static_cast<const cname *>(this), name);                     \\\n        if (override) {                                                                           \\\n            auto o = override(__VA_ARGS__);                                                       \\\n            if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) {           \\\n                static pybind11::detail::override_caster_t<ret_type> caster;                      \\\n                return pybind11::detail::cast_ref<ret_type>(std::move(o), caster);                \\\n            }                                                                                     \\\n            return pybind11::detail::cast_safe<ret_type>(std::move(o));                           \\\n        }                                                                                         \\\n    } while (false)\n\n/** \\rst\n    Macro to populate the virtual method in the trampoline class. This macro tries to look up a\n    method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument\n    conversions to call this method and return the appropriate type.\n    See :ref:`overriding_virtuals` for more information. This macro should be used when the method\n    name in C is not the same as the method name in Python. For example with `__str__`.\n\n    .. code-block:: cpp\n\n      std::string toString() override {\n        PYBIND11_OVERRIDE_NAME(\n            std::string, // Return type (ret_type)\n            Animal,      // Parent class (cname)\n            \"__str__\",   // Name of method in Python (name)\n            toString,    // Name of function in C++ (fn)\n        );\n      }\n\\endrst */\n#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...)                                    \\\n    do {                                                                                          \\\n        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \\\n        return cname::fn(__VA_ARGS__);                                                            \\\n    } while (false)\n\n/** \\rst\n    Macro for pure virtual functions, this function is identical to\n    :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found.\n\\endrst */\n#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...)                               \\\n    do {                                                                                          \\\n        PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \\\n        pybind11::pybind11_fail(                                                                  \\\n            \"Tried to call pure virtual function \\\"\" PYBIND11_STRINGIFY(cname) \"::\" name \"\\\"\");   \\\n    } while (false)\n\n/** \\rst\n    Macro to populate the virtual method in the trampoline class. This macro tries to look up the\n    method from the Python side, deals with the :ref:`gil` and necessary argument conversions to\n    call this method and return the appropriate type. This macro should be used if the method name\n    in C and in Python are identical.\n    See :ref:`overriding_virtuals` for more information.\n\n    .. code-block:: cpp\n\n      class PyAnimal : public Animal {\n      public:\n          // Inherit the constructors\n          using Animal::Animal;\n\n          // Trampoline (need one for each virtual function)\n          std::string go(int n_times) override {\n              PYBIND11_OVERRIDE_PURE(\n                  std::string, // Return type (ret_type)\n                  Animal,      // Parent class (cname)\n                  go,          // Name of function in C++ (must match Python name) (fn)\n                  n_times      // Argument(s) (...)\n              );\n          }\n      };\n\\endrst */\n#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...)                                               \\\n    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)\n\n/** \\rst\n    Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`,\n    except that it throws if no override can be found.\n\\endrst */\n#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...)                                          \\\n    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \\\n        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)\n\n// Deprecated versions\n\nPYBIND11_DEPRECATED(\"get_type_overload has been deprecated\")\ninline function\nget_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {\n    return detail::get_type_override(this_ptr, this_type, name);\n}\n\ntemplate <class T>\ninline function get_overload(const T *this_ptr, const char *name) {\n    return get_override(this_ptr, name);\n}\n\n#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...)                                         \\\n    PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...)                                    \\\n    PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...)                               \\\n    PYBIND11_OVERRIDE_PURE_NAME(                                                                  \\\n        PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);\n#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...)                                               \\\n    PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)\n#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...)                                          \\\n    PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n\n#if defined(__GNUC__) && __GNUC__ == 7\n#    pragma GCC diagnostic pop // -Wnoexcept-type\n#endif\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/pytypes.h",
    "content": "/*\n    pybind11/pytypes.h: Convenience wrapper classes for basic Python types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"buffer_info.h\"\n\n#include <type_traits>\n#include <utility>\n\n#if defined(PYBIND11_HAS_OPTIONAL)\n#    include <optional>\n#endif\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n#    include <string_view>\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\n\n/* A few forward declarations */\nclass handle;\nclass object;\nclass str;\nclass iterator;\nclass type;\nstruct arg;\nstruct arg_v;\n\nPYBIND11_NAMESPACE_BEGIN(detail)\nclass args_proxy;\nbool isinstance_generic(handle obj, const std::type_info &tp);\n\n// Accessor forward declarations\ntemplate <typename Policy>\nclass accessor;\nnamespace accessor_policies {\nstruct obj_attr;\nstruct str_attr;\nstruct generic_item;\nstruct sequence_item;\nstruct list_item;\nstruct tuple_item;\n} // namespace accessor_policies\nusing obj_attr_accessor = accessor<accessor_policies::obj_attr>;\nusing str_attr_accessor = accessor<accessor_policies::str_attr>;\nusing item_accessor = accessor<accessor_policies::generic_item>;\nusing sequence_accessor = accessor<accessor_policies::sequence_item>;\nusing list_accessor = accessor<accessor_policies::list_item>;\nusing tuple_accessor = accessor<accessor_policies::tuple_item>;\n\n/// Tag and check to identify a class which implements the Python object API\nclass pyobject_tag {};\ntemplate <typename T>\nusing is_pyobject = std::is_base_of<pyobject_tag, remove_reference_t<T>>;\n\n/** \\rst\n    A mixin class which adds common functions to `handle`, `object` and various accessors.\n    The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``.\n\\endrst */\ntemplate <typename Derived>\nclass object_api : public pyobject_tag {\n    const Derived &derived() const { return static_cast<const Derived &>(*this); }\n\npublic:\n    /** \\rst\n        Return an iterator equivalent to calling ``iter()`` in Python. The object\n        must be a collection which supports the iteration protocol.\n    \\endrst */\n    iterator begin() const;\n    /// Return a sentinel which ends iteration.\n    iterator end() const;\n\n    /** \\rst\n        Return an internal functor to invoke the object's sequence protocol. Casting\n        the returned ``detail::item_accessor`` instance to a `handle` or `object`\n        subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`\n        or `object` subclass causes a call to ``__setitem__``.\n    \\endrst */\n    item_accessor operator[](handle key) const;\n    /// See above (the only difference is that they key is provided as a string literal)\n    item_accessor operator[](const char *key) const;\n\n    /** \\rst\n        Return an internal functor to access the object's attributes. Casting the\n        returned ``detail::obj_attr_accessor`` instance to a `handle` or `object`\n        subclass causes a corresponding call to ``getattr``. Assigning a `handle`\n        or `object` subclass causes a call to ``setattr``.\n    \\endrst */\n    obj_attr_accessor attr(handle key) const;\n    /// See above (the only difference is that they key is provided as a string literal)\n    str_attr_accessor attr(const char *key) const;\n\n    /** \\rst\n        Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple``\n        or ``list`` for a function call. Applying another * to the result yields\n        ** unpacking, e.g. to unpack a dict as function keyword arguments.\n        See :ref:`calling_python_functions`.\n    \\endrst */\n    args_proxy operator*() const;\n\n    /// Check if the given item is contained within this object, i.e. ``item in obj``.\n    template <typename T>\n    bool contains(T &&item) const;\n\n    /** \\rst\n        Assuming the Python object is a function or implements the ``__call__``\n        protocol, ``operator()`` invokes the underlying function, passing an\n        arbitrary set of parameters. The result is returned as a `object` and\n        may need to be converted back into a Python object using `handle::cast()`.\n\n        When some of the arguments cannot be converted to Python objects, the\n        function will throw a `cast_error` exception. When the Python function\n        call fails, a `error_already_set` exception is thrown.\n    \\endrst */\n    template <return_value_policy policy = return_value_policy::automatic_reference,\n              typename... Args>\n    object operator()(Args &&...args) const;\n    template <return_value_policy policy = return_value_policy::automatic_reference,\n              typename... Args>\n    PYBIND11_DEPRECATED(\"call(...) was deprecated in favor of operator()(...)\")\n    object call(Args &&...args) const;\n\n    /// Equivalent to ``obj is other`` in Python.\n    bool is(object_api const &other) const { return derived().ptr() == other.derived().ptr(); }\n    /// Equivalent to ``obj is None`` in Python.\n    bool is_none() const { return derived().ptr() == Py_None; }\n    /// Equivalent to obj == other in Python\n    bool equal(object_api const &other) const { return rich_compare(other, Py_EQ); }\n    bool not_equal(object_api const &other) const { return rich_compare(other, Py_NE); }\n    bool operator<(object_api const &other) const { return rich_compare(other, Py_LT); }\n    bool operator<=(object_api const &other) const { return rich_compare(other, Py_LE); }\n    bool operator>(object_api const &other) const { return rich_compare(other, Py_GT); }\n    bool operator>=(object_api const &other) const { return rich_compare(other, Py_GE); }\n\n    object operator-() const;\n    object operator~() const;\n    object operator+(object_api const &other) const;\n    object operator+=(object_api const &other) const;\n    object operator-(object_api const &other) const;\n    object operator-=(object_api const &other) const;\n    object operator*(object_api const &other) const;\n    object operator*=(object_api const &other) const;\n    object operator/(object_api const &other) const;\n    object operator/=(object_api const &other) const;\n    object operator|(object_api const &other) const;\n    object operator|=(object_api const &other) const;\n    object operator&(object_api const &other) const;\n    object operator&=(object_api const &other) const;\n    object operator^(object_api const &other) const;\n    object operator^=(object_api const &other) const;\n    object operator<<(object_api const &other) const;\n    object operator<<=(object_api const &other) const;\n    object operator>>(object_api const &other) const;\n    object operator>>=(object_api const &other) const;\n\n    PYBIND11_DEPRECATED(\"Use py::str(obj) instead\")\n    pybind11::str str() const;\n\n    /// Get or set the object's docstring, i.e. ``obj.__doc__``.\n    str_attr_accessor doc() const;\n\n    /// Return the object's current reference count\n    int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }\n\n    // TODO PYBIND11_DEPRECATED(\n    //     \"Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()\")\n    handle get_type() const;\n\nprivate:\n    bool rich_compare(object_api const &other, int value) const;\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\n/** \\rst\n    Holds a reference to a Python object (no reference counting)\n\n    The `handle` class is a thin wrapper around an arbitrary Python object (i.e. a\n    ``PyObject *`` in Python's C API). It does not perform any automatic reference\n    counting and merely provides a basic C++ interface to various Python API functions.\n\n    .. seealso::\n        The `object` class inherits from `handle` and adds automatic reference\n        counting features.\n\\endrst */\nclass handle : public detail::object_api<handle> {\npublic:\n    /// The default constructor creates a handle with a ``nullptr``-valued pointer\n    handle() = default;\n    /// Creates a ``handle`` from the given raw Python object pointer\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    handle(PyObject *ptr) : m_ptr(ptr) {} // Allow implicit conversion from PyObject*\n\n    /// Return the underlying ``PyObject *`` pointer\n    PyObject *ptr() const { return m_ptr; }\n    PyObject *&ptr() { return m_ptr; }\n\n    /** \\rst\n        Manually increase the reference count of the Python object. Usually, it is\n        preferable to use the `object` class which derives from `handle` and calls\n        this function automatically. Returns a reference to itself.\n    \\endrst */\n    const handle &inc_ref() const & {\n        Py_XINCREF(m_ptr);\n        return *this;\n    }\n\n    /** \\rst\n        Manually decrease the reference count of the Python object. Usually, it is\n        preferable to use the `object` class which derives from `handle` and calls\n        this function automatically. Returns a reference to itself.\n    \\endrst */\n    const handle &dec_ref() const & {\n        Py_XDECREF(m_ptr);\n        return *this;\n    }\n\n    /** \\rst\n        Attempt to cast the Python object into the given C++ type. A `cast_error`\n        will be throw upon failure.\n    \\endrst */\n    template <typename T>\n    T cast() const;\n    /// Return ``true`` when the `handle` wraps a valid Python object\n    explicit operator bool() const { return m_ptr != nullptr; }\n    /** \\rst\n        Deprecated: Check that the underlying pointers are the same.\n        Equivalent to ``obj1 is obj2`` in Python.\n    \\endrst */\n    PYBIND11_DEPRECATED(\"Use obj1.is(obj2) instead\")\n    bool operator==(const handle &h) const { return m_ptr == h.m_ptr; }\n    PYBIND11_DEPRECATED(\"Use !obj1.is(obj2) instead\")\n    bool operator!=(const handle &h) const { return m_ptr != h.m_ptr; }\n    PYBIND11_DEPRECATED(\"Use handle::operator bool() instead\")\n    bool check() const { return m_ptr != nullptr; }\n\nprotected:\n    PyObject *m_ptr = nullptr;\n};\n\n/** \\rst\n    Holds a reference to a Python object (with reference counting)\n\n    Like `handle`, the `object` class is a thin wrapper around an arbitrary Python\n    object (i.e. a ``PyObject *`` in Python's C API). In contrast to `handle`, it\n    optionally increases the object's reference count upon construction, and it\n    *always* decreases the reference count when the `object` instance goes out of\n    scope and is destructed. When using `object` instances consistently, it is much\n    easier to get reference counting right at the first attempt.\n\\endrst */\nclass object : public handle {\npublic:\n    object() = default;\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<object>() or reinterpret_steal<object>()\")\n    object(handle h, bool is_borrowed) : handle(h) {\n        if (is_borrowed) {\n            inc_ref();\n        }\n    }\n    /// Copy constructor; always increases the reference count\n    object(const object &o) : handle(o) { inc_ref(); }\n    /// Move constructor; steals the object from ``other`` and preserves its reference count\n    object(object &&other) noexcept {\n        m_ptr = other.m_ptr;\n        other.m_ptr = nullptr;\n    }\n    /// Destructor; automatically calls `handle::dec_ref()`\n    ~object() { dec_ref(); }\n\n    /** \\rst\n        Resets the internal pointer to ``nullptr`` without decreasing the\n        object's reference count. The function returns a raw handle to the original\n        Python object.\n    \\endrst */\n    handle release() {\n        PyObject *tmp = m_ptr;\n        m_ptr = nullptr;\n        return handle(tmp);\n    }\n\n    object &operator=(const object &other) {\n        other.inc_ref();\n        // Use temporary variable to ensure `*this` remains valid while\n        // `Py_XDECREF` executes, in case `*this` is accessible from Python.\n        handle temp(m_ptr);\n        m_ptr = other.m_ptr;\n        temp.dec_ref();\n        return *this;\n    }\n\n    object &operator=(object &&other) noexcept {\n        if (this != &other) {\n            handle temp(m_ptr);\n            m_ptr = other.m_ptr;\n            other.m_ptr = nullptr;\n            temp.dec_ref();\n        }\n        return *this;\n    }\n\n    // Calling cast() on an object lvalue just copies (via handle::cast)\n    template <typename T>\n    T cast() const &;\n    // Calling on an object rvalue does a move, if needed and/or possible\n    template <typename T>\n    T cast() &&;\n\nprotected:\n    // Tags for choosing constructors from raw PyObject *\n    struct borrowed_t {};\n    struct stolen_t {};\n\n    /// @cond BROKEN\n    template <typename T>\n    friend T reinterpret_borrow(handle);\n    template <typename T>\n    friend T reinterpret_steal(handle);\n    /// @endcond\n\npublic:\n    // Only accessible from derived classes and the reinterpret_* functions\n    object(handle h, borrowed_t) : handle(h) { inc_ref(); }\n    object(handle h, stolen_t) : handle(h) {}\n};\n\n/** \\rst\n    Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference.\n    The target type ``T`` must be `object` or one of its derived classes. The function\n    doesn't do any conversions or checks. It's up to the user to make sure that the\n    target type is correct.\n\n    .. code-block:: cpp\n\n        PyObject *p = PyList_GetItem(obj, index);\n        py::object o = reinterpret_borrow<py::object>(p);\n        // or\n        py::tuple t = reinterpret_borrow<py::tuple>(p); // <-- `p` must be already be a `tuple`\n\\endrst */\ntemplate <typename T>\nT reinterpret_borrow(handle h) {\n    return {h, object::borrowed_t{}};\n}\n\n/** \\rst\n    Like `reinterpret_borrow`, but steals the reference.\n\n     .. code-block:: cpp\n\n        PyObject *p = PyObject_Str(obj);\n        py::str s = reinterpret_steal<py::str>(p); // <-- `p` must be already be a `str`\n\\endrst */\ntemplate <typename T>\nT reinterpret_steal(handle h) {\n    return {h, object::stolen_t{}};\n}\n\nPYBIND11_NAMESPACE_BEGIN(detail)\nstd::string error_string();\nPYBIND11_NAMESPACE_END(detail)\n\n#if defined(_MSC_VER)\n#    pragma warning(push)\n#    pragma warning(disable : 4275 4251)\n//     warning C4275: An exported class was derived from a class that wasn't exported.\n//     Can be ignored when derived from a STL class.\n#endif\n/// Fetch and hold an error which was already set in Python.  An instance of this is typically\n/// thrown to propagate python-side errors back through C++ which can either be caught manually or\n/// else falls back to the function dispatcher (which then raises the captured error back to\n/// python).\nclass PYBIND11_EXPORT_EXCEPTION error_already_set : public std::runtime_error {\npublic:\n    /// Constructs a new exception from the current Python error indicator, if any.  The current\n    /// Python error indicator will be cleared.\n    error_already_set() : std::runtime_error(detail::error_string()) {\n        PyErr_Fetch(&m_type.ptr(), &m_value.ptr(), &m_trace.ptr());\n    }\n\n    error_already_set(const error_already_set &) = default;\n    error_already_set(error_already_set &&) = default;\n\n    inline ~error_already_set() override;\n\n    /// Give the currently-held error back to Python, if any.  If there is currently a Python error\n    /// already set it is cleared first.  After this call, the current object no longer stores the\n    /// error variables (but the `.what()` string is still available).\n    void restore() {\n        PyErr_Restore(m_type.release().ptr(), m_value.release().ptr(), m_trace.release().ptr());\n    }\n\n    /// If it is impossible to raise the currently-held error, such as in a destructor, we can\n    /// write it out using Python's unraisable hook (`sys.unraisablehook`). The error context\n    /// should be some object whose `repr()` helps identify the location of the error. Python\n    /// already knows the type and value of the error, so there is no need to repeat that. After\n    /// this call, the current object no longer stores the error variables, and neither does\n    /// Python.\n    void discard_as_unraisable(object err_context) {\n        restore();\n        PyErr_WriteUnraisable(err_context.ptr());\n    }\n    /// An alternate version of `discard_as_unraisable()`, where a string provides information on\n    /// the location of the error. For example, `__func__` could be helpful.\n    void discard_as_unraisable(const char *err_context) {\n        discard_as_unraisable(reinterpret_steal<object>(PYBIND11_FROM_STRING(err_context)));\n    }\n\n    // Does nothing; provided for backwards compatibility.\n    PYBIND11_DEPRECATED(\"Use of error_already_set.clear() is deprecated\")\n    void clear() {}\n\n    /// Check if the currently trapped error type matches the given Python exception class (or a\n    /// subclass thereof).  May also be passed a tuple to search for any exception class matches in\n    /// the given tuple.\n    bool matches(handle exc) const {\n        return (PyErr_GivenExceptionMatches(m_type.ptr(), exc.ptr()) != 0);\n    }\n\n    const object &type() const { return m_type; }\n    const object &value() const { return m_value; }\n    const object &trace() const { return m_trace; }\n\nprivate:\n    object m_type, m_value, m_trace;\n};\n#if defined(_MSC_VER)\n#    pragma warning(pop)\n#endif\n\n#if PY_VERSION_HEX >= 0x03030000\n\n/// Replaces the current Python error indicator with the chosen error, performing a\n/// 'raise from' to indicate that the chosen error was caused by the original error.\ninline void raise_from(PyObject *type, const char *message) {\n    // Based on _PyErr_FormatVFromCause:\n    // https://github.com/python/cpython/blob/467ab194fc6189d9f7310c89937c51abeac56839/Python/errors.c#L405\n    // See https://github.com/pybind/pybind11/pull/2112 for details.\n    PyObject *exc = nullptr, *val = nullptr, *val2 = nullptr, *tb = nullptr;\n\n    assert(PyErr_Occurred());\n    PyErr_Fetch(&exc, &val, &tb);\n    PyErr_NormalizeException(&exc, &val, &tb);\n    if (tb != nullptr) {\n        PyException_SetTraceback(val, tb);\n        Py_DECREF(tb);\n    }\n    Py_DECREF(exc);\n    assert(!PyErr_Occurred());\n\n    PyErr_SetString(type, message);\n\n    PyErr_Fetch(&exc, &val2, &tb);\n    PyErr_NormalizeException(&exc, &val2, &tb);\n    Py_INCREF(val);\n    PyException_SetCause(val2, val);\n    PyException_SetContext(val2, val);\n    PyErr_Restore(exc, val2, tb);\n}\n\n/// Sets the current Python error indicator with the chosen error, performing a 'raise from'\n/// from the error contained in error_already_set to indicate that the chosen error was\n/// caused by the original error. After this function is called error_already_set will\n/// no longer contain an error.\ninline void raise_from(error_already_set &err, PyObject *type, const char *message) {\n    err.restore();\n    raise_from(type, message);\n}\n\n#endif\n\n/** \\defgroup python_builtins const_name\n    Unless stated otherwise, the following C++ functions behave the same\n    as their Python counterparts.\n */\n\n/** \\ingroup python_builtins\n    \\rst\n    Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of\n    `object` or a class which was exposed to Python as ``py::class_<T>``.\n\\endrst */\ntemplate <typename T, detail::enable_if_t<std::is_base_of<object, T>::value, int> = 0>\nbool isinstance(handle obj) {\n    return T::check_(obj);\n}\n\ntemplate <typename T, detail::enable_if_t<!std::is_base_of<object, T>::value, int> = 0>\nbool isinstance(handle obj) {\n    return detail::isinstance_generic(obj, typeid(T));\n}\n\ntemplate <>\ninline bool isinstance<handle>(handle) = delete;\ntemplate <>\ninline bool isinstance<object>(handle obj) {\n    return obj.ptr() != nullptr;\n}\n\n/// \\ingroup python_builtins\n/// Return true if ``obj`` is an instance of the ``type``.\ninline bool isinstance(handle obj, handle type) {\n    const auto result = PyObject_IsInstance(obj.ptr(), type.ptr());\n    if (result == -1) {\n        throw error_already_set();\n    }\n    return result != 0;\n}\n\n/// \\addtogroup python_builtins\n/// @{\ninline bool hasattr(handle obj, handle name) {\n    return PyObject_HasAttr(obj.ptr(), name.ptr()) == 1;\n}\n\ninline bool hasattr(handle obj, const char *name) {\n    return PyObject_HasAttrString(obj.ptr(), name) == 1;\n}\n\ninline void delattr(handle obj, handle name) {\n    if (PyObject_DelAttr(obj.ptr(), name.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline void delattr(handle obj, const char *name) {\n    if (PyObject_DelAttrString(obj.ptr(), name) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline object getattr(handle obj, handle name) {\n    PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ninline object getattr(handle obj, const char *name) {\n    PyObject *result = PyObject_GetAttrString(obj.ptr(), name);\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<object>(result);\n}\n\ninline object getattr(handle obj, handle name, handle default_) {\n    if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {\n        return reinterpret_steal<object>(result);\n    }\n    PyErr_Clear();\n    return reinterpret_borrow<object>(default_);\n}\n\ninline object getattr(handle obj, const char *name, handle default_) {\n    if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {\n        return reinterpret_steal<object>(result);\n    }\n    PyErr_Clear();\n    return reinterpret_borrow<object>(default_);\n}\n\ninline void setattr(handle obj, handle name, handle value) {\n    if (PyObject_SetAttr(obj.ptr(), name.ptr(), value.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline void setattr(handle obj, const char *name, handle value) {\n    if (PyObject_SetAttrString(obj.ptr(), name, value.ptr()) != 0) {\n        throw error_already_set();\n    }\n}\n\ninline ssize_t hash(handle obj) {\n    auto h = PyObject_Hash(obj.ptr());\n    if (h == -1) {\n        throw error_already_set();\n    }\n    return h;\n}\n\n/// @} python_builtins\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ninline handle get_function(handle value) {\n    if (value) {\n#if PY_MAJOR_VERSION >= 3\n        if (PyInstanceMethod_Check(value.ptr())) {\n            value = PyInstanceMethod_GET_FUNCTION(value.ptr());\n        } else\n#endif\n            if (PyMethod_Check(value.ptr())) {\n            value = PyMethod_GET_FUNCTION(value.ptr());\n        }\n    }\n    return value;\n}\n\n// Reimplementation of python's dict helper functions to ensure that exceptions\n// aren't swallowed (see #2862)\n\n// copied from cpython _PyDict_GetItemStringWithError\ninline PyObject *dict_getitemstring(PyObject *v, const char *key) {\n#if PY_MAJOR_VERSION >= 3\n    PyObject *kv = nullptr, *rv = nullptr;\n    kv = PyUnicode_FromString(key);\n    if (kv == NULL) {\n        throw error_already_set();\n    }\n\n    rv = PyDict_GetItemWithError(v, kv);\n    Py_DECREF(kv);\n    if (rv == NULL && PyErr_Occurred()) {\n        throw error_already_set();\n    }\n    return rv;\n#else\n    return PyDict_GetItemString(v, key);\n#endif\n}\n\ninline PyObject *dict_getitem(PyObject *v, PyObject *key) {\n#if PY_MAJOR_VERSION >= 3\n    PyObject *rv = PyDict_GetItemWithError(v, key);\n    if (rv == NULL && PyErr_Occurred()) {\n        throw error_already_set();\n    }\n    return rv;\n#else\n    return PyDict_GetItem(v, key);\n#endif\n}\n\n// Helper aliases/functions to support implicit casting of values given to python\n// accessors/methods. When given a pyobject, this simply returns the pyobject as-is; for other C++\n// type, the value goes through pybind11::cast(obj) to convert it to an `object`.\ntemplate <typename T, enable_if_t<is_pyobject<T>::value, int> = 0>\nauto object_or_cast(T &&o) -> decltype(std::forward<T>(o)) {\n    return std::forward<T>(o);\n}\n// The following casting version is implemented in cast.h:\ntemplate <typename T, enable_if_t<!is_pyobject<T>::value, int> = 0>\nobject object_or_cast(T &&o);\n// Match a PyObject*, which we want to convert directly to handle via its converting constructor\ninline handle object_or_cast(PyObject *ptr) { return ptr; }\n\n#if defined(_MSC_VER) && _MSC_VER < 1920\n#    pragma warning(push)\n#    pragma warning(disable : 4522) // warning C4522: multiple assignment operators specified\n#endif\ntemplate <typename Policy>\nclass accessor : public object_api<accessor<Policy>> {\n    using key_type = typename Policy::key_type;\n\npublic:\n    accessor(handle obj, key_type key) : obj(obj), key(std::move(key)) {}\n    accessor(const accessor &) = default;\n    accessor(accessor &&) noexcept = default;\n\n    // accessor overload required to override default assignment operator (templates are not\n    // allowed to replace default compiler-generated assignments).\n    void operator=(const accessor &a) && { std::move(*this).operator=(handle(a)); }\n    void operator=(const accessor &a) & { operator=(handle(a)); }\n\n    template <typename T>\n    void operator=(T &&value) && {\n        Policy::set(obj, key, object_or_cast(std::forward<T>(value)));\n    }\n    template <typename T>\n    void operator=(T &&value) & {\n        get_cache() = reinterpret_borrow<object>(object_or_cast(std::forward<T>(value)));\n    }\n\n    template <typename T = Policy>\n    PYBIND11_DEPRECATED(\n        \"Use of obj.attr(...) as bool is deprecated in favor of pybind11::hasattr(obj, ...)\")\n    explicit\n    operator enable_if_t<std::is_same<T, accessor_policies::str_attr>::value\n                             || std::is_same<T, accessor_policies::obj_attr>::value,\n                         bool>() const {\n        return hasattr(obj, key);\n    }\n    template <typename T = Policy>\n    PYBIND11_DEPRECATED(\"Use of obj[key] as bool is deprecated in favor of obj.contains(key)\")\n    explicit\n    operator enable_if_t<std::is_same<T, accessor_policies::generic_item>::value, bool>() const {\n        return obj.contains(key);\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator object() const { return get_cache(); }\n    PyObject *ptr() const { return get_cache().ptr(); }\n    template <typename T>\n    T cast() const {\n        return get_cache().template cast<T>();\n    }\n\nprivate:\n    object &get_cache() const {\n        if (!cache) {\n            cache = Policy::get(obj, key);\n        }\n        return cache;\n    }\n\nprivate:\n    handle obj;\n    key_type key;\n    mutable object cache;\n};\n#if defined(_MSC_VER) && _MSC_VER < 1920\n#    pragma warning(pop)\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(accessor_policies)\nstruct obj_attr {\n    using key_type = object;\n    static object get(handle obj, handle key) { return getattr(obj, key); }\n    static void set(handle obj, handle key, handle val) { setattr(obj, key, val); }\n};\n\nstruct str_attr {\n    using key_type = const char *;\n    static object get(handle obj, const char *key) { return getattr(obj, key); }\n    static void set(handle obj, const char *key, handle val) { setattr(obj, key, val); }\n};\n\nstruct generic_item {\n    using key_type = object;\n\n    static object get(handle obj, handle key) {\n        PyObject *result = PyObject_GetItem(obj.ptr(), key.ptr());\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\n    static void set(handle obj, handle key, handle val) {\n        if (PyObject_SetItem(obj.ptr(), key.ptr(), val.ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct sequence_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PySequence_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_steal<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PySequence_SetItem does not steal a reference to 'val'\n        if (PySequence_SetItem(obj.ptr(), ssize_t_cast(index), val.ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct list_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PyList_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_borrow<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PyList_SetItem steals a reference to 'val'\n        if (PyList_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\n\nstruct tuple_item {\n    using key_type = size_t;\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static object get(handle obj, const IdxType &index) {\n        PyObject *result = PyTuple_GetItem(obj.ptr(), ssize_t_cast(index));\n        if (!result) {\n            throw error_already_set();\n        }\n        return reinterpret_borrow<object>(result);\n    }\n\n    template <typename IdxType, detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    static void set(handle obj, const IdxType &index, handle val) {\n        // PyTuple_SetItem steals a reference to 'val'\n        if (PyTuple_SetItem(obj.ptr(), ssize_t_cast(index), val.inc_ref().ptr()) != 0) {\n            throw error_already_set();\n        }\n    }\n};\nPYBIND11_NAMESPACE_END(accessor_policies)\n\n/// STL iterator template used for tuple, list, sequence and dict\ntemplate <typename Policy>\nclass generic_iterator : public Policy {\n    using It = generic_iterator;\n\npublic:\n    using difference_type = ssize_t;\n    using iterator_category = typename Policy::iterator_category;\n    using value_type = typename Policy::value_type;\n    using reference = typename Policy::reference;\n    using pointer = typename Policy::pointer;\n\n    generic_iterator() = default;\n    generic_iterator(handle seq, ssize_t index) : Policy(seq, index) {}\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator*() const { return Policy::dereference(); }\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator[](difference_type n) const { return *(*this + n); }\n    pointer operator->() const { return **this; }\n\n    It &operator++() {\n        Policy::increment();\n        return *this;\n    }\n    It operator++(int) {\n        auto copy = *this;\n        Policy::increment();\n        return copy;\n    }\n    It &operator--() {\n        Policy::decrement();\n        return *this;\n    }\n    It operator--(int) {\n        auto copy = *this;\n        Policy::decrement();\n        return copy;\n    }\n    It &operator+=(difference_type n) {\n        Policy::advance(n);\n        return *this;\n    }\n    It &operator-=(difference_type n) {\n        Policy::advance(-n);\n        return *this;\n    }\n\n    friend It operator+(const It &a, difference_type n) {\n        auto copy = a;\n        return copy += n;\n    }\n    friend It operator+(difference_type n, const It &b) { return b + n; }\n    friend It operator-(const It &a, difference_type n) {\n        auto copy = a;\n        return copy -= n;\n    }\n    friend difference_type operator-(const It &a, const It &b) { return a.distance_to(b); }\n\n    friend bool operator==(const It &a, const It &b) { return a.equal(b); }\n    friend bool operator!=(const It &a, const It &b) { return !(a == b); }\n    friend bool operator<(const It &a, const It &b) { return b - a > 0; }\n    friend bool operator>(const It &a, const It &b) { return b < a; }\n    friend bool operator>=(const It &a, const It &b) { return !(a < b); }\n    friend bool operator<=(const It &a, const It &b) { return !(a > b); }\n};\n\nPYBIND11_NAMESPACE_BEGIN(iterator_policies)\n/// Quick proxy class needed to implement ``operator->`` for iterators which can't return pointers\ntemplate <typename T>\nstruct arrow_proxy {\n    T value;\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    arrow_proxy(T &&value) noexcept : value(std::move(value)) {}\n    T *operator->() const { return &value; }\n};\n\n/// Lightweight iterator policy using just a simple pointer: see ``PySequence_Fast_ITEMS``\nclass sequence_fast_readonly {\nprotected:\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = handle;\n    using reference = const handle; // PR #3263\n    using pointer = arrow_proxy<const handle>;\n\n    sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) {}\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference dereference() const { return *ptr; }\n    void increment() { ++ptr; }\n    void decrement() { --ptr; }\n    void advance(ssize_t n) { ptr += n; }\n    bool equal(const sequence_fast_readonly &b) const { return ptr == b.ptr; }\n    ssize_t distance_to(const sequence_fast_readonly &b) const { return ptr - b.ptr; }\n\nprivate:\n    PyObject **ptr;\n};\n\n/// Full read and write access using the sequence protocol: see ``detail::sequence_accessor``\nclass sequence_slow_readwrite {\nprotected:\n    using iterator_category = std::random_access_iterator_tag;\n    using value_type = object;\n    using reference = sequence_accessor;\n    using pointer = arrow_proxy<const sequence_accessor>;\n\n    sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) {}\n\n    reference dereference() const { return {obj, static_cast<size_t>(index)}; }\n    void increment() { ++index; }\n    void decrement() { --index; }\n    void advance(ssize_t n) { index += n; }\n    bool equal(const sequence_slow_readwrite &b) const { return index == b.index; }\n    ssize_t distance_to(const sequence_slow_readwrite &b) const { return index - b.index; }\n\nprivate:\n    handle obj;\n    ssize_t index;\n};\n\n/// Python's dictionary protocol permits this to be a forward iterator\nclass dict_readonly {\nprotected:\n    using iterator_category = std::forward_iterator_tag;\n    using value_type = std::pair<handle, handle>;\n    using reference = const value_type; // PR #3263\n    using pointer = arrow_proxy<const value_type>;\n\n    dict_readonly() = default;\n    dict_readonly(handle obj, ssize_t pos) : obj(obj), pos(pos) { increment(); }\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference dereference() const { return {key, value}; }\n    void increment() {\n        if (PyDict_Next(obj.ptr(), &pos, &key, &value) == 0) {\n            pos = -1;\n        }\n    }\n    bool equal(const dict_readonly &b) const { return pos == b.pos; }\n\nprivate:\n    handle obj;\n    PyObject *key = nullptr, *value = nullptr;\n    ssize_t pos = -1;\n};\nPYBIND11_NAMESPACE_END(iterator_policies)\n\n#if !defined(PYPY_VERSION)\nusing tuple_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;\nusing list_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;\n#else\nusing tuple_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\nusing list_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\n#endif\n\nusing sequence_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;\nusing dict_iterator = generic_iterator<iterator_policies::dict_readonly>;\n\ninline bool PyIterable_Check(PyObject *obj) {\n    PyObject *iter = PyObject_GetIter(obj);\n    if (iter) {\n        Py_DECREF(iter);\n        return true;\n    }\n    PyErr_Clear();\n    return false;\n}\n\ninline bool PyNone_Check(PyObject *o) { return o == Py_None; }\ninline bool PyEllipsis_Check(PyObject *o) { return o == Py_Ellipsis; }\n\n#ifdef PYBIND11_STR_LEGACY_PERMISSIVE\ninline bool PyUnicode_Check_Permissive(PyObject *o) {\n    return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o);\n}\n#    define PYBIND11_STR_CHECK_FUN detail::PyUnicode_Check_Permissive\n#else\n#    define PYBIND11_STR_CHECK_FUN PyUnicode_Check\n#endif\n\ninline bool PyStaticMethod_Check(PyObject *o) { return o->ob_type == &PyStaticMethod_Type; }\n\nclass kwargs_proxy : public handle {\npublic:\n    explicit kwargs_proxy(handle h) : handle(h) {}\n};\n\nclass args_proxy : public handle {\npublic:\n    explicit args_proxy(handle h) : handle(h) {}\n    kwargs_proxy operator*() const { return kwargs_proxy(*this); }\n};\n\n/// Python argument categories (using PEP 448 terms)\ntemplate <typename T>\nusing is_keyword = std::is_base_of<arg, T>;\ntemplate <typename T>\nusing is_s_unpacking = std::is_same<args_proxy, T>; // * unpacking\ntemplate <typename T>\nusing is_ds_unpacking = std::is_same<kwargs_proxy, T>; // ** unpacking\ntemplate <typename T>\nusing is_positional = satisfies_none_of<T, is_keyword, is_s_unpacking, is_ds_unpacking>;\ntemplate <typename T>\nusing is_keyword_or_ds = satisfies_any_of<T, is_keyword, is_ds_unpacking>;\n\n// Call argument collector forward declarations\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\nclass simple_collector;\ntemplate <return_value_policy policy = return_value_policy::automatic_reference>\nclass unpacking_collector;\n\nPYBIND11_NAMESPACE_END(detail)\n\n// TODO: After the deprecated constructors are removed, this macro can be simplified by\n//       inheriting ctors: `using Parent::Parent`. It's not an option right now because\n//       the `using` statement triggers the parent deprecation warning even if the ctor\n//       isn't even used.\n#define PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                            \\\npublic:                                                                                           \\\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<\" #Name \">() or reinterpret_steal<\" #Name \">()\")  \\\n    Name(handle h, bool is_borrowed)                                                              \\\n        : Parent(is_borrowed ? Parent(h, borrowed_t{}) : Parent(h, stolen_t{})) {}                \\\n    Name(handle h, borrowed_t) : Parent(h, borrowed_t{}) {}                                       \\\n    Name(handle h, stolen_t) : Parent(h, stolen_t{}) {}                                           \\\n    PYBIND11_DEPRECATED(\"Use py::isinstance<py::python_type>(obj) instead\")                       \\\n    bool check() const { return m_ptr != nullptr && (CheckFun(m_ptr) != 0); }                     \\\n    static bool check_(handle h) { return h.ptr() != nullptr && CheckFun(h.ptr()); }              \\\n    template <typename Policy_> /* NOLINTNEXTLINE(google-explicit-constructor) */                 \\\n    Name(const ::pybind11::detail::accessor<Policy_> &a) : Name(object(a)) {}\n\n#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)                                   \\\n    PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                                \\\n    /* This is deliberately not 'explicit' to allow implicit conversion from object: */           \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(const object &o)                                                                         \\\n        : Parent(check_(o) ? o.inc_ref().ptr() : ConvertFun(o.ptr()), stolen_t{}) {               \\\n        if (!m_ptr)                                                                               \\\n            throw error_already_set();                                                            \\\n    }                                                                                             \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(object &&o) : Parent(check_(o) ? o.release().ptr() : ConvertFun(o.ptr()), stolen_t{}) {  \\\n        if (!m_ptr)                                                                               \\\n            throw error_already_set();                                                            \\\n    }\n\n#define PYBIND11_OBJECT_CVT_DEFAULT(Name, Parent, CheckFun, ConvertFun)                           \\\n    PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, ConvertFun)                                       \\\n    Name() : Parent() {}\n\n#define PYBIND11_OBJECT_CHECK_FAILED(Name, o_ptr)                                                 \\\n    ::pybind11::type_error(\"Object of type '\"                                                     \\\n                           + ::pybind11::detail::get_fully_qualified_tp_name(Py_TYPE(o_ptr))      \\\n                           + \"' is not an instance of '\" #Name \"'\")\n\n#define PYBIND11_OBJECT(Name, Parent, CheckFun)                                                   \\\n    PYBIND11_OBJECT_COMMON(Name, Parent, CheckFun)                                                \\\n    /* This is deliberately not 'explicit' to allow implicit conversion from object: */           \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(const object &o) : Parent(o) {                                                           \\\n        if (m_ptr && !check_(m_ptr))                                                              \\\n            throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr);                                      \\\n    }                                                                                             \\\n    /* NOLINTNEXTLINE(google-explicit-constructor) */                                             \\\n    Name(object &&o) : Parent(std::move(o)) {                                                     \\\n        if (m_ptr && !check_(m_ptr))                                                              \\\n            throw PYBIND11_OBJECT_CHECK_FAILED(Name, m_ptr);                                      \\\n    }\n\n#define PYBIND11_OBJECT_DEFAULT(Name, Parent, CheckFun)                                           \\\n    PYBIND11_OBJECT(Name, Parent, CheckFun)                                                       \\\n    Name() : Parent() {}\n\n/// \\addtogroup pytypes\n/// @{\n\n/** \\rst\n    Wraps a Python iterator so that it can also be used as a C++ input iterator\n\n    Caveat: copying an iterator does not (and cannot) clone the internal\n    state of the Python iterable. This also applies to the post-increment\n    operator. This iterator should only be used to retrieve the current\n    value using ``operator*()``.\n\\endrst */\nclass iterator : public object {\npublic:\n    using iterator_category = std::input_iterator_tag;\n    using difference_type = ssize_t;\n    using value_type = handle;\n    using reference = const handle; // PR #3263\n    using pointer = const handle *;\n\n    PYBIND11_OBJECT_DEFAULT(iterator, object, PyIter_Check)\n\n    iterator &operator++() {\n        advance();\n        return *this;\n    }\n\n    iterator operator++(int) {\n        auto rv = *this;\n        advance();\n        return rv;\n    }\n\n    // NOLINTNEXTLINE(readability-const-return-type) // PR #3263\n    reference operator*() const {\n        if (m_ptr && !value.ptr()) {\n            auto &self = const_cast<iterator &>(*this);\n            self.advance();\n        }\n        return value;\n    }\n\n    pointer operator->() const {\n        operator*();\n        return &value;\n    }\n\n    /** \\rst\n         The value which marks the end of the iteration. ``it == iterator::sentinel()``\n         is equivalent to catching ``StopIteration`` in Python.\n\n         .. code-block:: cpp\n\n             void foo(py::iterator it) {\n                 while (it != py::iterator::sentinel()) {\n                    // use `*it`\n                    ++it;\n                 }\n             }\n    \\endrst */\n    static iterator sentinel() { return {}; }\n\n    friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); }\n    friend bool operator!=(const iterator &a, const iterator &b) { return a->ptr() != b->ptr(); }\n\nprivate:\n    void advance() {\n        value = reinterpret_steal<object>(PyIter_Next(m_ptr));\n        if (PyErr_Occurred()) {\n            throw error_already_set();\n        }\n    }\n\nprivate:\n    object value = {};\n};\n\nclass type : public object {\npublic:\n    PYBIND11_OBJECT(type, object, PyType_Check)\n\n    /// Return a type handle from a handle or an object\n    static handle handle_of(handle h) { return handle((PyObject *) Py_TYPE(h.ptr())); }\n\n    /// Return a type object from a handle or an object\n    static type of(handle h) { return type(type::handle_of(h), borrowed_t{}); }\n\n    // Defined in pybind11/cast.h\n    /// Convert C++ type to handle if previously registered. Does not convert\n    /// standard types, like int, float. etc. yet.\n    /// See https://github.com/pybind/pybind11/issues/2486\n    template <typename T>\n    static handle handle_of();\n\n    /// Convert C++ type to type if previously registered. Does not convert\n    /// standard types, like int, float. etc. yet.\n    /// See https://github.com/pybind/pybind11/issues/2486\n    template <typename T>\n    static type of() {\n        return type(type::handle_of<T>(), borrowed_t{});\n    }\n};\n\nclass iterable : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(iterable, object, detail::PyIterable_Check)\n};\n\nclass bytes;\n\nclass str : public object {\npublic:\n    PYBIND11_OBJECT_CVT(str, object, PYBIND11_STR_CHECK_FUN, raw_str)\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    str(const char *c, const SzType &n)\n        : object(PyUnicode_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate string object!\");\n        }\n    }\n\n    // 'explicit' is explicitly omitted from the following constructors to allow implicit\n    // conversion to py::str from C++ string-like objects\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(const char *c = \"\") : object(PyUnicode_FromString(c), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate string object!\");\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(const std::string &s) : str(s.data(), s.size()) {}\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n    // enable_if is needed to avoid \"ambiguous conversion\" errors (see PR #3521).\n    template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(T s) : str(s.data(), s.size()) {}\n\n#    ifdef PYBIND11_HAS_U8STRING\n    // reinterpret_cast here is safe (C++20 guarantees char8_t has the same size/alignment as char)\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    str(std::u8string_view s) : str(reinterpret_cast<const char *>(s.data()), s.size()) {}\n#    endif\n\n#endif\n\n    explicit str(const bytes &b);\n\n    /** \\rst\n        Return a string representation of the object. This is analogous to\n        the ``str()`` function in Python.\n    \\endrst */\n    explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            throw error_already_set();\n        }\n    }\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string() const {\n        object temp = *this;\n        if (PyUnicode_Check(m_ptr)) {\n            temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(m_ptr));\n            if (!temp) {\n                throw error_already_set();\n            }\n        }\n        char *buffer = nullptr;\n        ssize_t length = 0;\n        if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) {\n            pybind11_fail(\"Unable to extract string contents! (invalid type)\");\n        }\n        return std::string(buffer, (size_t) length);\n    }\n\n    template <typename... Args>\n    str format(Args &&...args) const {\n        return attr(\"format\")(std::forward<Args>(args)...);\n    }\n\nprivate:\n    /// Return string representation -- always returns a new reference, even if already a str\n    static PyObject *raw_str(PyObject *op) {\n        PyObject *str_value = PyObject_Str(op);\n#if PY_MAJOR_VERSION < 3\n        if (!str_value)\n            throw error_already_set();\n        PyObject *unicode = PyUnicode_FromEncodedObject(str_value, \"utf-8\", nullptr);\n        Py_XDECREF(str_value);\n        str_value = unicode;\n#endif\n        return str_value;\n    }\n};\n/// @} pytypes\n\ninline namespace literals {\n/** \\rst\n    String literal version of `str`\n \\endrst */\ninline str operator\"\" _s(const char *s, size_t size) { return {s, size}; }\n} // namespace literals\n\n/// \\addtogroup pytypes\n/// @{\nclass bytes : public object {\npublic:\n    PYBIND11_OBJECT(bytes, object, PYBIND11_BYTES_CHECK)\n\n    // Allow implicit conversion:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(const char *c = \"\") : object(PYBIND11_BYTES_FROM_STRING(c), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytes object!\");\n        }\n    }\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    bytes(const char *c, const SzType &n)\n        : object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytes object!\");\n        }\n    }\n\n    // Allow implicit conversion:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(const std::string &s) : bytes(s.data(), s.size()) {}\n\n    explicit bytes(const pybind11::str &s);\n\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string() const {\n        char *buffer = nullptr;\n        ssize_t length = 0;\n        if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) {\n            pybind11_fail(\"Unable to extract bytes contents!\");\n        }\n        return std::string(buffer, (size_t) length);\n    }\n\n#ifdef PYBIND11_HAS_STRING_VIEW\n    // enable_if is needed to avoid \"ambiguous conversion\" errors (see PR #3521).\n    template <typename T, detail::enable_if_t<std::is_same<T, std::string_view>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bytes(T s) : bytes(s.data(), s.size()) {}\n\n    // Obtain a string view that views the current `bytes` buffer value.  Note that this is only\n    // valid so long as the `bytes` instance remains alive and so generally should not outlive the\n    // lifetime of the `bytes` instance.\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator std::string_view() const {\n        char *buffer = nullptr;\n        ssize_t length = 0;\n        if (PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length)) {\n            pybind11_fail(\"Unable to extract bytes contents!\");\n        }\n        return {buffer, static_cast<size_t>(length)};\n    }\n#endif\n};\n// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors\n// are included in the doxygen group; close here and reopen after as a workaround\n/// @} pytypes\n\ninline bytes::bytes(const pybind11::str &s) {\n    object temp = s;\n    if (PyUnicode_Check(s.ptr())) {\n        temp = reinterpret_steal<object>(PyUnicode_AsUTF8String(s.ptr()));\n        if (!temp) {\n            pybind11_fail(\"Unable to extract string contents! (encoding issue)\");\n        }\n    }\n    char *buffer = nullptr;\n    ssize_t length = 0;\n    if (PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length)) {\n        pybind11_fail(\"Unable to extract string contents! (invalid type)\");\n    }\n    auto obj = reinterpret_steal<object>(PYBIND11_BYTES_FROM_STRING_AND_SIZE(buffer, length));\n    if (!obj) {\n        pybind11_fail(\"Could not allocate bytes object!\");\n    }\n    m_ptr = obj.release().ptr();\n}\n\ninline str::str(const bytes &b) {\n    char *buffer = nullptr;\n    ssize_t length = 0;\n    if (PYBIND11_BYTES_AS_STRING_AND_SIZE(b.ptr(), &buffer, &length)) {\n        pybind11_fail(\"Unable to extract bytes contents!\");\n    }\n    auto obj = reinterpret_steal<object>(PyUnicode_FromStringAndSize(buffer, length));\n    if (!obj) {\n        pybind11_fail(\"Could not allocate string object!\");\n    }\n    m_ptr = obj.release().ptr();\n}\n\n/// \\addtogroup pytypes\n/// @{\nclass bytearray : public object {\npublic:\n    PYBIND11_OBJECT_CVT(bytearray, object, PyByteArray_Check, PyByteArray_FromObject)\n\n    template <typename SzType, detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    bytearray(const char *c, const SzType &n)\n        : object(PyByteArray_FromStringAndSize(c, ssize_t_cast(n)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate bytearray object!\");\n        }\n    }\n\n    bytearray() : bytearray(\"\", 0) {}\n\n    explicit bytearray(const std::string &s) : bytearray(s.data(), s.size()) {}\n\n    size_t size() const { return static_cast<size_t>(PyByteArray_Size(m_ptr)); }\n\n    explicit operator std::string() const {\n        char *buffer = PyByteArray_AS_STRING(m_ptr);\n        ssize_t size = PyByteArray_GET_SIZE(m_ptr);\n        return std::string(buffer, static_cast<size_t>(size));\n    }\n};\n// Note: breathe >= 4.17.0 will fail to build docs if the below two constructors\n// are included in the doxygen group; close here and reopen after as a workaround\n/// @} pytypes\n\n/// \\addtogroup pytypes\n/// @{\nclass none : public object {\npublic:\n    PYBIND11_OBJECT(none, object, detail::PyNone_Check)\n    none() : object(Py_None, borrowed_t{}) {}\n};\n\nclass ellipsis : public object {\npublic:\n    PYBIND11_OBJECT(ellipsis, object, detail::PyEllipsis_Check)\n    ellipsis() : object(Py_Ellipsis, borrowed_t{}) {}\n};\n\nclass bool_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(bool_, object, PyBool_Check, raw_bool)\n    bool_() : object(Py_False, borrowed_t{}) {}\n    // Allow implicit conversion from and to `bool`:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    bool_(bool value) : object(value ? Py_True : Py_False, borrowed_t{}) {}\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator bool() const { return (m_ptr != nullptr) && PyLong_AsLong(m_ptr) != 0; }\n\nprivate:\n    /// Return the truth value of an object -- always returns a new reference\n    static PyObject *raw_bool(PyObject *op) {\n        const auto value = PyObject_IsTrue(op);\n        if (value == -1) {\n            return nullptr;\n        }\n        return handle(value != 0 ? Py_True : Py_False).inc_ref().ptr();\n    }\n};\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n// Converts a value to the given unsigned type.  If an error occurs, you get back (Unsigned) -1;\n// otherwise you get back the unsigned long or unsigned long long value cast to (Unsigned).\n// (The distinction is critically important when casting a returned -1 error value to some other\n// unsigned type: (A)-1 != (B)-1 when A and B are unsigned types of different sizes).\ntemplate <typename Unsigned>\nUnsigned as_unsigned(PyObject *o) {\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(Unsigned) <= sizeof(unsigned long))\n#if PY_VERSION_HEX < 0x03000000\n        || PyInt_Check(o)\n#endif\n    ) {\n        unsigned long v = PyLong_AsUnsignedLong(o);\n        return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;\n    }\n    unsigned long long v = PyLong_AsUnsignedLongLong(o);\n    return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;\n}\nPYBIND11_NAMESPACE_END(detail)\n\nclass int_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(int_, object, PYBIND11_LONG_CHECK, PyNumber_Long)\n    int_() : object(PyLong_FromLong(0), stolen_t{}) {}\n    // Allow implicit conversion from C++ integral types:\n    template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    int_(T value) {\n        if (PYBIND11_SILENCE_MSVC_C4127(sizeof(T) <= sizeof(long))) {\n            if (std::is_signed<T>::value) {\n                m_ptr = PyLong_FromLong((long) value);\n            } else {\n                m_ptr = PyLong_FromUnsignedLong((unsigned long) value);\n            }\n        } else {\n            if (std::is_signed<T>::value) {\n                m_ptr = PyLong_FromLongLong((long long) value);\n            } else {\n                m_ptr = PyLong_FromUnsignedLongLong((unsigned long long) value);\n            }\n        }\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate int object!\");\n        }\n    }\n\n    template <typename T, detail::enable_if_t<std::is_integral<T>::value, int> = 0>\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator T() const {\n        return std::is_unsigned<T>::value  ? detail::as_unsigned<T>(m_ptr)\n               : sizeof(T) <= sizeof(long) ? (T) PyLong_AsLong(m_ptr)\n                                           : (T) PYBIND11_LONG_AS_LONGLONG(m_ptr);\n    }\n};\n\nclass float_ : public object {\npublic:\n    PYBIND11_OBJECT_CVT(float_, object, PyFloat_Check, PyNumber_Float)\n    // Allow implicit conversion from float/double:\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    float_(float value) : object(PyFloat_FromDouble((double) value), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate float object!\");\n        }\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    float_(double value = .0) : object(PyFloat_FromDouble((double) value), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate float object!\");\n        }\n    }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator float() const { return (float) PyFloat_AsDouble(m_ptr); }\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    operator double() const { return (double) PyFloat_AsDouble(m_ptr); }\n};\n\nclass weakref : public object {\npublic:\n    PYBIND11_OBJECT_CVT_DEFAULT(weakref, object, PyWeakref_Check, raw_weakref)\n    explicit weakref(handle obj, handle callback = {})\n        : object(PyWeakref_NewRef(obj.ptr(), callback.ptr()), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate weak reference!\");\n        }\n    }\n\nprivate:\n    static PyObject *raw_weakref(PyObject *o) { return PyWeakref_NewRef(o, nullptr); }\n};\n\nclass slice : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(slice, object, PySlice_Check)\n    slice(handle start, handle stop, handle step) {\n        m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr());\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate slice object!\");\n        }\n    }\n\n#ifdef PYBIND11_HAS_OPTIONAL\n    slice(std::optional<ssize_t> start, std::optional<ssize_t> stop, std::optional<ssize_t> step)\n        : slice(index_to_object(start), index_to_object(stop), index_to_object(step)) {}\n#else\n    slice(ssize_t start_, ssize_t stop_, ssize_t step_)\n        : slice(int_(start_), int_(stop_), int_(step_)) {}\n#endif\n\n    bool\n    compute(size_t length, size_t *start, size_t *stop, size_t *step, size_t *slicelength) const {\n        return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr,\n                                    (ssize_t) length,\n                                    (ssize_t *) start,\n                                    (ssize_t *) stop,\n                                    (ssize_t *) step,\n                                    (ssize_t *) slicelength)\n               == 0;\n    }\n    bool compute(\n        ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {\n        return PySlice_GetIndicesEx(\n                   (PYBIND11_SLICE_OBJECT *) m_ptr, length, start, stop, step, slicelength)\n               == 0;\n    }\n\nprivate:\n    template <typename T>\n    static object index_to_object(T index) {\n        return index ? object(int_(*index)) : object(none());\n    }\n};\n\nclass capsule : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(capsule, object, PyCapsule_CheckExact)\n    PYBIND11_DEPRECATED(\"Use reinterpret_borrow<capsule>() or reinterpret_steal<capsule>()\")\n    capsule(PyObject *ptr, bool is_borrowed)\n        : object(is_borrowed ? object(ptr, borrowed_t{}) : object(ptr, stolen_t{})) {}\n\n    explicit capsule(const void *value,\n                     const char *name = nullptr,\n                     void (*destructor)(PyObject *) = nullptr)\n        : object(PyCapsule_New(const_cast<void *>(value), name, destructor), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate capsule object!\");\n        }\n    }\n\n    PYBIND11_DEPRECATED(\"Please pass a destructor that takes a void pointer as input\")\n    capsule(const void *value, void (*destruct)(PyObject *))\n        : object(PyCapsule_New(const_cast<void *>(value), nullptr, destruct), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate capsule object!\");\n        }\n    }\n\n    capsule(const void *value, void (*destructor)(void *)) {\n        m_ptr = PyCapsule_New(const_cast<void *>(value), nullptr, [](PyObject *o) {\n            auto destructor = reinterpret_cast<void (*)(void *)>(PyCapsule_GetContext(o));\n            void *ptr = PyCapsule_GetPointer(o, nullptr);\n            destructor(ptr);\n        });\n\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate capsule object!\");\n        }\n\n        if (PyCapsule_SetContext(m_ptr, (void *) destructor) != 0) {\n            pybind11_fail(\"Could not set capsule context!\");\n        }\n    }\n\n    explicit capsule(void (*destructor)()) {\n        m_ptr = PyCapsule_New(reinterpret_cast<void *>(destructor), nullptr, [](PyObject *o) {\n            auto destructor = reinterpret_cast<void (*)()>(PyCapsule_GetPointer(o, nullptr));\n            destructor();\n        });\n\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate capsule object!\");\n        }\n    }\n\n    template <typename T>\n    operator T *() const { // NOLINT(google-explicit-constructor)\n        return get_pointer<T>();\n    }\n\n    /// Get the pointer the capsule holds.\n    template <typename T = void>\n    T *get_pointer() const {\n        const auto *name = this->name();\n        T *result = static_cast<T *>(PyCapsule_GetPointer(m_ptr, name));\n        if (!result) {\n            PyErr_Clear();\n            pybind11_fail(\"Unable to extract capsule contents!\");\n        }\n        return result;\n    }\n\n    /// Replaces a capsule's pointer *without* calling the destructor on the existing one.\n    void set_pointer(const void *value) {\n        if (PyCapsule_SetPointer(m_ptr, const_cast<void *>(value)) != 0) {\n            PyErr_Clear();\n            pybind11_fail(\"Could not set capsule pointer\");\n        }\n    }\n\n    const char *name() const { return PyCapsule_GetName(m_ptr); }\n};\n\nclass tuple : public object {\npublic:\n    PYBIND11_OBJECT_CVT(tuple, object, PyTuple_Check, PySequence_Tuple)\n    template <typename SzType = ssize_t,\n              detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    // Some compilers generate link errors when using `const SzType &` here:\n    explicit tuple(SzType size = 0) : object(PyTuple_New(ssize_t_cast(size)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate tuple object!\");\n        }\n    }\n    size_t size() const { return (size_t) PyTuple_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }\n    detail::item_accessor operator[](handle h) const { return object::operator[](h); }\n    detail::tuple_iterator begin() const { return {*this, 0}; }\n    detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }\n};\n\n// We need to put this into a separate function because the Intel compiler\n// fails to compile enable_if_t<all_of<is_keyword_or_ds<Args>...>::value> part below\n// (tested with ICC 2021.1 Beta 20200827).\ntemplate <typename... Args>\nconstexpr bool args_are_all_keyword_or_ds() {\n    return detail::all_of<detail::is_keyword_or_ds<Args>...>::value;\n}\n\nclass dict : public object {\npublic:\n    PYBIND11_OBJECT_CVT(dict, object, PyDict_Check, raw_dict)\n    dict() : object(PyDict_New(), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate dict object!\");\n        }\n    }\n    template <typename... Args,\n              typename = detail::enable_if_t<args_are_all_keyword_or_ds<Args...>()>,\n              // MSVC workaround: it can't compile an out-of-line definition, so defer the\n              // collector\n              typename collector = detail::deferred_t<detail::unpacking_collector<>, Args...>>\n    explicit dict(Args &&...args) : dict(collector(std::forward<Args>(args)...).kwargs()) {}\n\n    size_t size() const { return (size_t) PyDict_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::dict_iterator begin() const { return {*this, 0}; }\n    detail::dict_iterator end() const { return {}; }\n    void clear() /* py-non-const */ { PyDict_Clear(ptr()); }\n    template <typename T>\n    bool contains(T &&key) const {\n        return PyDict_Contains(m_ptr, detail::object_or_cast(std::forward<T>(key)).ptr()) == 1;\n    }\n\nprivate:\n    /// Call the `dict` Python type -- always returns a new reference\n    static PyObject *raw_dict(PyObject *op) {\n        if (PyDict_Check(op)) {\n            return handle(op).inc_ref().ptr();\n        }\n        return PyObject_CallFunctionObjArgs((PyObject *) &PyDict_Type, op, nullptr);\n    }\n};\n\nclass sequence : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check)\n    size_t size() const {\n        ssize_t result = PySequence_Size(m_ptr);\n        if (result == -1) {\n            throw error_already_set();\n        }\n        return (size_t) result;\n    }\n    bool empty() const { return size() == 0; }\n    detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }\n    detail::item_accessor operator[](handle h) const { return object::operator[](h); }\n    detail::sequence_iterator begin() const { return {*this, 0}; }\n    detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }\n};\n\nclass list : public object {\npublic:\n    PYBIND11_OBJECT_CVT(list, object, PyList_Check, PySequence_List)\n    template <typename SzType = ssize_t,\n              detail::enable_if_t<std::is_integral<SzType>::value, int> = 0>\n    // Some compilers generate link errors when using `const SzType &` here:\n    explicit list(SzType size = 0) : object(PyList_New(ssize_t_cast(size)), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate list object!\");\n        }\n    }\n    size_t size() const { return (size_t) PyList_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    detail::list_accessor operator[](size_t index) const { return {*this, index}; }\n    detail::item_accessor operator[](handle h) const { return object::operator[](h); }\n    detail::list_iterator begin() const { return {*this, 0}; }\n    detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }\n    template <typename T>\n    void append(T &&val) /* py-non-const */ {\n        PyList_Append(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr());\n    }\n    template <typename IdxType,\n              typename ValType,\n              detail::enable_if_t<std::is_integral<IdxType>::value, int> = 0>\n    void insert(const IdxType &index, ValType &&val) /* py-non-const */ {\n        PyList_Insert(\n            m_ptr, ssize_t_cast(index), detail::object_or_cast(std::forward<ValType>(val)).ptr());\n    }\n};\n\nclass args : public tuple {\n    PYBIND11_OBJECT_DEFAULT(args, tuple, PyTuple_Check)\n};\nclass kwargs : public dict {\n    PYBIND11_OBJECT_DEFAULT(kwargs, dict, PyDict_Check)\n};\n\nclass set : public object {\npublic:\n    PYBIND11_OBJECT_CVT(set, object, PySet_Check, PySet_New)\n    set() : object(PySet_New(nullptr), stolen_t{}) {\n        if (!m_ptr) {\n            pybind11_fail(\"Could not allocate set object!\");\n        }\n    }\n    size_t size() const { return (size_t) PySet_Size(m_ptr); }\n    bool empty() const { return size() == 0; }\n    template <typename T>\n    bool add(T &&val) /* py-non-const */ {\n        return PySet_Add(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) == 0;\n    }\n    void clear() /* py-non-const */ { PySet_Clear(m_ptr); }\n    template <typename T>\n    bool contains(T &&val) const {\n        return PySet_Contains(m_ptr, detail::object_or_cast(std::forward<T>(val)).ptr()) == 1;\n    }\n};\n\nclass function : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(function, object, PyCallable_Check)\n    handle cpp_function() const {\n        handle fun = detail::get_function(m_ptr);\n        if (fun && PyCFunction_Check(fun.ptr())) {\n            return fun;\n        }\n        return handle();\n    }\n    bool is_cpp_function() const { return (bool) cpp_function(); }\n};\n\nclass staticmethod : public object {\npublic:\n    PYBIND11_OBJECT_CVT(staticmethod, object, detail::PyStaticMethod_Check, PyStaticMethod_New)\n};\n\nclass buffer : public object {\npublic:\n    PYBIND11_OBJECT_DEFAULT(buffer, object, PyObject_CheckBuffer)\n\n    buffer_info request(bool writable = false) const {\n        int flags = PyBUF_STRIDES | PyBUF_FORMAT;\n        if (writable) {\n            flags |= PyBUF_WRITABLE;\n        }\n        auto *view = new Py_buffer();\n        if (PyObject_GetBuffer(m_ptr, view, flags) != 0) {\n            delete view;\n            throw error_already_set();\n        }\n        return buffer_info(view);\n    }\n};\n\nclass memoryview : public object {\npublic:\n    PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject)\n\n    /** \\rst\n        Creates ``memoryview`` from ``buffer_info``.\n\n        ``buffer_info`` must be created from ``buffer::request()``. Otherwise\n        throws an exception.\n\n        For creating a ``memoryview`` from objects that support buffer protocol,\n        use ``memoryview(const object& obj)`` instead of this constructor.\n     \\endrst */\n    explicit memoryview(const buffer_info &info) {\n        if (!info.view()) {\n            pybind11_fail(\"Prohibited to create memoryview without Py_buffer\");\n        }\n        // Note: PyMemoryView_FromBuffer never increments obj reference.\n        m_ptr = (info.view()->obj) ? PyMemoryView_FromObject(info.view()->obj)\n                                   : PyMemoryView_FromBuffer(info.view());\n        if (!m_ptr) {\n            pybind11_fail(\"Unable to create memoryview from buffer descriptor\");\n        }\n    }\n\n    /** \\rst\n        Creates ``memoryview`` from static buffer.\n\n        This method is meant for providing a ``memoryview`` for C/C++ buffer not\n        managed by Python. The caller is responsible for managing the lifetime\n        of ``ptr`` and ``format``, which MUST outlive the memoryview constructed\n        here.\n\n        See also: Python C API documentation for `PyMemoryView_FromBuffer`_.\n\n        .. _PyMemoryView_FromBuffer:\n           https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer\n\n        :param ptr: Pointer to the buffer.\n        :param itemsize: Byte size of an element.\n        :param format: Pointer to the null-terminated format string. For\n            homogeneous Buffers, this should be set to\n            ``format_descriptor<T>::value``.\n        :param shape: Shape of the tensor (1 entry per dimension).\n        :param strides: Number of bytes between adjacent entries (for each\n            per dimension).\n        :param readonly: Flag to indicate if the underlying storage may be\n            written to.\n     \\endrst */\n    static memoryview from_buffer(void *ptr,\n                                  ssize_t itemsize,\n                                  const char *format,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides,\n                                  bool readonly = false);\n\n    static memoryview from_buffer(const void *ptr,\n                                  ssize_t itemsize,\n                                  const char *format,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides) {\n        return memoryview::from_buffer(\n            const_cast<void *>(ptr), itemsize, format, std::move(shape), std::move(strides), true);\n    }\n\n    template <typename T>\n    static memoryview from_buffer(T *ptr,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides,\n                                  bool readonly = false) {\n        return memoryview::from_buffer(reinterpret_cast<void *>(ptr),\n                                       sizeof(T),\n                                       format_descriptor<T>::value,\n                                       shape,\n                                       strides,\n                                       readonly);\n    }\n\n    template <typename T>\n    static memoryview from_buffer(const T *ptr,\n                                  detail::any_container<ssize_t> shape,\n                                  detail::any_container<ssize_t> strides) {\n        return memoryview::from_buffer(const_cast<T *>(ptr), shape, strides, true);\n    }\n\n#if PY_MAJOR_VERSION >= 3\n    /** \\rst\n        Creates ``memoryview`` from static memory.\n\n        This method is meant for providing a ``memoryview`` for C/C++ buffer not\n        managed by Python. The caller is responsible for managing the lifetime\n        of ``mem``, which MUST outlive the memoryview constructed here.\n\n        This method is not available in Python 2.\n\n        See also: Python C API documentation for `PyMemoryView_FromBuffer`_.\n\n        .. _PyMemoryView_FromMemory:\n           https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory\n     \\endrst */\n    static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) {\n        PyObject *ptr = PyMemoryView_FromMemory(\n            reinterpret_cast<char *>(mem), size, (readonly) ? PyBUF_READ : PyBUF_WRITE);\n        if (!ptr) {\n            pybind11_fail(\"Could not allocate memoryview object!\");\n        }\n        return memoryview(object(ptr, stolen_t{}));\n    }\n\n    static memoryview from_memory(const void *mem, ssize_t size) {\n        return memoryview::from_memory(const_cast<void *>(mem), size, true);\n    }\n\n#    ifdef PYBIND11_HAS_STRING_VIEW\n    static memoryview from_memory(std::string_view mem) {\n        return from_memory(const_cast<char *>(mem.data()), static_cast<ssize_t>(mem.size()), true);\n    }\n#    endif\n\n#endif\n};\n\n/// @cond DUPLICATE\ninline memoryview memoryview::from_buffer(void *ptr,\n                                          ssize_t itemsize,\n                                          const char *format,\n                                          detail::any_container<ssize_t> shape,\n                                          detail::any_container<ssize_t> strides,\n                                          bool readonly) {\n    size_t ndim = shape->size();\n    if (ndim != strides->size()) {\n        pybind11_fail(\"memoryview: shape length doesn't match strides length\");\n    }\n    ssize_t size = ndim != 0u ? 1 : 0;\n    for (size_t i = 0; i < ndim; ++i) {\n        size *= (*shape)[i];\n    }\n    Py_buffer view;\n    view.buf = ptr;\n    view.obj = nullptr;\n    view.len = size * itemsize;\n    view.readonly = static_cast<int>(readonly);\n    view.itemsize = itemsize;\n    view.format = const_cast<char *>(format);\n    view.ndim = static_cast<int>(ndim);\n    view.shape = shape->data();\n    view.strides = strides->data();\n    view.suboffsets = nullptr;\n    view.internal = nullptr;\n    PyObject *obj = PyMemoryView_FromBuffer(&view);\n    if (!obj) {\n        throw error_already_set();\n    }\n    return memoryview(object(obj, stolen_t{}));\n}\n/// @endcond\n/// @} pytypes\n\n/// \\addtogroup python_builtins\n/// @{\n\n/// Get the length of a Python object.\ninline size_t len(handle h) {\n    ssize_t result = PyObject_Length(h.ptr());\n    if (result < 0) {\n        throw error_already_set();\n    }\n    return (size_t) result;\n}\n\n/// Get the length hint of a Python object.\n/// Returns 0 when this cannot be determined.\ninline size_t len_hint(handle h) {\n#if PY_VERSION_HEX >= 0x03040000\n    ssize_t result = PyObject_LengthHint(h.ptr(), 0);\n#else\n    ssize_t result = PyObject_Length(h.ptr());\n#endif\n    if (result < 0) {\n        // Sometimes a length can't be determined at all (eg generators)\n        // In which case simply return 0\n        PyErr_Clear();\n        return 0;\n    }\n    return (size_t) result;\n}\n\ninline str repr(handle h) {\n    PyObject *str_value = PyObject_Repr(h.ptr());\n    if (!str_value) {\n        throw error_already_set();\n    }\n#if PY_MAJOR_VERSION < 3\n    PyObject *unicode = PyUnicode_FromEncodedObject(str_value, \"utf-8\", nullptr);\n    Py_XDECREF(str_value);\n    str_value = unicode;\n    if (!str_value)\n        throw error_already_set();\n#endif\n    return reinterpret_steal<str>(str_value);\n}\n\ninline iterator iter(handle obj) {\n    PyObject *result = PyObject_GetIter(obj.ptr());\n    if (!result) {\n        throw error_already_set();\n    }\n    return reinterpret_steal<iterator>(result);\n}\n/// @} python_builtins\n\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <typename D>\niterator object_api<D>::begin() const {\n    return iter(derived());\n}\ntemplate <typename D>\niterator object_api<D>::end() const {\n    return iterator::sentinel();\n}\ntemplate <typename D>\nitem_accessor object_api<D>::operator[](handle key) const {\n    return {derived(), reinterpret_borrow<object>(key)};\n}\ntemplate <typename D>\nitem_accessor object_api<D>::operator[](const char *key) const {\n    return {derived(), pybind11::str(key)};\n}\ntemplate <typename D>\nobj_attr_accessor object_api<D>::attr(handle key) const {\n    return {derived(), reinterpret_borrow<object>(key)};\n}\ntemplate <typename D>\nstr_attr_accessor object_api<D>::attr(const char *key) const {\n    return {derived(), key};\n}\ntemplate <typename D>\nargs_proxy object_api<D>::operator*() const {\n    return args_proxy(derived().ptr());\n}\ntemplate <typename D>\ntemplate <typename T>\nbool object_api<D>::contains(T &&item) const {\n    return attr(\"__contains__\")(std::forward<T>(item)).template cast<bool>();\n}\n\ntemplate <typename D>\npybind11::str object_api<D>::str() const {\n    return pybind11::str(derived());\n}\n\ntemplate <typename D>\nstr_attr_accessor object_api<D>::doc() const {\n    return attr(\"__doc__\");\n}\n\ntemplate <typename D>\nhandle object_api<D>::get_type() const {\n    return type::handle_of(derived());\n}\n\ntemplate <typename D>\nbool object_api<D>::rich_compare(object_api const &other, int value) const {\n    int rv = PyObject_RichCompareBool(derived().ptr(), other.derived().ptr(), value);\n    if (rv == -1) {\n        throw error_already_set();\n    }\n    return rv == 1;\n}\n\n#define PYBIND11_MATH_OPERATOR_UNARY(op, fn)                                                      \\\n    template <typename D>                                                                         \\\n    object object_api<D>::op() const {                                                            \\\n        object result = reinterpret_steal<object>(fn(derived().ptr()));                           \\\n        if (!result.ptr())                                                                        \\\n            throw error_already_set();                                                            \\\n        return result;                                                                            \\\n    }\n\n#define PYBIND11_MATH_OPERATOR_BINARY(op, fn)                                                     \\\n    template <typename D>                                                                         \\\n    object object_api<D>::op(object_api const &other) const {                                     \\\n        object result = reinterpret_steal<object>(fn(derived().ptr(), other.derived().ptr()));    \\\n        if (!result.ptr())                                                                        \\\n            throw error_already_set();                                                            \\\n        return result;                                                                            \\\n    }\n\nPYBIND11_MATH_OPERATOR_UNARY(operator~, PyNumber_Invert)\nPYBIND11_MATH_OPERATOR_UNARY(operator-, PyNumber_Negative)\nPYBIND11_MATH_OPERATOR_BINARY(operator+, PyNumber_Add)\nPYBIND11_MATH_OPERATOR_BINARY(operator+=, PyNumber_InPlaceAdd)\nPYBIND11_MATH_OPERATOR_BINARY(operator-, PyNumber_Subtract)\nPYBIND11_MATH_OPERATOR_BINARY(operator-=, PyNumber_InPlaceSubtract)\nPYBIND11_MATH_OPERATOR_BINARY(operator*, PyNumber_Multiply)\nPYBIND11_MATH_OPERATOR_BINARY(operator*=, PyNumber_InPlaceMultiply)\nPYBIND11_MATH_OPERATOR_BINARY(operator/, PyNumber_TrueDivide)\nPYBIND11_MATH_OPERATOR_BINARY(operator/=, PyNumber_InPlaceTrueDivide)\nPYBIND11_MATH_OPERATOR_BINARY(operator|, PyNumber_Or)\nPYBIND11_MATH_OPERATOR_BINARY(operator|=, PyNumber_InPlaceOr)\nPYBIND11_MATH_OPERATOR_BINARY(operator&, PyNumber_And)\nPYBIND11_MATH_OPERATOR_BINARY(operator&=, PyNumber_InPlaceAnd)\nPYBIND11_MATH_OPERATOR_BINARY(operator^, PyNumber_Xor)\nPYBIND11_MATH_OPERATOR_BINARY(operator^=, PyNumber_InPlaceXor)\nPYBIND11_MATH_OPERATOR_BINARY(operator<<, PyNumber_Lshift)\nPYBIND11_MATH_OPERATOR_BINARY(operator<<=, PyNumber_InPlaceLshift)\nPYBIND11_MATH_OPERATOR_BINARY(operator>>, PyNumber_Rshift)\nPYBIND11_MATH_OPERATOR_BINARY(operator>>=, PyNumber_InPlaceRshift)\n\n#undef PYBIND11_MATH_OPERATOR_UNARY\n#undef PYBIND11_MATH_OPERATOR_BINARY\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/stl/filesystem.h",
    "content": "// Copyright (c) 2021 The Pybind Development Team.\n// All rights reserved. Use of this source code is governed by a\n// BSD-style license that can be found in the LICENSE file.\n\n#pragma once\n\n#include \"../pybind11.h\"\n#include \"../detail/common.h\"\n#include \"../detail/descr.h\"\n#include \"../cast.h\"\n#include \"../pytypes.h\"\n\n#include <string>\n\n#ifdef __has_include\n#    if defined(PYBIND11_CPP17) && __has_include(<filesystem>) && \\\n      PY_VERSION_HEX >= 0x03060000\n#        include <filesystem>\n#        define PYBIND11_HAS_FILESYSTEM 1\n#    endif\n#endif\n\n#if !defined(PYBIND11_HAS_FILESYSTEM) && !defined(PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL)\n#    error                                                                                        \\\n        \"#include <filesystem> is not available. (Use -DPYBIND11_HAS_FILESYSTEM_IS_OPTIONAL to ignore.)\"\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n#if defined(PYBIND11_HAS_FILESYSTEM)\ntemplate <typename T>\nstruct path_caster {\n\nprivate:\n    static PyObject *unicode_from_fs_native(const std::string &w) {\n#    if !defined(PYPY_VERSION)\n        return PyUnicode_DecodeFSDefaultAndSize(w.c_str(), ssize_t(w.size()));\n#    else\n        // PyPy mistakenly declares the first parameter as non-const.\n        return PyUnicode_DecodeFSDefaultAndSize(const_cast<char *>(w.c_str()), ssize_t(w.size()));\n#    endif\n    }\n\n    static PyObject *unicode_from_fs_native(const std::wstring &w) {\n        return PyUnicode_FromWideChar(w.c_str(), ssize_t(w.size()));\n    }\n\npublic:\n    static handle cast(const T &path, return_value_policy, handle) {\n        if (auto py_str = unicode_from_fs_native(path.native())) {\n            return module_::import(\"pathlib\")\n                .attr(\"Path\")(reinterpret_steal<object>(py_str))\n                .release();\n        }\n        return nullptr;\n    }\n\n    bool load(handle handle, bool) {\n        // PyUnicode_FSConverter and PyUnicode_FSDecoder normally take care of\n        // calling PyOS_FSPath themselves, but that's broken on PyPy (PyPy\n        // issue #3168) so we do it ourselves instead.\n        PyObject *buf = PyOS_FSPath(handle.ptr());\n        if (!buf) {\n            PyErr_Clear();\n            return false;\n        }\n        PyObject *native = nullptr;\n        if constexpr (std::is_same_v<typename T::value_type, char>) {\n            if (PyUnicode_FSConverter(buf, &native) != 0) {\n                if (auto *c_str = PyBytes_AsString(native)) {\n                    // AsString returns a pointer to the internal buffer, which\n                    // must not be free'd.\n                    value = c_str;\n                }\n            }\n        } else if constexpr (std::is_same_v<typename T::value_type, wchar_t>) {\n            if (PyUnicode_FSDecoder(buf, &native) != 0) {\n                if (auto *c_str = PyUnicode_AsWideCharString(native, nullptr)) {\n                    // AsWideCharString returns a new string that must be free'd.\n                    value = c_str; // Copies the string.\n                    PyMem_Free(c_str);\n                }\n            }\n        }\n        Py_XDECREF(native);\n        Py_DECREF(buf);\n        if (PyErr_Occurred()) {\n            PyErr_Clear();\n            return false;\n        }\n        return true;\n    }\n\n    PYBIND11_TYPE_CASTER(T, const_name(\"os.PathLike\"));\n};\n\ntemplate <>\nstruct type_caster<std::filesystem::path> : public path_caster<std::filesystem::path> {};\n#endif // PYBIND11_HAS_FILESYSTEM\n\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/stl.h",
    "content": "/*\n    pybind11/stl.h: Transparent conversion for STL data types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"pybind11.h\"\n#include \"detail/common.h\"\n\n#include <deque>\n#include <iostream>\n#include <list>\n#include <map>\n#include <set>\n#include <unordered_map>\n#include <unordered_set>\n#include <valarray>\n\n// See `detail/common.h` for implementation of these guards.\n#if defined(PYBIND11_HAS_OPTIONAL)\n#    include <optional>\n#elif defined(PYBIND11_HAS_EXP_OPTIONAL)\n#    include <experimental/optional>\n#endif\n\n#if defined(PYBIND11_HAS_VARIANT)\n#    include <variant>\n#endif\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/// Extracts an const lvalue reference or rvalue reference for U based on the type of T (e.g. for\n/// forwarding a container element).  Typically used indirect via forwarded_type(), below.\ntemplate <typename T, typename U>\nusing forwarded_type = conditional_t<std::is_lvalue_reference<T>::value,\n                                     remove_reference_t<U> &,\n                                     remove_reference_t<U> &&>;\n\n/// Forwards a value U as rvalue or lvalue according to whether T is rvalue or lvalue; typically\n/// used for forwarding a container's elements.\ntemplate <typename T, typename U>\nforwarded_type<T, U> forward_like(U &&u) {\n    return std::forward<detail::forwarded_type<T, U>>(std::forward<U>(u));\n}\n\ntemplate <typename Type, typename Key>\nstruct set_caster {\n    using type = Type;\n    using key_conv = make_caster<Key>;\n\n    bool load(handle src, bool convert) {\n        if (!isinstance<pybind11::set>(src)) {\n            return false;\n        }\n        auto s = reinterpret_borrow<pybind11::set>(src);\n        value.clear();\n        for (auto entry : s) {\n            key_conv conv;\n            if (!conv.load(entry, convert)) {\n                return false;\n            }\n            value.insert(cast_op<Key &&>(std::move(conv)));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Key>::policy(policy);\n        }\n        pybind11::set s;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                key_conv::cast(forward_like<T>(value), policy, parent));\n            if (!value_ || !s.add(value_)) {\n                return handle();\n            }\n        }\n        return s.release();\n    }\n\n    PYBIND11_TYPE_CASTER(type, const_name(\"Set[\") + key_conv::name + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Key, typename Value>\nstruct map_caster {\n    using key_conv = make_caster<Key>;\n    using value_conv = make_caster<Value>;\n\n    bool load(handle src, bool convert) {\n        if (!isinstance<dict>(src)) {\n            return false;\n        }\n        auto d = reinterpret_borrow<dict>(src);\n        value.clear();\n        for (auto it : d) {\n            key_conv kconv;\n            value_conv vconv;\n            if (!kconv.load(it.first.ptr(), convert) || !vconv.load(it.second.ptr(), convert)) {\n                return false;\n            }\n            value.emplace(cast_op<Key &&>(std::move(kconv)), cast_op<Value &&>(std::move(vconv)));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        dict d;\n        return_value_policy policy_key = policy;\n        return_value_policy policy_value = policy;\n        if (!std::is_lvalue_reference<T>::value) {\n            policy_key = return_value_policy_override<Key>::policy(policy_key);\n            policy_value = return_value_policy_override<Value>::policy(policy_value);\n        }\n        for (auto &&kv : src) {\n            auto key = reinterpret_steal<object>(\n                key_conv::cast(forward_like<T>(kv.first), policy_key, parent));\n            auto value = reinterpret_steal<object>(\n                value_conv::cast(forward_like<T>(kv.second), policy_value, parent));\n            if (!key || !value) {\n                return handle();\n            }\n            d[key] = value;\n        }\n        return d.release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name(\"Dict[\") + key_conv::name + const_name(\", \") + value_conv::name\n                             + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Value>\nstruct list_caster {\n    using value_conv = make_caster<Value>;\n\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src) || isinstance<bytes>(src) || isinstance<str>(src)) {\n            return false;\n        }\n        auto s = reinterpret_borrow<sequence>(src);\n        value.clear();\n        reserve_maybe(s, &value);\n        for (auto it : s) {\n            value_conv conv;\n            if (!conv.load(it, convert)) {\n                return false;\n            }\n            value.push_back(cast_op<Value &&>(std::move(conv)));\n        }\n        return true;\n    }\n\nprivate:\n    template <\n        typename T = Type,\n        enable_if_t<std::is_same<decltype(std::declval<T>().reserve(0)), void>::value, int> = 0>\n    void reserve_maybe(const sequence &s, Type *) {\n        value.reserve(s.size());\n    }\n    void reserve_maybe(const sequence &, void *) {}\n\npublic:\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Value>::policy(policy);\n        }\n        list l(src.size());\n        ssize_t index = 0;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                value_conv::cast(forward_like<T>(value), policy, parent));\n            if (!value_) {\n                return handle();\n            }\n            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference\n        }\n        return l.release();\n    }\n\n    PYBIND11_TYPE_CASTER(Type, const_name(\"List[\") + value_conv::name + const_name(\"]\"));\n};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::vector<Type, Alloc>> : list_caster<std::vector<Type, Alloc>, Type> {};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc>, Type> {};\n\ntemplate <typename Type, typename Alloc>\nstruct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};\n\ntemplate <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>\nstruct array_caster {\n    using value_conv = make_caster<Value>;\n\nprivate:\n    template <bool R = Resizable>\n    bool require_size(enable_if_t<R, size_t> size) {\n        if (value.size() != size) {\n            value.resize(size);\n        }\n        return true;\n    }\n    template <bool R = Resizable>\n    bool require_size(enable_if_t<!R, size_t> size) {\n        return size == Size;\n    }\n\npublic:\n    bool load(handle src, bool convert) {\n        if (!isinstance<sequence>(src)) {\n            return false;\n        }\n        auto l = reinterpret_borrow<sequence>(src);\n        if (!require_size(l.size())) {\n            return false;\n        }\n        size_t ctr = 0;\n        for (auto it : l) {\n            value_conv conv;\n            if (!conv.load(it, convert)) {\n                return false;\n            }\n            value[ctr++] = cast_op<Value &&>(std::move(conv));\n        }\n        return true;\n    }\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        list l(src.size());\n        ssize_t index = 0;\n        for (auto &&value : src) {\n            auto value_ = reinterpret_steal<object>(\n                value_conv::cast(forward_like<T>(value), policy, parent));\n            if (!value_) {\n                return handle();\n            }\n            PyList_SET_ITEM(l.ptr(), index++, value_.release().ptr()); // steals a reference\n        }\n        return l.release();\n    }\n\n    PYBIND11_TYPE_CASTER(ArrayType,\n                         const_name(\"List[\") + value_conv::name\n                             + const_name<Resizable>(const_name(\"\"),\n                                                     const_name(\"[\") + const_name<Size>()\n                                                         + const_name(\"]\"))\n                             + const_name(\"]\"));\n};\n\ntemplate <typename Type, size_t Size>\nstruct type_caster<std::array<Type, Size>>\n    : array_caster<std::array<Type, Size>, Type, false, Size> {};\n\ntemplate <typename Type>\nstruct type_caster<std::valarray<Type>> : array_caster<std::valarray<Type>, Type, true> {};\n\ntemplate <typename Key, typename Compare, typename Alloc>\nstruct type_caster<std::set<Key, Compare, Alloc>>\n    : set_caster<std::set<Key, Compare, Alloc>, Key> {};\n\ntemplate <typename Key, typename Hash, typename Equal, typename Alloc>\nstruct type_caster<std::unordered_set<Key, Hash, Equal, Alloc>>\n    : set_caster<std::unordered_set<Key, Hash, Equal, Alloc>, Key> {};\n\ntemplate <typename Key, typename Value, typename Compare, typename Alloc>\nstruct type_caster<std::map<Key, Value, Compare, Alloc>>\n    : map_caster<std::map<Key, Value, Compare, Alloc>, Key, Value> {};\n\ntemplate <typename Key, typename Value, typename Hash, typename Equal, typename Alloc>\nstruct type_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>>\n    : map_caster<std::unordered_map<Key, Value, Hash, Equal, Alloc>, Key, Value> {};\n\n// This type caster is intended to be used for std::optional and std::experimental::optional\ntemplate <typename Type, typename Value = typename Type::value_type>\nstruct optional_caster {\n    using value_conv = make_caster<Value>;\n\n    template <typename T>\n    static handle cast(T &&src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().inc_ref();\n        }\n        if (!std::is_lvalue_reference<T>::value) {\n            policy = return_value_policy_override<Value>::policy(policy);\n        }\n        return value_conv::cast(*std::forward<T>(src), policy, parent);\n    }\n\n    bool load(handle src, bool convert) {\n        if (!src) {\n            return false;\n        }\n        if (src.is_none()) {\n            return true; // default-constructed value is already empty\n        }\n        value_conv inner_caster;\n        if (!inner_caster.load(src, convert)) {\n            return false;\n        }\n\n        value.emplace(cast_op<Value &&>(std::move(inner_caster)));\n        return true;\n    }\n\n    PYBIND11_TYPE_CASTER(Type, const_name(\"Optional[\") + value_conv::name + const_name(\"]\"));\n};\n\n#if defined(PYBIND11_HAS_OPTIONAL)\ntemplate <typename T>\nstruct type_caster<std::optional<T>> : public optional_caster<std::optional<T>> {};\n\ntemplate <>\nstruct type_caster<std::nullopt_t> : public void_caster<std::nullopt_t> {};\n#endif\n\n#if defined(PYBIND11_HAS_EXP_OPTIONAL)\ntemplate <typename T>\nstruct type_caster<std::experimental::optional<T>>\n    : public optional_caster<std::experimental::optional<T>> {};\n\ntemplate <>\nstruct type_caster<std::experimental::nullopt_t>\n    : public void_caster<std::experimental::nullopt_t> {};\n#endif\n\n/// Visit a variant and cast any found type to Python\nstruct variant_caster_visitor {\n    return_value_policy policy;\n    handle parent;\n\n    using result_type = handle; // required by boost::variant in C++11\n\n    template <typename T>\n    result_type operator()(T &&src) const {\n        return make_caster<T>::cast(std::forward<T>(src), policy, parent);\n    }\n};\n\n/// Helper class which abstracts away variant's `visit` function. `std::variant` and similar\n/// `namespace::variant` types which provide a `namespace::visit()` function are handled here\n/// automatically using argument-dependent lookup. Users can provide specializations for other\n/// variant-like classes, e.g. `boost::variant` and `boost::apply_visitor`.\ntemplate <template <typename...> class Variant>\nstruct visit_helper {\n    template <typename... Args>\n    static auto call(Args &&...args) -> decltype(visit(std::forward<Args>(args)...)) {\n        return visit(std::forward<Args>(args)...);\n    }\n};\n\n/// Generic variant caster\ntemplate <typename Variant>\nstruct variant_caster;\n\ntemplate <template <typename...> class V, typename... Ts>\nstruct variant_caster<V<Ts...>> {\n    static_assert(sizeof...(Ts) > 0, \"Variant must consist of at least one alternative.\");\n\n    template <typename U, typename... Us>\n    bool load_alternative(handle src, bool convert, type_list<U, Us...>) {\n        auto caster = make_caster<U>();\n        if (caster.load(src, convert)) {\n            value = cast_op<U>(caster);\n            return true;\n        }\n        return load_alternative(src, convert, type_list<Us...>{});\n    }\n\n    bool load_alternative(handle, bool, type_list<>) { return false; }\n\n    bool load(handle src, bool convert) {\n        // Do a first pass without conversions to improve constructor resolution.\n        // E.g. `py::int_(1).cast<variant<double, int>>()` needs to fill the `int`\n        // slot of the variant. Without two-pass loading `double` would be filled\n        // because it appears first and a conversion is possible.\n        if (convert && load_alternative(src, false, type_list<Ts...>{})) {\n            return true;\n        }\n        return load_alternative(src, convert, type_list<Ts...>{});\n    }\n\n    template <typename Variant>\n    static handle cast(Variant &&src, return_value_policy policy, handle parent) {\n        return visit_helper<V>::call(variant_caster_visitor{policy, parent},\n                                     std::forward<Variant>(src));\n    }\n\n    using Type = V<Ts...>;\n    PYBIND11_TYPE_CASTER(Type,\n                         const_name(\"Union[\") + detail::concat(make_caster<Ts>::name...)\n                             + const_name(\"]\"));\n};\n\n#if defined(PYBIND11_HAS_VARIANT)\ntemplate <typename... Ts>\nstruct type_caster<std::variant<Ts...>> : variant_caster<std::variant<Ts...>> {};\n#endif\n\nPYBIND11_NAMESPACE_END(detail)\n\ninline std::ostream &operator<<(std::ostream &os, const handle &obj) {\n#ifdef PYBIND11_HAS_STRING_VIEW\n    os << str(obj).cast<std::string_view>();\n#else\n    os << (std::string) str(obj);\n#endif\n    return os;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/include/pybind11/stl_bind.h",
    "content": "/*\n    pybind11/std_bind.h: Binding generators for STL data types\n\n    Copyright (c) 2016 Sergey Lyskov and Wenzel Jakob\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#pragma once\n\n#include \"detail/common.h\"\n#include \"operators.h\"\n\n#include <algorithm>\n#include <sstream>\n\nPYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/* SFINAE helper class used by 'is_comparable */\ntemplate <typename T>\nstruct container_traits {\n    template <typename T2>\n    static std::true_type\n    test_comparable(decltype(std::declval<const T2 &>() == std::declval<const T2 &>()) *);\n    template <typename T2>\n    static std::false_type test_comparable(...);\n    template <typename T2>\n    static std::true_type test_value(typename T2::value_type *);\n    template <typename T2>\n    static std::false_type test_value(...);\n    template <typename T2>\n    static std::true_type test_pair(typename T2::first_type *, typename T2::second_type *);\n    template <typename T2>\n    static std::false_type test_pair(...);\n\n    static constexpr const bool is_comparable\n        = std::is_same<std::true_type, decltype(test_comparable<T>(nullptr))>::value;\n    static constexpr const bool is_pair\n        = std::is_same<std::true_type, decltype(test_pair<T>(nullptr, nullptr))>::value;\n    static constexpr const bool is_vector\n        = std::is_same<std::true_type, decltype(test_value<T>(nullptr))>::value;\n    static constexpr const bool is_element = !is_pair && !is_vector;\n};\n\n/* Default: is_comparable -> std::false_type */\ntemplate <typename T, typename SFINAE = void>\nstruct is_comparable : std::false_type {};\n\n/* For non-map data structures, check whether operator== can be instantiated */\ntemplate <typename T>\nstruct is_comparable<\n    T,\n    enable_if_t<container_traits<T>::is_element && container_traits<T>::is_comparable>>\n    : std::true_type {};\n\n/* For a vector/map data structure, recursively check the value type\n   (which is std::pair for maps) */\ntemplate <typename T>\nstruct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {\n    static constexpr const bool value = is_comparable<typename T::value_type>::value;\n};\n\n/* For pairs, recursively check the two data types */\ntemplate <typename T>\nstruct is_comparable<T, enable_if_t<container_traits<T>::is_pair>> {\n    static constexpr const bool value = is_comparable<typename T::first_type>::value\n                                        && is_comparable<typename T::second_type>::value;\n};\n\n/* Fallback functions */\ntemplate <typename, typename, typename... Args>\nvoid vector_if_copy_constructible(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_if_equal_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_if_insertion_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid vector_modifiers(const Args &...) {}\n\ntemplate <typename Vector, typename Class_>\nvoid vector_if_copy_constructible(enable_if_t<is_copy_constructible<Vector>::value, Class_> &cl) {\n    cl.def(init<const Vector &>(), \"Copy constructor\");\n}\n\ntemplate <typename Vector, typename Class_>\nvoid vector_if_equal_operator(enable_if_t<is_comparable<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n\n    cl.def(self == self);\n    cl.def(self != self);\n\n    cl.def(\n        \"count\",\n        [](const Vector &v, const T &x) { return std::count(v.begin(), v.end(), x); },\n        arg(\"x\"),\n        \"Return the number of times ``x`` appears in the list\");\n\n    cl.def(\n        \"remove\",\n        [](Vector &v, const T &x) {\n            auto p = std::find(v.begin(), v.end(), x);\n            if (p != v.end()) {\n                v.erase(p);\n            } else {\n                throw value_error();\n            }\n        },\n        arg(\"x\"),\n        \"Remove the first item from the list whose value is x. \"\n        \"It is an error if there is no such item.\");\n\n    cl.def(\n        \"__contains__\",\n        [](const Vector &v, const T &x) { return std::find(v.begin(), v.end(), x) != v.end(); },\n        arg(\"x\"),\n        \"Return true the container contains ``x``\");\n}\n\n// Vector modifiers -- requires a copyable vector_type:\n// (Technically, some of these (pop and __delitem__) don't actually require copyability, but it\n// seems silly to allow deletion but not insertion, so include them here too.)\ntemplate <typename Vector, typename Class_>\nvoid vector_modifiers(\n    enable_if_t<is_copy_constructible<typename Vector::value_type>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n\n    auto wrap_i = [](DiffType i, SizeType n) {\n        if (i < 0) {\n            i += n;\n        }\n        if (i < 0 || (SizeType) i >= n) {\n            throw index_error();\n        }\n        return i;\n    };\n\n    cl.def(\n        \"append\",\n        [](Vector &v, const T &value) { v.push_back(value); },\n        arg(\"x\"),\n        \"Add an item to the end of the list\");\n\n    cl.def(init([](const iterable &it) {\n        auto v = std::unique_ptr<Vector>(new Vector());\n        v->reserve(len_hint(it));\n        for (handle h : it) {\n            v->push_back(h.cast<T>());\n        }\n        return v.release();\n    }));\n\n    cl.def(\n        \"clear\", [](Vector &v) { v.clear(); }, \"Clear the contents\");\n\n    cl.def(\n        \"extend\",\n        [](Vector &v, const Vector &src) { v.insert(v.end(), src.begin(), src.end()); },\n        arg(\"L\"),\n        \"Extend the list by appending all the items in the given list\");\n\n    cl.def(\n        \"extend\",\n        [](Vector &v, const iterable &it) {\n            const size_t old_size = v.size();\n            v.reserve(old_size + len_hint(it));\n            try {\n                for (handle h : it) {\n                    v.push_back(h.cast<T>());\n                }\n            } catch (const cast_error &) {\n                v.erase(v.begin() + static_cast<typename Vector::difference_type>(old_size),\n                        v.end());\n                try {\n                    v.shrink_to_fit();\n                } catch (const std::exception &) {\n                    // Do nothing\n                }\n                throw;\n            }\n        },\n        arg(\"L\"),\n        \"Extend the list by appending all the items in the given list\");\n\n    cl.def(\n        \"insert\",\n        [](Vector &v, DiffType i, const T &x) {\n            // Can't use wrap_i; i == v.size() is OK\n            if (i < 0) {\n                i += v.size();\n            }\n            if (i < 0 || (SizeType) i > v.size()) {\n                throw index_error();\n            }\n            v.insert(v.begin() + i, x);\n        },\n        arg(\"i\"),\n        arg(\"x\"),\n        \"Insert an item at a given position.\");\n\n    cl.def(\n        \"pop\",\n        [](Vector &v) {\n            if (v.empty()) {\n                throw index_error();\n            }\n            T t = std::move(v.back());\n            v.pop_back();\n            return t;\n        },\n        \"Remove and return the last item\");\n\n    cl.def(\n        \"pop\",\n        [wrap_i](Vector &v, DiffType i) {\n            i = wrap_i(i, v.size());\n            T t = std::move(v[(SizeType) i]);\n            v.erase(std::next(v.begin(), i));\n            return t;\n        },\n        arg(\"i\"),\n        \"Remove and return the item at index ``i``\");\n\n    cl.def(\"__setitem__\", [wrap_i](Vector &v, DiffType i, const T &t) {\n        i = wrap_i(i, v.size());\n        v[(SizeType) i] = t;\n    });\n\n    /// Slicing protocol\n    cl.def(\n        \"__getitem__\",\n        [](const Vector &v, slice slice) -> Vector * {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            auto *seq = new Vector();\n            seq->reserve((size_t) slicelength);\n\n            for (size_t i = 0; i < slicelength; ++i) {\n                seq->push_back(v[start]);\n                start += step;\n            }\n            return seq;\n        },\n        arg(\"s\"),\n        \"Retrieve list elements using a slice object\");\n\n    cl.def(\n        \"__setitem__\",\n        [](Vector &v, slice slice, const Vector &value) {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            if (slicelength != value.size()) {\n                throw std::runtime_error(\n                    \"Left and right hand size of slice assignment have different sizes!\");\n            }\n\n            for (size_t i = 0; i < slicelength; ++i) {\n                v[start] = value[i];\n                start += step;\n            }\n        },\n        \"Assign list elements using a slice object\");\n\n    cl.def(\n        \"__delitem__\",\n        [wrap_i](Vector &v, DiffType i) {\n            i = wrap_i(i, v.size());\n            v.erase(v.begin() + i);\n        },\n        \"Delete the list elements at index ``i``\");\n\n    cl.def(\n        \"__delitem__\",\n        [](Vector &v, slice slice) {\n            size_t start = 0, stop = 0, step = 0, slicelength = 0;\n\n            if (!slice.compute(v.size(), &start, &stop, &step, &slicelength)) {\n                throw error_already_set();\n            }\n\n            if (step == 1 && false) {\n                v.erase(v.begin() + (DiffType) start, v.begin() + DiffType(start + slicelength));\n            } else {\n                for (size_t i = 0; i < slicelength; ++i) {\n                    v.erase(v.begin() + DiffType(start));\n                    start += step - 1;\n                }\n            }\n        },\n        \"Delete list elements using a slice object\");\n}\n\n// If the type has an operator[] that doesn't return a reference (most notably std::vector<bool>),\n// we have to access by copying; otherwise we return by reference.\ntemplate <typename Vector>\nusing vector_needs_copy\n    = negation<std::is_same<decltype(std::declval<Vector>()[typename Vector::size_type()]),\n                            typename Vector::value_type &>>;\n\n// The usual case: access and iterate by reference\ntemplate <typename Vector, typename Class_>\nvoid vector_accessor(enable_if_t<!vector_needs_copy<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n    using ItType = typename Vector::iterator;\n\n    auto wrap_i = [](DiffType i, SizeType n) {\n        if (i < 0) {\n            i += n;\n        }\n        if (i < 0 || (SizeType) i >= n) {\n            throw index_error();\n        }\n        return i;\n    };\n\n    cl.def(\n        \"__getitem__\",\n        [wrap_i](Vector &v, DiffType i) -> T & {\n            i = wrap_i(i, v.size());\n            return v[(SizeType) i];\n        },\n        return_value_policy::reference_internal // ref + keepalive\n    );\n\n    cl.def(\n        \"__iter__\",\n        [](Vector &v) {\n            return make_iterator<return_value_policy::reference_internal, ItType, ItType, T &>(\n                v.begin(), v.end());\n        },\n        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */\n    );\n}\n\n// The case for special objects, like std::vector<bool>, that have to be returned-by-copy:\ntemplate <typename Vector, typename Class_>\nvoid vector_accessor(enable_if_t<vector_needs_copy<Vector>::value, Class_> &cl) {\n    using T = typename Vector::value_type;\n    using SizeType = typename Vector::size_type;\n    using DiffType = typename Vector::difference_type;\n    using ItType = typename Vector::iterator;\n    cl.def(\"__getitem__\", [](const Vector &v, DiffType i) -> T {\n        if (i < 0 && (i += v.size()) < 0) {\n            throw index_error();\n        }\n        if ((SizeType) i >= v.size()) {\n            throw index_error();\n        }\n        return v[(SizeType) i];\n    });\n\n    cl.def(\n        \"__iter__\",\n        [](Vector &v) {\n            return make_iterator<return_value_policy::copy, ItType, ItType, T>(v.begin(), v.end());\n        },\n        keep_alive<0, 1>() /* Essential: keep list alive while iterator exists */\n    );\n}\n\ntemplate <typename Vector, typename Class_>\nauto vector_if_insertion_operator(Class_ &cl, std::string const &name)\n    -> decltype(std::declval<std::ostream &>() << std::declval<typename Vector::value_type>(),\n                void()) {\n    using size_type = typename Vector::size_type;\n\n    cl.def(\n        \"__repr__\",\n        [name](Vector &v) {\n            std::ostringstream s;\n            s << name << '[';\n            for (size_type i = 0; i < v.size(); ++i) {\n                s << v[i];\n                if (i != v.size() - 1) {\n                    s << \", \";\n                }\n            }\n            s << ']';\n            return s.str();\n        },\n        \"Return the canonical string representation of this list.\");\n}\n\n// Provide the buffer interface for vectors if we have data() and we have a format for it\n// GCC seems to have \"void std::vector<bool>::data()\" - doing SFINAE on the existence of data()\n// is insufficient, we need to check it returns an appropriate pointer\ntemplate <typename Vector, typename = void>\nstruct vector_has_data_and_format : std::false_type {};\ntemplate <typename Vector>\nstruct vector_has_data_and_format<\n    Vector,\n    enable_if_t<std::is_same<decltype(format_descriptor<typename Vector::value_type>::format(),\n                                      std::declval<Vector>().data()),\n                             typename Vector::value_type *>::value>> : std::true_type {};\n\n// [workaround(intel)] Separate function required here\n// Workaround as the Intel compiler does not compile the enable_if_t part below\n// (tested with icc (ICC) 2021.1 Beta 20200827)\ntemplate <typename... Args>\nconstexpr bool args_any_are_buffer() {\n    return detail::any_of<std::is_same<Args, buffer_protocol>...>::value;\n}\n\n// [workaround(intel)] Separate function required here\n// [workaround(msvc)] Can't use constexpr bool in return type\n\n// Add the buffer interface to a vector\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer_impl(Class_ &cl, std::true_type) {\n    using T = typename Vector::value_type;\n\n    static_assert(vector_has_data_and_format<Vector>::value,\n                  \"There is not an appropriate format descriptor for this vector\");\n\n    // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard\n    // at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here\n    format_descriptor<T>::format();\n\n    cl.def_buffer([](Vector &v) -> buffer_info {\n        return buffer_info(v.data(),\n                           static_cast<ssize_t>(sizeof(T)),\n                           format_descriptor<T>::format(),\n                           1,\n                           {v.size()},\n                           {sizeof(T)});\n    });\n\n    cl.def(init([](const buffer &buf) {\n        auto info = buf.request();\n        if (info.ndim != 1 || info.strides[0] % static_cast<ssize_t>(sizeof(T))) {\n            throw type_error(\"Only valid 1D buffers can be copied to a vector\");\n        }\n        if (!detail::compare_buffer_info<T>::compare(info)\n            || (ssize_t) sizeof(T) != info.itemsize) {\n            throw type_error(\"Format mismatch (Python: \" + info.format\n                             + \" C++: \" + format_descriptor<T>::format() + \")\");\n        }\n\n        T *p = static_cast<T *>(info.ptr);\n        ssize_t step = info.strides[0] / static_cast<ssize_t>(sizeof(T));\n        T *end = p + info.shape[0] * step;\n        if (step == 1) {\n            return Vector(p, end);\n        }\n        Vector vec;\n        vec.reserve((size_t) info.shape[0]);\n        for (; p != end; p += step) {\n            vec.push_back(*p);\n        }\n        return vec;\n    }));\n\n    return;\n}\n\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer_impl(Class_ &, std::false_type) {}\n\ntemplate <typename Vector, typename Class_, typename... Args>\nvoid vector_buffer(Class_ &cl) {\n    vector_buffer_impl<Vector, Class_, Args...>(\n        cl, detail::any_of<std::is_same<Args, buffer_protocol>...>{});\n}\n\nPYBIND11_NAMESPACE_END(detail)\n\n//\n// std::vector\n//\ntemplate <typename Vector, typename holder_type = std::unique_ptr<Vector>, typename... Args>\nclass_<Vector, holder_type> bind_vector(handle scope, std::string const &name, Args &&...args) {\n    using Class_ = class_<Vector, holder_type>;\n\n    // If the value_type is unregistered (e.g. a converting type) or is itself registered\n    // module-local then make the vector binding module-local as well:\n    using vtype = typename Vector::value_type;\n    auto *vtype_info = detail::get_type_info(typeid(vtype));\n    bool local = !vtype_info || vtype_info->module_local;\n\n    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);\n\n    // Declare the buffer interface if a buffer_protocol() is passed in\n    detail::vector_buffer<Vector, Class_, Args...>(cl);\n\n    cl.def(init<>());\n\n    // Register copy constructor (if possible)\n    detail::vector_if_copy_constructible<Vector, Class_>(cl);\n\n    // Register comparison-related operators and functions (if possible)\n    detail::vector_if_equal_operator<Vector, Class_>(cl);\n\n    // Register stream insertion operator (if possible)\n    detail::vector_if_insertion_operator<Vector, Class_>(cl, name);\n\n    // Modifiers require copyable vector value type\n    detail::vector_modifiers<Vector, Class_>(cl);\n\n    // Accessor and iterator; return by value if copyable, otherwise we return by ref + keep-alive\n    detail::vector_accessor<Vector, Class_>(cl);\n\n    cl.def(\n        \"__bool__\",\n        [](const Vector &v) -> bool { return !v.empty(); },\n        \"Check whether the list is nonempty\");\n\n    cl.def(\"__len__\", &Vector::size);\n\n#if 0\n    // C++ style functions deprecated, leaving it here as an example\n    cl.def(init<size_type>());\n\n    cl.def(\"resize\",\n         (void (Vector::*) (size_type count)) & Vector::resize,\n         \"changes the number of elements stored\");\n\n    cl.def(\"erase\",\n        [](Vector &v, SizeType i) {\n        if (i >= v.size())\n            throw index_error();\n        v.erase(v.begin() + i);\n    }, \"erases element at index ``i``\");\n\n    cl.def(\"empty\",         &Vector::empty,         \"checks whether the container is empty\");\n    cl.def(\"size\",          &Vector::size,          \"returns the number of elements\");\n    cl.def(\"push_back\", (void (Vector::*)(const T&)) &Vector::push_back, \"adds an element to the end\");\n    cl.def(\"pop_back\",                               &Vector::pop_back, \"removes the last element\");\n\n    cl.def(\"max_size\",      &Vector::max_size,      \"returns the maximum possible number of elements\");\n    cl.def(\"reserve\",       &Vector::reserve,       \"reserves storage\");\n    cl.def(\"capacity\",      &Vector::capacity,      \"returns the number of elements that can be held in currently allocated storage\");\n    cl.def(\"shrink_to_fit\", &Vector::shrink_to_fit, \"reduces memory usage by freeing unused memory\");\n\n    cl.def(\"clear\", &Vector::clear, \"clears the contents\");\n    cl.def(\"swap\",   &Vector::swap, \"swaps the contents\");\n\n    cl.def(\"front\", [](Vector &v) {\n        if (v.size()) return v.front();\n        else throw index_error();\n    }, \"access the first element\");\n\n    cl.def(\"back\", [](Vector &v) {\n        if (v.size()) return v.back();\n        else throw index_error();\n    }, \"access the last element \");\n\n#endif\n\n    return cl;\n}\n\n//\n// std::map, std::unordered_map\n//\n\nPYBIND11_NAMESPACE_BEGIN(detail)\n\n/* Fallback functions */\ntemplate <typename, typename, typename... Args>\nvoid map_if_insertion_operator(const Args &...) {}\ntemplate <typename, typename, typename... Args>\nvoid map_assignment(const Args &...) {}\n\n// Map assignment when copy-assignable: just copy the value\ntemplate <typename Map, typename Class_>\nvoid map_assignment(\n    enable_if_t<is_copy_assignable<typename Map::mapped_type>::value, Class_> &cl) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n\n    cl.def(\"__setitem__\", [](Map &m, const KeyType &k, const MappedType &v) {\n        auto it = m.find(k);\n        if (it != m.end()) {\n            it->second = v;\n        } else {\n            m.emplace(k, v);\n        }\n    });\n}\n\n// Not copy-assignable, but still copy-constructible: we can update the value by erasing and\n// reinserting\ntemplate <typename Map, typename Class_>\nvoid map_assignment(enable_if_t<!is_copy_assignable<typename Map::mapped_type>::value\n                                    && is_copy_constructible<typename Map::mapped_type>::value,\n                                Class_> &cl) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n\n    cl.def(\"__setitem__\", [](Map &m, const KeyType &k, const MappedType &v) {\n        // We can't use m[k] = v; because value type might not be default constructable\n        auto r = m.emplace(k, v);\n        if (!r.second) {\n            // value type is not copy assignable so the only way to insert it is to erase it\n            // first...\n            m.erase(r.first);\n            m.emplace(k, v);\n        }\n    });\n}\n\ntemplate <typename Map, typename Class_>\nauto map_if_insertion_operator(Class_ &cl, std::string const &name)\n    -> decltype(std::declval<std::ostream &>() << std::declval<typename Map::key_type>()\n                                               << std::declval<typename Map::mapped_type>(),\n                void()) {\n\n    cl.def(\n        \"__repr__\",\n        [name](Map &m) {\n            std::ostringstream s;\n            s << name << '{';\n            bool f = false;\n            for (auto const &kv : m) {\n                if (f) {\n                    s << \", \";\n                }\n                s << kv.first << \": \" << kv.second;\n                f = true;\n            }\n            s << '}';\n            return s.str();\n        },\n        \"Return the canonical string representation of this map.\");\n}\n\ntemplate <typename Map>\nstruct keys_view {\n    Map &map;\n};\n\ntemplate <typename Map>\nstruct values_view {\n    Map &map;\n};\n\ntemplate <typename Map>\nstruct items_view {\n    Map &map;\n};\n\nPYBIND11_NAMESPACE_END(detail)\n\ntemplate <typename Map, typename holder_type = std::unique_ptr<Map>, typename... Args>\nclass_<Map, holder_type> bind_map(handle scope, const std::string &name, Args &&...args) {\n    using KeyType = typename Map::key_type;\n    using MappedType = typename Map::mapped_type;\n    using KeysView = detail::keys_view<Map>;\n    using ValuesView = detail::values_view<Map>;\n    using ItemsView = detail::items_view<Map>;\n    using Class_ = class_<Map, holder_type>;\n\n    // If either type is a non-module-local bound type then make the map binding non-local as well;\n    // otherwise (e.g. both types are either module-local or converting) the map will be\n    // module-local.\n    auto *tinfo = detail::get_type_info(typeid(MappedType));\n    bool local = !tinfo || tinfo->module_local;\n    if (local) {\n        tinfo = detail::get_type_info(typeid(KeyType));\n        local = !tinfo || tinfo->module_local;\n    }\n\n    Class_ cl(scope, name.c_str(), pybind11::module_local(local), std::forward<Args>(args)...);\n    class_<KeysView> keys_view(\n        scope, (\"KeysView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n    class_<ValuesView> values_view(\n        scope, (\"ValuesView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n    class_<ItemsView> items_view(\n        scope, (\"ItemsView[\" + name + \"]\").c_str(), pybind11::module_local(local));\n\n    cl.def(init<>());\n\n    // Register stream insertion operator (if possible)\n    detail::map_if_insertion_operator<Map, Class_>(cl, name);\n\n    cl.def(\n        \"__bool__\",\n        [](const Map &m) -> bool { return !m.empty(); },\n        \"Check whether the map is nonempty\");\n\n    cl.def(\n        \"__iter__\",\n        [](Map &m) { return make_key_iterator(m.begin(), m.end()); },\n        keep_alive<0, 1>() /* Essential: keep map alive while iterator exists */\n    );\n\n    cl.def(\n        \"keys\",\n        [](Map &m) { return KeysView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"values\",\n        [](Map &m) { return ValuesView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"items\",\n        [](Map &m) { return ItemsView{m}; },\n        keep_alive<0, 1>() /* Essential: keep map alive while view exists */\n    );\n\n    cl.def(\n        \"__getitem__\",\n        [](Map &m, const KeyType &k) -> MappedType & {\n            auto it = m.find(k);\n            if (it == m.end()) {\n                throw key_error();\n            }\n            return it->second;\n        },\n        return_value_policy::reference_internal // ref + keepalive\n    );\n\n    cl.def(\"__contains__\", [](Map &m, const KeyType &k) -> bool {\n        auto it = m.find(k);\n        if (it == m.end()) {\n            return false;\n        }\n        return true;\n    });\n    // Fallback for when the object is not of the key type\n    cl.def(\"__contains__\", [](Map &, const object &) -> bool { return false; });\n\n    // Assignment provided only if the type is copyable\n    detail::map_assignment<Map, Class_>(cl);\n\n    cl.def(\"__delitem__\", [](Map &m, const KeyType &k) {\n        auto it = m.find(k);\n        if (it == m.end()) {\n            throw key_error();\n        }\n        m.erase(it);\n    });\n\n    cl.def(\"__len__\", &Map::size);\n\n    keys_view.def(\"__len__\", [](KeysView &view) { return view.map.size(); });\n    keys_view.def(\n        \"__iter__\",\n        [](KeysView &view) { return make_key_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n    keys_view.def(\"__contains__\", [](KeysView &view, const KeyType &k) -> bool {\n        auto it = view.map.find(k);\n        if (it == view.map.end()) {\n            return false;\n        }\n        return true;\n    });\n    // Fallback for when the object is not of the key type\n    keys_view.def(\"__contains__\", [](KeysView &, const object &) -> bool { return false; });\n\n    values_view.def(\"__len__\", [](ValuesView &view) { return view.map.size(); });\n    values_view.def(\n        \"__iter__\",\n        [](ValuesView &view) { return make_value_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n\n    items_view.def(\"__len__\", [](ItemsView &view) { return view.map.size(); });\n    items_view.def(\n        \"__iter__\",\n        [](ItemsView &view) { return make_iterator(view.map.begin(), view.map.end()); },\n        keep_alive<0, 1>() /* Essential: keep view alive while iterator exists */\n    );\n\n    return cl;\n}\n\nPYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/noxfile.py",
    "content": "import nox\n\nnox.needs_version = \">=2022.1.7\"\nnox.options.sessions = [\"lint\", \"tests\", \"tests_packaging\"]\n\nPYTHON_VERSIONS = [\"2.7\", \"3.5\", \"3.6\", \"3.7\", \"3.8\", \"3.9\", \"3.10\", \"3.11\"]\n\n\n@nox.session(reuse_venv=True)\ndef lint(session: nox.Session) -> None:\n    \"\"\"\n    Lint the codebase (except for clang-format/tidy).\n    \"\"\"\n    session.install(\"pre-commit\")\n    session.run(\"pre-commit\", \"run\", \"-a\")\n\n\n@nox.session(python=PYTHON_VERSIONS)\ndef tests(session: nox.Session) -> None:\n    \"\"\"\n    Run the tests (requires a compiler).\n    \"\"\"\n    tmpdir = session.create_tmp()\n    session.install(\"cmake\")\n    session.install(\"-r\", \"tests/requirements.txt\")\n    session.run(\n        \"cmake\",\n        \"-S.\",\n        f\"-B{tmpdir}\",\n        \"-DPYBIND11_WERROR=ON\",\n        \"-DDOWNLOAD_CATCH=ON\",\n        \"-DDOWNLOAD_EIGEN=ON\",\n        *session.posargs,\n    )\n    session.run(\"cmake\", \"--build\", tmpdir)\n    session.run(\"cmake\", \"--build\", tmpdir, \"--config=Release\", \"--target\", \"check\")\n\n\n@nox.session\ndef tests_packaging(session: nox.Session) -> None:\n    \"\"\"\n    Run the packaging tests.\n    \"\"\"\n\n    session.install(\"-r\", \"tests/requirements.txt\", \"--prefer-binary\")\n    session.run(\"pytest\", \"tests/extra_python_package\")\n\n\n@nox.session(reuse_venv=True)\ndef docs(session: nox.Session) -> None:\n    \"\"\"\n    Build the docs. Pass \"serve\" to serve.\n    \"\"\"\n\n    session.install(\"-r\", \"docs/requirements.txt\")\n    session.chdir(\"docs\")\n\n    if \"pdf\" in session.posargs:\n        session.run(\"sphinx-build\", \"-b\", \"latexpdf\", \".\", \"_build\")\n        return\n\n    session.run(\"sphinx-build\", \"-b\", \"html\", \".\", \"_build\")\n\n    if \"serve\" in session.posargs:\n        session.log(\"Launching docs at http://localhost:8000/ - use Ctrl-C to quit\")\n        session.run(\"python\", \"-m\", \"http.server\", \"8000\", \"-d\", \"_build/html\")\n    elif session.posargs:\n        session.error(\"Unsupported argument to docs\")\n\n\n@nox.session(reuse_venv=True)\ndef make_changelog(session: nox.Session) -> None:\n    \"\"\"\n    Inspect the closed issues and make entries for a changelog.\n    \"\"\"\n    session.install(\"ghapi\", \"rich\")\n    session.run(\"python\", \"tools/make_changelog.py\")\n\n\n@nox.session(reuse_venv=True)\ndef build(session: nox.Session) -> None:\n    \"\"\"\n    Build SDists and wheels.\n    \"\"\"\n\n    session.install(\"build\")\n    session.log(\"Building normal files\")\n    session.run(\"python\", \"-m\", \"build\", *session.posargs)\n    session.log(\"Building pybind11-global files (PYBIND11_GLOBAL_SDIST=1)\")\n    session.run(\n        \"python\", \"-m\", \"build\", *session.posargs, env={\"PYBIND11_GLOBAL_SDIST\": \"1\"}\n    )\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/__init__.py",
    "content": "# -*- coding: utf-8 -*-\n\nfrom ._version import __version__, version_info\nfrom .commands import get_cmake_dir, get_include\n\n__all__ = (\n    \"version_info\",\n    \"__version__\",\n    \"get_include\",\n    \"get_cmake_dir\",\n)\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/__main__.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import print_function\n\nimport argparse\nimport sys\nimport sysconfig\n\nfrom .commands import get_cmake_dir, get_include\n\n\ndef print_includes():\n    # type: () -> None\n    dirs = [\n        sysconfig.get_path(\"include\"),\n        sysconfig.get_path(\"platinclude\"),\n        get_include(),\n    ]\n\n    # Make unique but preserve order\n    unique_dirs = []\n    for d in dirs:\n        if d and d not in unique_dirs:\n            unique_dirs.append(d)\n\n    print(\" \".join(\"-I\" + d for d in unique_dirs))\n\n\ndef main():\n    # type: () -> None\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        \"--includes\",\n        action=\"store_true\",\n        help=\"Include flags for both pybind11 and Python headers.\",\n    )\n    parser.add_argument(\n        \"--cmakedir\",\n        action=\"store_true\",\n        help=\"Print the CMake module directory, ideal for setting -Dpybind11_ROOT in CMake.\",\n    )\n    args = parser.parse_args()\n    if not sys.argv[1:]:\n        parser.print_help()\n    if args.includes:\n        print_includes()\n    if args.cmakedir:\n        print(get_cmake_dir())\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/_version.py",
    "content": "# -*- coding: utf-8 -*-\n\n\ndef _to_int(s):\n    try:\n        return int(s)\n    except ValueError:\n        return s\n\n\n__version__ = \"2.9.2\"\nversion_info = tuple(_to_int(s) for s in __version__.split(\".\"))\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/_version.pyi",
    "content": "from typing import Tuple, Union\n\ndef _to_int(s: str) -> Union[int, str]: ...\n\n__version__: str\nversion_info: Tuple[Union[int, str], ...]\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/commands.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\n\nDIR = os.path.abspath(os.path.dirname(__file__))\n\n\ndef get_include(user=False):\n    # type: (bool) -> str\n    installed_path = os.path.join(DIR, \"include\")\n    source_path = os.path.join(os.path.dirname(DIR), \"include\")\n    return installed_path if os.path.exists(installed_path) else source_path\n\n\ndef get_cmake_dir():\n    # type: () -> str\n    cmake_installed_path = os.path.join(DIR, \"share\", \"cmake\", \"pybind11\")\n    if os.path.exists(cmake_installed_path):\n        return cmake_installed_path\n    else:\n        msg = \"pybind11 not installed, installation required to access the CMake files\"\n        raise ImportError(msg)\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/py.typed",
    "content": ""
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/setup_helpers.py",
    "content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nThis module provides helpers for C++11+ projects using pybind11.\n\nLICENSE:\n\nCopyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>, All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its contributors\n   may be used to endorse or promote products derived from this software\n   without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\"\"\"\n\n# IMPORTANT: If you change this file in the pybind11 repo, also review\n# setup_helpers.pyi for matching changes.\n#\n# If you copy this file in, you don't\n# need the .pyi file; it's just an interface file for static type checkers.\n\nimport contextlib\nimport os\nimport platform\nimport shlex\nimport shutil\nimport sys\nimport sysconfig\nimport tempfile\nimport threading\nimport warnings\n\ntry:\n    from setuptools import Extension as _Extension\n    from setuptools.command.build_ext import build_ext as _build_ext\nexcept ImportError:\n    from distutils.command.build_ext import build_ext as _build_ext\n    from distutils.extension import Extension as _Extension\n\nimport distutils.ccompiler\nimport distutils.errors\n\nWIN = sys.platform.startswith(\"win32\") and \"mingw\" not in sysconfig.get_platform()\nPY2 = sys.version_info[0] < 3\nMACOS = sys.platform.startswith(\"darwin\")\nSTD_TMPL = \"/std:c++{}\" if WIN else \"-std=c++{}\"\n\n\n# It is recommended to use PEP 518 builds if using this module. However, this\n# file explicitly supports being copied into a user's project directory\n# standalone, and pulling pybind11 with the deprecated setup_requires feature.\n# If you copy the file, remember to add it to your MANIFEST.in, and add the current\n# directory into your path if it sits beside your setup.py.\n\n\nclass Pybind11Extension(_Extension):\n    \"\"\"\n    Build a C++11+ Extension module with pybind11. This automatically adds the\n    recommended flags when you init the extension and assumes C++ sources - you\n    can further modify the options yourself.\n\n    The customizations are:\n\n    * ``/EHsc`` and ``/bigobj`` on Windows\n    * ``stdlib=libc++`` on macOS\n    * ``visibility=hidden`` and ``-g0`` on Unix\n\n    Finally, you can set ``cxx_std`` via constructor or afterwards to enable\n    flags for C++ std, and a few extra helper flags related to the C++ standard\n    level. It is _highly_ recommended you either set this, or use the provided\n    ``build_ext``, which will search for the highest supported extension for\n    you if the ``cxx_std`` property is not set. Do not set the ``cxx_std``\n    property more than once, as flags are added when you set it. Set the\n    property to None to disable the addition of C++ standard flags.\n\n    If you want to add pybind11 headers manually, for example for an exact\n    git checkout, then set ``include_pybind11=False``.\n\n    Warning: do not use property-based access to the instance on Python 2 -\n    this is an ugly old-style class due to Distutils.\n    \"\"\"\n\n    # flags are prepended, so that they can be further overridden, e.g. by\n    # ``extra_compile_args=[\"-g\"]``.\n\n    def _add_cflags(self, flags):\n        self.extra_compile_args[:0] = flags\n\n    def _add_ldflags(self, flags):\n        self.extra_link_args[:0] = flags\n\n    def __init__(self, *args, **kwargs):\n\n        self._cxx_level = 0\n        cxx_std = kwargs.pop(\"cxx_std\", 0)\n\n        if \"language\" not in kwargs:\n            kwargs[\"language\"] = \"c++\"\n\n        include_pybind11 = kwargs.pop(\"include_pybind11\", True)\n\n        # Can't use super here because distutils has old-style classes in\n        # Python 2!\n        _Extension.__init__(self, *args, **kwargs)\n\n        # Include the installed package pybind11 headers\n        if include_pybind11:\n            # If using setup_requires, this fails the first time - that's okay\n            try:\n                import pybind11\n\n                pyinc = pybind11.get_include()\n\n                if pyinc not in self.include_dirs:\n                    self.include_dirs.append(pyinc)\n            except ImportError:\n                pass\n\n        # Have to use the accessor manually to support Python 2 distutils\n        Pybind11Extension.cxx_std.__set__(self, cxx_std)\n\n        cflags = []\n        ldflags = []\n        if WIN:\n            cflags += [\"/EHsc\", \"/bigobj\"]\n        else:\n            cflags += [\"-fvisibility=hidden\"]\n            env_cflags = os.environ.get(\"CFLAGS\", \"\")\n            env_cppflags = os.environ.get(\"CPPFLAGS\", \"\")\n            c_cpp_flags = shlex.split(env_cflags) + shlex.split(env_cppflags)\n            if not any(opt.startswith(\"-g\") for opt in c_cpp_flags):\n                cflags += [\"-g0\"]\n            if MACOS:\n                cflags += [\"-stdlib=libc++\"]\n                ldflags += [\"-stdlib=libc++\"]\n        self._add_cflags(cflags)\n        self._add_ldflags(ldflags)\n\n    @property\n    def cxx_std(self):\n        \"\"\"\n        The CXX standard level. If set, will add the required flags. If left\n        at 0, it will trigger an automatic search when pybind11's build_ext\n        is used. If None, will have no effect.  Besides just the flags, this\n        may add a register warning/error fix for Python 2 or macos-min 10.9\n        or 10.14.\n        \"\"\"\n        return self._cxx_level\n\n    @cxx_std.setter\n    def cxx_std(self, level):\n\n        if self._cxx_level:\n            warnings.warn(\"You cannot safely change the cxx_level after setting it!\")\n\n        # MSVC 2015 Update 3 and later only have 14 (and later 17) modes, so\n        # force a valid flag here.\n        if WIN and level == 11:\n            level = 14\n\n        self._cxx_level = level\n\n        if not level:\n            return\n\n        cflags = [STD_TMPL.format(level)]\n        ldflags = []\n\n        if MACOS and \"MACOSX_DEPLOYMENT_TARGET\" not in os.environ:\n            # C++17 requires a higher min version of macOS. An earlier version\n            # (10.12 or 10.13) can be set manually via environment variable if\n            # you are careful in your feature usage, but 10.14 is the safest\n            # setting for general use. However, never set higher than the\n            # current macOS version!\n            current_macos = tuple(int(x) for x in platform.mac_ver()[0].split(\".\")[:2])\n            desired_macos = (10, 9) if level < 17 else (10, 14)\n            macos_string = \".\".join(str(x) for x in min(current_macos, desired_macos))\n            macosx_min = \"-mmacosx-version-min=\" + macos_string\n            cflags += [macosx_min]\n            ldflags += [macosx_min]\n\n        if PY2:\n            if WIN:\n                # Will be ignored on MSVC 2015, where C++17 is not supported so\n                # this flag is not valid.\n                cflags += [\"/wd5033\"]\n            elif level >= 17:\n                cflags += [\"-Wno-register\"]\n            elif level >= 14:\n                cflags += [\"-Wno-deprecated-register\"]\n\n        self._add_cflags(cflags)\n        self._add_ldflags(ldflags)\n\n\n# Just in case someone clever tries to multithread\ntmp_chdir_lock = threading.Lock()\ncpp_cache_lock = threading.Lock()\n\n\n@contextlib.contextmanager\ndef tmp_chdir():\n    \"Prepare and enter a temporary directory, cleanup when done\"\n\n    # Threadsafe\n    with tmp_chdir_lock:\n        olddir = os.getcwd()\n        try:\n            tmpdir = tempfile.mkdtemp()\n            os.chdir(tmpdir)\n            yield tmpdir\n        finally:\n            os.chdir(olddir)\n            shutil.rmtree(tmpdir)\n\n\n# cf http://bugs.python.org/issue26689\ndef has_flag(compiler, flag):\n    \"\"\"\n    Return the flag if a flag name is supported on the\n    specified compiler, otherwise None (can be used as a boolean).\n    If multiple flags are passed, return the first that matches.\n    \"\"\"\n\n    with tmp_chdir():\n        fname = \"flagcheck.cpp\"\n        with open(fname, \"w\") as f:\n            # Don't trigger -Wunused-parameter.\n            f.write(\"int main (int, char **) { return 0; }\")\n\n        try:\n            compiler.compile([fname], extra_postargs=[flag])\n        except distutils.errors.CompileError:\n            return False\n        return True\n\n\n# Every call will cache the result\ncpp_flag_cache = None\n\n\ndef auto_cpp_level(compiler):\n    \"\"\"\n    Return the max supported C++ std level (17, 14, or 11). Returns latest on Windows.\n    \"\"\"\n\n    if WIN:\n        return \"latest\"\n\n    global cpp_flag_cache\n\n    # If this has been previously calculated with the same args, return that\n    with cpp_cache_lock:\n        if cpp_flag_cache:\n            return cpp_flag_cache\n\n    levels = [17, 14, 11]\n\n    for level in levels:\n        if has_flag(compiler, STD_TMPL.format(level)):\n            with cpp_cache_lock:\n                cpp_flag_cache = level\n            return level\n\n    msg = \"Unsupported compiler -- at least C++11 support is needed!\"\n    raise RuntimeError(msg)\n\n\nclass build_ext(_build_ext):  # noqa: N801\n    \"\"\"\n    Customized build_ext that allows an auto-search for the highest supported\n    C++ level for Pybind11Extension. This is only needed for the auto-search\n    for now, and is completely optional otherwise.\n    \"\"\"\n\n    def build_extensions(self):\n        \"\"\"\n        Build extensions, injecting C++ std for Pybind11Extension if needed.\n        \"\"\"\n\n        for ext in self.extensions:\n            if hasattr(ext, \"_cxx_level\") and ext._cxx_level == 0:\n                # Python 2 syntax - old-style distutils class\n                ext.__class__.cxx_std.__set__(ext, auto_cpp_level(self.compiler))\n\n        # Python 2 doesn't allow super here, since distutils uses old-style\n        # classes!\n        _build_ext.build_extensions(self)\n\n\ndef intree_extensions(paths, package_dir=None):\n    \"\"\"\n    Generate Pybind11Extensions from source files directly located in a Python\n    source tree.\n\n    ``package_dir`` behaves as in ``setuptools.setup``.  If unset, the Python\n    package root parent is determined as the first parent directory that does\n    not contain an ``__init__.py`` file.\n    \"\"\"\n    exts = []\n    for path in paths:\n        if package_dir is None:\n            parent, _ = os.path.split(path)\n            while os.path.exists(os.path.join(parent, \"__init__.py\")):\n                parent, _ = os.path.split(parent)\n            relname, _ = os.path.splitext(os.path.relpath(path, parent))\n            qualified_name = relname.replace(os.path.sep, \".\")\n            exts.append(Pybind11Extension(qualified_name, [path]))\n        else:\n            found = False\n            for prefix, parent in package_dir.items():\n                if path.startswith(parent):\n                    found = True\n                    relname, _ = os.path.splitext(os.path.relpath(path, parent))\n                    qualified_name = relname.replace(os.path.sep, \".\")\n                    if prefix:\n                        qualified_name = prefix + \".\" + qualified_name\n                    exts.append(Pybind11Extension(qualified_name, [path]))\n            if not found:\n                raise ValueError(\n                    \"path {} is not a child of any of the directories listed \"\n                    \"in 'package_dir' ({})\".format(path, package_dir)\n                )\n    return exts\n\n\ndef naive_recompile(obj, src):\n    \"\"\"\n    This will recompile only if the source file changes. It does not check\n    header files, so a more advanced function or Ccache is better if you have\n    editable header files in your package.\n    \"\"\"\n    return os.stat(obj).st_mtime < os.stat(src).st_mtime\n\n\ndef no_recompile(obg, src):\n    \"\"\"\n    This is the safest but slowest choice (and is the default) - will always\n    recompile sources.\n    \"\"\"\n    return True\n\n\n# Optional parallel compile utility\n# inspired by: http://stackoverflow.com/questions/11013851/speeding-up-build-process-with-distutils\n# and: https://github.com/tbenthompson/cppimport/blob/stable/cppimport/build_module.py\n# and NumPy's parallel distutils module:\n#              https://github.com/numpy/numpy/blob/master/numpy/distutils/ccompiler.py\nclass ParallelCompile(object):\n    \"\"\"\n    Make a parallel compile function. Inspired by\n    numpy.distutils.ccompiler.CCompiler_compile and cppimport.\n\n    This takes several arguments that allow you to customize the compile\n    function created:\n\n    envvar:\n        Set an environment variable to control the compilation threads, like\n        NPY_NUM_BUILD_JOBS\n    default:\n        0 will automatically multithread, or 1 will only multithread if the\n        envvar is set.\n    max:\n        The limit for automatic multithreading if non-zero\n    needs_recompile:\n        A function of (obj, src) that returns True when recompile is needed.  No\n        effect in isolated mode; use ccache instead, see\n        https://github.com/matplotlib/matplotlib/issues/1507/\n\n    To use::\n\n        ParallelCompile(\"NPY_NUM_BUILD_JOBS\").install()\n\n    or::\n\n        with ParallelCompile(\"NPY_NUM_BUILD_JOBS\"):\n            setup(...)\n\n    By default, this assumes all files need to be recompiled. A smarter\n    function can be provided via needs_recompile.  If the output has not yet\n    been generated, the compile will always run, and this function is not\n    called.\n    \"\"\"\n\n    __slots__ = (\"envvar\", \"default\", \"max\", \"_old\", \"needs_recompile\")\n\n    def __init__(self, envvar=None, default=0, max=0, needs_recompile=no_recompile):\n        self.envvar = envvar\n        self.default = default\n        self.max = max\n        self.needs_recompile = needs_recompile\n        self._old = []\n\n    def function(self):\n        \"\"\"\n        Builds a function object usable as distutils.ccompiler.CCompiler.compile.\n        \"\"\"\n\n        def compile_function(\n            compiler,\n            sources,\n            output_dir=None,\n            macros=None,\n            include_dirs=None,\n            debug=0,\n            extra_preargs=None,\n            extra_postargs=None,\n            depends=None,\n        ):\n\n            # These lines are directly from distutils.ccompiler.CCompiler\n            macros, objects, extra_postargs, pp_opts, build = compiler._setup_compile(\n                output_dir, macros, include_dirs, sources, depends, extra_postargs\n            )\n            cc_args = compiler._get_cc_args(pp_opts, debug, extra_preargs)\n\n            # The number of threads; start with default.\n            threads = self.default\n\n            # Determine the number of compilation threads, unless set by an environment variable.\n            if self.envvar is not None:\n                threads = int(os.environ.get(self.envvar, self.default))\n\n            def _single_compile(obj):\n                try:\n                    src, ext = build[obj]\n                except KeyError:\n                    return\n\n                if not os.path.exists(obj) or self.needs_recompile(obj, src):\n                    compiler._compile(obj, src, ext, cc_args, extra_postargs, pp_opts)\n\n            try:\n                # Importing .synchronize checks for platforms that have some multiprocessing\n                # capabilities but lack semaphores, such as AWS Lambda and Android Termux.\n                import multiprocessing.synchronize\n                from multiprocessing.pool import ThreadPool\n            except ImportError:\n                threads = 1\n\n            if threads == 0:\n                try:\n                    threads = multiprocessing.cpu_count()\n                    threads = self.max if self.max and self.max < threads else threads\n                except NotImplementedError:\n                    threads = 1\n\n            if threads > 1:\n                pool = ThreadPool(threads)\n                # In Python 2, ThreadPool can't be used as a context manager.\n                # Once we are no longer supporting it, this can be 'with pool:'\n                try:\n                    for _ in pool.imap_unordered(_single_compile, objects):\n                        pass\n                finally:\n                    pool.terminate()\n            else:\n                for ob in objects:\n                    _single_compile(ob)\n\n            return objects\n\n        return compile_function\n\n    def install(self):\n        distutils.ccompiler.CCompiler.compile = self.function()\n        return self\n\n    def __enter__(self):\n        self._old.append(distutils.ccompiler.CCompiler.compile)\n        return self.install()\n\n    def __exit__(self, *args):\n        distutils.ccompiler.CCompiler.compile = self._old.pop()\n"
  },
  {
    "path": "external/pybind11_2.9.2/pybind11/setup_helpers.pyi",
    "content": "# IMPORTANT: Should stay in sync with setup_helpers.py (mostly checked by CI /\n# pre-commit).\n\nimport contextlib\nimport distutils.ccompiler\nfrom distutils.command.build_ext import build_ext as _build_ext  # type: ignore\nfrom distutils.extension import Extension as _Extension\nfrom types import TracebackType\nfrom typing import Any, Callable, Dict, Iterator, List, Optional, Type, TypeVar, Union\n\nWIN: bool\nPY2: bool\nMACOS: bool\nSTD_TMPL: str\n\nclass Pybind11Extension(_Extension):\n    def _add_cflags(self, *flags: str) -> None: ...\n    def _add_lflags(self, *flags: str) -> None: ...\n    def __init__(\n        self, *args: Any, cxx_std: int = 0, language: str = \"c++\", **kwargs: Any\n    ) -> None: ...\n    @property\n    def cxx_std(self) -> int: ...\n    @cxx_std.setter\n    def cxx_std(self, level: int) -> None: ...\n\n@contextlib.contextmanager\ndef tmp_chdir() -> Iterator[str]: ...\ndef has_flag(compiler: distutils.ccompiler.CCompiler, flag: str) -> bool: ...\ndef auto_cpp_level(compiler: distutils.ccompiler.CCompiler) -> Union[int, str]: ...\n\nclass build_ext(_build_ext):  # type: ignore\n    def build_extensions(self) -> None: ...\n\ndef intree_extensions(\n    paths: Iterator[str], package_dir: Optional[Dict[str, str]] = None\n) -> List[Pybind11Extension]: ...\ndef no_recompile(obj: str, src: str) -> bool: ...\ndef naive_recompile(obj: str, src: str) -> bool: ...\n\nT = TypeVar(\"T\", bound=\"ParallelCompile\")\n\nclass ParallelCompile:\n    envvar: Optional[str]\n    default: int\n    max: int\n    needs_recompile: Callable[[str, str], bool]\n    def __init__(\n        self,\n        envvar: Optional[str] = None,\n        default: int = 0,\n        max: int = 0,\n        needs_recompile: Callable[[str, str], bool] = no_recompile,\n    ) -> None: ...\n    def function(self) -> Any: ...\n    def install(self: T) -> T: ...\n    def __enter__(self: T) -> T: ...\n    def __exit__(\n        self,\n        exc_type: Optional[Type[BaseException]],\n        exc_value: Optional[BaseException],\n        traceback: Optional[TracebackType],\n    ) -> None: ...\n"
  },
  {
    "path": "external/pybind11_2.9.2/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\", \"cmake>=3.18\", \"ninja\"]\nbuild-backend = \"setuptools.build_meta\"\n\n[tool.check-manifest]\nignore = [\n    \"tests/**\",\n    \"docs/**\",\n    \"tools/**\",\n    \"include/**\",\n    \".*\",\n    \"pybind11/include/**\",\n    \"pybind11/share/**\",\n    \"CMakeLists.txt\",\n    \"noxfile.py\",\n]\n\n[tool.isort]\n# Needs the compiled .so modules and env.py from tests\nknown_first_party = \"env,pybind11_cross_module_tests,pybind11_tests,\"\n# For black compatibility\nprofile = \"black\"\n\n[tool.mypy]\nfiles = \"pybind11\"\npython_version = \"2.7\"\nwarn_unused_configs = true\n\ndisallow_any_generics = true\ndisallow_subclassing_any = true\ndisallow_untyped_calls = true\ndisallow_untyped_defs = true\ndisallow_incomplete_defs = true\ncheck_untyped_defs = true\ndisallow_untyped_decorators = true\nno_implicit_optional = true\nwarn_redundant_casts = true\nwarn_unused_ignores = true\nwarn_return_any = true\nno_implicit_reexport = true\nstrict_equality = true\n"
  },
  {
    "path": "external/pybind11_2.9.2/setup.cfg",
    "content": "[metadata]\nlong_description = file: README.rst\nlong_description_content_type = text/x-rst\ndescription = Seamless operability between C++11 and Python\nauthor = Wenzel Jakob\nauthor_email = wenzel.jakob@epfl.ch\nurl = https://github.com/pybind/pybind11\nlicense = BSD\n\nclassifiers =\n    Development Status :: 5 - Production/Stable\n    Intended Audience :: Developers\n    Topic :: Software Development :: Libraries :: Python Modules\n    Topic :: Utilities\n    Programming Language :: C++\n    Programming Language :: Python :: 2.7\n    Programming Language :: Python :: 3\n    Programming Language :: Python :: 3.5\n    Programming Language :: Python :: 3.6\n    Programming Language :: Python :: 3.7\n    Programming Language :: Python :: 3.8\n    Programming Language :: Python :: 3.9\n    Programming Language :: Python :: 3.10\n    License :: OSI Approved :: BSD License\n    Programming Language :: Python :: Implementation :: PyPy\n    Programming Language :: Python :: Implementation :: CPython\n    Programming Language :: C++\n    Topic :: Software Development :: Libraries :: Python Modules\n\nkeywords =\n    C++11\n    Python bindings\n\nproject_urls =\n    Documentation = https://pybind11.readthedocs.io/\n    Bug Tracker = https://github.com/pybind/pybind11/issues\n    Discussions = https://github.com/pybind/pybind11/discussions\n    Changelog = https://pybind11.readthedocs.io/en/latest/changelog.html\n    Chat = https://gitter.im/pybind/Lobby\n\n[options]\npython_requires = >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*\nzip_safe = False\n\n[bdist_wheel]\nuniversal=1\n\n\n[flake8]\nmax-line-length = 99\nshow_source = True\nexclude = .git, __pycache__, build, dist, docs, tools, venv\nignore =\n    # required for pretty matrix formatting: multiple spaces after `,` and `[`\n    E201, E241, W504,\n    # camelcase 'cPickle' imported as lowercase 'pickle'\n    N813\n    # Black conflict\n    W503, E203\n\n\n[tool:pytest]\ntimeout = 300\n"
  },
  {
    "path": "external/pybind11_2.9.2/setup.py",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n# Setup script for PyPI; use CMakeFile.txt to build extension modules\n\nimport contextlib\nimport io\nimport os\nimport re\nimport shutil\nimport string\nimport subprocess\nimport sys\nimport tempfile\n\nimport setuptools.command.sdist\n\nDIR = os.path.abspath(os.path.dirname(__file__))\nVERSION_REGEX = re.compile(\n    r\"^\\s*#\\s*define\\s+PYBIND11_VERSION_([A-Z]+)\\s+(.*)$\", re.MULTILINE\n)\n\n\ndef build_expected_version_hex(matches):\n    patch_level_serial = matches[\"PATCH\"]\n    serial = None\n    try:\n        major = int(matches[\"MAJOR\"])\n        minor = int(matches[\"MINOR\"])\n        flds = patch_level_serial.split(\".\")\n        if flds:\n            patch = int(flds[0])\n            level = None\n            if len(flds) == 1:\n                level = \"0\"\n                serial = 0\n            elif len(flds) == 2:\n                level_serial = flds[1]\n                for level in (\"a\", \"b\", \"c\", \"dev\"):\n                    if level_serial.startswith(level):\n                        serial = int(level_serial[len(level) :])\n                        break\n    except ValueError:\n        pass\n    if serial is None:\n        msg = 'Invalid PYBIND11_VERSION_PATCH: \"{}\"'.format(patch_level_serial)\n        raise RuntimeError(msg)\n    return (\n        \"0x\"\n        + \"{:02x}{:02x}{:02x}{}{:x}\".format(\n            major, minor, patch, level[:1], serial\n        ).upper()\n    )\n\n\n# PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers\n# files, and the sys.prefix files (CMake and headers).\n\nglobal_sdist = os.environ.get(\"PYBIND11_GLOBAL_SDIST\", False)\n\nsetup_py = \"tools/setup_global.py.in\" if global_sdist else \"tools/setup_main.py.in\"\nextra_cmd = 'cmdclass[\"sdist\"] = SDist\\n'\n\nto_src = (\n    (\"pyproject.toml\", \"tools/pyproject.toml\"),\n    (\"setup.py\", setup_py),\n)\n\n# Read the listed version\nwith open(\"pybind11/_version.py\") as f:\n    code = compile(f.read(), \"pybind11/_version.py\", \"exec\")\nloc = {}\nexec(code, loc)\nversion = loc[\"__version__\"]\n\n# Verify that the version matches the one in C++\nwith io.open(\"include/pybind11/detail/common.h\", encoding=\"utf8\") as f:\n    matches = dict(VERSION_REGEX.findall(f.read()))\ncpp_version = \"{MAJOR}.{MINOR}.{PATCH}\".format(**matches)\nif version != cpp_version:\n    msg = \"Python version {} does not match C++ version {}!\".format(\n        version, cpp_version\n    )\n    raise RuntimeError(msg)\n\nversion_hex = matches.get(\"HEX\", \"MISSING\")\nexpected_version_hex = build_expected_version_hex(matches)\nif version_hex != expected_version_hex:\n    msg = \"PYBIND11_VERSION_HEX {} does not match expected value {}!\".format(\n        version_hex,\n        expected_version_hex,\n    )\n    raise RuntimeError(msg)\n\n\ndef get_and_replace(filename, binary=False, **opts):\n    with open(filename, \"rb\" if binary else \"r\") as f:\n        contents = f.read()\n    # Replacement has to be done on text in Python 3 (both work in Python 2)\n    if binary:\n        return string.Template(contents.decode()).substitute(opts).encode()\n    else:\n        return string.Template(contents).substitute(opts)\n\n\n# Use our input files instead when making the SDist (and anything that depends\n# on it, like a wheel)\nclass SDist(setuptools.command.sdist.sdist):\n    def make_release_tree(self, base_dir, files):\n        setuptools.command.sdist.sdist.make_release_tree(self, base_dir, files)\n\n        for to, src in to_src:\n            txt = get_and_replace(src, binary=True, version=version, extra_cmd=\"\")\n\n            dest = os.path.join(base_dir, to)\n\n            # This is normally linked, so unlink before writing!\n            os.unlink(dest)\n            with open(dest, \"wb\") as f:\n                f.write(txt)\n\n\n# Backport from Python 3\n@contextlib.contextmanager\ndef TemporaryDirectory():  # noqa: N802\n    \"Prepare a temporary directory, cleanup when done\"\n    try:\n        tmpdir = tempfile.mkdtemp()\n        yield tmpdir\n    finally:\n        shutil.rmtree(tmpdir)\n\n\n# Remove the CMake install directory when done\n@contextlib.contextmanager\ndef remove_output(*sources):\n    try:\n        yield\n    finally:\n        for src in sources:\n            shutil.rmtree(src)\n\n\nwith remove_output(\"pybind11/include\", \"pybind11/share\"):\n    # Generate the files if they are not present.\n    with TemporaryDirectory() as tmpdir:\n        cmd = [\"cmake\", \"-S\", \".\", \"-B\", tmpdir] + [\n            \"-DCMAKE_INSTALL_PREFIX=pybind11\",\n            \"-DBUILD_TESTING=OFF\",\n            \"-DPYBIND11_NOPYTHON=ON\",\n        ]\n        if \"CMAKE_ARGS\" in os.environ:\n            fcommand = [\n                c\n                for c in os.environ[\"CMAKE_ARGS\"].split()\n                if \"DCMAKE_INSTALL_PREFIX\" not in c\n            ]\n            cmd += fcommand\n        cmake_opts = dict(cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)\n        subprocess.check_call(cmd, **cmake_opts)\n        subprocess.check_call([\"cmake\", \"--install\", tmpdir], **cmake_opts)\n\n    txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)\n    code = compile(txt, setup_py, \"exec\")\n    exec(code, {\"SDist\": SDist})\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/CMakeLists.txt",
    "content": "# CMakeLists.txt -- Build system for the pybind11 test suite\n#\n# Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\ncmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.21)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.21)\nendif()\n\n# Only needed for CMake < 3.5 support\ninclude(CMakeParseArguments)\n\n# Filter out items; print an optional message if any items filtered. This ignores extensions.\n#\n# Usage:\n#   pybind11_filter_tests(LISTNAME file1.cpp file2.cpp ... MESSAGE \"\")\n#\nmacro(pybind11_filter_tests LISTNAME)\n  cmake_parse_arguments(ARG \"\" \"MESSAGE\" \"\" ${ARGN})\n  set(PYBIND11_FILTER_TESTS_FOUND OFF)\n  # Make a list of the test without any extensions, for easier filtering.\n  set(_TMP_ACTUAL_LIST \"${${LISTNAME}};\") # enforce ';' at the end to allow matching last item.\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" LIST_WITHOUT_EXTENSIONS \"${_TMP_ACTUAL_LIST}\")\n  foreach(filename IN LISTS ARG_UNPARSED_ARGUMENTS)\n    string(REGEX REPLACE \"\\\\.[^.]*$\" \"\" filename_no_ext ${filename})\n    # Search in the list without extensions.\n    list(FIND LIST_WITHOUT_EXTENSIONS ${filename_no_ext} _FILE_FOUND)\n    if(_FILE_FOUND GREATER -1)\n      list(REMOVE_AT ${LISTNAME} ${_FILE_FOUND}) # And remove from the list with extensions.\n      list(REMOVE_AT LIST_WITHOUT_EXTENSIONS ${_FILE_FOUND}\n      )# And our search list, to ensure it is in sync.\n      set(PYBIND11_FILTER_TESTS_FOUND ON)\n    endif()\n  endforeach()\n  if(PYBIND11_FILTER_TESTS_FOUND AND ARG_MESSAGE)\n    message(STATUS \"${ARG_MESSAGE}\")\n  endif()\nendmacro()\n\nmacro(possibly_uninitialized)\n  foreach(VARNAME ${ARGN})\n    if(NOT DEFINED \"${VARNAME}\")\n      set(\"${VARNAME}\" \"\")\n    endif()\n  endforeach()\nendmacro()\n\n# Function to add additional targets if any of the provided tests are found.\n# Needles; Specifies the test names to look for.\n# Additions; Specifies the additional test targets to add when any of the needles are found.\nmacro(tests_extra_targets needles additions)\n  # Add the index for this relation to the index extra targets map.\n  list(LENGTH PYBIND11_TEST_EXTRA_TARGETS PYBIND11_TEST_EXTRA_TARGETS_LEN)\n  list(APPEND PYBIND11_TEST_EXTRA_TARGETS ${PYBIND11_TEST_EXTRA_TARGETS_LEN})\n  # Add the test names to look for, and the associated test target additions.\n  set(PYBIND11_TEST_EXTRA_TARGETS_NEEDLES_${PYBIND11_TEST_EXTRA_TARGETS_LEN} ${needles})\n  set(PYBIND11_TEST_EXTRA_TARGETS_ADDITION_${PYBIND11_TEST_EXTRA_TARGETS_LEN} ${additions})\nendmacro()\n\n# New Python support\nif(DEFINED Python_EXECUTABLE)\n  set(PYTHON_EXECUTABLE \"${Python_EXECUTABLE}\")\n  set(PYTHON_VERSION \"${Python_VERSION}\")\nendif()\n\n# There's no harm in including a project in a project\nproject(pybind11_tests CXX)\n\n# Access FindCatch and more\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}/../tools\")\n\noption(PYBIND11_WERROR \"Report all warnings as errors\" OFF)\noption(DOWNLOAD_EIGEN \"Download EIGEN (requires CMake 3.11+)\" OFF)\noption(PYBIND11_CUDA_TESTS \"Enable building CUDA tests (requires CMake 3.12+)\" OFF)\nset(PYBIND11_TEST_OVERRIDE\n    \"\"\n    CACHE STRING \"Tests from ;-separated list of *.cpp files will be built instead of all tests\")\nset(PYBIND11_TEST_FILTER\n    \"\"\n    CACHE STRING \"Tests from ;-separated list of *.cpp files will be removed from all tests\")\n\nif(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n  # We're being loaded directly, i.e. not via add_subdirectory, so make this\n  # work as its own project and load the pybind11Config to get the tools we need\n  find_package(pybind11 REQUIRED CONFIG)\nendif()\n\nif(NOT CMAKE_BUILD_TYPE AND NOT DEFINED CMAKE_CONFIGURATION_TYPES)\n  message(STATUS \"Setting tests build type to MinSizeRel as none was specified\")\n  set(CMAKE_BUILD_TYPE\n      MinSizeRel\n      CACHE STRING \"Choose the type of build.\" FORCE)\n  set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS \"Debug\" \"Release\" \"MinSizeRel\"\n                                               \"RelWithDebInfo\")\nendif()\n\nif(PYBIND11_CUDA_TESTS)\n  enable_language(CUDA)\n  if(DEFINED CMAKE_CXX_STANDARD)\n    set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD})\n  endif()\n  set(CMAKE_CUDA_STANDARD_REQUIRED ON)\nendif()\n\n# Full set of test files (you can override these; see below, overrides ignore extension)\n# Any test that has no extension is both .py and .cpp, so 'foo' will add 'foo.cpp' and 'foo.py'.\n# Any test that has an extension is exclusively that and handled as such.\nset(PYBIND11_TEST_FILES\n    test_async\n    test_buffers\n    test_builtin_casters\n    test_call_policies\n    test_callbacks\n    test_chrono\n    test_class\n    test_const_name\n    test_constants_and_functions\n    test_copy_move\n    test_custom_type_casters\n    test_custom_type_setup\n    test_docstring_options\n    test_eigen\n    test_enum\n    test_eval\n    test_exceptions\n    test_factory_constructors\n    test_gil_scoped\n    test_iostream\n    test_kwargs_and_defaults\n    test_local_bindings\n    test_methods_and_attributes\n    test_modules\n    test_multiple_inheritance\n    test_numpy_array\n    test_numpy_dtypes\n    test_numpy_vectorize\n    test_opaque_types\n    test_operator_overloading\n    test_pickling\n    test_pytypes\n    test_sequences_and_iterators\n    test_smart_ptr\n    test_stl\n    test_stl_binders\n    test_tagbased_polymorphic\n    test_thread\n    test_union\n    test_virtual_functions)\n\n# Invoking cmake with something like:\n#     cmake -DPYBIND11_TEST_OVERRIDE=\"test_callbacks.cpp;test_pickling.cpp\" ..\n# lets you override the tests that get compiled and run.  You can restore to all tests with:\n#     cmake -DPYBIND11_TEST_OVERRIDE= ..\nif(PYBIND11_TEST_OVERRIDE)\n  # Instead of doing a direct override here, we iterate over the overrides without extension and\n  # match them against entries from the PYBIND11_TEST_FILES, anything that not matches goes into the filter list.\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" TEST_OVERRIDE_NO_EXT \"${PYBIND11_TEST_OVERRIDE};\")\n  string(REGEX REPLACE \"\\\\.[^.;]*;\" \";\" TEST_FILES_NO_EXT \"${PYBIND11_TEST_FILES};\")\n  # This allows the override to be done with extensions, preserving backwards compatibility.\n  foreach(test_name ${TEST_FILES_NO_EXT})\n    if(NOT ${test_name} IN_LIST TEST_OVERRIDE_NO_EXT\n    )# If not in the whitelist, add to be filtered out.\n      list(APPEND PYBIND11_TEST_FILTER ${test_name})\n    endif()\n  endforeach()\nendif()\n\n# You can also filter tests:\nif(PYBIND11_TEST_FILTER)\n  pybind11_filter_tests(PYBIND11_TEST_FILES ${PYBIND11_TEST_FILTER})\nendif()\n\nif(PYTHON_VERSION VERSION_LESS 3.5)\n  pybind11_filter_tests(PYBIND11_TEST_FILES test_async.cpp MESSAGE\n                        \"Skipping test_async on Python 2\")\nendif()\n\n# Skip tests for CUDA check:\n# /pybind11/tests/test_constants_and_functions.cpp(125):\n#   error: incompatible exception specifications\nif(PYBIND11_CUDA_TESTS)\n  pybind11_filter_tests(\n    PYBIND11_TEST_FILES test_constants_and_functions.cpp MESSAGE\n    \"Skipping test_constants_and_functions due to incompatible exception specifications\")\nendif()\n\n# Now that the test filtering is complete, we need to split the list into the test for PYTEST\n# and the list for the cpp targets.\nset(PYBIND11_CPPTEST_FILES \"\")\nset(PYBIND11_PYTEST_FILES \"\")\n\nforeach(test_name ${PYBIND11_TEST_FILES})\n  if(test_name MATCHES \"\\\\.py$\") # Ends in .py, purely python test.\n    list(APPEND PYBIND11_PYTEST_FILES ${test_name})\n  elseif(test_name MATCHES \"\\\\.cpp$\") # Ends in .cpp, purely cpp test.\n    list(APPEND PYBIND11_CPPTEST_FILES ${test_name})\n  elseif(NOT test_name MATCHES \"\\\\.\") # No extension specified, assume both, add extension.\n    list(APPEND PYBIND11_PYTEST_FILES ${test_name}.py)\n    list(APPEND PYBIND11_CPPTEST_FILES ${test_name}.cpp)\n  else()\n    message(WARNING \"Unhanded test extension in test: ${test_name}\")\n  endif()\nendforeach()\nset(PYBIND11_TEST_FILES ${PYBIND11_CPPTEST_FILES})\nlist(SORT PYBIND11_PYTEST_FILES)\n\n# Contains the set of test files that require pybind11_cross_module_tests to be\n# built; if none of these are built (i.e. because TEST_OVERRIDE is used and\n# doesn't include them) the second module doesn't get built.\ntests_extra_targets(\"test_exceptions.py;test_local_bindings.py;test_stl.py;test_stl_binders.py\"\n                    \"pybind11_cross_module_tests\")\n\n# And add additional targets for other tests.\ntests_extra_targets(\"test_gil_scoped.py\" \"cross_module_gil_utils\")\n\nset(PYBIND11_EIGEN_REPO\n    \"https://gitlab.com/libeigen/eigen.git\"\n    CACHE STRING \"Eigen repository to use for tests\")\n# Always use a hash for reconfigure speed and security reasons\n# Include the version number for pretty printing (keep in sync)\nset(PYBIND11_EIGEN_VERSION_AND_HASH\n    \"3.4.0;929bc0e191d0927b1735b9a1ddc0e8b77e3a25ec\"\n    CACHE STRING \"Eigen version to use for tests, format: VERSION;HASH\")\n\nlist(GET PYBIND11_EIGEN_VERSION_AND_HASH 0 PYBIND11_EIGEN_VERSION_STRING)\nlist(GET PYBIND11_EIGEN_VERSION_AND_HASH 1 PYBIND11_EIGEN_VERSION_HASH)\n\n# Check if Eigen is available; if not, remove from PYBIND11_TEST_FILES (but\n# keep it in PYBIND11_PYTEST_FILES, so that we get the \"eigen is not installed\"\n# skip message).\nlist(FIND PYBIND11_TEST_FILES test_eigen.cpp PYBIND11_TEST_FILES_EIGEN_I)\nif(PYBIND11_TEST_FILES_EIGEN_I GREATER -1)\n  # Try loading via newer Eigen's Eigen3Config first (bypassing tools/FindEigen3.cmake).\n  # Eigen 3.3.1+ exports a cmake 3.0+ target for handling dependency requirements, but also\n  # produces a fatal error if loaded from a pre-3.0 cmake.\n  if(DOWNLOAD_EIGEN)\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      message(FATAL_ERROR \"CMake 3.11+ required when using DOWNLOAD_EIGEN\")\n    endif()\n\n    include(FetchContent)\n    FetchContent_Declare(\n      eigen\n      GIT_REPOSITORY \"${PYBIND11_EIGEN_REPO}\"\n      GIT_TAG \"${PYBIND11_EIGEN_VERSION_HASH}\")\n\n    FetchContent_GetProperties(eigen)\n    if(NOT eigen_POPULATED)\n      message(\n        STATUS\n          \"Downloading Eigen ${PYBIND11_EIGEN_VERSION_STRING} (${PYBIND11_EIGEN_VERSION_HASH}) from ${PYBIND11_EIGEN_REPO}\"\n      )\n      FetchContent_Populate(eigen)\n    endif()\n\n    set(EIGEN3_INCLUDE_DIR ${eigen_SOURCE_DIR})\n    set(EIGEN3_FOUND TRUE)\n    # When getting locally, the version is not visible from a superprojet,\n    # so just force it.\n    set(EIGEN3_VERSION \"${PYBIND11_EIGEN_VERSION_STRING}\")\n\n  else()\n    find_package(Eigen3 3.2.7 QUIET CONFIG)\n\n    if(NOT EIGEN3_FOUND)\n      # Couldn't load via target, so fall back to allowing module mode finding, which will pick up\n      # tools/FindEigen3.cmake\n      find_package(Eigen3 3.2.7 QUIET)\n    endif()\n  endif()\n\n  if(EIGEN3_FOUND)\n    if(NOT TARGET Eigen3::Eigen)\n      add_library(Eigen3::Eigen IMPORTED INTERFACE)\n      set_property(TARGET Eigen3::Eigen PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                 \"${EIGEN3_INCLUDE_DIR}\")\n    endif()\n\n    # Eigen 3.3.1+ cmake sets EIGEN3_VERSION_STRING (and hard codes the version when installed\n    # rather than looking it up in the cmake script); older versions, and the\n    # tools/FindEigen3.cmake, set EIGEN3_VERSION instead.\n    if(NOT EIGEN3_VERSION AND EIGEN3_VERSION_STRING)\n      set(EIGEN3_VERSION ${EIGEN3_VERSION_STRING})\n    endif()\n    message(STATUS \"Building tests with Eigen v${EIGEN3_VERSION}\")\n  else()\n    list(REMOVE_AT PYBIND11_TEST_FILES ${PYBIND11_TEST_FILES_EIGEN_I})\n    message(\n      STATUS \"Building tests WITHOUT Eigen, use -DDOWNLOAD_EIGEN=ON on CMake 3.11+ to download\")\n  endif()\nendif()\n\n# Optional dependency for some tests (boost::variant is only supported with version >= 1.56)\nfind_package(Boost 1.56)\n\nif(Boost_FOUND)\n  if(NOT TARGET Boost::headers)\n    add_library(Boost::headers IMPORTED INTERFACE)\n    if(TARGET Boost::boost)\n      # Classic FindBoost\n      set_property(TARGET Boost::boost PROPERTY INTERFACE_LINK_LIBRARIES Boost::boost)\n    else()\n      # Very old FindBoost, or newer Boost than CMake in older CMakes\n      set_property(TARGET Boost::headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                  ${Boost_INCLUDE_DIRS})\n    endif()\n  endif()\nendif()\n\n# Check if we need to add -lstdc++fs or -lc++fs or nothing\nif(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD LESS 17)\n  set(STD_FS_NO_LIB_NEEDED TRUE)\nelseif(MSVC)\n  set(STD_FS_NO_LIB_NEEDED TRUE)\nelse()\n  file(\n    WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    \"#include <filesystem>\\nint main(int argc, char ** argv) {\\n  std::filesystem::path p(argv[0]);\\n  return p.string().length();\\n}\"\n  )\n  try_compile(\n    STD_FS_NO_LIB_NEEDED ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17)\n  try_compile(\n    STD_FS_NEEDS_STDCXXFS ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17\n    LINK_LIBRARIES stdc++fs)\n  try_compile(\n    STD_FS_NEEDS_CXXFS ${CMAKE_CURRENT_BINARY_DIR}\n    SOURCES ${CMAKE_CURRENT_BINARY_DIR}/main.cpp\n    COMPILE_DEFINITIONS -std=c++17\n    LINK_LIBRARIES c++fs)\nendif()\n\nif(${STD_FS_NEEDS_STDCXXFS})\n  set(STD_FS_LIB stdc++fs)\nelseif(${STD_FS_NEEDS_CXXFS})\n  set(STD_FS_LIB c++fs)\nelseif(${STD_FS_NO_LIB_NEEDED})\n  set(STD_FS_LIB \"\")\nelse()\n  message(WARNING \"Unknown C++17 compiler - not passing -lstdc++fs\")\n  set(STD_FS_LIB \"\")\nendif()\n\n# Compile with compiler warnings turned on\nfunction(pybind11_enable_warnings target_name)\n  if(MSVC)\n    target_compile_options(${target_name} PRIVATE /W4)\n  elseif(CMAKE_CXX_COMPILER_ID MATCHES \"(GNU|Intel|Clang)\" AND NOT PYBIND11_CUDA_TESTS)\n    target_compile_options(\n      ${target_name}\n      PRIVATE -Wall\n              -Wextra\n              -Wconversion\n              -Wcast-qual\n              -Wdeprecated\n              -Wundef\n              -Wnon-virtual-dtor)\n  endif()\n\n  if(PYBIND11_WERROR)\n    if(MSVC)\n      target_compile_options(${target_name} PRIVATE /WX)\n    elseif(PYBIND11_CUDA_TESTS)\n      target_compile_options(${target_name} PRIVATE \"SHELL:-Werror all-warnings\")\n    elseif(CMAKE_CXX_COMPILER_ID MATCHES \"(GNU|Clang|IntelLLVM)\")\n      target_compile_options(${target_name} PRIVATE -Werror)\n    elseif(CMAKE_CXX_COMPILER_ID STREQUAL \"Intel\")\n      if(CMAKE_CXX_STANDARD EQUAL 17) # See PR #3570\n        target_compile_options(${target_name} PRIVATE -Wno-conversion)\n      endif()\n      target_compile_options(\n        ${target_name}\n        PRIVATE\n          -Werror-all\n          # \"Inlining inhibited by limit max-size\", \"Inlining inhibited by limit max-total-size\"\n          -diag-disable 11074,11076)\n    endif()\n  endif()\n\n  # Needs to be re-added since the ordering requires these to be after the ones above\n  if(CMAKE_CXX_STANDARD\n     AND CMAKE_CXX_COMPILER_ID MATCHES \"Clang\"\n     AND PYTHON_VERSION VERSION_LESS 3.0)\n    if(CMAKE_CXX_STANDARD LESS 17)\n      target_compile_options(${target_name} PUBLIC -Wno-deprecated-register)\n    else()\n      target_compile_options(${target_name} PUBLIC -Wno-register)\n    endif()\n  endif()\nendfunction()\n\nset(test_targets pybind11_tests)\n\n# Check if any tests need extra targets by iterating through the mappings registered.\nforeach(i ${PYBIND11_TEST_EXTRA_TARGETS})\n  foreach(needle ${PYBIND11_TEST_EXTRA_TARGETS_NEEDLES_${i}})\n    if(needle IN_LIST PYBIND11_PYTEST_FILES)\n      # Add all the additional targets to the test list. List join in newer cmake.\n      foreach(extra_target ${PYBIND11_TEST_EXTRA_TARGETS_ADDITION_${i}})\n        list(APPEND test_targets ${extra_target})\n      endforeach()\n      break() # Breaks out of the needle search, continues with the next mapping.\n    endif()\n  endforeach()\nendforeach()\n\n# Support CUDA testing by forcing the target file to compile with NVCC\nif(PYBIND11_CUDA_TESTS)\n  set_property(SOURCE ${PYBIND11_TEST_FILES} PROPERTY LANGUAGE CUDA)\nendif()\n\nforeach(target ${test_targets})\n  set(test_files ${PYBIND11_TEST_FILES})\n  if(NOT \"${target}\" STREQUAL \"pybind11_tests\")\n    set(test_files \"\")\n  endif()\n\n  # Support CUDA testing by forcing the target file to compile with NVCC\n  if(PYBIND11_CUDA_TESTS)\n    set_property(SOURCE ${target}.cpp PROPERTY LANGUAGE CUDA)\n  endif()\n\n  # Create the binding library\n  pybind11_add_module(${target} THIN_LTO ${target}.cpp ${test_files} ${PYBIND11_HEADERS})\n  pybind11_enable_warnings(${target})\n\n  if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n    get_property(\n      suffix\n      TARGET ${target}\n      PROPERTY SUFFIX)\n    set(source_output \"${CMAKE_CURRENT_SOURCE_DIR}/${target}${suffix}\")\n    if(suffix AND EXISTS \"${source_output}\")\n      message(WARNING \"Output file also in source directory; \"\n                      \"please remove to avoid confusion: ${source_output}\")\n    endif()\n  endif()\n\n  if(MSVC)\n    target_compile_options(${target} PRIVATE /utf-8)\n  endif()\n\n  if(EIGEN3_FOUND)\n    target_link_libraries(${target} PRIVATE Eigen3::Eigen)\n    target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_EIGEN)\n  endif()\n\n  if(Boost_FOUND)\n    target_link_libraries(${target} PRIVATE Boost::headers)\n    target_compile_definitions(${target} PRIVATE -DPYBIND11_TEST_BOOST)\n  endif()\n\n  target_link_libraries(${target} PRIVATE ${STD_FS_LIB})\n\n  # Always write the output file directly into the 'tests' directory (even on MSVC)\n  if(NOT CMAKE_LIBRARY_OUTPUT_DIRECTORY)\n    set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n                                               \"${CMAKE_CURRENT_BINARY_DIR}\")\n\n    if(DEFINED CMAKE_CONFIGURATION_TYPES)\n      foreach(config ${CMAKE_CONFIGURATION_TYPES})\n        string(TOUPPER ${config} config)\n        set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config}\n                                                   \"${CMAKE_CURRENT_BINARY_DIR}\")\n      endforeach()\n    endif()\n  endif()\nendforeach()\n\n# Provide nice organisation in IDEs\nif(NOT CMAKE_VERSION VERSION_LESS 3.8)\n  source_group(\n    TREE \"${CMAKE_CURRENT_SOURCE_DIR}/../include\"\n    PREFIX \"Header Files\"\n    FILES ${PYBIND11_HEADERS})\nendif()\n\n# Make sure pytest is found or produce a warning\npybind11_find_import(pytest VERSION 3.1)\n\nif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n  # This is not used later in the build, so it's okay to regenerate each time.\n  configure_file(\"${CMAKE_CURRENT_SOURCE_DIR}/pytest.ini\" \"${CMAKE_CURRENT_BINARY_DIR}/pytest.ini\"\n                 COPYONLY)\n  file(APPEND \"${CMAKE_CURRENT_BINARY_DIR}/pytest.ini\"\n       \"\\ntestpaths = \\\"${CMAKE_CURRENT_SOURCE_DIR}\\\"\")\n\nendif()\n\n# cmake 3.12 added list(transform <list> prepend\n# but we can't use it yet\nstring(REPLACE \"test_\" \"${CMAKE_CURRENT_SOURCE_DIR}/test_\" PYBIND11_ABS_PYTEST_FILES\n               \"${PYBIND11_PYTEST_FILES}\")\n\nset(PYBIND11_TEST_PREFIX_COMMAND\n    \"\"\n    CACHE STRING \"Put this before pytest, use for checkers and such\")\n\n# A single command to compile and run the tests\nadd_custom_target(\n  pytest\n  COMMAND ${PYBIND11_TEST_PREFIX_COMMAND} ${PYTHON_EXECUTABLE} -m pytest\n          ${PYBIND11_ABS_PYTEST_FILES}\n  DEPENDS ${test_targets}\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\"\n  USES_TERMINAL)\n\nif(PYBIND11_TEST_OVERRIDE)\n  add_custom_command(\n    TARGET pytest\n    POST_BUILD\n    COMMAND ${CMAKE_COMMAND} -E echo\n            \"Note: not all tests run: -DPYBIND11_TEST_OVERRIDE is in effect\")\nendif()\n\n# cmake-format: off\nadd_custom_target(\n  memcheck\n  COMMAND\n    PYTHONMALLOC=malloc\n    valgrind\n    --leak-check=full\n    --show-leak-kinds=definite,indirect\n    --errors-for-leak-kinds=definite,indirect\n    --error-exitcode=1\n    --read-var-info=yes\n    --track-origins=yes\n    --suppressions=\"${CMAKE_CURRENT_SOURCE_DIR}/valgrind-python.supp\"\n    --suppressions=\"${CMAKE_CURRENT_SOURCE_DIR}/valgrind-numpy-scipy.supp\"\n    --gen-suppressions=all\n    ${PYTHON_EXECUTABLE} -m pytest ${PYBIND11_ABS_PYTEST_FILES}\n  DEPENDS ${test_targets}\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\"\n  USES_TERMINAL)\n# cmake-format: on\n\n# Add a check target to run all the tests, starting with pytest (we add dependencies to this below)\nadd_custom_target(check DEPENDS pytest)\n\n# The remaining tests only apply when being built as part of the pybind11 project, but not if the\n# tests are being built independently.\nif(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)\n  return()\nendif()\n\n# Add a post-build comment to show the primary test suite .so size and, if a previous size, compare it:\nadd_custom_command(\n  TARGET pybind11_tests\n  POST_BUILD\n  COMMAND\n    ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../tools/libsize.py\n    $<TARGET_FILE:pybind11_tests>\n    ${CMAKE_CURRENT_BINARY_DIR}/sosize-$<TARGET_FILE_NAME:pybind11_tests>.txt)\n\nif(NOT PYBIND11_CUDA_TESTS)\n  # Test embedding the interpreter. Provides the `cpptest` target.\n  add_subdirectory(test_embed)\n\n  # Test CMake build using functions and targets from subdirectory or installed location\n  add_subdirectory(test_cmake_build)\nendif()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/catch/catch.hpp",
    "content": "/*\n *  Catch v2.13.9\n *  Generated: 2022-04-12 22:37:23.260201\n *  ----------------------------------------------------------\n *  This file has been merged from multiple headers. Please don't edit it directly\n *  Copyright (c) 2022 Two Blue Cubes Ltd. All rights reserved.\n *\n *  Distributed under the Boost Software License, Version 1.0. (See accompanying\n *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n */\n#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n// start catch.hpp\n\n\n#define CATCH_VERSION_MAJOR 2\n#define CATCH_VERSION_MINOR 13\n#define CATCH_VERSION_PATCH 9\n\n#ifdef __clang__\n#    pragma clang system_header\n#elif defined __GNUC__\n#    pragma GCC system_header\n#endif\n\n// start catch_suppress_warnings.h\n\n#ifdef __clang__\n#   ifdef __ICC // icpc defines the __clang__ macro\n#       pragma warning(push)\n#       pragma warning(disable: 161 1682)\n#   else // __ICC\n#       pragma clang diagnostic push\n#       pragma clang diagnostic ignored \"-Wpadded\"\n#       pragma clang diagnostic ignored \"-Wswitch-enum\"\n#       pragma clang diagnostic ignored \"-Wcovered-switch-default\"\n#    endif\n#elif defined __GNUC__\n     // Because REQUIREs trigger GCC's -Wparentheses, and because still\n     // supported version of g++ have only buggy support for _Pragmas,\n     // Wparentheses have to be suppressed globally.\n#    pragma GCC diagnostic ignored \"-Wparentheses\" // See #674 for details\n\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wunused-variable\"\n#    pragma GCC diagnostic ignored \"-Wpadded\"\n#endif\n// end catch_suppress_warnings.h\n#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER)\n#  define CATCH_IMPL\n#  define CATCH_CONFIG_ALL_PARTS\n#endif\n\n// In the impl file, we want to have access to all parts of the headers\n// Can also be used to sanely support PCHs\n#if defined(CATCH_CONFIG_ALL_PARTS)\n#  define CATCH_CONFIG_EXTERNAL_INTERFACES\n#  if defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#    undef CATCH_CONFIG_DISABLE_MATCHERS\n#  endif\n#  if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#    define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  endif\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n// start catch_platform.h\n\n// See e.g.:\n// https://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/TargetConditionals.h.auto.html\n#ifdef __APPLE__\n#  include <TargetConditionals.h>\n#  if (defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1) || \\\n      (defined(TARGET_OS_MAC) && TARGET_OS_MAC == 1)\n#    define CATCH_PLATFORM_MAC\n#  elif (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE == 1)\n#    define CATCH_PLATFORM_IPHONE\n#  endif\n\n#elif defined(linux) || defined(__linux) || defined(__linux__)\n#  define CATCH_PLATFORM_LINUX\n\n#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__)\n#  define CATCH_PLATFORM_WINDOWS\n#endif\n\n// end catch_platform.h\n\n#ifdef CATCH_IMPL\n#  ifndef CLARA_CONFIG_MAIN\n#    define CLARA_CONFIG_MAIN_NOT_DEFINED\n#    define CLARA_CONFIG_MAIN\n#  endif\n#endif\n\n// start catch_user_interfaces.h\n\nnamespace Catch {\n    unsigned int rngSeed();\n}\n\n// end catch_user_interfaces.h\n// start catch_tag_alias_autoregistrar.h\n\n// start catch_common.h\n\n// start catch_compiler_capabilities.h\n\n// Detect a number of compiler features - by compiler\n// The following features are defined:\n//\n// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported?\n// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported?\n// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported?\n// CATCH_CONFIG_DISABLE_EXCEPTIONS : Are exceptions enabled?\n// ****************\n// Note to maintainers: if new toggles are added please document them\n// in configuration.md, too\n// ****************\n\n// In general each macro has a _NO_<feature name> form\n// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature.\n// Many features, at point of detection, define an _INTERNAL_ macro, so they\n// can be combined, en-mass, with the _NO_ forms later.\n\n#ifdef __cplusplus\n\n#  if (__cplusplus >= 201402L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)\n#    define CATCH_CPP14_OR_GREATER\n#  endif\n\n#  if (__cplusplus >= 201703L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)\n#    define CATCH_CPP17_OR_GREATER\n#  endif\n\n#endif\n\n// Only GCC compiler should be used in this block, so other compilers trying to\n// mask themselves as GCC should be ignored.\n#if defined(__GNUC__) && !defined(__clang__) && !defined(__ICC) && !defined(__CUDACC__) && !defined(__LCC__)\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"GCC diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"GCC diagnostic pop\" )\n\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__)\n\n#endif\n\n#if defined(__clang__)\n\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION _Pragma( \"clang diagnostic push\" )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  _Pragma( \"clang diagnostic pop\" )\n\n// As of this writing, IBM XL's implementation of __builtin_constant_p has a bug\n// which results in calls to destructors being emitted for each temporary,\n// without a matching initialization. In practice, this can result in something\n// like `std::string::~string` being called on an uninitialized value.\n//\n// For example, this code will likely segfault under IBM XL:\n// ```\n// REQUIRE(std::string(\"12\") + \"34\" == \"1234\")\n// ```\n//\n// Therefore, `CATCH_INTERNAL_IGNORE_BUT_WARN` is not implemented.\n#  if !defined(__ibmxl__) && !defined(__CUDACC__)\n#    define CATCH_INTERNAL_IGNORE_BUT_WARN(...) (void)__builtin_constant_p(__VA_ARGS__) /* NOLINT(cppcoreguidelines-pro-type-vararg, hicpp-vararg) */\n#  endif\n\n#    define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wexit-time-destructors\\\"\" ) \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wglobal-constructors\\\"\")\n\n#    define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wparentheses\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-variable\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wgnu-zero-variadic-macro-arguments\\\"\" )\n\n#    define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n         _Pragma( \"clang diagnostic ignored \\\"-Wunused-template\\\"\" )\n\n#endif // __clang__\n\n////////////////////////////////////////////////////////////////////////////////\n// Assume that non-Windows platforms support posix signals by default\n#if !defined(CATCH_PLATFORM_WINDOWS)\n    #define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// We know some environments not to support full POSIX signals\n#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__)\n    #define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#endif\n\n#ifdef __OS400__\n#       define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS\n#       define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Android somehow still does not support std::to_string\n#if defined(__ANDROID__)\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n#    define CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Not all Windows environments support SEH properly\n#if defined(__MINGW32__)\n#    define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// PS4\n#if defined(__ORBIS__)\n#    define CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// Cygwin\n#ifdef __CYGWIN__\n\n// Required for some versions of Cygwin to declare gettimeofday\n// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin\n#   define _BSD_SOURCE\n// some versions of cygwin (most) do not support std::to_string. Use the libstd check.\n// https://gcc.gnu.org/onlinedocs/gcc-4.8.2/libstdc++/api/a01053_source.html line 2812-2813\n# if !((__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99) \\\n           && !defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))\n\n#    define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING\n\n# endif\n#endif // __CYGWIN__\n\n////////////////////////////////////////////////////////////////////////////////\n// Visual C++\n#if defined(_MSC_VER)\n\n// Universal Windows platform does not support SEH\n// Or console colours (or console at all...)\n#  if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)\n#    define CATCH_CONFIG_COLOUR_NONE\n#  else\n#    define CATCH_INTERNAL_CONFIG_WINDOWS_SEH\n#  endif\n\n#  if !defined(__clang__) // Handle Clang masquerading for msvc\n\n// MSVC traditional preprocessor needs some workaround for __VA_ARGS__\n// _MSVC_TRADITIONAL == 0 means new conformant preprocessor\n// _MSVC_TRADITIONAL == 1 means old traditional non-conformant preprocessor\n#    if !defined(_MSVC_TRADITIONAL) || (defined(_MSVC_TRADITIONAL) && _MSVC_TRADITIONAL)\n#      define CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#    endif // MSVC_TRADITIONAL\n\n// Only do this if we're not using clang on Windows, which uses `diagnostic push` & `diagnostic pop`\n#    define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION __pragma( warning(push) )\n#    define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION  __pragma( warning(pop) )\n#  endif // __clang__\n\n#endif // _MSC_VER\n\n#if defined(_REENTRANT) || defined(_MSC_VER)\n// Enable async processing, as -pthread is specified or no additional linking is required\n# define CATCH_INTERNAL_CONFIG_USE_ASYNC\n#endif // _MSC_VER\n\n////////////////////////////////////////////////////////////////////////////////\n// Check if we are compiled with -fno-exceptions or equivalent\n#if defined(__EXCEPTIONS) || defined(__cpp_exceptions) || defined(_CPPUNWIND)\n#  define CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n// DJGPP\n#ifdef __DJGPP__\n#  define CATCH_INTERNAL_CONFIG_NO_WCHAR\n#endif // __DJGPP__\n\n////////////////////////////////////////////////////////////////////////////////\n// Embarcadero C++Build\n#if defined(__BORLANDC__)\n    #define CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// Use of __COUNTER__ is suppressed during code analysis in\n// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly\n// handled by it.\n// Otherwise all supported compilers support COUNTER macro,\n// but user still might want to turn it off\n#if ( !defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L )\n    #define CATCH_INTERNAL_CONFIG_COUNTER\n#endif\n\n////////////////////////////////////////////////////////////////////////////////\n\n// RTX is a special version of Windows that is real time.\n// This means that it is detected as Windows, but does not provide\n// the same set of capabilities as real Windows does.\n#if defined(UNDER_RTSS) || defined(RTX64_BUILD)\n    #define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH\n    #define CATCH_INTERNAL_CONFIG_NO_ASYNC\n    #define CATCH_CONFIG_COLOUR_NONE\n#endif\n\n#if !defined(_GLIBCXX_USE_C99_MATH_TR1)\n#define CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Various stdlib support checks that require __has_include\n#if defined(__has_include)\n  // Check if string_view is available and usable\n  #if __has_include(<string_view>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW\n  #endif\n\n  // Check if optional is available and usable\n  #  if __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n  #    define CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL\n  #  endif // __has_include(<optional>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if byte is available and usable\n  #  if __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n  #    include <cstddef>\n  #    if defined(__cpp_lib_byte) && (__cpp_lib_byte > 0)\n  #      define CATCH_INTERNAL_CONFIG_CPP17_BYTE\n  #    endif\n  #  endif // __has_include(<cstddef>) && defined(CATCH_CPP17_OR_GREATER)\n\n  // Check if variant is available and usable\n  #  if __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n  #    if defined(__clang__) && (__clang_major__ < 8)\n         // work around clang bug with libstdc++ https://bugs.llvm.org/show_bug.cgi?id=31852\n         // fix should be in clang 8, workaround in libstdc++ 8.2\n  #      include <ciso646>\n  #      if defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #        define CATCH_CONFIG_NO_CPP17_VARIANT\n  #      else\n  #        define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #      endif // defined(__GLIBCXX__) && defined(_GLIBCXX_RELEASE) && (_GLIBCXX_RELEASE < 9)\n  #    else\n  #      define CATCH_INTERNAL_CONFIG_CPP17_VARIANT\n  #    endif // defined(__clang__) && (__clang_major__ < 8)\n  #  endif // __has_include(<variant>) && defined(CATCH_CPP17_OR_GREATER)\n#endif // defined(__has_include)\n\n#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)\n#   define CATCH_CONFIG_COUNTER\n#endif\n#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH)\n#   define CATCH_CONFIG_WINDOWS_SEH\n#endif\n// This is set by default, because we assume that unix compilers are posix-signal-compatible by default.\n#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS)\n#   define CATCH_CONFIG_POSIX_SIGNALS\n#endif\n// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions.\n#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR)\n#   define CATCH_CONFIG_WCHAR\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_CPP11_TO_STRING)\n#    define CATCH_CONFIG_CPP11_TO_STRING\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_NO_CPP17_OPTIONAL) && !defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#  define CATCH_CONFIG_CPP17_OPTIONAL\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_NO_CPP17_STRING_VIEW) && !defined(CATCH_CONFIG_CPP17_STRING_VIEW)\n#  define CATCH_CONFIG_CPP17_STRING_VIEW\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_VARIANT) && !defined(CATCH_CONFIG_NO_CPP17_VARIANT) && !defined(CATCH_CONFIG_CPP17_VARIANT)\n#  define CATCH_CONFIG_CPP17_VARIANT\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_BYTE) && !defined(CATCH_CONFIG_NO_CPP17_BYTE) && !defined(CATCH_CONFIG_CPP17_BYTE)\n#  define CATCH_CONFIG_CPP17_BYTE\n#endif\n\n#if defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n#  define CATCH_INTERNAL_CONFIG_NEW_CAPTURE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_NEW_CAPTURE) && !defined(CATCH_INTERNAL_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NO_NEW_CAPTURE) && !defined(CATCH_CONFIG_NEW_CAPTURE)\n#  define CATCH_CONFIG_NEW_CAPTURE\n#endif\n\n#if !defined(CATCH_INTERNAL_CONFIG_EXCEPTIONS_ENABLED) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#  define CATCH_CONFIG_DISABLE_EXCEPTIONS\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_NO_POLYFILL_ISNAN) && !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n#  define CATCH_CONFIG_POLYFILL_ISNAN\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_USE_ASYNC)  && !defined(CATCH_INTERNAL_CONFIG_NO_ASYNC) && !defined(CATCH_CONFIG_NO_USE_ASYNC) && !defined(CATCH_CONFIG_USE_ASYNC)\n#  define CATCH_CONFIG_USE_ASYNC\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_NO_ANDROID_LOGWRITE) && !defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#  define CATCH_CONFIG_ANDROID_LOGWRITE\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_NO_GLOBAL_NEXTAFTER) && !defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n#  define CATCH_CONFIG_GLOBAL_NEXTAFTER\n#endif\n\n// Even if we do not think the compiler has that warning, we still have\n// to provide a macro that can be used by the code.\n#if !defined(CATCH_INTERNAL_START_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION)\n#   define CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS\n#endif\n#if !defined(CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS\n#endif\n\n// The goal of this macro is to avoid evaluation of the arguments, but\n// still have the compiler warn on problems inside...\n#if !defined(CATCH_INTERNAL_IGNORE_BUT_WARN)\n#   define CATCH_INTERNAL_IGNORE_BUT_WARN(...)\n#endif\n\n#if defined(__APPLE__) && defined(__apple_build_version__) && (__clang_major__ < 10)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#elif defined(__clang__) && (__clang_major__ < 5)\n#   undef CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if !defined(CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS)\n#   define CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS\n#endif\n\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n#define CATCH_TRY if ((true))\n#define CATCH_CATCH_ALL if ((false))\n#define CATCH_CATCH_ANON(type) if ((false))\n#else\n#define CATCH_TRY try\n#define CATCH_CATCH_ALL catch (...)\n#define CATCH_CATCH_ANON(type) catch (type)\n#endif\n\n#if defined(CATCH_INTERNAL_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_NO_TRADITIONAL_MSVC_PREPROCESSOR) && !defined(CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR)\n#define CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#endif\n\n// end catch_compiler_capabilities.h\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line\n#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line )\n#ifdef CATCH_CONFIG_COUNTER\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __COUNTER__ )\n#else\n#  define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ )\n#endif\n\n#include <iosfwd>\n#include <string>\n#include <cstdint>\n\n// We need a dummy global operator<< so we can bring it into Catch namespace later\nstruct Catch_global_namespace_dummy {};\nstd::ostream& operator<<(std::ostream&, Catch_global_namespace_dummy);\n\nnamespace Catch {\n\n    struct CaseSensitive { enum Choice {\n        Yes,\n        No\n    }; };\n\n    class NonCopyable {\n        NonCopyable( NonCopyable const& )              = delete;\n        NonCopyable( NonCopyable && )                  = delete;\n        NonCopyable& operator = ( NonCopyable const& ) = delete;\n        NonCopyable& operator = ( NonCopyable && )     = delete;\n\n    protected:\n        NonCopyable();\n        virtual ~NonCopyable();\n    };\n\n    struct SourceLineInfo {\n\n        SourceLineInfo() = delete;\n        SourceLineInfo( char const* _file, std::size_t _line ) noexcept\n        :   file( _file ),\n            line( _line )\n        {}\n\n        SourceLineInfo( SourceLineInfo const& other )            = default;\n        SourceLineInfo& operator = ( SourceLineInfo const& )     = default;\n        SourceLineInfo( SourceLineInfo&& )              noexcept = default;\n        SourceLineInfo& operator = ( SourceLineInfo&& ) noexcept = default;\n\n        bool empty() const noexcept { return file[0] == '\\0'; }\n        bool operator == ( SourceLineInfo const& other ) const noexcept;\n        bool operator < ( SourceLineInfo const& other ) const noexcept;\n\n        char const* file;\n        std::size_t line;\n    };\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info );\n\n    // Bring in operator<< from global namespace into Catch namespace\n    // This is necessary because the overload of operator<< above makes\n    // lookup stop at namespace Catch\n    using ::operator<<;\n\n    // Use this in variadic streaming macros to allow\n    //    >> +StreamEndStop\n    // as well as\n    //    >> stuff +StreamEndStop\n    struct StreamEndStop {\n        std::string operator+() const;\n    };\n    template<typename T>\n    T const& operator + ( T const& value, StreamEndStop ) {\n        return value;\n    }\n}\n\n#define CATCH_INTERNAL_LINEINFO \\\n    ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) )\n\n// end catch_common.h\nnamespace Catch {\n\n    struct RegistrarForTagAliases {\n        RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo );\n    };\n\n} // end namespace Catch\n\n#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_tag_alias_autoregistrar.h\n// start catch_test_registry.h\n\n// start catch_interfaces_testcase.h\n\n#include <vector>\n\nnamespace Catch {\n\n    class TestSpec;\n\n    struct ITestInvoker {\n        virtual void invoke () const = 0;\n        virtual ~ITestInvoker();\n    };\n\n    class TestCase;\n    struct IConfig;\n\n    struct ITestCaseRegistry {\n        virtual ~ITestCaseRegistry();\n        virtual std::vector<TestCase> const& getAllTests() const = 0;\n        virtual std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const = 0;\n    };\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n}\n\n// end catch_interfaces_testcase.h\n// start catch_stringref.h\n\n#include <cstddef>\n#include <string>\n#include <iosfwd>\n#include <cassert>\n\nnamespace Catch {\n\n    /// A non-owning string class (similar to the forthcoming std::string_view)\n    /// Note that, because a StringRef may be a substring of another string,\n    /// it may not be null terminated.\n    class StringRef {\n    public:\n        using size_type = std::size_t;\n        using const_iterator = const char*;\n\n    private:\n        static constexpr char const* const s_empty = \"\";\n\n        char const* m_start = s_empty;\n        size_type m_size = 0;\n\n    public: // construction\n        constexpr StringRef() noexcept = default;\n\n        StringRef( char const* rawChars ) noexcept;\n\n        constexpr StringRef( char const* rawChars, size_type size ) noexcept\n        :   m_start( rawChars ),\n            m_size( size )\n        {}\n\n        StringRef( std::string const& stdString ) noexcept\n        :   m_start( stdString.c_str() ),\n            m_size( stdString.size() )\n        {}\n\n        explicit operator std::string() const {\n            return std::string(m_start, m_size);\n        }\n\n    public: // operators\n        auto operator == ( StringRef const& other ) const noexcept -> bool;\n        auto operator != (StringRef const& other) const noexcept -> bool {\n            return !(*this == other);\n        }\n\n        auto operator[] ( size_type index ) const noexcept -> char {\n            assert(index < m_size);\n            return m_start[index];\n        }\n\n    public: // named queries\n        constexpr auto empty() const noexcept -> bool {\n            return m_size == 0;\n        }\n        constexpr auto size() const noexcept -> size_type {\n            return m_size;\n        }\n\n        // Returns the current start pointer. If the StringRef is not\n        // null-terminated, throws std::domain_exception\n        auto c_str() const -> char const*;\n\n    public: // substrings and searches\n        // Returns a substring of [start, start + length).\n        // If start + length > size(), then the substring is [start, size()).\n        // If start > size(), then the substring is empty.\n        auto substr( size_type start, size_type length ) const noexcept -> StringRef;\n\n        // Returns the current start pointer. May not be null-terminated.\n        auto data() const noexcept -> char const*;\n\n        constexpr auto isNullTerminated() const noexcept -> bool {\n            return m_start[m_size] == '\\0';\n        }\n\n    public: // iterators\n        constexpr const_iterator begin() const { return m_start; }\n        constexpr const_iterator end() const { return m_start + m_size; }\n    };\n\n    auto operator += ( std::string& lhs, StringRef const& sr ) -> std::string&;\n    auto operator << ( std::ostream& os, StringRef const& sr ) -> std::ostream&;\n\n    constexpr auto operator \"\" _sr( char const* rawChars, std::size_t size ) noexcept -> StringRef {\n        return StringRef( rawChars, size );\n    }\n} // namespace Catch\n\nconstexpr auto operator \"\" _catch_sr( char const* rawChars, std::size_t size ) noexcept -> Catch::StringRef {\n    return Catch::StringRef( rawChars, size );\n}\n\n// end catch_stringref.h\n// start catch_preprocessor.hpp\n\n\n#define CATCH_RECURSION_LEVEL0(...) __VA_ARGS__\n#define CATCH_RECURSION_LEVEL1(...) CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(CATCH_RECURSION_LEVEL0(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL2(...) CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(CATCH_RECURSION_LEVEL1(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL3(...) CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(CATCH_RECURSION_LEVEL2(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL4(...) CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(CATCH_RECURSION_LEVEL3(__VA_ARGS__)))\n#define CATCH_RECURSION_LEVEL5(...) CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(CATCH_RECURSION_LEVEL4(__VA_ARGS__)))\n\n#ifdef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_EXPAND_VARGS(...) __VA_ARGS__\n// MSVC needs more evaluations\n#define CATCH_RECURSION_LEVEL6(...) CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(CATCH_RECURSION_LEVEL5(__VA_ARGS__)))\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL6(CATCH_RECURSION_LEVEL6(__VA_ARGS__))\n#else\n#define CATCH_RECURSE(...)  CATCH_RECURSION_LEVEL5(__VA_ARGS__)\n#endif\n\n#define CATCH_REC_END(...)\n#define CATCH_REC_OUT\n\n#define CATCH_EMPTY()\n#define CATCH_DEFER(id) id CATCH_EMPTY()\n\n#define CATCH_REC_GET_END2() 0, CATCH_REC_END\n#define CATCH_REC_GET_END1(...) CATCH_REC_GET_END2\n#define CATCH_REC_GET_END(...) CATCH_REC_GET_END1\n#define CATCH_REC_NEXT0(test, next, ...) next CATCH_REC_OUT\n#define CATCH_REC_NEXT1(test, next) CATCH_DEFER ( CATCH_REC_NEXT0 ) ( test, next, 0)\n#define CATCH_REC_NEXT(test, next)  CATCH_REC_NEXT1(CATCH_REC_GET_END test, next)\n\n#define CATCH_REC_LIST0(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1(f, x, peek, ...) , f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0) ) ( f, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2(f, x, peek, ...)   f(x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1) ) ( f, peek, __VA_ARGS__ )\n\n#define CATCH_REC_LIST0_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST1_UD(f, userdata, x, peek, ...) , f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST0_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n#define CATCH_REC_LIST2_UD(f, userdata, x, peek, ...)   f(userdata, x) CATCH_DEFER ( CATCH_REC_NEXT(peek, CATCH_REC_LIST1_UD) ) ( f, userdata, peek, __VA_ARGS__ )\n\n// Applies the function macro `f` to each of the remaining parameters, inserts commas between the results,\n// and passes userdata as the first parameter to each invocation,\n// e.g. CATCH_REC_LIST_UD(f, x, a, b, c) evaluates to f(x, a), f(x, b), f(x, c)\n#define CATCH_REC_LIST_UD(f, userdata, ...) CATCH_RECURSE(CATCH_REC_LIST2_UD(f, userdata, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define CATCH_REC_LIST(f, ...) CATCH_RECURSE(CATCH_REC_LIST2(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0))\n\n#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param)\n#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO## __VA_ARGS__\n#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__\n#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE(...) INTERNAL_CATCH_STRINGIZE2(__VA_ARGS__)\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_STRINGIZE2(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param))\n#else\n// MSVC is adding extra space and needs another indirection to expand INTERNAL_CATCH_NOINTERNAL_CATCH_DEF\n#define INTERNAL_CATCH_STRINGIZE2(...) INTERNAL_CATCH_STRINGIZE3(__VA_ARGS__)\n#define INTERNAL_CATCH_STRINGIZE3(...) #__VA_ARGS__\n#define INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS(param) (INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_REMOVE_PARENS(param)) + 1)\n#endif\n\n#define INTERNAL_CATCH_MAKE_NAMESPACE2(...) ns_##__VA_ARGS__\n#define INTERNAL_CATCH_MAKE_NAMESPACE(name) INTERNAL_CATCH_MAKE_NAMESPACE2(name)\n\n#define INTERNAL_CATCH_REMOVE_PARENS(...) INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF __VA_ARGS__)\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>())\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__))\n#else\n#define INTERNAL_CATCH_MAKE_TYPE_LIST2(...) INTERNAL_CATCH_EXPAND_VARGS(decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS_GEN(__VA_ARGS__)>()))\n#define INTERNAL_CATCH_MAKE_TYPE_LIST(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_MAKE_TYPE_LIST2(INTERNAL_CATCH_REMOVE_PARENS(__VA_ARGS__)))\n#endif\n\n#define INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(...)\\\n    CATCH_REC_LIST(INTERNAL_CATCH_MAKE_TYPE_LIST,__VA_ARGS__)\n\n#define INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_0) INTERNAL_CATCH_REMOVE_PARENS(_0)\n#define INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_0, _1) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_1_ARG(_1)\n#define INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_0, _1, _2) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_2_ARG(_1, _2)\n#define INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_0, _1, _2, _3) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_3_ARG(_1, _2, _3)\n#define INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_0, _1, _2, _3, _4) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_4_ARG(_1, _2, _3, _4)\n#define INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_0, _1, _2, _3, _4, _5) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_5_ARG(_1, _2, _3, _4, _5)\n#define INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_0, _1, _2, _3, _4, _5, _6) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_6_ARG(_1, _2, _3, _4, _5, _6)\n#define INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_0, _1, _2, _3, _4, _5, _6, _7) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_7_ARG(_1, _2, _3, _4, _5, _6, _7)\n#define INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_8_ARG(_1, _2, _3, _4, _5, _6, _7, _8)\n#define INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_9_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9)\n#define INTERNAL_CATCH_REMOVE_PARENS_11_ARG(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) INTERNAL_CATCH_REMOVE_PARENS(_0), INTERNAL_CATCH_REMOVE_PARENS_10_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10)\n\n#define INTERNAL_CATCH_VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N\n\n#define INTERNAL_CATCH_TYPE_GEN\\\n    template<typename...> struct TypeList {};\\\n    template<typename...Ts>\\\n    constexpr auto get_wrapper() noexcept -> TypeList<Ts...> { return {}; }\\\n    template<template<typename...> class...> struct TemplateTypeList{};\\\n    template<template<typename...> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> TemplateTypeList<Cs...> { return {}; }\\\n    template<typename...>\\\n    struct append;\\\n    template<typename...>\\\n    struct rewrap;\\\n    template<template<typename...> class, typename...>\\\n    struct create;\\\n    template<template<typename...> class, typename>\\\n    struct convert;\\\n    \\\n    template<typename T> \\\n    struct append<T> { using type = T; };\\\n    template< template<typename...> class L1, typename...E1, template<typename...> class L2, typename...E2, typename...Rest>\\\n    struct append<L1<E1...>, L2<E2...>, Rest...> { using type = typename append<L1<E1...,E2...>, Rest...>::type; };\\\n    template< template<typename...> class L1, typename...E1, typename...Rest>\\\n    struct append<L1<E1...>, TypeList<mpl_::na>, Rest...> { using type = L1<E1...>; };\\\n    \\\n    template< template<typename...> class Container, template<typename...> class List, typename...elems>\\\n    struct rewrap<TemplateTypeList<Container>, List<elems...>> { using type = TypeList<Container<elems...>>; };\\\n    template< template<typename...> class Container, template<typename...> class List, class...Elems, typename...Elements>\\\n    struct rewrap<TemplateTypeList<Container>, List<Elems...>, Elements...> { using type = typename append<TypeList<Container<Elems...>>, typename rewrap<TemplateTypeList<Container>, Elements...>::type>::type; };\\\n    \\\n    template<template <typename...> class Final, template< typename...> class...Containers, typename...Types>\\\n    struct create<Final, TemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<TemplateTypeList<Containers>, Types...>::type...>::type; };\\\n    template<template <typename...> class Final, template <typename...> class List, typename...Ts>\\\n    struct convert<Final, List<Ts...>> { using type = typename append<Final<>,TypeList<Ts>...>::type; };\n\n#define INTERNAL_CATCH_NTTP_1(signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> struct Nttp{};\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    constexpr auto get_wrapper() noexcept -> Nttp<__VA_ARGS__> { return {}; } \\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...> struct NttpTemplateTypeList{};\\\n    template<template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Cs>\\\n    constexpr auto get_wrapper() noexcept -> NttpTemplateTypeList<Cs...> { return {}; } \\\n    \\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>> { using type = TypeList<Container<__VA_ARGS__>>; };\\\n    template< template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class Container, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class List, INTERNAL_CATCH_REMOVE_PARENS(signature), typename...Elements>\\\n    struct rewrap<NttpTemplateTypeList<Container>, List<__VA_ARGS__>, Elements...> { using type = typename append<TypeList<Container<__VA_ARGS__>>, typename rewrap<NttpTemplateTypeList<Container>, Elements...>::type>::type; };\\\n    template<template <typename...> class Final, template<INTERNAL_CATCH_REMOVE_PARENS(signature)> class...Containers, typename...Types>\\\n    struct create<Final, NttpTemplateTypeList<Containers...>, TypeList<Types...>> { using type = typename append<Final<>, typename rewrap<NttpTemplateTypeList<Containers>, Types...>::type...>::type; };\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST1(TestName, signature)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_X(TestName, signature,...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    static void TestName()\n\n#define INTERNAL_CATCH_NTTP_REGISTER0(TestFunc, signature)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<Type>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER(TestFunc, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestFunc<__VA_ARGS__>), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD0(TestName, signature, ...)\\\n    template<typename Type>\\\n    void reg_test(TypeList<Type>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<Type>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_NTTP_REGISTER_METHOD(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)>\\\n    void reg_test(Nttp<__VA_ARGS__>, Catch::StringRef className, Catch::NameAndTags nameAndTags)\\\n    {\\\n        Catch::AutoReg( Catch::makeTestInvoker(&TestName<__VA_ARGS__>::test), CATCH_INTERNAL_LINEINFO, className, nameAndTags);\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0(TestName, ClassName)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1(TestName, ClassName, signature)\\\n    template<typename TestType> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<TestType> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X(TestName, ClassName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName)<__VA_ARGS__> { \\\n        void test();\\\n    }\n\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0(TestName)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1(TestName, signature)\\\n    template<typename TestType> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<TestType>::test()\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X(TestName, signature, ...)\\\n    template<INTERNAL_CATCH_REMOVE_PARENS(signature)> \\\n    void INTERNAL_CATCH_MAKE_NAMESPACE(TestName)::TestName<__VA_ARGS__>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define INTERNAL_CATCH_NTTP_0\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1(__VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_1( __VA_ARGS__),INTERNAL_CATCH_NTTP_1( __VA_ARGS__), INTERNAL_CATCH_NTTP_0)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__)\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__)\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__)\n#else\n#define INTERNAL_CATCH_NTTP_0(signature)\n#define INTERNAL_CATCH_NTTP_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_1,INTERNAL_CATCH_NTTP_1, INTERNAL_CATCH_NTTP_0)( __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD1, INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X,INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD_X, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD1, INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD0)(TestName, ClassName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD, INTERNAL_CATCH_NTTP_REGISTER_METHOD0, INTERNAL_CATCH_NTTP_REGISTER_METHOD0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_NTTP_REG_GEN(TestFunc, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER, INTERNAL_CATCH_NTTP_REGISTER0, INTERNAL_CATCH_NTTP_REGISTER0)(TestFunc, __VA_ARGS__))\n#define INTERNAL_CATCH_DEFINE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DEFINE_SIG_TEST1, INTERNAL_CATCH_DEFINE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_DECLARE_SIG_TEST(TestName, ...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL( \"dummy\", __VA_ARGS__, INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DEFINE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X,INTERNAL_CATCH_DECLARE_SIG_TEST_X, INTERNAL_CATCH_DECLARE_SIG_TEST1, INTERNAL_CATCH_DECLARE_SIG_TEST0)(TestName, __VA_ARGS__))\n#define INTERNAL_CATCH_REMOVE_PARENS_GEN(...) INTERNAL_CATCH_EXPAND_VARGS(INTERNAL_CATCH_VA_NARGS_IMPL(__VA_ARGS__, INTERNAL_CATCH_REMOVE_PARENS_11_ARG,INTERNAL_CATCH_REMOVE_PARENS_10_ARG,INTERNAL_CATCH_REMOVE_PARENS_9_ARG,INTERNAL_CATCH_REMOVE_PARENS_8_ARG,INTERNAL_CATCH_REMOVE_PARENS_7_ARG,INTERNAL_CATCH_REMOVE_PARENS_6_ARG,INTERNAL_CATCH_REMOVE_PARENS_5_ARG,INTERNAL_CATCH_REMOVE_PARENS_4_ARG,INTERNAL_CATCH_REMOVE_PARENS_3_ARG,INTERNAL_CATCH_REMOVE_PARENS_2_ARG,INTERNAL_CATCH_REMOVE_PARENS_1_ARG)(__VA_ARGS__))\n#endif\n\n// end catch_preprocessor.hpp\n// start catch_meta.hpp\n\n\n#include <type_traits>\n\nnamespace Catch {\n    template<typename T>\n    struct always_false : std::false_type {};\n\n    template <typename> struct true_given : std::true_type {};\n    struct is_callable_tester {\n        template <typename Fun, typename... Args>\n        true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int);\n        template <typename...>\n        std::false_type static test(...);\n    };\n\n    template <typename T>\n    struct is_callable;\n\n    template <typename Fun, typename... Args>\n    struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {};\n\n#if defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703\n    // std::result_of is deprecated in C++17 and removed in C++20. Hence, it is\n    // replaced with std::invoke_result here.\n    template <typename Func, typename... U>\n    using FunctionReturnType = std::remove_reference_t<std::remove_cv_t<std::invoke_result_t<Func, U...>>>;\n#else\n    // Keep ::type here because we still support C++11\n    template <typename Func, typename... U>\n    using FunctionReturnType = typename std::remove_reference<typename std::remove_cv<typename std::result_of<Func(U...)>::type>::type>::type;\n#endif\n\n} // namespace Catch\n\nnamespace mpl_{\n    struct na;\n}\n\n// end catch_meta.hpp\nnamespace Catch {\n\ntemplate<typename C>\nclass TestInvokerAsMethod : public ITestInvoker {\n    void (C::*m_testAsMethod)();\npublic:\n    TestInvokerAsMethod( void (C::*testAsMethod)() ) noexcept : m_testAsMethod( testAsMethod ) {}\n\n    void invoke() const override {\n        C obj;\n        (obj.*m_testAsMethod)();\n    }\n};\n\nauto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker*;\n\ntemplate<typename C>\nauto makeTestInvoker( void (C::*testAsMethod)() ) noexcept -> ITestInvoker* {\n    return new(std::nothrow) TestInvokerAsMethod<C>( testAsMethod );\n}\n\nstruct NameAndTags {\n    NameAndTags( StringRef const& name_ = StringRef(), StringRef const& tags_ = StringRef() ) noexcept;\n    StringRef name;\n    StringRef tags;\n};\n\nstruct AutoReg : NonCopyable {\n    AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept;\n    ~AutoReg();\n};\n\n} // end namespace Catch\n\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION( TestName, ... ) \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION( TestName, ClassName, ... ) \\\n        namespace{                        \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test();              \\\n            };                            \\\n        }                                 \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( TestName, TestFunc, Name, Tags, Signature, ... )  \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... )    \\\n        namespace{                                                                                  \\\n            namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                      \\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        }                                                                                           \\\n        }                                                                                           \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(Name, Tags, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(Name, Tags, Signature, ...) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION( ClassName, Name, Tags,... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n    #endif\n\n    #ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n    #else\n        #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION( ClassName, Name, Tags, Signature, ... ) \\\n            INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n    #endif\n#endif\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TESTCASE2( TestName, ... ) \\\n        static void TestName(); \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &TestName ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        static void TestName()\n    #define INTERNAL_CATCH_TESTCASE( ... ) \\\n        INTERNAL_CATCH_TESTCASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( &QualifiedMethod ), CATCH_INTERNAL_LINEINFO, \"&\" #QualifiedMethod, Catch::NameAndTags{ __VA_ARGS__ } ); } /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEST_CASE_METHOD2( TestName, ClassName, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        namespace{ \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName) { \\\n                void test(); \\\n            }; \\\n            Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( Catch::makeTestInvoker( &TestName::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        } \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        void TestName::test()\n    #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... ) \\\n        INTERNAL_CATCH_TEST_CASE_METHOD2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), ClassName, __VA_ARGS__ )\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_REGISTER_TESTCASE( Function, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( Catch::makeTestInvoker( Function ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ __VA_ARGS__ } ); /* NOLINT */ \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n    ///////////////////////////////////////////////////////////////////////////////\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_2(TestName, TestFunc, Name, Tags, Signature, ... )\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        INTERNAL_CATCH_DECLARE_SIG_TEST(TestFunc, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_NTTP_REG_GEN(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestName{\\\n                TestName(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n            TestName<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n            return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST(TestFunc,INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE(Name, Tags, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename TestType, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG(Name, Tags, Signature, ...) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(TestName, TestFuncName, Name, Tags, Signature, TmplTypes, TypesList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION                      \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS                      \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS                \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS              \\\n        template<typename TestType> static void TestFuncName();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName) {                                     \\\n            INTERNAL_CATCH_TYPE_GEN                                                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))         \\\n            template<typename... Types>                               \\\n            struct TestName {                                         \\\n                void reg_tests() {                                          \\\n                    int index = 0;                                    \\\n                    using expander = int[];                           \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFuncName<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */\\\n                }                                                     \\\n            };                                                        \\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename create<TestName, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }                                                             \\\n        }                                                             \\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFuncName()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T,__VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE(Name, Tags, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__)\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG(Name, Tags, Signature, ...)\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2(TestName, TestFunc, Name, Tags, TmplList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> static void TestFunc();       \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){\\\n        INTERNAL_CATCH_TYPE_GEN\\\n        template<typename... Types>                               \\\n        struct TestName {                                         \\\n            void reg_tests() {                                          \\\n                int index = 0;                                    \\\n                using expander = int[];                           \\\n                (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestFunc<Types> ), CATCH_INTERNAL_LINEINFO, Catch::StringRef(), Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */\\\n            }                                                     \\\n        };\\\n        static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){ \\\n                using TestInit = typename convert<TestName, TmplList>::type; \\\n                TestInit t;                                           \\\n                t.reg_tests();                                        \\\n                return 0;                                             \\\n            }();                                                      \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION                       \\\n        template<typename TestType>                                   \\\n        static void TestFunc()\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), Name, Tags, TmplList )\n\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, Signature, ... ) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            INTERNAL_CATCH_DECLARE_SIG_TEST_METHOD(TestName, ClassName, INTERNAL_CATCH_REMOVE_PARENS(Signature));\\\n            INTERNAL_CATCH_NTTP_REG_METHOD_GEN(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types> \\\n            struct TestNameClass{\\\n                TestNameClass(){\\\n                    int index = 0;                                    \\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, __VA_ARGS__)};\\\n                    using expander = int[];\\\n                    (void)expander{(reg_test(Types{}, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index]), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                TestNameClass<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(__VA_ARGS__)>();\\\n                return 0;\\\n        }();\\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        INTERNAL_CATCH_DEFINE_SIG_TEST_METHOD(TestName, INTERNAL_CATCH_REMOVE_PARENS(Signature))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( ClassName, Name, Tags,... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, typename T, __VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... ) \\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_C_L_A_S_S_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ) , ClassName, Name, Tags, Signature, __VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2(TestNameClass, TestName, ClassName, Name, Tags, Signature, TmplTypes, TypesList)\\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_ZERO_VARIADIC_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n            struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n                void test();\\\n            };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestNameClass) {\\\n            INTERNAL_CATCH_TYPE_GEN                  \\\n            INTERNAL_CATCH_NTTP_GEN(INTERNAL_CATCH_REMOVE_PARENS(Signature))\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    constexpr char const* tmpl_types[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TmplTypes))};\\\n                    constexpr char const* types_list[] = {CATCH_REC_LIST(INTERNAL_CATCH_STRINGIZE_WITHOUT_PARENS, INTERNAL_CATCH_REMOVE_PARENS(TypesList))};\\\n                    constexpr auto num_types = sizeof(types_list) / sizeof(types_list[0]);\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(tmpl_types[index / num_types]) + \"<\" + std::string(types_list[index % num_types]) + \">\", Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename create<TestNameClass, decltype(get_wrapper<INTERNAL_CATCH_REMOVE_PARENS(TmplTypes)>()), TypeList<INTERNAL_CATCH_MAKE_TYPE_LISTS_FROM_TYPES(INTERNAL_CATCH_REMOVE_PARENS(TypesList))>>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }\\\n        }\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( ClassName, Name, Tags, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, typename T,__VA_ARGS__ ) )\n#endif\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature, __VA_ARGS__ )\n#else\n    #define INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( ClassName, Name, Tags, Signature, ... )\\\n        INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, Signature,__VA_ARGS__ ) )\n#endif\n\n    #define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( TestNameClass, TestName, ClassName, Name, Tags, TmplList) \\\n        CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n        CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n        CATCH_INTERNAL_SUPPRESS_UNUSED_TEMPLATE_WARNINGS \\\n        template<typename TestType> \\\n        struct TestName : INTERNAL_CATCH_REMOVE_PARENS(ClassName <TestType>) { \\\n            void test();\\\n        };\\\n        namespace {\\\n        namespace INTERNAL_CATCH_MAKE_NAMESPACE(TestName){ \\\n            INTERNAL_CATCH_TYPE_GEN\\\n            template<typename...Types>\\\n            struct TestNameClass{\\\n                void reg_tests(){\\\n                    int index = 0;\\\n                    using expander = int[];\\\n                    (void)expander{(Catch::AutoReg( Catch::makeTestInvoker( &TestName<Types>::test ), CATCH_INTERNAL_LINEINFO, #ClassName, Catch::NameAndTags{ Name \" - \" + std::string(INTERNAL_CATCH_STRINGIZE(TmplList)) + \" - \" + std::to_string(index), Tags } ), index++)... };/* NOLINT */ \\\n                }\\\n            };\\\n            static int INTERNAL_CATCH_UNIQUE_NAME( globalRegistrar ) = [](){\\\n                using TestInit = typename convert<TestNameClass, TmplList>::type;\\\n                TestInit t;\\\n                t.reg_tests();\\\n                return 0;\\\n            }(); \\\n        }}\\\n        CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        template<typename TestType> \\\n        void TestName<TestType>::test()\n\n#define INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD(ClassName, Name, Tags, TmplList) \\\n        INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD_2( INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_ ), INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_M_P_L_A_T_E_T_E_S_T_F_U_N_C_ ), ClassName, Name, Tags, TmplList )\n\n// end catch_test_registry.h\n// start catch_capture.hpp\n\n// start catch_assertionhandler.h\n\n// start catch_assertioninfo.h\n\n// start catch_result_type.h\n\nnamespace Catch {\n\n    // ResultWas::OfType enum\n    struct ResultWas { enum OfType {\n        Unknown = -1,\n        Ok = 0,\n        Info = 1,\n        Warning = 2,\n\n        FailureBit = 0x10,\n\n        ExpressionFailed = FailureBit | 1,\n        ExplicitFailure = FailureBit | 2,\n\n        Exception = 0x100 | FailureBit,\n\n        ThrewException = Exception | 1,\n        DidntThrowException = Exception | 2,\n\n        FatalErrorCondition = 0x200 | FailureBit\n\n    }; };\n\n    bool isOk( ResultWas::OfType resultType );\n    bool isJustInfo( int flags );\n\n    // ResultDisposition::Flags enum\n    struct ResultDisposition { enum Flags {\n        Normal = 0x01,\n\n        ContinueOnFailure = 0x02,   // Failures fail test, but execution continues\n        FalseTest = 0x04,           // Prefix expression with !\n        SuppressFail = 0x08         // Failures are reported but do not fail the test\n    }; };\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs );\n\n    bool shouldContinueOnFailure( int flags );\n    inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; }\n    bool shouldSuppressFailure( int flags );\n\n} // end namespace Catch\n\n// end catch_result_type.h\nnamespace Catch {\n\n    struct AssertionInfo\n    {\n        StringRef macroName;\n        SourceLineInfo lineInfo;\n        StringRef capturedExpression;\n        ResultDisposition::Flags resultDisposition;\n\n        // We want to delete this constructor but a compiler bug in 4.8 means\n        // the struct is then treated as non-aggregate\n        //AssertionInfo() = delete;\n    };\n\n} // end namespace Catch\n\n// end catch_assertioninfo.h\n// start catch_decomposer.h\n\n// start catch_tostring.h\n\n#include <vector>\n#include <cstddef>\n#include <type_traits>\n#include <string>\n// start catch_stream.h\n\n#include <iosfwd>\n#include <cstddef>\n#include <ostream>\n\nnamespace Catch {\n\n    std::ostream& cout();\n    std::ostream& cerr();\n    std::ostream& clog();\n\n    class StringRef;\n\n    struct IStream {\n        virtual ~IStream();\n        virtual std::ostream& stream() const = 0;\n    };\n\n    auto makeStream( StringRef const &filename ) -> IStream const*;\n\n    class ReusableStringStream : NonCopyable {\n        std::size_t m_index;\n        std::ostream* m_oss;\n    public:\n        ReusableStringStream();\n        ~ReusableStringStream();\n\n        auto str() const -> std::string;\n\n        template<typename T>\n        auto operator << ( T const& value ) -> ReusableStringStream& {\n            *m_oss << value;\n            return *this;\n        }\n        auto get() -> std::ostream& { return *m_oss; }\n    };\n}\n\n// end catch_stream.h\n// start catch_interfaces_enum_values_registry.h\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace Detail {\n        struct EnumInfo {\n            StringRef m_name;\n            std::vector<std::pair<int, StringRef>> m_values;\n\n            ~EnumInfo();\n\n            StringRef lookup( int value ) const;\n        };\n    } // namespace Detail\n\n    struct IMutableEnumValuesRegistry {\n        virtual ~IMutableEnumValuesRegistry();\n\n        virtual Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values ) = 0;\n\n        template<typename E>\n        Detail::EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::initializer_list<E> values ) {\n            static_assert(sizeof(int) >= sizeof(E), \"Cannot serialize enum to int\");\n            std::vector<int> intValues;\n            intValues.reserve( values.size() );\n            for( auto enumValue : values )\n                intValues.push_back( static_cast<int>( enumValue ) );\n            return registerEnum( enumName, allEnums, intValues );\n        }\n    };\n\n} // Catch\n\n// end catch_interfaces_enum_values_registry.h\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n#include <string_view>\n#endif\n\n#ifdef __OBJC__\n// start catch_objc_arc.hpp\n\n#import <Foundation/Foundation.h>\n\n#ifdef __has_feature\n#define CATCH_ARC_ENABLED __has_feature(objc_arc)\n#else\n#define CATCH_ARC_ENABLED 0\n#endif\n\nvoid arcSafeRelease( NSObject* obj );\nid performOptionalSelector( id obj, SEL sel );\n\n#if !CATCH_ARC_ENABLED\ninline void arcSafeRelease( NSObject* obj ) {\n    [obj release];\n}\ninline id performOptionalSelector( id obj, SEL sel ) {\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED\n#define CATCH_ARC_STRONG\n#else\ninline void arcSafeRelease( NSObject* ){}\ninline id performOptionalSelector( id obj, SEL sel ) {\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Warc-performSelector-leaks\"\n#endif\n    if( [obj respondsToSelector: sel] )\n        return [obj performSelector: sel];\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n    return nil;\n}\n#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained\n#define CATCH_ARC_STRONG __strong\n#endif\n\n// end catch_objc_arc.hpp\n#endif\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless\n#endif\n\nnamespace Catch {\n    namespace Detail {\n\n        extern const std::string unprintableString;\n\n        std::string rawMemoryToString( const void *object, std::size_t size );\n\n        template<typename T>\n        std::string rawMemoryToString( const T& object ) {\n          return rawMemoryToString( &object, sizeof(object) );\n        }\n\n        template<typename T>\n        class IsStreamInsertable {\n            template<typename Stream, typename U>\n            static auto test(int)\n                -> decltype(std::declval<Stream&>() << std::declval<U>(), std::true_type());\n\n            template<typename, typename>\n            static auto test(...)->std::false_type;\n\n        public:\n            static const bool value = decltype(test<std::ostream, const T&>(0))::value;\n        };\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e );\n\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && !std::is_base_of<std::exception, T>::value,\n        std::string>::type convertUnstreamable( T const& ) {\n            return Detail::unprintableString;\n        }\n        template<typename T>\n        typename std::enable_if<\n            !std::is_enum<T>::value && std::is_base_of<std::exception, T>::value,\n         std::string>::type convertUnstreamable(T const& ex) {\n            return ex.what();\n        }\n\n        template<typename T>\n        typename std::enable_if<\n            std::is_enum<T>::value\n        , std::string>::type convertUnstreamable( T const& value ) {\n            return convertUnknownEnumToString( value );\n        }\n\n#if defined(_MANAGED)\n        //! Convert a CLR string to a utf8 std::string\n        template<typename T>\n        std::string clrReferenceToString( T^ ref ) {\n            if (ref == nullptr)\n                return std::string(\"null\");\n            auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString());\n            cli::pin_ptr<System::Byte> p = &bytes[0];\n            return std::string(reinterpret_cast<char const *>(p), bytes->Length);\n        }\n#endif\n\n    } // namespace Detail\n\n    // If we decide for C++14, change these to enable_if_ts\n    template <typename T, typename = void>\n    struct StringMaker {\n        template <typename Fake = T>\n        static\n        typename std::enable_if<::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert(const Fake& value) {\n                ReusableStringStream rss;\n                // NB: call using the function-like syntax to avoid ambiguity with\n                // user-defined templated operator<< under clang.\n                rss.operator<<(value);\n                return rss.str();\n        }\n\n        template <typename Fake = T>\n        static\n        typename std::enable_if<!::Catch::Detail::IsStreamInsertable<Fake>::value, std::string>::type\n            convert( const Fake& value ) {\n#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER)\n            return Detail::convertUnstreamable(value);\n#else\n            return CATCH_CONFIG_FALLBACK_STRINGIFIER(value);\n#endif\n        }\n    };\n\n    namespace Detail {\n\n        // This function dispatches all stringification requests inside of Catch.\n        // Should be preferably called fully qualified, like ::Catch::Detail::stringify\n        template <typename T>\n        std::string stringify(const T& e) {\n            return ::Catch::StringMaker<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::convert(e);\n        }\n\n        template<typename E>\n        std::string convertUnknownEnumToString( E e ) {\n            return ::Catch::Detail::stringify(static_cast<typename std::underlying_type<E>::type>(e));\n        }\n\n#if defined(_MANAGED)\n        template <typename T>\n        std::string stringify( T^ e ) {\n            return ::Catch::StringMaker<T^>::convert(e);\n        }\n#endif\n\n    } // namespace Detail\n\n    // Some predefined specializations\n\n    template<>\n    struct StringMaker<std::string> {\n        static std::string convert(const std::string& str);\n    };\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::string_view> {\n        static std::string convert(std::string_view str);\n    };\n#endif\n\n    template<>\n    struct StringMaker<char const *> {\n        static std::string convert(char const * str);\n    };\n    template<>\n    struct StringMaker<char *> {\n        static std::string convert(char * str);\n    };\n\n#ifdef CATCH_CONFIG_WCHAR\n    template<>\n    struct StringMaker<std::wstring> {\n        static std::string convert(const std::wstring& wstr);\n    };\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\n    template<>\n    struct StringMaker<std::wstring_view> {\n        static std::string convert(std::wstring_view str);\n    };\n# endif\n\n    template<>\n    struct StringMaker<wchar_t const *> {\n        static std::string convert(wchar_t const * str);\n    };\n    template<>\n    struct StringMaker<wchar_t *> {\n        static std::string convert(wchar_t * str);\n    };\n#endif\n\n    // TBD: Should we use `strnlen` to ensure that we don't go out of the buffer,\n    //      while keeping string semantics?\n    template<int SZ>\n    struct StringMaker<char[SZ]> {\n        static std::string convert(char const* str) {\n            return ::Catch::Detail::stringify(std::string{ str });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<signed char[SZ]> {\n        static std::string convert(signed char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n    template<int SZ>\n    struct StringMaker<unsigned char[SZ]> {\n        static std::string convert(unsigned char const* str) {\n            return ::Catch::Detail::stringify(std::string{ reinterpret_cast<char const *>(str) });\n        }\n    };\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<std::byte> {\n        static std::string convert(std::byte value);\n    };\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n    template<>\n    struct StringMaker<int> {\n        static std::string convert(int value);\n    };\n    template<>\n    struct StringMaker<long> {\n        static std::string convert(long value);\n    };\n    template<>\n    struct StringMaker<long long> {\n        static std::string convert(long long value);\n    };\n    template<>\n    struct StringMaker<unsigned int> {\n        static std::string convert(unsigned int value);\n    };\n    template<>\n    struct StringMaker<unsigned long> {\n        static std::string convert(unsigned long value);\n    };\n    template<>\n    struct StringMaker<unsigned long long> {\n        static std::string convert(unsigned long long value);\n    };\n\n    template<>\n    struct StringMaker<bool> {\n        static std::string convert(bool b);\n    };\n\n    template<>\n    struct StringMaker<char> {\n        static std::string convert(char c);\n    };\n    template<>\n    struct StringMaker<signed char> {\n        static std::string convert(signed char c);\n    };\n    template<>\n    struct StringMaker<unsigned char> {\n        static std::string convert(unsigned char c);\n    };\n\n    template<>\n    struct StringMaker<std::nullptr_t> {\n        static std::string convert(std::nullptr_t);\n    };\n\n    template<>\n    struct StringMaker<float> {\n        static std::string convert(float value);\n        static int precision;\n    };\n\n    template<>\n    struct StringMaker<double> {\n        static std::string convert(double value);\n        static int precision;\n    };\n\n    template <typename T>\n    struct StringMaker<T*> {\n        template <typename U>\n        static std::string convert(U* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n    template <typename R, typename C>\n    struct StringMaker<R C::*> {\n        static std::string convert(R C::* p) {\n            if (p) {\n                return ::Catch::Detail::rawMemoryToString(p);\n            } else {\n                return \"nullptr\";\n            }\n        }\n    };\n\n#if defined(_MANAGED)\n    template <typename T>\n    struct StringMaker<T^> {\n        static std::string convert( T^ ref ) {\n            return ::Catch::Detail::clrReferenceToString(ref);\n        }\n    };\n#endif\n\n    namespace Detail {\n        template<typename InputIterator, typename Sentinel = InputIterator>\n        std::string rangeToString(InputIterator first, Sentinel last) {\n            ReusableStringStream rss;\n            rss << \"{ \";\n            if (first != last) {\n                rss << ::Catch::Detail::stringify(*first);\n                for (++first; first != last; ++first)\n                    rss << \", \" << ::Catch::Detail::stringify(*first);\n            }\n            rss << \" }\";\n            return rss.str();\n        }\n    }\n\n#ifdef __OBJC__\n    template<>\n    struct StringMaker<NSString*> {\n        static std::string convert(NSString * nsstring) {\n            if (!nsstring)\n                return \"nil\";\n            return std::string(\"@\") + [nsstring UTF8String];\n        }\n    };\n    template<>\n    struct StringMaker<NSObject*> {\n        static std::string convert(NSObject* nsObject) {\n            return ::Catch::Detail::stringify([nsObject description]);\n        }\n\n    };\n    namespace Detail {\n        inline std::string stringify( NSString* nsstring ) {\n            return StringMaker<NSString*>::convert( nsstring );\n        }\n\n    } // namespace Detail\n#endif // __OBJC__\n\n} // namespace Catch\n\n//////////////////////////////////////////////////////\n// Separate std-lib types stringification, so it can be selectively enabled\n// This means that we do not bring in\n\n#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS)\n#  define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#  define CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n#endif\n\n// Separate std::pair specialization\n#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER)\n#include <utility>\nnamespace Catch {\n    template<typename T1, typename T2>\n    struct StringMaker<std::pair<T1, T2> > {\n        static std::string convert(const std::pair<T1, T2>& pair) {\n            ReusableStringStream rss;\n            rss << \"{ \"\n                << ::Catch::Detail::stringify(pair.first)\n                << \", \"\n                << ::Catch::Detail::stringify(pair.second)\n                << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_OPTIONAL)\n#include <optional>\nnamespace Catch {\n    template<typename T>\n    struct StringMaker<std::optional<T> > {\n        static std::string convert(const std::optional<T>& optional) {\n            ReusableStringStream rss;\n            if (optional.has_value()) {\n                rss << ::Catch::Detail::stringify(*optional);\n            } else {\n                rss << \"{ }\";\n            }\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER\n\n// Separate std::tuple specialization\n#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER)\n#include <tuple>\nnamespace Catch {\n    namespace Detail {\n        template<\n            typename Tuple,\n            std::size_t N = 0,\n            bool = (N < std::tuple_size<Tuple>::value)\n            >\n            struct TupleElementPrinter {\n            static void print(const Tuple& tuple, std::ostream& os) {\n                os << (N ? \", \" : \" \")\n                    << ::Catch::Detail::stringify(std::get<N>(tuple));\n                TupleElementPrinter<Tuple, N + 1>::print(tuple, os);\n            }\n        };\n\n        template<\n            typename Tuple,\n            std::size_t N\n        >\n            struct TupleElementPrinter<Tuple, N, false> {\n            static void print(const Tuple&, std::ostream&) {}\n        };\n\n    }\n\n    template<typename ...Types>\n    struct StringMaker<std::tuple<Types...>> {\n        static std::string convert(const std::tuple<Types...>& tuple) {\n            ReusableStringStream rss;\n            rss << '{';\n            Detail::TupleElementPrinter<std::tuple<Types...>>::print(tuple, rss.get());\n            rss << \" }\";\n            return rss.str();\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER\n\n#if defined(CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER) && defined(CATCH_CONFIG_CPP17_VARIANT)\n#include <variant>\nnamespace Catch {\n    template<>\n    struct StringMaker<std::monostate> {\n        static std::string convert(const std::monostate&) {\n            return \"{ }\";\n        }\n    };\n\n    template<typename... Elements>\n    struct StringMaker<std::variant<Elements...>> {\n        static std::string convert(const std::variant<Elements...>& variant) {\n            if (variant.valueless_by_exception()) {\n                return \"{valueless variant}\";\n            } else {\n                return std::visit(\n                    [](const auto& value) {\n                        return ::Catch::Detail::stringify(value);\n                    },\n                    variant\n                );\n            }\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_VARIANT_STRINGMAKER\n\nnamespace Catch {\n    // Import begin/ end from std here\n    using std::begin;\n    using std::end;\n\n    namespace detail {\n        template <typename...>\n        struct void_type {\n            using type = void;\n        };\n\n        template <typename T, typename = void>\n        struct is_range_impl : std::false_type {\n        };\n\n        template <typename T>\n        struct is_range_impl<T, typename void_type<decltype(begin(std::declval<T>()))>::type> : std::true_type {\n        };\n    } // namespace detail\n\n    template <typename T>\n    struct is_range : detail::is_range_impl<T> {\n    };\n\n#if defined(_MANAGED) // Managed types are never ranges\n    template <typename T>\n    struct is_range<T^> {\n        static const bool value = false;\n    };\n#endif\n\n    template<typename Range>\n    std::string rangeToString( Range const& range ) {\n        return ::Catch::Detail::rangeToString( begin( range ), end( range ) );\n    }\n\n    // Handle vector<bool> specially\n    template<typename Allocator>\n    std::string rangeToString( std::vector<bool, Allocator> const& v ) {\n        ReusableStringStream rss;\n        rss << \"{ \";\n        bool first = true;\n        for( bool b : v ) {\n            if( first )\n                first = false;\n            else\n                rss << \", \";\n            rss << ::Catch::Detail::stringify( b );\n        }\n        rss << \" }\";\n        return rss.str();\n    }\n\n    template<typename R>\n    struct StringMaker<R, typename std::enable_if<is_range<R>::value && !::Catch::Detail::IsStreamInsertable<R>::value>::type> {\n        static std::string convert( R const& range ) {\n            return rangeToString( range );\n        }\n    };\n\n    template <typename T, int SZ>\n    struct StringMaker<T[SZ]> {\n        static std::string convert(T const(&arr)[SZ]) {\n            return rangeToString(arr);\n        }\n    };\n\n} // namespace Catch\n\n// Separate std::chrono::duration specialization\n#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#include <ctime>\n#include <ratio>\n#include <chrono>\n\nnamespace Catch {\n\ntemplate <class Ratio>\nstruct ratio_string {\n    static std::string symbol();\n};\n\ntemplate <class Ratio>\nstd::string ratio_string<Ratio>::symbol() {\n    Catch::ReusableStringStream rss;\n    rss << '[' << Ratio::num << '/'\n        << Ratio::den << ']';\n    return rss.str();\n}\ntemplate <>\nstruct ratio_string<std::atto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::femto> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::pico> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::nano> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::micro> {\n    static std::string symbol();\n};\ntemplate <>\nstruct ratio_string<std::milli> {\n    static std::string symbol();\n};\n\n    ////////////\n    // std::chrono::duration specializations\n    template<typename Value, typename Ratio>\n    struct StringMaker<std::chrono::duration<Value, Ratio>> {\n        static std::string convert(std::chrono::duration<Value, Ratio> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << ' ' << ratio_string<Ratio>::symbol() << 's';\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<1>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<1>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" s\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<60>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<60>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" m\";\n            return rss.str();\n        }\n    };\n    template<typename Value>\n    struct StringMaker<std::chrono::duration<Value, std::ratio<3600>>> {\n        static std::string convert(std::chrono::duration<Value, std::ratio<3600>> const& duration) {\n            ReusableStringStream rss;\n            rss << duration.count() << \" h\";\n            return rss.str();\n        }\n    };\n\n    ////////////\n    // std::chrono::time_point specialization\n    // Generic time_point cannot be specialized, only std::chrono::time_point<system_clock>\n    template<typename Clock, typename Duration>\n    struct StringMaker<std::chrono::time_point<Clock, Duration>> {\n        static std::string convert(std::chrono::time_point<Clock, Duration> const& time_point) {\n            return ::Catch::Detail::stringify(time_point.time_since_epoch()) + \" since epoch\";\n        }\n    };\n    // std::chrono::time_point<system_clock> specialization\n    template<typename Duration>\n    struct StringMaker<std::chrono::time_point<std::chrono::system_clock, Duration>> {\n        static std::string convert(std::chrono::time_point<std::chrono::system_clock, Duration> const& time_point) {\n            auto converted = std::chrono::system_clock::to_time_t(time_point);\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &converted);\n#else\n            std::tm* timeInfo = std::gmtime(&converted);\n#endif\n\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp);\n        }\n    };\n}\n#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n\n#define INTERNAL_CATCH_REGISTER_ENUM( enumName, ... ) \\\nnamespace Catch { \\\n    template<> struct StringMaker<enumName> { \\\n        static std::string convert( enumName value ) { \\\n            static const auto& enumInfo = ::Catch::getMutableRegistryHub().getMutableEnumValuesRegistry().registerEnum( #enumName, #__VA_ARGS__, { __VA_ARGS__ } ); \\\n            return static_cast<std::string>(enumInfo.lookup( static_cast<int>( value ) )); \\\n        } \\\n    }; \\\n}\n\n#define CATCH_REGISTER_ENUM( enumName, ... ) INTERNAL_CATCH_REGISTER_ENUM( enumName, __VA_ARGS__ )\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_tostring.h\n#include <iosfwd>\n\n#ifdef _MSC_VER\n#pragma warning(push)\n#pragma warning(disable:4389) // '==' : signed/unsigned mismatch\n#pragma warning(disable:4018) // more \"signed/unsigned mismatch\"\n#pragma warning(disable:4312) // Converting int to T* using reinterpret_cast (issue on x64 platform)\n#pragma warning(disable:4180) // qualifier applied to function type has no meaning\n#pragma warning(disable:4800) // Forcing result to true or false\n#endif\n\nnamespace Catch {\n\n    struct ITransientExpression {\n        auto isBinaryExpression() const -> bool { return m_isBinaryExpression; }\n        auto getResult() const -> bool { return m_result; }\n        virtual void streamReconstructedExpression( std::ostream &os ) const = 0;\n\n        ITransientExpression( bool isBinaryExpression, bool result )\n        :   m_isBinaryExpression( isBinaryExpression ),\n            m_result( result )\n        {}\n\n        // We don't actually need a virtual destructor, but many static analysers\n        // complain if it's not here :-(\n        virtual ~ITransientExpression();\n\n        bool m_isBinaryExpression;\n        bool m_result;\n\n    };\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs );\n\n    template<typename LhsT, typename RhsT>\n    class BinaryExpr  : public ITransientExpression {\n        LhsT m_lhs;\n        StringRef m_op;\n        RhsT m_rhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            formatReconstructedExpression\n                    ( os, Catch::Detail::stringify( m_lhs ), m_op, Catch::Detail::stringify( m_rhs ) );\n        }\n\n    public:\n        BinaryExpr( bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs )\n        :   ITransientExpression{ true, comparisonResult },\n            m_lhs( lhs ),\n            m_op( op ),\n            m_rhs( rhs )\n        {}\n\n        template<typename T>\n        auto operator && ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator || ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator == ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator != ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator > ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator < ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator >= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename T>\n        auto operator <= ( T ) const -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<T>::value,\n            \"chained comparisons are not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n    };\n\n    template<typename LhsT>\n    class UnaryExpr : public ITransientExpression {\n        LhsT m_lhs;\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            os << Catch::Detail::stringify( m_lhs );\n        }\n\n    public:\n        explicit UnaryExpr( LhsT lhs )\n        :   ITransientExpression{ false, static_cast<bool>(lhs) },\n            m_lhs( lhs )\n        {}\n    };\n\n    // Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int)\n    template<typename LhsT, typename RhsT>\n    auto compareEqual( LhsT const& lhs, RhsT const& rhs ) -> bool { return static_cast<bool>(lhs == rhs); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, int rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( T* const& lhs, long rhs ) -> bool { return lhs == reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n    template<typename T>\n    auto compareEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) == rhs; }\n\n    template<typename LhsT, typename RhsT>\n    auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, int rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( T* const& lhs, long rhs ) -> bool { return lhs != reinterpret_cast<void const*>( rhs ); }\n    template<typename T>\n    auto compareNotEqual( int lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n    template<typename T>\n    auto compareNotEqual( long lhs, T* const& rhs ) -> bool { return reinterpret_cast<void const*>( lhs ) != rhs; }\n\n    template<typename LhsT>\n    class ExprLhs {\n        LhsT m_lhs;\n    public:\n        explicit ExprLhs( LhsT lhs ) : m_lhs( lhs ) {}\n\n        template<typename RhsT>\n        auto operator == ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareEqual( m_lhs, rhs ), m_lhs, \"==\", rhs };\n        }\n        auto operator == ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs == rhs, m_lhs, \"==\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator != ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { compareNotEqual( m_lhs, rhs ), m_lhs, \"!=\", rhs };\n        }\n        auto operator != ( bool rhs ) -> BinaryExpr<LhsT, bool> const {\n            return { m_lhs != rhs, m_lhs, \"!=\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator > ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs > rhs), m_lhs, \">\", rhs };\n        }\n        template<typename RhsT>\n        auto operator < ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs < rhs), m_lhs, \"<\", rhs };\n        }\n        template<typename RhsT>\n        auto operator >= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs >= rhs), m_lhs, \">=\", rhs };\n        }\n        template<typename RhsT>\n        auto operator <= ( RhsT const& rhs ) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs <= rhs), m_lhs, \"<=\", rhs };\n        }\n        template <typename RhsT>\n        auto operator | (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs | rhs), m_lhs, \"|\", rhs };\n        }\n        template <typename RhsT>\n        auto operator & (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs & rhs), m_lhs, \"&\", rhs };\n        }\n        template <typename RhsT>\n        auto operator ^ (RhsT const& rhs) -> BinaryExpr<LhsT, RhsT const&> const {\n            return { static_cast<bool>(m_lhs ^ rhs), m_lhs, \"^\", rhs };\n        }\n\n        template<typename RhsT>\n        auto operator && ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator&& is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        template<typename RhsT>\n        auto operator || ( RhsT const& ) -> BinaryExpr<LhsT, RhsT const&> const {\n            static_assert(always_false<RhsT>::value,\n            \"operator|| is not supported inside assertions, \"\n            \"wrap the expression inside parentheses, or decompose it\");\n        }\n\n        auto makeUnaryExpr() const -> UnaryExpr<LhsT> {\n            return UnaryExpr<LhsT>{ m_lhs };\n        }\n    };\n\n    void handleExpression( ITransientExpression const& expr );\n\n    template<typename T>\n    void handleExpression( ExprLhs<T> const& expr ) {\n        handleExpression( expr.makeUnaryExpr() );\n    }\n\n    struct Decomposer {\n        template<typename T>\n        auto operator <= ( T const& lhs ) -> ExprLhs<T const&> {\n            return ExprLhs<T const&>{ lhs };\n        }\n\n        auto operator <=( bool value ) -> ExprLhs<bool> {\n            return ExprLhs<bool>{ value };\n        }\n    };\n\n} // end namespace Catch\n\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n\n// end catch_decomposer.h\n// start catch_interfaces_capture.h\n\n#include <string>\n#include <chrono>\n\nnamespace Catch {\n\n    class AssertionResult;\n    struct AssertionInfo;\n    struct SectionInfo;\n    struct SectionEndInfo;\n    struct MessageInfo;\n    struct MessageBuilder;\n    struct Counts;\n    struct AssertionReaction;\n    struct SourceLineInfo;\n\n    struct ITransientExpression;\n    struct IGeneratorTracker;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo;\n    template <typename Duration = std::chrono::duration<double, std::nano>>\n    struct BenchmarkStats;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IResultCapture {\n\n        virtual ~IResultCapture();\n\n        virtual bool sectionStarted(    SectionInfo const& sectionInfo,\n                                        Counts& assertions ) = 0;\n        virtual void sectionEnded( SectionEndInfo const& endInfo ) = 0;\n        virtual void sectionEndedEarly( SectionEndInfo const& endInfo ) = 0;\n\n        virtual auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& name ) = 0;\n        virtual void benchmarkStarting( BenchmarkInfo const& info ) = 0;\n        virtual void benchmarkEnded( BenchmarkStats<> const& stats ) = 0;\n        virtual void benchmarkFailed( std::string const& error ) = 0;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void pushScopedMessage( MessageInfo const& message ) = 0;\n        virtual void popScopedMessage( MessageInfo const& message ) = 0;\n\n        virtual void emplaceUnscopedMessage( MessageBuilder const& builder ) = 0;\n\n        virtual void handleFatalErrorCondition( StringRef message ) = 0;\n\n        virtual void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) = 0;\n        virtual void handleIncomplete\n                (   AssertionInfo const& info ) = 0;\n        virtual void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) = 0;\n\n        virtual bool lastAssertionPassed() = 0;\n        virtual void assertionPassed() = 0;\n\n        // Deprecated, do not use:\n        virtual std::string getCurrentTestName() const = 0;\n        virtual const AssertionResult* getLastResult() const = 0;\n        virtual void exceptionEarlyReported() = 0;\n    };\n\n    IResultCapture& getResultCapture();\n}\n\n// end catch_interfaces_capture.h\nnamespace Catch {\n\n    struct TestFailureException{};\n    struct AssertionResultData;\n    struct IResultCapture;\n    class RunContext;\n\n    class LazyExpression {\n        friend class AssertionHandler;\n        friend struct AssertionStats;\n        friend class RunContext;\n\n        ITransientExpression const* m_transientExpression = nullptr;\n        bool m_isNegated;\n    public:\n        LazyExpression( bool isNegated );\n        LazyExpression( LazyExpression const& other );\n        LazyExpression& operator = ( LazyExpression const& ) = delete;\n\n        explicit operator bool() const;\n\n        friend auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream&;\n    };\n\n    struct AssertionReaction {\n        bool shouldDebugBreak = false;\n        bool shouldThrow = false;\n    };\n\n    class AssertionHandler {\n        AssertionInfo m_assertionInfo;\n        AssertionReaction m_reaction;\n        bool m_completed = false;\n        IResultCapture& m_resultCapture;\n\n    public:\n        AssertionHandler\n            (   StringRef const& macroName,\n                SourceLineInfo const& lineInfo,\n                StringRef capturedExpression,\n                ResultDisposition::Flags resultDisposition );\n        ~AssertionHandler() {\n            if ( !m_completed ) {\n                m_resultCapture.handleIncomplete( m_assertionInfo );\n            }\n        }\n\n        template<typename T>\n        void handleExpr( ExprLhs<T> const& expr ) {\n            handleExpr( expr.makeUnaryExpr() );\n        }\n        void handleExpr( ITransientExpression const& expr );\n\n        void handleMessage(ResultWas::OfType resultType, StringRef const& message);\n\n        void handleExceptionThrownAsExpected();\n        void handleUnexpectedExceptionNotThrown();\n        void handleExceptionNotThrownAsExpected();\n        void handleThrowingCallSkipped();\n        void handleUnexpectedInflightException();\n\n        void complete();\n        void setCompleted();\n\n        // query\n        auto allowThrows() const -> bool;\n    };\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString );\n\n} // namespace Catch\n\n// end catch_assertionhandler.h\n// start catch_message.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\n\n    struct MessageInfo {\n        MessageInfo(    StringRef const& _macroName,\n                        SourceLineInfo const& _lineInfo,\n                        ResultWas::OfType _type );\n\n        StringRef macroName;\n        std::string message;\n        SourceLineInfo lineInfo;\n        ResultWas::OfType type;\n        unsigned int sequence;\n\n        bool operator == ( MessageInfo const& other ) const;\n        bool operator < ( MessageInfo const& other ) const;\n    private:\n        static unsigned int globalCount;\n    };\n\n    struct MessageStream {\n\n        template<typename T>\n        MessageStream& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        ReusableStringStream m_stream;\n    };\n\n    struct MessageBuilder : MessageStream {\n        MessageBuilder( StringRef const& macroName,\n                        SourceLineInfo const& lineInfo,\n                        ResultWas::OfType type );\n\n        template<typename T>\n        MessageBuilder& operator << ( T const& value ) {\n            m_stream << value;\n            return *this;\n        }\n\n        MessageInfo m_info;\n    };\n\n    class ScopedMessage {\n    public:\n        explicit ScopedMessage( MessageBuilder const& builder );\n        ScopedMessage( ScopedMessage& duplicate ) = delete;\n        ScopedMessage( ScopedMessage&& old );\n        ~ScopedMessage();\n\n        MessageInfo m_info;\n        bool m_moved;\n    };\n\n    class Capturer {\n        std::vector<MessageInfo> m_messages;\n        IResultCapture& m_resultCapture = getResultCapture();\n        size_t m_captured = 0;\n    public:\n        Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names );\n        ~Capturer();\n\n        void captureValue( size_t index, std::string const& value );\n\n        template<typename T>\n        void captureValues( size_t index, T const& value ) {\n            captureValue( index, Catch::Detail::stringify( value ) );\n        }\n\n        template<typename T, typename... Ts>\n        void captureValues( size_t index, T const& value, Ts const&... values ) {\n            captureValue( index, Catch::Detail::stringify(value) );\n            captureValues( index+1, values... );\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_message.h\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION)\n  #define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__\n#else\n  #define CATCH_INTERNAL_STRINGIFY(...) \"Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION\"\n#endif\n\n#if defined(CATCH_CONFIG_FAST_COMPILE) || defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n\n///////////////////////////////////////////////////////////////////////////////\n// Another way to speed-up compilation is to omit local try-catch for REQUIRE*\n// macros.\n#define INTERNAL_CATCH_TRY\n#define INTERNAL_CATCH_CATCH( capturer )\n\n#else // CATCH_CONFIG_FAST_COMPILE\n\n#define INTERNAL_CATCH_TRY try\n#define INTERNAL_CATCH_CATCH( handler ) catch(...) { handler.handleUnexpectedInflightException(); }\n\n#endif\n\n#define INTERNAL_CATCH_REACT( handler ) handler.complete();\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TEST( macroName, resultDisposition, ... ) \\\n    do { \\\n        CATCH_INTERNAL_IGNORE_BUT_WARN(__VA_ARGS__); \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n            CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \\\n            catchAssertionHandler.handleExpr( Catch::Decomposer() <= __VA_ARGS__ ); \\\n            CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( (void)0, (false) && static_cast<bool>( !!(__VA_ARGS__) ) )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_IF( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_ELSE( macroName, resultDisposition, ... ) \\\n    INTERNAL_CATCH_TEST( macroName, resultDisposition, __VA_ARGS__ ); \\\n    if( !Catch::getResultCapture().lastAssertionPassed() )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_NO_THROW( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition ); \\\n        try { \\\n            static_cast<void>(__VA_ARGS__); \\\n            catchAssertionHandler.handleExceptionNotThrownAsExpected(); \\\n        } \\\n        catch( ... ) { \\\n            catchAssertionHandler.handleUnexpectedInflightException(); \\\n        } \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS( macroName, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_AS( macroName, exceptionType, resultDisposition, expr ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(expr) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(expr); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ) { \\\n                catchAssertionHandler.handleExceptionThrownAsExpected(); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_MSG( macroName, messageType, resultDisposition, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::StringRef(), resultDisposition ); \\\n        catchAssertionHandler.handleMessage( messageType, ( Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop() ).m_stream.str() ); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_CAPTURE( varName, macroName, ... ) \\\n    auto varName = Catch::Capturer( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info, #__VA_ARGS__ ); \\\n    varName.captureValues( 0, __VA_ARGS__ )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_INFO( macroName, log ) \\\n    Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage )( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log );\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_UNSCOPED_INFO( macroName, log ) \\\n    Catch::getResultCapture().emplaceUnscopedMessage( Catch::MessageBuilder( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log )\n\n///////////////////////////////////////////////////////////////////////////////\n// Although this is matcher-based, it can be used with just a string\n#define INTERNAL_CATCH_THROWS_STR_MATCHES( macroName, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( ... ) { \\\n                Catch::handleExceptionMatchExpr( catchAssertionHandler, matcher, #matcher##_catch_sr ); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_capture.hpp\n// start catch_section.h\n\n// start catch_section_info.h\n\n// start catch_totals.h\n\n#include <cstddef>\n\nnamespace Catch {\n\n    struct Counts {\n        Counts operator - ( Counts const& other ) const;\n        Counts& operator += ( Counts const& other );\n\n        std::size_t total() const;\n        bool allPassed() const;\n        bool allOk() const;\n\n        std::size_t passed = 0;\n        std::size_t failed = 0;\n        std::size_t failedButOk = 0;\n    };\n\n    struct Totals {\n\n        Totals operator - ( Totals const& other ) const;\n        Totals& operator += ( Totals const& other );\n\n        Totals delta( Totals const& prevTotals ) const;\n\n        int error = 0;\n        Counts assertions;\n        Counts testCases;\n    };\n}\n\n// end catch_totals.h\n#include <string>\n\nnamespace Catch {\n\n    struct SectionInfo {\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name );\n\n        // Deprecated\n        SectionInfo\n            (   SourceLineInfo const& _lineInfo,\n                std::string const& _name,\n                std::string const& ) : SectionInfo( _lineInfo, _name ) {}\n\n        std::string name;\n        std::string description; // !Deprecated: this will always be empty\n        SourceLineInfo lineInfo;\n    };\n\n    struct SectionEndInfo {\n        SectionInfo sectionInfo;\n        Counts prevAssertions;\n        double durationInSeconds;\n    };\n\n} // end namespace Catch\n\n// end catch_section_info.h\n// start catch_timer.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t;\n    auto getEstimatedClockResolution() -> uint64_t;\n\n    class Timer {\n        uint64_t m_nanoseconds = 0;\n    public:\n        void start();\n        auto getElapsedNanoseconds() const -> uint64_t;\n        auto getElapsedMicroseconds() const -> uint64_t;\n        auto getElapsedMilliseconds() const -> unsigned int;\n        auto getElapsedSeconds() const -> double;\n    };\n\n} // namespace Catch\n\n// end catch_timer.h\n#include <string>\n\nnamespace Catch {\n\n    class Section : NonCopyable {\n    public:\n        Section( SectionInfo const& info );\n        ~Section();\n\n        // This indicates whether the section should be executed or not\n        explicit operator bool() const;\n\n    private:\n        SectionInfo m_info;\n\n        std::string m_name;\n        Counts m_assertions;\n        bool m_sectionIncluded;\n        Timer m_timer;\n    };\n\n} // end namespace Catch\n\n#define INTERNAL_CATCH_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define INTERNAL_CATCH_DYNAMIC_SECTION( ... ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_UNUSED_WARNINGS \\\n    if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, (Catch::ReusableStringStream() << __VA_ARGS__).str() ) ) \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n// end catch_section.h\n// start catch_interfaces_exception.h\n\n// start catch_interfaces_registry_hub.h\n\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class TestCase;\n    struct ITestCaseRegistry;\n    struct IExceptionTranslatorRegistry;\n    struct IExceptionTranslator;\n    struct IReporterRegistry;\n    struct IReporterFactory;\n    struct ITagAliasRegistry;\n    struct IMutableEnumValuesRegistry;\n\n    class StartupExceptionRegistry;\n\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IRegistryHub {\n        virtual ~IRegistryHub();\n\n        virtual IReporterRegistry const& getReporterRegistry() const = 0;\n        virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0;\n        virtual ITagAliasRegistry const& getTagAliasRegistry() const = 0;\n        virtual IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const = 0;\n\n        virtual StartupExceptionRegistry const& getStartupExceptionRegistry() const = 0;\n    };\n\n    struct IMutableRegistryHub {\n        virtual ~IMutableRegistryHub();\n        virtual void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerListener( IReporterFactoryPtr const& factory ) = 0;\n        virtual void registerTest( TestCase const& testInfo ) = 0;\n        virtual void registerTranslator( const IExceptionTranslator* translator ) = 0;\n        virtual void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) = 0;\n        virtual void registerStartupException() noexcept = 0;\n        virtual IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() = 0;\n    };\n\n    IRegistryHub const& getRegistryHub();\n    IMutableRegistryHub& getMutableRegistryHub();\n    void cleanUp();\n    std::string translateActiveException();\n\n}\n\n// end catch_interfaces_registry_hub.h\n#if defined(CATCH_CONFIG_DISABLE)\n    #define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( translatorName, signature) \\\n        static std::string translatorName( signature )\n#endif\n\n#include <exception>\n#include <string>\n#include <vector>\n\nnamespace Catch {\n    using exceptionTranslateFunction = std::string(*)();\n\n    struct IExceptionTranslator;\n    using ExceptionTranslators = std::vector<std::unique_ptr<IExceptionTranslator const>>;\n\n    struct IExceptionTranslator {\n        virtual ~IExceptionTranslator();\n        virtual std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const = 0;\n    };\n\n    struct IExceptionTranslatorRegistry {\n        virtual ~IExceptionTranslatorRegistry();\n\n        virtual std::string translateActiveException() const = 0;\n    };\n\n    class ExceptionTranslatorRegistrar {\n        template<typename T>\n        class ExceptionTranslator : public IExceptionTranslator {\n        public:\n\n            ExceptionTranslator( std::string(*translateFunction)( T& ) )\n            : m_translateFunction( translateFunction )\n            {}\n\n            std::string translate( ExceptionTranslators::const_iterator it, ExceptionTranslators::const_iterator itEnd ) const override {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                return \"\";\n#else\n                try {\n                    if( it == itEnd )\n                        std::rethrow_exception(std::current_exception());\n                    else\n                        return (*it)->translate( it+1, itEnd );\n                }\n                catch( T& ex ) {\n                    return m_translateFunction( ex );\n                }\n#endif\n            }\n\n        protected:\n            std::string(*m_translateFunction)( T& );\n        };\n\n    public:\n        template<typename T>\n        ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) {\n            getMutableRegistryHub().registerTranslator\n                ( new ExceptionTranslator<T>( translateFunction ) );\n        }\n    };\n}\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2( translatorName, signature ) \\\n    static std::string translatorName( signature ); \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \\\n    namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &translatorName ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION \\\n    static std::string translatorName( signature )\n\n#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION2( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// end catch_interfaces_exception.h\n// start catch_approx.h\n\n#include <type_traits>\n\nnamespace Catch {\nnamespace Detail {\n\n    class Approx {\n    private:\n        bool equalityComparisonImpl(double other) const;\n        // Validates the new margin (margin >= 0)\n        // out-of-line to avoid including stdexcept in the header\n        void setMargin(double margin);\n        // Validates the new epsilon (0 < epsilon < 1)\n        // out-of-line to avoid including stdexcept in the header\n        void setEpsilon(double epsilon);\n\n    public:\n        explicit Approx ( double value );\n\n        static Approx custom();\n\n        Approx operator-() const;\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx operator()( T const& value ) const {\n            Approx approx( static_cast<double>(value) );\n            approx.m_epsilon = m_epsilon;\n            approx.m_margin = m_margin;\n            approx.m_scale = m_scale;\n            return approx;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        explicit Approx( T const& value ): Approx(static_cast<double>(value))\n        {}\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( const T& lhs, Approx const& rhs ) {\n            auto lhs_v = static_cast<double>(lhs);\n            return rhs.equalityComparisonImpl(lhs_v);\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator == ( Approx const& lhs, const T& rhs ) {\n            return operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( T const& lhs, Approx const& rhs ) {\n            return !operator==( lhs, rhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator != ( Approx const& lhs, T const& rhs ) {\n            return !operator==( rhs, lhs );\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) < rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator <= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value < static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( T const& lhs, Approx const& rhs ) {\n            return static_cast<double>(lhs) > rhs.m_value || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        friend bool operator >= ( Approx const& lhs, T const& rhs ) {\n            return lhs.m_value > static_cast<double>(rhs) || lhs == rhs;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& epsilon( T const& newEpsilon ) {\n            double epsilonAsDouble = static_cast<double>(newEpsilon);\n            setEpsilon(epsilonAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& margin( T const& newMargin ) {\n            double marginAsDouble = static_cast<double>(newMargin);\n            setMargin(marginAsDouble);\n            return *this;\n        }\n\n        template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n        Approx& scale( T const& newScale ) {\n            m_scale = static_cast<double>(newScale);\n            return *this;\n        }\n\n        std::string toString() const;\n\n    private:\n        double m_epsilon;\n        double m_margin;\n        double m_scale;\n        double m_value;\n    };\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val);\n    Detail::Approx operator \"\" _a(unsigned long long val);\n} // end namespace literals\n\ntemplate<>\nstruct StringMaker<Catch::Detail::Approx> {\n    static std::string convert(Catch::Detail::Approx const& value);\n};\n\n} // end namespace Catch\n\n// end catch_approx.h\n// start catch_string_manip.h\n\n#include <string>\n#include <iosfwd>\n#include <vector>\n\nnamespace Catch {\n\n    bool startsWith( std::string const& s, std::string const& prefix );\n    bool startsWith( std::string const& s, char prefix );\n    bool endsWith( std::string const& s, std::string const& suffix );\n    bool endsWith( std::string const& s, char suffix );\n    bool contains( std::string const& s, std::string const& infix );\n    void toLowerInPlace( std::string& s );\n    std::string toLower( std::string const& s );\n    //! Returns a new string without whitespace at the start/end\n    std::string trim( std::string const& str );\n    //! Returns a substring of the original ref without whitespace. Beware lifetimes!\n    StringRef trim(StringRef ref);\n\n    // !!! Be aware, returns refs into original string - make sure original string outlives them\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter );\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis );\n\n    struct pluralise {\n        pluralise( std::size_t count, std::string const& label );\n\n        friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser );\n\n        std::size_t m_count;\n        std::string m_label;\n    };\n}\n\n// end catch_string_manip.h\n#ifndef CATCH_CONFIG_DISABLE_MATCHERS\n// start catch_capture_matchers.h\n\n// start catch_matchers.h\n\n#include <string>\n#include <vector>\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        template<typename ArgT> struct MatchAllOf;\n        template<typename ArgT> struct MatchAnyOf;\n        template<typename ArgT> struct MatchNotOf;\n\n        class MatcherUntypedBase {\n        public:\n            MatcherUntypedBase() = default;\n            MatcherUntypedBase ( MatcherUntypedBase const& ) = default;\n            MatcherUntypedBase& operator = ( MatcherUntypedBase const& ) = delete;\n            std::string toString() const;\n\n        protected:\n            virtual ~MatcherUntypedBase();\n            virtual std::string describe() const = 0;\n            mutable std::string m_cachedToString;\n        };\n\n#ifdef __clang__\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wnon-virtual-dtor\"\n#endif\n\n        template<typename ObjectT>\n        struct MatcherMethod {\n            virtual bool match( ObjectT const& arg ) const = 0;\n        };\n\n#if defined(__OBJC__)\n        // Hack to fix Catch GH issue #1661. Could use id for generic Object support.\n        // use of const for Object pointers is very uncommon and under ARC it causes some kind of signature mismatch that breaks compilation\n        template<>\n        struct MatcherMethod<NSString*> {\n            virtual bool match( NSString* arg ) const = 0;\n        };\n#endif\n\n#ifdef __clang__\n#    pragma clang diagnostic pop\n#endif\n\n        template<typename T>\n        struct MatcherBase : MatcherUntypedBase, MatcherMethod<T> {\n\n            MatchAllOf<T> operator && ( MatcherBase const& other ) const;\n            MatchAnyOf<T> operator || ( MatcherBase const& other ) const;\n            MatchNotOf<T> operator ! () const;\n        };\n\n        template<typename ArgT>\n        struct MatchAllOf : MatcherBase<ArgT> {\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (!matcher->match(arg))\n                        return false;\n                }\n                return true;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" and \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAllOf<ArgT> operator && ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n        template<typename ArgT>\n        struct MatchAnyOf : MatcherBase<ArgT> {\n\n            bool match( ArgT const& arg ) const override {\n                for( auto matcher : m_matchers ) {\n                    if (matcher->match(arg))\n                        return true;\n                }\n                return false;\n            }\n            std::string describe() const override {\n                std::string description;\n                description.reserve( 4 + m_matchers.size()*32 );\n                description += \"( \";\n                bool first = true;\n                for( auto matcher : m_matchers ) {\n                    if( first )\n                        first = false;\n                    else\n                        description += \" or \";\n                    description += matcher->toString();\n                }\n                description += \" )\";\n                return description;\n            }\n\n            MatchAnyOf<ArgT> operator || ( MatcherBase<ArgT> const& other ) {\n                auto copy(*this);\n                copy.m_matchers.push_back( &other );\n                return copy;\n            }\n\n            std::vector<MatcherBase<ArgT> const*> m_matchers;\n        };\n\n        template<typename ArgT>\n        struct MatchNotOf : MatcherBase<ArgT> {\n\n            MatchNotOf( MatcherBase<ArgT> const& underlyingMatcher ) : m_underlyingMatcher( underlyingMatcher ) {}\n\n            bool match( ArgT const& arg ) const override {\n                return !m_underlyingMatcher.match( arg );\n            }\n\n            std::string describe() const override {\n                return \"not \" + m_underlyingMatcher.toString();\n            }\n            MatcherBase<ArgT> const& m_underlyingMatcher;\n        };\n\n        template<typename T>\n        MatchAllOf<T> MatcherBase<T>::operator && ( MatcherBase const& other ) const {\n            return MatchAllOf<T>() && *this && other;\n        }\n        template<typename T>\n        MatchAnyOf<T> MatcherBase<T>::operator || ( MatcherBase const& other ) const {\n            return MatchAnyOf<T>() || *this || other;\n        }\n        template<typename T>\n        MatchNotOf<T> MatcherBase<T>::operator ! () const {\n            return MatchNotOf<T>( *this );\n        }\n\n    } // namespace Impl\n\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n\n// end catch_matchers.h\n// start catch_matchers_exception.hpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nclass ExceptionMessageMatcher : public MatcherBase<std::exception> {\n    std::string m_message;\npublic:\n\n    ExceptionMessageMatcher(std::string const& message):\n        m_message(message)\n    {}\n\n    bool match(std::exception const& ex) const override;\n\n    std::string describe() const override;\n};\n\n} // namespace Exception\n\nException::ExceptionMessageMatcher Message(std::string const& message);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_exception.hpp\n// start catch_matchers_floating.h\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Floating {\n\n        enum class FloatingPointKind : uint8_t;\n\n        struct WithinAbsMatcher : MatcherBase<double> {\n            WithinAbsMatcher(double target, double margin);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_margin;\n        };\n\n        struct WithinUlpsMatcher : MatcherBase<double> {\n            WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            uint64_t m_ulps;\n            FloatingPointKind m_type;\n        };\n\n        // Given IEEE-754 format for floats and doubles, we can assume\n        // that float -> double promotion is lossless. Given this, we can\n        // assume that if we do the standard relative comparison of\n        // |lhs - rhs| <= epsilon * max(fabs(lhs), fabs(rhs)), then we get\n        // the same result if we do this for floats, as if we do this for\n        // doubles that were promoted from floats.\n        struct WithinRelMatcher : MatcherBase<double> {\n            WithinRelMatcher(double target, double epsilon);\n            bool match(double const& matchee) const override;\n            std::string describe() const override;\n        private:\n            double m_target;\n            double m_epsilon;\n        };\n\n    } // namespace Floating\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n    Floating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff);\n    Floating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff);\n    Floating::WithinAbsMatcher WithinAbs(double target, double margin);\n    Floating::WithinRelMatcher WithinRel(double target, double eps);\n    // defaults epsilon to 100*numeric_limits<double>::epsilon()\n    Floating::WithinRelMatcher WithinRel(double target);\n    Floating::WithinRelMatcher WithinRel(float target, float eps);\n    // defaults epsilon to 100*numeric_limits<float>::epsilon()\n    Floating::WithinRelMatcher WithinRel(float target);\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_floating.h\n// start catch_matchers_generic.hpp\n\n#include <functional>\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Generic {\n\nnamespace Detail {\n    std::string finalizeDescription(const std::string& desc);\n}\n\ntemplate <typename T>\nclass PredicateMatcher : public MatcherBase<T> {\n    std::function<bool(T const&)> m_predicate;\n    std::string m_description;\npublic:\n\n    PredicateMatcher(std::function<bool(T const&)> const& elem, std::string const& descr)\n        :m_predicate(std::move(elem)),\n        m_description(Detail::finalizeDescription(descr))\n    {}\n\n    bool match( T const& item ) const override {\n        return m_predicate(item);\n    }\n\n    std::string describe() const override {\n        return m_description;\n    }\n};\n\n} // namespace Generic\n\n    // The following functions create the actual matcher objects.\n    // The user has to explicitly specify type to the function, because\n    // inferring std::function<bool(T const&)> is hard (but possible) and\n    // requires a lot of TMP.\n    template<typename T>\n    Generic::PredicateMatcher<T> Predicate(std::function<bool(T const&)> const& predicate, std::string const& description = \"\") {\n        return Generic::PredicateMatcher<T>(predicate, description);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_generic.hpp\n// start catch_matchers_string.h\n\n#include <string>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        struct CasedString\n        {\n            CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity );\n            std::string adjustString( std::string const& str ) const;\n            std::string caseSensitivitySuffix() const;\n\n            CaseSensitive::Choice m_caseSensitivity;\n            std::string m_str;\n        };\n\n        struct StringMatcherBase : MatcherBase<std::string> {\n            StringMatcherBase( std::string const& operation, CasedString const& comparator );\n            std::string describe() const override;\n\n            CasedString m_comparator;\n            std::string m_operation;\n        };\n\n        struct EqualsMatcher : StringMatcherBase {\n            EqualsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct ContainsMatcher : StringMatcherBase {\n            ContainsMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct StartsWithMatcher : StringMatcherBase {\n            StartsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n        struct EndsWithMatcher : StringMatcherBase {\n            EndsWithMatcher( CasedString const& comparator );\n            bool match( std::string const& source ) const override;\n        };\n\n        struct RegexMatcher : MatcherBase<std::string> {\n            RegexMatcher( std::string regex, CaseSensitive::Choice caseSensitivity );\n            bool match( std::string const& matchee ) const override;\n            std::string describe() const override;\n\n        private:\n            std::string m_regex;\n            CaseSensitive::Choice m_caseSensitivity;\n        };\n\n    } // namespace StdString\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n    StdString::RegexMatcher Matches( std::string const& regex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes );\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_string.h\n// start catch_matchers_vector.h\n\n#include <algorithm>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace Vector {\n        template<typename T, typename Alloc>\n        struct ContainsElementMatcher : MatcherBase<std::vector<T, Alloc>> {\n\n            ContainsElementMatcher(T const &comparator) : m_comparator( comparator) {}\n\n            bool match(std::vector<T, Alloc> const &v) const override {\n                for (auto const& el : v) {\n                    if (el == m_comparator) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            T const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ContainsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ContainsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: see note in EqualsMatcher\n                if (m_comparator.size() > v.size())\n                    return false;\n                for (auto const& comparator : m_comparator) {\n                    auto present = false;\n                    for (const auto& el : v) {\n                        if (el == comparator) {\n                            present = true;\n                            break;\n                        }\n                    }\n                    if (!present) {\n                        return false;\n                    }\n                }\n                return true;\n            }\n            std::string describe() const override {\n                return \"Contains: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct EqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            EqualsMatcher(std::vector<T, AllocComp> const &comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                // !TBD: This currently works if all elements can be compared using !=\n                // - a more general approach would be via a compare template that defaults\n                // to using !=. but could be specialised for, e.g. std::vector<T, Alloc> etc\n                // - then just call that directly\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != v[i])\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"Equals: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            std::vector<T, AllocComp> const& m_comparator;\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct ApproxMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n\n            ApproxMatcher(std::vector<T, AllocComp> const& comparator) : m_comparator( comparator ) {}\n\n            bool match(std::vector<T, AllocMatch> const &v) const override {\n                if (m_comparator.size() != v.size())\n                    return false;\n                for (std::size_t i = 0; i < v.size(); ++i)\n                    if (m_comparator[i] != approx(v[i]))\n                        return false;\n                return true;\n            }\n            std::string describe() const override {\n                return \"is approx: \" + ::Catch::Detail::stringify( m_comparator );\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& epsilon( T const& newEpsilon ) {\n                approx.epsilon(newEpsilon);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& margin( T const& newMargin ) {\n                approx.margin(newMargin);\n                return *this;\n            }\n            template <typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>\n            ApproxMatcher& scale( T const& newScale ) {\n                approx.scale(newScale);\n                return *this;\n            }\n\n            std::vector<T, AllocComp> const& m_comparator;\n            mutable Catch::Detail::Approx approx = Catch::Detail::Approx::custom();\n        };\n\n        template<typename T, typename AllocComp, typename AllocMatch>\n        struct UnorderedEqualsMatcher : MatcherBase<std::vector<T, AllocMatch>> {\n            UnorderedEqualsMatcher(std::vector<T, AllocComp> const& target) : m_target(target) {}\n            bool match(std::vector<T, AllocMatch> const& vec) const override {\n                if (m_target.size() != vec.size()) {\n                    return false;\n                }\n                return std::is_permutation(m_target.begin(), m_target.end(), vec.begin());\n            }\n\n            std::string describe() const override {\n                return \"UnorderedEquals: \" + ::Catch::Detail::stringify(m_target);\n            }\n        private:\n            std::vector<T, AllocComp> const& m_target;\n        };\n\n    } // namespace Vector\n\n    // The following functions create the actual matcher objects.\n    // This allows the types to be inferred\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ContainsMatcher<T, AllocComp, AllocMatch> Contains( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ContainsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename Alloc = std::allocator<T>>\n    Vector::ContainsElementMatcher<T, Alloc> VectorContains( T const& comparator ) {\n        return Vector::ContainsElementMatcher<T, Alloc>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::EqualsMatcher<T, AllocComp, AllocMatch> Equals( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::EqualsMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::ApproxMatcher<T, AllocComp, AllocMatch> Approx( std::vector<T, AllocComp> const& comparator ) {\n        return Vector::ApproxMatcher<T, AllocComp, AllocMatch>( comparator );\n    }\n\n    template<typename T, typename AllocComp = std::allocator<T>, typename AllocMatch = AllocComp>\n    Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch> UnorderedEquals(std::vector<T, AllocComp> const& target) {\n        return Vector::UnorderedEqualsMatcher<T, AllocComp, AllocMatch>( target );\n    }\n\n} // namespace Matchers\n} // namespace Catch\n\n// end catch_matchers_vector.h\nnamespace Catch {\n\n    template<typename ArgT, typename MatcherT>\n    class MatchExpr : public ITransientExpression {\n        ArgT const& m_arg;\n        MatcherT m_matcher;\n        StringRef m_matcherString;\n    public:\n        MatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString )\n        :   ITransientExpression{ true, matcher.match( arg ) },\n            m_arg( arg ),\n            m_matcher( matcher ),\n            m_matcherString( matcherString )\n        {}\n\n        void streamReconstructedExpression( std::ostream &os ) const override {\n            auto matcherAsString = m_matcher.toString();\n            os << Catch::Detail::stringify( m_arg ) << ' ';\n            if( matcherAsString == Detail::unprintableString )\n                os << m_matcherString;\n            else\n                os << matcherAsString;\n        }\n    };\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  );\n\n    template<typename ArgT, typename MatcherT>\n    auto makeMatchExpr( ArgT const& arg, MatcherT const& matcher, StringRef const& matcherString  ) -> MatchExpr<ArgT, MatcherT> {\n        return MatchExpr<ArgT, MatcherT>( arg, matcher, matcherString );\n    }\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CHECK_THAT( macroName, matcher, resultDisposition, arg ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        INTERNAL_CATCH_TRY { \\\n            catchAssertionHandler.handleExpr( Catch::makeMatchExpr( arg, matcher, #matcher##_catch_sr ) ); \\\n        } INTERNAL_CATCH_CATCH( catchAssertionHandler ) \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n///////////////////////////////////////////////////////////////////////////////\n#define INTERNAL_CATCH_THROWS_MATCHES( macroName, exceptionType, resultDisposition, matcher, ... ) \\\n    do { \\\n        Catch::AssertionHandler catchAssertionHandler( macroName##_catch_sr, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) \", \" CATCH_INTERNAL_STRINGIFY(exceptionType) \", \" CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition ); \\\n        if( catchAssertionHandler.allowThrows() ) \\\n            try { \\\n                static_cast<void>(__VA_ARGS__ ); \\\n                catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \\\n            } \\\n            catch( exceptionType const& ex ) { \\\n                catchAssertionHandler.handleExpr( Catch::makeMatchExpr( ex, matcher, #matcher##_catch_sr ) ); \\\n            } \\\n            catch( ... ) { \\\n                catchAssertionHandler.handleUnexpectedInflightException(); \\\n            } \\\n        else \\\n            catchAssertionHandler.handleThrowingCallSkipped(); \\\n        INTERNAL_CATCH_REACT( catchAssertionHandler ) \\\n    } while( false )\n\n// end catch_capture_matchers.h\n#endif\n// start catch_generators.hpp\n\n// start catch_interfaces_generatortracker.h\n\n\n#include <memory>\n\nnamespace Catch {\n\n    namespace Generators {\n        class GeneratorUntypedBase {\n        public:\n            GeneratorUntypedBase() = default;\n            virtual ~GeneratorUntypedBase();\n            // Attempts to move the generator to the next element\n             //\n             // Returns true iff the move succeeded (and a valid element\n             // can be retrieved).\n            virtual bool next() = 0;\n        };\n        using GeneratorBasePtr = std::unique_ptr<GeneratorUntypedBase>;\n\n    } // namespace Generators\n\n    struct IGeneratorTracker {\n        virtual ~IGeneratorTracker();\n        virtual auto hasGenerator() const -> bool = 0;\n        virtual auto getGenerator() const -> Generators::GeneratorBasePtr const& = 0;\n        virtual void setGenerator( Generators::GeneratorBasePtr&& generator ) = 0;\n    };\n\n} // namespace Catch\n\n// end catch_interfaces_generatortracker.h\n// start catch_enforce.h\n\n#include <exception>\n\nnamespace Catch {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    template <typename Ex>\n    [[noreturn]]\n    void throw_exception(Ex const& e) {\n        throw e;\n    }\n#else // ^^ Exceptions are enabled //  Exceptions are disabled vv\n    [[noreturn]]\n    void throw_exception(std::exception const& e);\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg);\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg);\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg);\n\n} // namespace Catch;\n\n#define CATCH_MAKE_MSG(...) \\\n    (Catch::ReusableStringStream() << __VA_ARGS__).str()\n\n#define CATCH_INTERNAL_ERROR(...) \\\n    Catch::throw_logic_error(CATCH_MAKE_MSG( CATCH_INTERNAL_LINEINFO << \": Internal Catch2 error: \" << __VA_ARGS__))\n\n#define CATCH_ERROR(...) \\\n    Catch::throw_domain_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_RUNTIME_ERROR(...) \\\n    Catch::throw_runtime_error(CATCH_MAKE_MSG( __VA_ARGS__ ))\n\n#define CATCH_ENFORCE( condition, ... ) \\\n    do{ if( !(condition) ) CATCH_ERROR( __VA_ARGS__ ); } while(false)\n\n// end catch_enforce.h\n#include <memory>\n#include <vector>\n#include <cassert>\n\n#include <utility>\n#include <exception>\n\nnamespace Catch {\n\nclass GeneratorException : public std::exception {\n    const char* const m_msg = \"\";\n\npublic:\n    GeneratorException(const char* msg):\n        m_msg(msg)\n    {}\n\n    const char* what() const noexcept override final;\n};\n\nnamespace Generators {\n\n    // !TBD move this into its own location?\n    namespace pf{\n        template<typename T, typename... Args>\n        std::unique_ptr<T> make_unique( Args&&... args ) {\n            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));\n        }\n    }\n\n    template<typename T>\n    struct IGenerator : GeneratorUntypedBase {\n        virtual ~IGenerator() = default;\n\n        // Returns the current element of the generator\n        //\n        // \\Precondition The generator is either freshly constructed,\n        // or the last call to `next()` returned true\n        virtual T const& get() const = 0;\n        using type = T;\n    };\n\n    template<typename T>\n    class SingleValueGenerator final : public IGenerator<T> {\n        T m_value;\n    public:\n        SingleValueGenerator(T&& value) : m_value(std::move(value)) {}\n\n        T const& get() const override {\n            return m_value;\n        }\n        bool next() override {\n            return false;\n        }\n    };\n\n    template<typename T>\n    class FixedValuesGenerator final : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"FixedValuesGenerator does not support bools because of std::vector<bool>\"\n            \"specialization, use SingleValue Generator instead.\");\n        std::vector<T> m_values;\n        size_t m_idx = 0;\n    public:\n        FixedValuesGenerator( std::initializer_list<T> values ) : m_values( values ) {}\n\n        T const& get() const override {\n            return m_values[m_idx];\n        }\n        bool next() override {\n            ++m_idx;\n            return m_idx < m_values.size();\n        }\n    };\n\n    template <typename T>\n    class GeneratorWrapper final {\n        std::unique_ptr<IGenerator<T>> m_generator;\n    public:\n        GeneratorWrapper(std::unique_ptr<IGenerator<T>> generator):\n            m_generator(std::move(generator))\n        {}\n        T const& get() const {\n            return m_generator->get();\n        }\n        bool next() {\n            return m_generator->next();\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> value(T&& value) {\n        return GeneratorWrapper<T>(pf::make_unique<SingleValueGenerator<T>>(std::forward<T>(value)));\n    }\n    template <typename T>\n    GeneratorWrapper<T> values(std::initializer_list<T> values) {\n        return GeneratorWrapper<T>(pf::make_unique<FixedValuesGenerator<T>>(values));\n    }\n\n    template<typename T>\n    class Generators : public IGenerator<T> {\n        std::vector<GeneratorWrapper<T>> m_generators;\n        size_t m_current = 0;\n\n        void populate(GeneratorWrapper<T>&& generator) {\n            m_generators.emplace_back(std::move(generator));\n        }\n        void populate(T&& val) {\n            m_generators.emplace_back(value(std::forward<T>(val)));\n        }\n        template<typename U>\n        void populate(U&& val) {\n            populate(T(std::forward<U>(val)));\n        }\n        template<typename U, typename... Gs>\n        void populate(U&& valueOrGenerator, Gs &&... moreGenerators) {\n            populate(std::forward<U>(valueOrGenerator));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n    public:\n        template <typename... Gs>\n        Generators(Gs &&... moreGenerators) {\n            m_generators.reserve(sizeof...(Gs));\n            populate(std::forward<Gs>(moreGenerators)...);\n        }\n\n        T const& get() const override {\n            return m_generators[m_current].get();\n        }\n\n        bool next() override {\n            if (m_current >= m_generators.size()) {\n                return false;\n            }\n            const bool current_status = m_generators[m_current].next();\n            if (!current_status) {\n                ++m_current;\n            }\n            return m_current < m_generators.size();\n        }\n    };\n\n    template<typename... Ts>\n    GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) {\n        return values<std::tuple<Ts...>>( tuples );\n    }\n\n    // Tag type to signal that a generator sequence should convert arguments to a specific type\n    template <typename T>\n    struct as {};\n\n    template<typename T, typename... Gs>\n    auto makeGenerators( GeneratorWrapper<T>&& generator, Gs &&... moreGenerators ) -> Generators<T> {\n        return Generators<T>(std::move(generator), std::forward<Gs>(moreGenerators)...);\n    }\n    template<typename T>\n    auto makeGenerators( GeneratorWrapper<T>&& generator ) -> Generators<T> {\n        return Generators<T>(std::move(generator));\n    }\n    template<typename T, typename... Gs>\n    auto makeGenerators( T&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( std::forward<T>( val ) ), std::forward<Gs>( moreGenerators )... );\n    }\n    template<typename T, typename U, typename... Gs>\n    auto makeGenerators( as<T>, U&& val, Gs &&... moreGenerators ) -> Generators<T> {\n        return makeGenerators( value( T( std::forward<U>( val ) ) ), std::forward<Gs>( moreGenerators )... );\n    }\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker&;\n\n    template<typename L>\n    // Note: The type after -> is weird, because VS2015 cannot parse\n    //       the expression used in the typedef inside, when it is in\n    //       return type. Yeah.\n    auto generate( StringRef generatorName, SourceLineInfo const& lineInfo, L const& generatorExpression ) -> decltype(std::declval<decltype(generatorExpression())>().get()) {\n        using UnderlyingType = typename decltype(generatorExpression())::type;\n\n        IGeneratorTracker& tracker = acquireGeneratorTracker( generatorName, lineInfo );\n        if (!tracker.hasGenerator()) {\n            tracker.setGenerator(pf::make_unique<Generators<UnderlyingType>>(generatorExpression()));\n        }\n\n        auto const& generator = static_cast<IGenerator<UnderlyingType> const&>( *tracker.getGenerator() );\n        return generator.get();\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n#define GENERATE( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [ ]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_COPY( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [=]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n#define GENERATE_REF( ... ) \\\n    Catch::Generators::generate( INTERNAL_CATCH_STRINGIZE(INTERNAL_CATCH_UNIQUE_NAME(generator)), \\\n                                 CATCH_INTERNAL_LINEINFO, \\\n                                 [&]{ using namespace Catch::Generators; return makeGenerators( __VA_ARGS__ ); } ) //NOLINT(google-build-using-namespace)\n\n// end catch_generators.hpp\n// start catch_generators_generic.hpp\n\nnamespace Catch {\nnamespace Generators {\n\n    template <typename T>\n    class TakeGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        size_t m_returned = 0;\n        size_t m_target;\n    public:\n        TakeGenerator(size_t target, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target(target)\n        {\n            assert(target != 0 && \"Empty generators are not allowed\");\n        }\n        T const& get() const override {\n            return m_generator.get();\n        }\n        bool next() override {\n            ++m_returned;\n            if (m_returned >= m_target) {\n                return false;\n            }\n\n            const auto success = m_generator.next();\n            // If the underlying generator does not contain enough values\n            // then we cut short as well\n            if (!success) {\n                m_returned = m_target;\n            }\n            return success;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> take(size_t target, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<TakeGenerator<T>>(target, std::move(generator)));\n    }\n\n    template <typename T, typename Predicate>\n    class FilterGenerator : public IGenerator<T> {\n        GeneratorWrapper<T> m_generator;\n        Predicate m_predicate;\n    public:\n        template <typename P = Predicate>\n        FilterGenerator(P&& pred, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_predicate(std::forward<P>(pred))\n        {\n            if (!m_predicate(m_generator.get())) {\n                // It might happen that there are no values that pass the\n                // filter. In that case we throw an exception.\n                auto has_initial_value = nextImpl();\n                if (!has_initial_value) {\n                    Catch::throw_exception(GeneratorException(\"No valid value found in filtered generator\"));\n                }\n            }\n        }\n\n        T const& get() const override {\n            return m_generator.get();\n        }\n\n        bool next() override {\n            return nextImpl();\n        }\n\n    private:\n        bool nextImpl() {\n            bool success = m_generator.next();\n            if (!success) {\n                return false;\n            }\n            while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);\n            return success;\n        }\n    };\n\n    template <typename T, typename Predicate>\n    GeneratorWrapper<T> filter(Predicate&& pred, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(std::unique_ptr<IGenerator<T>>(pf::make_unique<FilterGenerator<T, Predicate>>(std::forward<Predicate>(pred), std::move(generator))));\n    }\n\n    template <typename T>\n    class RepeatGenerator : public IGenerator<T> {\n        static_assert(!std::is_same<T, bool>::value,\n            \"RepeatGenerator currently does not support bools\"\n            \"because of std::vector<bool> specialization\");\n        GeneratorWrapper<T> m_generator;\n        mutable std::vector<T> m_returned;\n        size_t m_target_repeats;\n        size_t m_current_repeat = 0;\n        size_t m_repeat_index = 0;\n    public:\n        RepeatGenerator(size_t repeats, GeneratorWrapper<T>&& generator):\n            m_generator(std::move(generator)),\n            m_target_repeats(repeats)\n        {\n            assert(m_target_repeats > 0 && \"Repeat generator must repeat at least once\");\n        }\n\n        T const& get() const override {\n            if (m_current_repeat == 0) {\n                m_returned.push_back(m_generator.get());\n                return m_returned.back();\n            }\n            return m_returned[m_repeat_index];\n        }\n\n        bool next() override {\n            // There are 2 basic cases:\n            // 1) We are still reading the generator\n            // 2) We are reading our own cache\n\n            // In the first case, we need to poke the underlying generator.\n            // If it happily moves, we are left in that state, otherwise it is time to start reading from our cache\n            if (m_current_repeat == 0) {\n                const auto success = m_generator.next();\n                if (!success) {\n                    ++m_current_repeat;\n                }\n                return m_current_repeat < m_target_repeats;\n            }\n\n            // In the second case, we need to move indices forward and check that we haven't run up against the end\n            ++m_repeat_index;\n            if (m_repeat_index == m_returned.size()) {\n                m_repeat_index = 0;\n                ++m_current_repeat;\n            }\n            return m_current_repeat < m_target_repeats;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<T> repeat(size_t repeats, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<T>(pf::make_unique<RepeatGenerator<T>>(repeats, std::move(generator)));\n    }\n\n    template <typename T, typename U, typename Func>\n    class MapGenerator : public IGenerator<T> {\n        // TBD: provide static assert for mapping function, for friendly error message\n        GeneratorWrapper<U> m_generator;\n        Func m_function;\n        // To avoid returning dangling reference, we have to save the values\n        T m_cache;\n    public:\n        template <typename F2 = Func>\n        MapGenerator(F2&& function, GeneratorWrapper<U>&& generator) :\n            m_generator(std::move(generator)),\n            m_function(std::forward<F2>(function)),\n            m_cache(m_function(m_generator.get()))\n        {}\n\n        T const& get() const override {\n            return m_cache;\n        }\n        bool next() override {\n            const auto success = m_generator.next();\n            if (success) {\n                m_cache = m_function(m_generator.get());\n            }\n            return success;\n        }\n    };\n\n    template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T, typename U, typename Func>\n    GeneratorWrapper<T> map(Func&& function, GeneratorWrapper<U>&& generator) {\n        return GeneratorWrapper<T>(\n            pf::make_unique<MapGenerator<T, U, Func>>(std::forward<Func>(function), std::move(generator))\n        );\n    }\n\n    template <typename T>\n    class ChunkGenerator final : public IGenerator<std::vector<T>> {\n        std::vector<T> m_chunk;\n        size_t m_chunk_size;\n        GeneratorWrapper<T> m_generator;\n        bool m_used_up = false;\n    public:\n        ChunkGenerator(size_t size, GeneratorWrapper<T> generator) :\n            m_chunk_size(size), m_generator(std::move(generator))\n        {\n            m_chunk.reserve(m_chunk_size);\n            if (m_chunk_size != 0) {\n                m_chunk.push_back(m_generator.get());\n                for (size_t i = 1; i < m_chunk_size; ++i) {\n                    if (!m_generator.next()) {\n                        Catch::throw_exception(GeneratorException(\"Not enough values to initialize the first chunk\"));\n                    }\n                    m_chunk.push_back(m_generator.get());\n                }\n            }\n        }\n        std::vector<T> const& get() const override {\n            return m_chunk;\n        }\n        bool next() override {\n            m_chunk.clear();\n            for (size_t idx = 0; idx < m_chunk_size; ++idx) {\n                if (!m_generator.next()) {\n                    return false;\n                }\n                m_chunk.push_back(m_generator.get());\n            }\n            return true;\n        }\n    };\n\n    template <typename T>\n    GeneratorWrapper<std::vector<T>> chunk(size_t size, GeneratorWrapper<T>&& generator) {\n        return GeneratorWrapper<std::vector<T>>(\n            pf::make_unique<ChunkGenerator<T>>(size, std::move(generator))\n        );\n    }\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_generic.hpp\n// start catch_generators_specific.hpp\n\n// start catch_context.h\n\n#include <memory>\n\nnamespace Catch {\n\n    struct IResultCapture;\n    struct IRunner;\n    struct IConfig;\n    struct IMutableContext;\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n\n    struct IContext\n    {\n        virtual ~IContext();\n\n        virtual IResultCapture* getResultCapture() = 0;\n        virtual IRunner* getRunner() = 0;\n        virtual IConfigPtr const& getConfig() const = 0;\n    };\n\n    struct IMutableContext : IContext\n    {\n        virtual ~IMutableContext();\n        virtual void setResultCapture( IResultCapture* resultCapture ) = 0;\n        virtual void setRunner( IRunner* runner ) = 0;\n        virtual void setConfig( IConfigPtr const& config ) = 0;\n\n    private:\n        static IMutableContext *currentContext;\n        friend IMutableContext& getCurrentMutableContext();\n        friend void cleanUpContext();\n        static void createContext();\n    };\n\n    inline IMutableContext& getCurrentMutableContext()\n    {\n        if( !IMutableContext::currentContext )\n            IMutableContext::createContext();\n        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)\n        return *IMutableContext::currentContext;\n    }\n\n    inline IContext& getCurrentContext()\n    {\n        return getCurrentMutableContext();\n    }\n\n    void cleanUpContext();\n\n    class SimplePcg32;\n    SimplePcg32& rng();\n}\n\n// end catch_context.h\n// start catch_interfaces_config.h\n\n// start catch_option.hpp\n\nnamespace Catch {\n\n    // An optional type\n    template<typename T>\n    class Option {\n    public:\n        Option() : nullableValue( nullptr ) {}\n        Option( T const& _value )\n        : nullableValue( new( storage ) T( _value ) )\n        {}\n        Option( Option const& _other )\n        : nullableValue( _other ? new( storage ) T( *_other ) : nullptr )\n        {}\n\n        ~Option() {\n            reset();\n        }\n\n        Option& operator= ( Option const& _other ) {\n            if( &_other != this ) {\n                reset();\n                if( _other )\n                    nullableValue = new( storage ) T( *_other );\n            }\n            return *this;\n        }\n        Option& operator = ( T const& _value ) {\n            reset();\n            nullableValue = new( storage ) T( _value );\n            return *this;\n        }\n\n        void reset() {\n            if( nullableValue )\n                nullableValue->~T();\n            nullableValue = nullptr;\n        }\n\n        T& operator*() { return *nullableValue; }\n        T const& operator*() const { return *nullableValue; }\n        T* operator->() { return nullableValue; }\n        const T* operator->() const { return nullableValue; }\n\n        T valueOr( T const& defaultValue ) const {\n            return nullableValue ? *nullableValue : defaultValue;\n        }\n\n        bool some() const { return nullableValue != nullptr; }\n        bool none() const { return nullableValue == nullptr; }\n\n        bool operator !() const { return nullableValue == nullptr; }\n        explicit operator bool() const {\n            return some();\n        }\n\n    private:\n        T *nullableValue;\n        alignas(alignof(T)) char storage[sizeof(T)];\n    };\n\n} // end namespace Catch\n\n// end catch_option.hpp\n#include <chrono>\n#include <iosfwd>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    enum class Verbosity {\n        Quiet = 0,\n        Normal,\n        High\n    };\n\n    struct WarnAbout { enum What {\n        Nothing = 0x00,\n        NoAssertions = 0x01,\n        NoTests = 0x02\n    }; };\n\n    struct ShowDurations { enum OrNot {\n        DefaultForReporter,\n        Always,\n        Never\n    }; };\n    struct RunTests { enum InWhatOrder {\n        InDeclarationOrder,\n        InLexicographicalOrder,\n        InRandomOrder\n    }; };\n    struct UseColour { enum YesOrNo {\n        Auto,\n        Yes,\n        No\n    }; };\n    struct WaitForKeypress { enum When {\n        Never,\n        BeforeStart = 1,\n        BeforeExit = 2,\n        BeforeStartAndExit = BeforeStart | BeforeExit\n    }; };\n\n    class TestSpec;\n\n    struct IConfig : NonCopyable {\n\n        virtual ~IConfig();\n\n        virtual bool allowThrows() const = 0;\n        virtual std::ostream& stream() const = 0;\n        virtual std::string name() const = 0;\n        virtual bool includeSuccessfulResults() const = 0;\n        virtual bool shouldDebugBreak() const = 0;\n        virtual bool warnAboutMissingAssertions() const = 0;\n        virtual bool warnAboutNoTests() const = 0;\n        virtual int abortAfter() const = 0;\n        virtual bool showInvisibles() const = 0;\n        virtual ShowDurations::OrNot showDurations() const = 0;\n        virtual double minDuration() const = 0;\n        virtual TestSpec const& testSpec() const = 0;\n        virtual bool hasTestFilters() const = 0;\n        virtual std::vector<std::string> const& getTestsOrTags() const = 0;\n        virtual RunTests::InWhatOrder runOrder() const = 0;\n        virtual unsigned int rngSeed() const = 0;\n        virtual UseColour::YesOrNo useColour() const = 0;\n        virtual std::vector<std::string> const& getSectionsToRun() const = 0;\n        virtual Verbosity verbosity() const = 0;\n\n        virtual bool benchmarkNoAnalysis() const = 0;\n        virtual int benchmarkSamples() const = 0;\n        virtual double benchmarkConfidenceInterval() const = 0;\n        virtual unsigned int benchmarkResamples() const = 0;\n        virtual std::chrono::milliseconds benchmarkWarmupTime() const = 0;\n    };\n\n    using IConfigPtr = std::shared_ptr<IConfig const>;\n}\n\n// end catch_interfaces_config.h\n// start catch_random_number_generator.h\n\n#include <cstdint>\n\nnamespace Catch {\n\n    // This is a simple implementation of C++11 Uniform Random Number\n    // Generator. It does not provide all operators, because Catch2\n    // does not use it, but it should behave as expected inside stdlib's\n    // distributions.\n    // The implementation is based on the PCG family (http://pcg-random.org)\n    class SimplePcg32 {\n        using state_type = std::uint64_t;\n    public:\n        using result_type = std::uint32_t;\n        static constexpr result_type (min)() {\n            return 0;\n        }\n        static constexpr result_type (max)() {\n            return static_cast<result_type>(-1);\n        }\n\n        // Provide some default initial state for the default constructor\n        SimplePcg32():SimplePcg32(0xed743cc4U) {}\n\n        explicit SimplePcg32(result_type seed_);\n\n        void seed(result_type seed_);\n        void discard(uint64_t skip);\n\n        result_type operator()();\n\n    private:\n        friend bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n        friend bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs);\n\n        // In theory we also need operator<< and operator>>\n        // In practice we do not use them, so we will skip them for now\n\n        std::uint64_t m_state;\n        // This part of the state determines which \"stream\" of the numbers\n        // is chosen -- we take it as a constant for Catch2, so we only\n        // need to deal with seeding the main state.\n        // Picked by reading 8 bytes from `/dev/random` :-)\n        static const std::uint64_t s_inc = (0x13ed0cc53f939476ULL << 1ULL) | 1ULL;\n    };\n\n} // end namespace Catch\n\n// end catch_random_number_generator.h\n#include <random>\n\nnamespace Catch {\nnamespace Generators {\n\ntemplate <typename Float>\nclass RandomFloatingGenerator final : public IGenerator<Float> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_real_distribution<Float> m_dist;\n    Float m_current_number;\npublic:\n\n    RandomFloatingGenerator(Float a, Float b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Float const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\ntemplate <typename Integer>\nclass RandomIntegerGenerator final : public IGenerator<Integer> {\n    Catch::SimplePcg32& m_rng;\n    std::uniform_int_distribution<Integer> m_dist;\n    Integer m_current_number;\npublic:\n\n    RandomIntegerGenerator(Integer a, Integer b):\n        m_rng(rng()),\n        m_dist(a, b) {\n        static_cast<void>(next());\n    }\n\n    Integer const& get() const override {\n        return m_current_number;\n    }\n    bool next() override {\n        m_current_number = m_dist(m_rng);\n        return true;\n    }\n};\n\n// TODO: Ideally this would be also constrained against the various char types,\n//       but I don't expect users to run into that in practice.\ntemplate <typename T>\ntypename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomIntegerGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\ntypename std::enable_if<std::is_floating_point<T>::value,\nGeneratorWrapper<T>>::type\nrandom(T a, T b) {\n    return GeneratorWrapper<T>(\n        pf::make_unique<RandomFloatingGenerator<T>>(a, b)\n    );\n}\n\ntemplate <typename T>\nclass RangeGenerator final : public IGenerator<T> {\n    T m_current;\n    T m_end;\n    T m_step;\n    bool m_positive;\n\npublic:\n    RangeGenerator(T const& start, T const& end, T const& step):\n        m_current(start),\n        m_end(end),\n        m_step(step),\n        m_positive(m_step > T(0))\n    {\n        assert(m_current != m_end && \"Range start and end cannot be equal\");\n        assert(m_step != T(0) && \"Step size cannot be zero\");\n        assert(((m_positive && m_current <= m_end) || (!m_positive && m_current >= m_end)) && \"Step moves away from end\");\n    }\n\n    RangeGenerator(T const& start, T const& end):\n        RangeGenerator(start, end, (start < end) ? T(1) : T(-1))\n    {}\n\n    T const& get() const override {\n        return m_current;\n    }\n\n    bool next() override {\n        m_current += m_step;\n        return (m_positive) ? (m_current < m_end) : (m_current > m_end);\n    }\n};\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end, T const& step) {\n    static_assert(std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, \"Type must be numeric\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end, step));\n}\n\ntemplate <typename T>\nGeneratorWrapper<T> range(T const& start, T const& end) {\n    static_assert(std::is_integral<T>::value && !std::is_same<T, bool>::value, \"Type must be an integer\");\n    return GeneratorWrapper<T>(pf::make_unique<RangeGenerator<T>>(start, end));\n}\n\ntemplate <typename T>\nclass IteratorGenerator final : public IGenerator<T> {\n    static_assert(!std::is_same<T, bool>::value,\n        \"IteratorGenerator currently does not support bools\"\n        \"because of std::vector<bool> specialization\");\n\n    std::vector<T> m_elems;\n    size_t m_current = 0;\npublic:\n    template <typename InputIterator, typename InputSentinel>\n    IteratorGenerator(InputIterator first, InputSentinel last):m_elems(first, last) {\n        if (m_elems.empty()) {\n            Catch::throw_exception(GeneratorException(\"IteratorGenerator received no valid values\"));\n        }\n    }\n\n    T const& get() const override {\n        return m_elems[m_current];\n    }\n\n    bool next() override {\n        ++m_current;\n        return m_current != m_elems.size();\n    }\n};\n\ntemplate <typename InputIterator,\n          typename InputSentinel,\n          typename ResultType = typename std::iterator_traits<InputIterator>::value_type>\nGeneratorWrapper<ResultType> from_range(InputIterator from, InputSentinel to) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(from, to));\n}\n\ntemplate <typename Container,\n          typename ResultType = typename Container::value_type>\nGeneratorWrapper<ResultType> from_range(Container const& cnt) {\n    return GeneratorWrapper<ResultType>(pf::make_unique<IteratorGenerator<ResultType>>(cnt.begin(), cnt.end()));\n}\n\n} // namespace Generators\n} // namespace Catch\n\n// end catch_generators_specific.hpp\n\n// These files are included here so the single_include script doesn't put them\n// in the conditionally compiled sections\n// start catch_test_case_info.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\nnamespace Catch {\n\n    struct ITestInvoker;\n\n    struct TestCaseInfo {\n        enum SpecialProperties{\n            None = 0,\n            IsHidden = 1 << 1,\n            ShouldFail = 1 << 2,\n            MayFail = 1 << 3,\n            Throws = 1 << 4,\n            NonPortable = 1 << 5,\n            Benchmark = 1 << 6\n        };\n\n        TestCaseInfo(   std::string const& _name,\n                        std::string const& _className,\n                        std::string const& _description,\n                        std::vector<std::string> const& _tags,\n                        SourceLineInfo const& _lineInfo );\n\n        friend void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags );\n\n        bool isHidden() const;\n        bool throws() const;\n        bool okToFail() const;\n        bool expectedToFail() const;\n\n        std::string tagsAsString() const;\n\n        std::string name;\n        std::string className;\n        std::string description;\n        std::vector<std::string> tags;\n        std::vector<std::string> lcaseTags;\n        SourceLineInfo lineInfo;\n        SpecialProperties properties;\n    };\n\n    class TestCase : public TestCaseInfo {\n    public:\n\n        TestCase( ITestInvoker* testCase, TestCaseInfo&& info );\n\n        TestCase withName( std::string const& _newName ) const;\n\n        void invoke() const;\n\n        TestCaseInfo const& getTestCaseInfo() const;\n\n        bool operator == ( TestCase const& other ) const;\n        bool operator < ( TestCase const& other ) const;\n\n    private:\n        std::shared_ptr<ITestInvoker> test;\n    };\n\n    TestCase makeTestCase(  ITestInvoker* testCase,\n                            std::string const& className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& lineInfo );\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_case_info.h\n// start catch_interfaces_runner.h\n\nnamespace Catch {\n\n    struct IRunner {\n        virtual ~IRunner();\n        virtual bool aborting() const = 0;\n    };\n}\n\n// end catch_interfaces_runner.h\n\n#ifdef __OBJC__\n// start catch_objc.hpp\n\n#import <objc/runtime.h>\n\n#include <string>\n\n// NB. Any general catch headers included here must be included\n// in catch.hpp first to make sure they are included by the single\n// header for non obj-usage\n\n///////////////////////////////////////////////////////////////////////////////\n// This protocol is really only here for (self) documenting purposes, since\n// all its methods are optional.\n@protocol OcFixture\n\n@optional\n\n-(void) setUp;\n-(void) tearDown;\n\n@end\n\nnamespace Catch {\n\n    class OcMethod : public ITestInvoker {\n\n    public:\n        OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {}\n\n        virtual void invoke() const {\n            id obj = [[m_cls alloc] init];\n\n            performOptionalSelector( obj, @selector(setUp)  );\n            performOptionalSelector( obj, m_sel );\n            performOptionalSelector( obj, @selector(tearDown)  );\n\n            arcSafeRelease( obj );\n        }\n    private:\n        virtual ~OcMethod() {}\n\n        Class m_cls;\n        SEL m_sel;\n    };\n\n    namespace Detail{\n\n        inline std::string getAnnotation(   Class cls,\n                                            std::string const& annotationName,\n                                            std::string const& testCaseName ) {\n            NSString* selStr = [[NSString alloc] initWithFormat:@\"Catch_%s_%s\", annotationName.c_str(), testCaseName.c_str()];\n            SEL sel = NSSelectorFromString( selStr );\n            arcSafeRelease( selStr );\n            id value = performOptionalSelector( cls, sel );\n            if( value )\n                return [(NSString*)value UTF8String];\n            return \"\";\n        }\n    }\n\n    inline std::size_t registerTestMethods() {\n        std::size_t noTestMethods = 0;\n        int noClasses = objc_getClassList( nullptr, 0 );\n\n        Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses);\n        objc_getClassList( classes, noClasses );\n\n        for( int c = 0; c < noClasses; c++ ) {\n            Class cls = classes[c];\n            {\n                u_int count;\n                Method* methods = class_copyMethodList( cls, &count );\n                for( u_int m = 0; m < count ; m++ ) {\n                    SEL selector = method_getName(methods[m]);\n                    std::string methodName = sel_getName(selector);\n                    if( startsWith( methodName, \"Catch_TestCase_\" ) ) {\n                        std::string testCaseName = methodName.substr( 15 );\n                        std::string name = Detail::getAnnotation( cls, \"Name\", testCaseName );\n                        std::string desc = Detail::getAnnotation( cls, \"Description\", testCaseName );\n                        const char* className = class_getName( cls );\n\n                        getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, NameAndTags( name.c_str(), desc.c_str() ), SourceLineInfo(\"\",0) ) );\n                        noTestMethods++;\n                    }\n                }\n                free(methods);\n            }\n        }\n        return noTestMethods;\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n\n    namespace Matchers {\n        namespace Impl {\n        namespace NSStringMatchers {\n\n            struct StringHolder : MatcherBase<NSString*>{\n                StringHolder( NSString* substr ) : m_substr( [substr copy] ){}\n                StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){}\n                StringHolder() {\n                    arcSafeRelease( m_substr );\n                }\n\n                bool match( NSString* str ) const override {\n                    return false;\n                }\n\n                NSString* CATCH_ARC_STRONG m_substr;\n            };\n\n            struct Equals : StringHolder {\n                Equals( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str isEqualToString:m_substr];\n                }\n\n                std::string describe() const override {\n                    return \"equals string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct Contains : StringHolder {\n                Contains( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location != NSNotFound;\n                }\n\n                std::string describe() const override {\n                    return \"contains string: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n            struct StartsWith : StringHolder {\n                StartsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == 0;\n                }\n\n                std::string describe() const override {\n                    return \"starts with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n            struct EndsWith : StringHolder {\n                EndsWith( NSString* substr ) : StringHolder( substr ){}\n\n                bool match( NSString* str ) const override {\n                    return  (str != nil || m_substr == nil ) &&\n                            [str rangeOfString:m_substr].location == [str length] - [m_substr length];\n                }\n\n                std::string describe() const override {\n                    return \"ends with: \" + Catch::Detail::stringify( m_substr );\n                }\n            };\n\n        } // namespace NSStringMatchers\n        } // namespace Impl\n\n        inline Impl::NSStringMatchers::Equals\n            Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); }\n\n        inline Impl::NSStringMatchers::Contains\n            Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); }\n\n        inline Impl::NSStringMatchers::StartsWith\n            StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); }\n\n        inline Impl::NSStringMatchers::EndsWith\n            EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); }\n\n    } // namespace Matchers\n\n    using namespace Matchers;\n\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n} // namespace Catch\n\n///////////////////////////////////////////////////////////////////////////////\n#define OC_MAKE_UNIQUE_NAME( root, uniqueSuffix ) root##uniqueSuffix\n#define OC_TEST_CASE2( name, desc, uniqueSuffix ) \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Name_test_, uniqueSuffix ) \\\n{ \\\nreturn @ name; \\\n} \\\n+(NSString*) OC_MAKE_UNIQUE_NAME( Catch_Description_test_, uniqueSuffix ) \\\n{ \\\nreturn @ desc; \\\n} \\\n-(void) OC_MAKE_UNIQUE_NAME( Catch_TestCase_test_, uniqueSuffix )\n\n#define OC_TEST_CASE( name, desc ) OC_TEST_CASE2( name, desc, __LINE__ )\n\n// end catch_objc.hpp\n#endif\n\n// Benchmarking needs the externally-facing parts of reporters to work\n#if defined(CATCH_CONFIG_EXTERNAL_INTERFACES) || defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_external_interfaces.h\n\n// start catch_reporter_bases.hpp\n\n// start catch_interfaces_reporter.h\n\n// start catch_config.hpp\n\n// start catch_test_spec_parser.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_test_spec.h\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wpadded\"\n#endif\n\n// start catch_wildcard_pattern.h\n\nnamespace Catch\n{\n    class WildcardPattern {\n        enum WildcardPosition {\n            NoWildcard = 0,\n            WildcardAtStart = 1,\n            WildcardAtEnd = 2,\n            WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd\n        };\n\n    public:\n\n        WildcardPattern( std::string const& pattern, CaseSensitive::Choice caseSensitivity );\n        virtual ~WildcardPattern() = default;\n        virtual bool matches( std::string const& str ) const;\n\n    private:\n        std::string normaliseString( std::string const& str ) const;\n        CaseSensitive::Choice m_caseSensitivity;\n        WildcardPosition m_wildcard = NoWildcard;\n        std::string m_pattern;\n    };\n}\n\n// end catch_wildcard_pattern.h\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    struct IConfig;\n\n    class TestSpec {\n        class Pattern {\n        public:\n            explicit Pattern( std::string const& name );\n            virtual ~Pattern();\n            virtual bool matches( TestCaseInfo const& testCase ) const = 0;\n            std::string const& name() const;\n        private:\n            std::string const m_name;\n        };\n        using PatternPtr = std::shared_ptr<Pattern>;\n\n        class NamePattern : public Pattern {\n        public:\n            explicit NamePattern( std::string const& name, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            WildcardPattern m_wildcardPattern;\n        };\n\n        class TagPattern : public Pattern {\n        public:\n            explicit TagPattern( std::string const& tag, std::string const& filterString );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            std::string m_tag;\n        };\n\n        class ExcludedPattern : public Pattern {\n        public:\n            explicit ExcludedPattern( PatternPtr const& underlyingPattern );\n            bool matches( TestCaseInfo const& testCase ) const override;\n        private:\n            PatternPtr m_underlyingPattern;\n        };\n\n        struct Filter {\n            std::vector<PatternPtr> m_patterns;\n\n            bool matches( TestCaseInfo const& testCase ) const;\n            std::string name() const;\n        };\n\n    public:\n        struct FilterMatch {\n            std::string name;\n            std::vector<TestCase const*> tests;\n        };\n        using Matches = std::vector<FilterMatch>;\n        using vectorStrings = std::vector<std::string>;\n\n        bool hasFilters() const;\n        bool matches( TestCaseInfo const& testCase ) const;\n        Matches matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const;\n        const vectorStrings & getInvalidArgs() const;\n\n    private:\n        std::vector<Filter> m_filters;\n        std::vector<std::string> m_invalidArgs;\n        friend class TestSpecParser;\n    };\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec.h\n// start catch_interfaces_tag_alias_registry.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias;\n\n    struct ITagAliasRegistry {\n        virtual ~ITagAliasRegistry();\n        // Nullptr if not present\n        virtual TagAlias const* find( std::string const& alias ) const = 0;\n        virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0;\n\n        static ITagAliasRegistry const& get();\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_tag_alias_registry.h\nnamespace Catch {\n\n    class TestSpecParser {\n        enum Mode{ None, Name, QuotedName, Tag, EscapedName };\n        Mode m_mode = None;\n        Mode lastMode = None;\n        bool m_exclusion = false;\n        std::size_t m_pos = 0;\n        std::size_t m_realPatternPos = 0;\n        std::string m_arg;\n        std::string m_substring;\n        std::string m_patternName;\n        std::vector<std::size_t> m_escapeChars;\n        TestSpec::Filter m_currentFilter;\n        TestSpec m_testSpec;\n        ITagAliasRegistry const* m_tagAliases = nullptr;\n\n    public:\n        TestSpecParser( ITagAliasRegistry const& tagAliases );\n\n        TestSpecParser& parse( std::string const& arg );\n        TestSpec testSpec();\n\n    private:\n        bool visitChar( char c );\n        void startNewMode( Mode mode );\n        bool processNoneChar( char c );\n        void processNameChar( char c );\n        bool processOtherChar( char c );\n        void endMode();\n        void escape();\n        bool isControlChar( char c ) const;\n        void saveLastMode();\n        void revertBackToLastMode();\n        void addFilter();\n        bool separate();\n\n        // Handles common preprocessing of the pattern for name/tag patterns\n        std::string preprocessPattern();\n        // Adds the current pattern as a test name\n        void addNamePattern();\n        // Adds the current pattern as a tag\n        void addTagPattern();\n\n        inline void addCharToPattern(char c) {\n            m_substring += c;\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n\n    };\n    TestSpec parseTestSpec( std::string const& arg );\n\n} // namespace Catch\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_test_spec_parser.h\n// Libstdc++ doesn't like incomplete classes for unique_ptr\n\n#include <memory>\n#include <vector>\n#include <string>\n\n#ifndef CATCH_CONFIG_CONSOLE_WIDTH\n#define CATCH_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\n\n    struct IStream;\n\n    struct ConfigData {\n        bool listTests = false;\n        bool listTags = false;\n        bool listReporters = false;\n        bool listTestNamesOnly = false;\n\n        bool showSuccessfulTests = false;\n        bool shouldDebugBreak = false;\n        bool noThrow = false;\n        bool showHelp = false;\n        bool showInvisibles = false;\n        bool filenamesAsTags = false;\n        bool libIdentify = false;\n\n        int abortAfter = -1;\n        unsigned int rngSeed = 0;\n\n        bool benchmarkNoAnalysis = false;\n        unsigned int benchmarkSamples = 100;\n        double benchmarkConfidenceInterval = 0.95;\n        unsigned int benchmarkResamples = 100000;\n        std::chrono::milliseconds::rep benchmarkWarmupTime = 100;\n\n        Verbosity verbosity = Verbosity::Normal;\n        WarnAbout::What warnings = WarnAbout::Nothing;\n        ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter;\n        double minDuration = -1;\n        RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder;\n        UseColour::YesOrNo useColour = UseColour::Auto;\n        WaitForKeypress::When waitForKeypress = WaitForKeypress::Never;\n\n        std::string outputFilename;\n        std::string name;\n        std::string processName;\n#ifndef CATCH_CONFIG_DEFAULT_REPORTER\n#define CATCH_CONFIG_DEFAULT_REPORTER \"console\"\n#endif\n        std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER;\n#undef CATCH_CONFIG_DEFAULT_REPORTER\n\n        std::vector<std::string> testsOrTags;\n        std::vector<std::string> sectionsToRun;\n    };\n\n    class Config : public IConfig {\n    public:\n\n        Config() = default;\n        Config( ConfigData const& data );\n        virtual ~Config() = default;\n\n        std::string const& getFilename() const;\n\n        bool listTests() const;\n        bool listTestNamesOnly() const;\n        bool listTags() const;\n        bool listReporters() const;\n\n        std::string getProcessName() const;\n        std::string const& getReporterName() const;\n\n        std::vector<std::string> const& getTestsOrTags() const override;\n        std::vector<std::string> const& getSectionsToRun() const override;\n\n        TestSpec const& testSpec() const override;\n        bool hasTestFilters() const override;\n\n        bool showHelp() const;\n\n        // IConfig interface\n        bool allowThrows() const override;\n        std::ostream& stream() const override;\n        std::string name() const override;\n        bool includeSuccessfulResults() const override;\n        bool warnAboutMissingAssertions() const override;\n        bool warnAboutNoTests() const override;\n        ShowDurations::OrNot showDurations() const override;\n        double minDuration() const override;\n        RunTests::InWhatOrder runOrder() const override;\n        unsigned int rngSeed() const override;\n        UseColour::YesOrNo useColour() const override;\n        bool shouldDebugBreak() const override;\n        int abortAfter() const override;\n        bool showInvisibles() const override;\n        Verbosity verbosity() const override;\n        bool benchmarkNoAnalysis() const override;\n        int benchmarkSamples() const override;\n        double benchmarkConfidenceInterval() const override;\n        unsigned int benchmarkResamples() const override;\n        std::chrono::milliseconds benchmarkWarmupTime() const override;\n\n    private:\n\n        IStream const* openStream();\n        ConfigData m_data;\n\n        std::unique_ptr<IStream const> m_stream;\n        TestSpec m_testSpec;\n        bool m_hasTestFilters = false;\n    };\n\n} // end namespace Catch\n\n// end catch_config.hpp\n// start catch_assertionresult.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct AssertionResultData\n    {\n        AssertionResultData() = delete;\n\n        AssertionResultData( ResultWas::OfType _resultType, LazyExpression const& _lazyExpression );\n\n        std::string message;\n        mutable std::string reconstructedExpression;\n        LazyExpression lazyExpression;\n        ResultWas::OfType resultType;\n\n        std::string reconstructExpression() const;\n    };\n\n    class AssertionResult {\n    public:\n        AssertionResult() = delete;\n        AssertionResult( AssertionInfo const& info, AssertionResultData const& data );\n\n        bool isOk() const;\n        bool succeeded() const;\n        ResultWas::OfType getResultType() const;\n        bool hasExpression() const;\n        bool hasMessage() const;\n        std::string getExpression() const;\n        std::string getExpressionInMacro() const;\n        bool hasExpandedExpression() const;\n        std::string getExpandedExpression() const;\n        std::string getMessage() const;\n        SourceLineInfo getSourceInfo() const;\n        StringRef getTestMacroName() const;\n\n    //protected:\n        AssertionInfo m_info;\n        AssertionResultData m_resultData;\n    };\n\n} // end namespace Catch\n\n// end catch_assertionresult.h\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_estimate.hpp\n\n // Statistics estimates\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct Estimate {\n            Duration point;\n            Duration lower_bound;\n            Duration upper_bound;\n            double confidence_interval;\n\n            template <typename Duration2>\n            operator Estimate<Duration2>() const {\n                return { point, lower_bound, upper_bound, confidence_interval };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate.hpp\n// start catch_outlier_classification.hpp\n\n// Outlier information\n\nnamespace Catch {\n    namespace Benchmark {\n        struct OutlierClassification {\n            int samples_seen = 0;\n            int low_severe = 0;     // more than 3 times IQR below Q1\n            int low_mild = 0;       // 1.5 to 3 times IQR below Q1\n            int high_mild = 0;      // 1.5 to 3 times IQR above Q3\n            int high_severe = 0;    // more than 3 times IQR above Q3\n\n            int total() const {\n                return low_severe + low_mild + high_mild + high_severe;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_outlier_classification.hpp\n\n#include <iterator>\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n#include <string>\n#include <iosfwd>\n#include <map>\n#include <set>\n#include <memory>\n#include <algorithm>\n\nnamespace Catch {\n\n    struct ReporterConfig {\n        explicit ReporterConfig( IConfigPtr const& _fullConfig );\n\n        ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream );\n\n        std::ostream& stream() const;\n        IConfigPtr fullConfig() const;\n\n    private:\n        std::ostream* m_stream;\n        IConfigPtr m_fullConfig;\n    };\n\n    struct ReporterPreferences {\n        bool shouldRedirectStdOut = false;\n        bool shouldReportAllAssertions = false;\n    };\n\n    template<typename T>\n    struct LazyStat : Option<T> {\n        LazyStat& operator=( T const& _value ) {\n            Option<T>::operator=( _value );\n            used = false;\n            return *this;\n        }\n        void reset() {\n            Option<T>::reset();\n            used = false;\n        }\n        bool used = false;\n    };\n\n    struct TestRunInfo {\n        TestRunInfo( std::string const& _name );\n        std::string name;\n    };\n    struct GroupInfo {\n        GroupInfo(  std::string const& _name,\n                    std::size_t _groupIndex,\n                    std::size_t _groupsCount );\n\n        std::string name;\n        std::size_t groupIndex;\n        std::size_t groupsCounts;\n    };\n\n    struct AssertionStats {\n        AssertionStats( AssertionResult const& _assertionResult,\n                        std::vector<MessageInfo> const& _infoMessages,\n                        Totals const& _totals );\n\n        AssertionStats( AssertionStats const& )              = default;\n        AssertionStats( AssertionStats && )                  = default;\n        AssertionStats& operator = ( AssertionStats const& ) = delete;\n        AssertionStats& operator = ( AssertionStats && )     = delete;\n        virtual ~AssertionStats();\n\n        AssertionResult assertionResult;\n        std::vector<MessageInfo> infoMessages;\n        Totals totals;\n    };\n\n    struct SectionStats {\n        SectionStats(   SectionInfo const& _sectionInfo,\n                        Counts const& _assertions,\n                        double _durationInSeconds,\n                        bool _missingAssertions );\n        SectionStats( SectionStats const& )              = default;\n        SectionStats( SectionStats && )                  = default;\n        SectionStats& operator = ( SectionStats const& ) = default;\n        SectionStats& operator = ( SectionStats && )     = default;\n        virtual ~SectionStats();\n\n        SectionInfo sectionInfo;\n        Counts assertions;\n        double durationInSeconds;\n        bool missingAssertions;\n    };\n\n    struct TestCaseStats {\n        TestCaseStats(  TestCaseInfo const& _testInfo,\n                        Totals const& _totals,\n                        std::string const& _stdOut,\n                        std::string const& _stdErr,\n                        bool _aborting );\n\n        TestCaseStats( TestCaseStats const& )              = default;\n        TestCaseStats( TestCaseStats && )                  = default;\n        TestCaseStats& operator = ( TestCaseStats const& ) = default;\n        TestCaseStats& operator = ( TestCaseStats && )     = default;\n        virtual ~TestCaseStats();\n\n        TestCaseInfo testInfo;\n        Totals totals;\n        std::string stdOut;\n        std::string stdErr;\n        bool aborting;\n    };\n\n    struct TestGroupStats {\n        TestGroupStats( GroupInfo const& _groupInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n        TestGroupStats( GroupInfo const& _groupInfo );\n\n        TestGroupStats( TestGroupStats const& )              = default;\n        TestGroupStats( TestGroupStats && )                  = default;\n        TestGroupStats& operator = ( TestGroupStats const& ) = default;\n        TestGroupStats& operator = ( TestGroupStats && )     = default;\n        virtual ~TestGroupStats();\n\n        GroupInfo groupInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n    struct TestRunStats {\n        TestRunStats(   TestRunInfo const& _runInfo,\n                        Totals const& _totals,\n                        bool _aborting );\n\n        TestRunStats( TestRunStats const& )              = default;\n        TestRunStats( TestRunStats && )                  = default;\n        TestRunStats& operator = ( TestRunStats const& ) = default;\n        TestRunStats& operator = ( TestRunStats && )     = default;\n        virtual ~TestRunStats();\n\n        TestRunInfo runInfo;\n        Totals totals;\n        bool aborting;\n    };\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    struct BenchmarkInfo {\n        std::string name;\n        double estimatedDuration;\n        int iterations;\n        int samples;\n        unsigned int resamples;\n        double clockResolution;\n        double clockCost;\n    };\n\n    template <class Duration>\n    struct BenchmarkStats {\n        BenchmarkInfo info;\n\n        std::vector<Duration> samples;\n        Benchmark::Estimate<Duration> mean;\n        Benchmark::Estimate<Duration> standardDeviation;\n        Benchmark::OutlierClassification outliers;\n        double outlierVariance;\n\n        template <typename Duration2>\n        operator BenchmarkStats<Duration2>() const {\n            std::vector<Duration2> samples2;\n            samples2.reserve(samples.size());\n            std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n            return {\n                info,\n                std::move(samples2),\n                mean,\n                standardDeviation,\n                outliers,\n                outlierVariance,\n            };\n        }\n    };\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    struct IStreamingReporter {\n        virtual ~IStreamingReporter() = default;\n\n        // Implementing class must also provide the following static methods:\n        // static std::string getDescription();\n        // static std::set<Verbosity> getSupportedVerbosities()\n\n        virtual ReporterPreferences getPreferences() const = 0;\n\n        virtual void noMatchingTestCases( std::string const& spec ) = 0;\n\n        virtual void reportInvalidArguments(std::string const&) {}\n\n        virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0;\n        virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0;\n\n        virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0;\n        virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        virtual void benchmarkPreparing( std::string const& ) {}\n        virtual void benchmarkStarting( BenchmarkInfo const& ) {}\n        virtual void benchmarkEnded( BenchmarkStats<> const& ) {}\n        virtual void benchmarkFailed( std::string const& ) {}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0;\n\n        // The return value indicates if the messages buffer should be cleared:\n        virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0;\n\n        virtual void sectionEnded( SectionStats const& sectionStats ) = 0;\n        virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0;\n        virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0;\n        virtual void testRunEnded( TestRunStats const& testRunStats ) = 0;\n\n        virtual void skipTest( TestCaseInfo const& testInfo ) = 0;\n\n        // Default empty implementation provided\n        virtual void fatalErrorEncountered( StringRef name );\n\n        virtual bool isMulti() const;\n    };\n    using IStreamingReporterPtr = std::unique_ptr<IStreamingReporter>;\n\n    struct IReporterFactory {\n        virtual ~IReporterFactory();\n        virtual IStreamingReporterPtr create( ReporterConfig const& config ) const = 0;\n        virtual std::string getDescription() const = 0;\n    };\n    using IReporterFactoryPtr = std::shared_ptr<IReporterFactory>;\n\n    struct IReporterRegistry {\n        using FactoryMap = std::map<std::string, IReporterFactoryPtr>;\n        using Listeners = std::vector<IReporterFactoryPtr>;\n\n        virtual ~IReporterRegistry();\n        virtual IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const = 0;\n        virtual FactoryMap const& getFactories() const = 0;\n        virtual Listeners const& getListeners() const = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_interfaces_reporter.h\n#include <algorithm>\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n#include <ostream>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result);\n\n    // Returns double formatted as %.3f (format expected on output)\n    std::string getFormattedDuration( double duration );\n\n    //! Should the reporter show\n    bool shouldShowDuration( IConfig const& config, double duration );\n\n    std::string serializeFilters( std::vector<std::string> const& container );\n\n    template<typename DerivedT>\n    struct StreamingReporterBase : IStreamingReporter {\n\n        StreamingReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        ~StreamingReporterBase() override = default;\n\n        void noMatchingTestCases(std::string const&) override {}\n\n        void reportInvalidArguments(std::string const&) override {}\n\n        void testRunStarting(TestRunInfo const& _testRunInfo) override {\n            currentTestRunInfo = _testRunInfo;\n        }\n\n        void testGroupStarting(GroupInfo const& _groupInfo) override {\n            currentGroupInfo = _groupInfo;\n        }\n\n        void testCaseStarting(TestCaseInfo const& _testInfo) override  {\n            currentTestCaseInfo = _testInfo;\n        }\n        void sectionStarting(SectionInfo const& _sectionInfo) override {\n            m_sectionStack.push_back(_sectionInfo);\n        }\n\n        void sectionEnded(SectionStats const& /* _sectionStats */) override {\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& /* _testCaseStats */) override {\n            currentTestCaseInfo.reset();\n        }\n        void testGroupEnded(TestGroupStats const& /* _testGroupStats */) override {\n            currentGroupInfo.reset();\n        }\n        void testRunEnded(TestRunStats const& /* _testRunStats */) override {\n            currentTestCaseInfo.reset();\n            currentGroupInfo.reset();\n            currentTestRunInfo.reset();\n        }\n\n        void skipTest(TestCaseInfo const&) override {\n            // Don't do anything with this by default.\n            // It can optionally be overridden in the derived class.\n        }\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n\n        LazyStat<TestRunInfo> currentTestRunInfo;\n        LazyStat<GroupInfo> currentGroupInfo;\n        LazyStat<TestCaseInfo> currentTestCaseInfo;\n\n        std::vector<SectionInfo> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<typename DerivedT>\n    struct CumulativeReporterBase : IStreamingReporter {\n        template<typename T, typename ChildNodeT>\n        struct Node {\n            explicit Node( T const& _value ) : value( _value ) {}\n            virtual ~Node() {}\n\n            using ChildNodes = std::vector<std::shared_ptr<ChildNodeT>>;\n            T value;\n            ChildNodes children;\n        };\n        struct SectionNode {\n            explicit SectionNode(SectionStats const& _stats) : stats(_stats) {}\n            virtual ~SectionNode() = default;\n\n            bool operator == (SectionNode const& other) const {\n                return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo;\n            }\n            bool operator == (std::shared_ptr<SectionNode> const& other) const {\n                return operator==(*other);\n            }\n\n            SectionStats stats;\n            using ChildSections = std::vector<std::shared_ptr<SectionNode>>;\n            using Assertions = std::vector<AssertionStats>;\n            ChildSections childSections;\n            Assertions assertions;\n            std::string stdOut;\n            std::string stdErr;\n        };\n\n        struct BySectionInfo {\n            BySectionInfo( SectionInfo const& other ) : m_other( other ) {}\n            BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {}\n            bool operator() (std::shared_ptr<SectionNode> const& node) const {\n                return ((node->stats.sectionInfo.name == m_other.name) &&\n                        (node->stats.sectionInfo.lineInfo == m_other.lineInfo));\n            }\n            void operator=(BySectionInfo const&) = delete;\n\n        private:\n            SectionInfo const& m_other;\n        };\n\n        using TestCaseNode = Node<TestCaseStats, SectionNode>;\n        using TestGroupNode = Node<TestGroupStats, TestCaseNode>;\n        using TestRunNode = Node<TestRunStats, TestGroupNode>;\n\n        CumulativeReporterBase( ReporterConfig const& _config )\n        :   m_config( _config.fullConfig() ),\n            stream( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = false;\n            if( !DerivedT::getSupportedVerbosities().count( m_config->verbosity() ) )\n                CATCH_ERROR( \"Verbosity level not supported by this reporter\" );\n        }\n        ~CumulativeReporterBase() override = default;\n\n        ReporterPreferences getPreferences() const override {\n            return m_reporterPrefs;\n        }\n\n        static std::set<Verbosity> getSupportedVerbosities() {\n            return { Verbosity::Normal };\n        }\n\n        void testRunStarting( TestRunInfo const& ) override {}\n        void testGroupStarting( GroupInfo const& ) override {}\n\n        void testCaseStarting( TestCaseInfo const& ) override {}\n\n        void sectionStarting( SectionInfo const& sectionInfo ) override {\n            SectionStats incompleteStats( sectionInfo, Counts(), 0, false );\n            std::shared_ptr<SectionNode> node;\n            if( m_sectionStack.empty() ) {\n                if( !m_rootSection )\n                    m_rootSection = std::make_shared<SectionNode>( incompleteStats );\n                node = m_rootSection;\n            }\n            else {\n                SectionNode& parentNode = *m_sectionStack.back();\n                auto it =\n                    std::find_if(   parentNode.childSections.begin(),\n                                    parentNode.childSections.end(),\n                                    BySectionInfo( sectionInfo ) );\n                if( it == parentNode.childSections.end() ) {\n                    node = std::make_shared<SectionNode>( incompleteStats );\n                    parentNode.childSections.push_back( node );\n                }\n                else\n                    node = *it;\n            }\n            m_sectionStack.push_back( node );\n            m_deepestSection = std::move(node);\n        }\n\n        void assertionStarting(AssertionInfo const&) override {}\n\n        bool assertionEnded(AssertionStats const& assertionStats) override {\n            assert(!m_sectionStack.empty());\n            // AssertionResult holds a pointer to a temporary DecomposedExpression,\n            // which getExpandedExpression() calls to build the expression string.\n            // Our section stack copy of the assertionResult will likely outlive the\n            // temporary, so it must be expanded or discarded now to avoid calling\n            // a destroyed object later.\n            prepareExpandedExpression(const_cast<AssertionResult&>( assertionStats.assertionResult ) );\n            SectionNode& sectionNode = *m_sectionStack.back();\n            sectionNode.assertions.push_back(assertionStats);\n            return true;\n        }\n        void sectionEnded(SectionStats const& sectionStats) override {\n            assert(!m_sectionStack.empty());\n            SectionNode& node = *m_sectionStack.back();\n            node.stats = sectionStats;\n            m_sectionStack.pop_back();\n        }\n        void testCaseEnded(TestCaseStats const& testCaseStats) override {\n            auto node = std::make_shared<TestCaseNode>(testCaseStats);\n            assert(m_sectionStack.size() == 0);\n            node->children.push_back(m_rootSection);\n            m_testCases.push_back(node);\n            m_rootSection.reset();\n\n            assert(m_deepestSection);\n            m_deepestSection->stdOut = testCaseStats.stdOut;\n            m_deepestSection->stdErr = testCaseStats.stdErr;\n        }\n        void testGroupEnded(TestGroupStats const& testGroupStats) override {\n            auto node = std::make_shared<TestGroupNode>(testGroupStats);\n            node->children.swap(m_testCases);\n            m_testGroups.push_back(node);\n        }\n        void testRunEnded(TestRunStats const& testRunStats) override {\n            auto node = std::make_shared<TestRunNode>(testRunStats);\n            node->children.swap(m_testGroups);\n            m_testRuns.push_back(node);\n            testRunEndedCumulative();\n        }\n        virtual void testRunEndedCumulative() = 0;\n\n        void skipTest(TestCaseInfo const&) override {}\n\n        IConfigPtr m_config;\n        std::ostream& stream;\n        std::vector<AssertionStats> m_assertions;\n        std::vector<std::vector<std::shared_ptr<SectionNode>>> m_sections;\n        std::vector<std::shared_ptr<TestCaseNode>> m_testCases;\n        std::vector<std::shared_ptr<TestGroupNode>> m_testGroups;\n\n        std::vector<std::shared_ptr<TestRunNode>> m_testRuns;\n\n        std::shared_ptr<SectionNode> m_rootSection;\n        std::shared_ptr<SectionNode> m_deepestSection;\n        std::vector<std::shared_ptr<SectionNode>> m_sectionStack;\n        ReporterPreferences m_reporterPrefs;\n    };\n\n    template<char C>\n    char const* getLineOfChars() {\n        static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0};\n        if( !*line ) {\n            std::memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 );\n            line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0;\n        }\n        return line;\n    }\n\n    struct TestEventListenerBase : StreamingReporterBase<TestEventListenerBase> {\n        TestEventListenerBase( ReporterConfig const& _config );\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n        void assertionStarting(AssertionInfo const&) override;\n        bool assertionEnded(AssertionStats const&) override;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_bases.hpp\n// start catch_console_colour.h\n\nnamespace Catch {\n\n    struct Colour {\n        enum Code {\n            None = 0,\n\n            White,\n            Red,\n            Green,\n            Blue,\n            Cyan,\n            Yellow,\n            Grey,\n\n            Bright = 0x10,\n\n            BrightRed = Bright | Red,\n            BrightGreen = Bright | Green,\n            LightGrey = Bright | Grey,\n            BrightWhite = Bright | White,\n            BrightYellow = Bright | Yellow,\n\n            // By intention\n            FileName = LightGrey,\n            Warning = BrightYellow,\n            ResultError = BrightRed,\n            ResultSuccess = BrightGreen,\n            ResultExpectedFailure = Warning,\n\n            Error = BrightRed,\n            Success = Green,\n\n            OriginalExpression = Cyan,\n            ReconstructedExpression = BrightYellow,\n\n            SecondaryText = LightGrey,\n            Headers = White\n        };\n\n        // Use constructed object for RAII guard\n        Colour( Code _colourCode );\n        Colour( Colour&& other ) noexcept;\n        Colour& operator=( Colour&& other ) noexcept;\n        ~Colour();\n\n        // Use static method for one-shot changes\n        static void use( Code _colourCode );\n\n    private:\n        bool m_moved = false;\n    };\n\n    std::ostream& operator << ( std::ostream& os, Colour const& );\n\n} // end namespace Catch\n\n// end catch_console_colour.h\n// start catch_reporter_registrars.hpp\n\n\nnamespace Catch {\n\n    template<typename T>\n    class ReporterRegistrar {\n\n        class ReporterFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n\n            std::string getDescription() const override {\n                return T::getDescription();\n            }\n        };\n\n    public:\n\n        explicit ReporterRegistrar( std::string const& name ) {\n            getMutableRegistryHub().registerReporter( name, std::make_shared<ReporterFactory>() );\n        }\n    };\n\n    template<typename T>\n    class ListenerRegistrar {\n\n        class ListenerFactory : public IReporterFactory {\n\n            IStreamingReporterPtr create( ReporterConfig const& config ) const override {\n                return std::unique_ptr<T>( new T( config ) );\n            }\n            std::string getDescription() const override {\n                return std::string();\n            }\n        };\n\n    public:\n\n        ListenerRegistrar() {\n            getMutableRegistryHub().registerListener( std::make_shared<ListenerFactory>() );\n        }\n    };\n}\n\n#if !defined(CATCH_CONFIG_DISABLE)\n\n#define CATCH_REGISTER_REPORTER( name, reporterType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION         \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS          \\\n    namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n#define CATCH_REGISTER_LISTENER( listenerType ) \\\n    CATCH_INTERNAL_START_WARNINGS_SUPPRESSION   \\\n    CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS    \\\n    namespace{ Catch::ListenerRegistrar<listenerType> catch_internal_RegistrarFor##listenerType; } \\\n    CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n#else // CATCH_CONFIG_DISABLE\n\n#define CATCH_REGISTER_REPORTER(name, reporterType)\n#define CATCH_REGISTER_LISTENER(listenerType)\n\n#endif // CATCH_CONFIG_DISABLE\n\n// end catch_reporter_registrars.hpp\n// Allow users to base their work off existing reporters\n// start catch_reporter_compact.h\n\nnamespace Catch {\n\n    struct CompactReporter : StreamingReporterBase<CompactReporter> {\n\n        using StreamingReporterBase::StreamingReporterBase;\n\n        ~CompactReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_compact.h\n// start catch_reporter_console.h\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    // Fwd decls\n    struct SummaryColumn;\n    class TablePrinter;\n\n    struct ConsoleReporter : StreamingReporterBase<ConsoleReporter> {\n        std::unique_ptr<TablePrinter> m_tablePrinter;\n\n        ConsoleReporter(ReporterConfig const& config);\n        ~ConsoleReporter() override;\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& spec) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& _assertionStats) override;\n\n        void sectionStarting(SectionInfo const& _sectionInfo) override;\n        void sectionEnded(SectionStats const& _sectionStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const& info) override;\n        void benchmarkEnded(BenchmarkStats<> const& stats) override;\n        void benchmarkFailed(std::string const& error) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testCaseEnded(TestCaseStats const& _testCaseStats) override;\n        void testGroupEnded(TestGroupStats const& _testGroupStats) override;\n        void testRunEnded(TestRunStats const& _testRunStats) override;\n        void testRunStarting(TestRunInfo const& _testRunInfo) override;\n    private:\n\n        void lazyPrint();\n\n        void lazyPrintWithoutClosingBenchmarkTable();\n        void lazyPrintRunInfo();\n        void lazyPrintGroupInfo();\n        void printTestCaseAndSectionHeader();\n\n        void printClosedHeader(std::string const& _name);\n        void printOpenHeader(std::string const& _name);\n\n        // if string has a : in first line will set indent to follow it on\n        // subsequent lines\n        void printHeaderString(std::string const& _string, std::size_t indent = 0);\n\n        void printTotals(Totals const& totals);\n        void printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row);\n\n        void printTotalsDivider(Totals const& totals);\n        void printSummaryDivider();\n        void printTestFilters();\n\n    private:\n        bool m_headerPrinted = false;\n    };\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n// end catch_reporter_console.h\n// start catch_reporter_junit.h\n\n// start catch_xmlwriter.h\n\n#include <vector>\n\nnamespace Catch {\n    enum class XmlFormatting {\n        None = 0x00,\n        Indent = 0x01,\n        Newline = 0x02,\n    };\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs);\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs);\n\n    class XmlEncode {\n    public:\n        enum ForWhat { ForTextNodes, ForAttributes };\n\n        XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );\n\n        void encodeTo( std::ostream& os ) const;\n\n        friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );\n\n    private:\n        std::string m_str;\n        ForWhat m_forWhat;\n    };\n\n    class XmlWriter {\n    public:\n\n        class ScopedElement {\n        public:\n            ScopedElement( XmlWriter* writer, XmlFormatting fmt );\n\n            ScopedElement( ScopedElement&& other ) noexcept;\n            ScopedElement& operator=( ScopedElement&& other ) noexcept;\n\n            ~ScopedElement();\n\n            ScopedElement& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent );\n\n            template<typename T>\n            ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {\n                m_writer->writeAttribute( name, attribute );\n                return *this;\n            }\n\n        private:\n            mutable XmlWriter* m_writer = nullptr;\n            XmlFormatting m_fmt;\n        };\n\n        XmlWriter( std::ostream& os = Catch::cout() );\n        ~XmlWriter();\n\n        XmlWriter( XmlWriter const& ) = delete;\n        XmlWriter& operator=( XmlWriter const& ) = delete;\n\n        XmlWriter& startElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        ScopedElement scopedElement( std::string const& name, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& endElement(XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );\n\n        XmlWriter& writeAttribute( std::string const& name, bool attribute );\n\n        template<typename T>\n        XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {\n            ReusableStringStream rss;\n            rss << attribute;\n            return writeAttribute( name, rss.str() );\n        }\n\n        XmlWriter& writeText( std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        XmlWriter& writeComment(std::string const& text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent);\n\n        void writeStylesheetRef( std::string const& url );\n\n        XmlWriter& writeBlankLine();\n\n        void ensureTagClosed();\n\n    private:\n\n        void applyFormatting(XmlFormatting fmt);\n\n        void writeDeclaration();\n\n        void newlineIfNecessary();\n\n        bool m_tagIsOpen = false;\n        bool m_needsNewline = false;\n        std::vector<std::string> m_tags;\n        std::string m_indent;\n        std::ostream& m_os;\n    };\n\n}\n\n// end catch_xmlwriter.h\nnamespace Catch {\n\n    class JunitReporter : public CumulativeReporterBase<JunitReporter> {\n    public:\n        JunitReporter(ReporterConfig const& _config);\n\n        ~JunitReporter() override;\n\n        static std::string getDescription();\n\n        void noMatchingTestCases(std::string const& /*spec*/) override;\n\n        void testRunStarting(TestRunInfo const& runInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testCaseInfo) override;\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEndedCumulative() override;\n\n        void writeGroup(TestGroupNode const& groupNode, double suiteTime);\n\n        void writeTestCase(TestCaseNode const& testCaseNode);\n\n        void writeSection( std::string const& className,\n                           std::string const& rootName,\n                           SectionNode const& sectionNode,\n                           bool testOkToFail );\n\n        void writeAssertions(SectionNode const& sectionNode);\n        void writeAssertion(AssertionStats const& stats);\n\n        XmlWriter xml;\n        Timer suiteTimer;\n        std::string stdOutForSuite;\n        std::string stdErrForSuite;\n        unsigned int unexpectedExceptions = 0;\n        bool m_okToFail = false;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_junit.h\n// start catch_reporter_xml.h\n\nnamespace Catch {\n    class XmlReporter : public StreamingReporterBase<XmlReporter> {\n    public:\n        XmlReporter(ReporterConfig const& _config);\n\n        ~XmlReporter() override;\n\n        static std::string getDescription();\n\n        virtual std::string getStylesheetRef() const;\n\n        void writeSourceInfo(SourceLineInfo const& sourceInfo);\n\n    public: // StreamingReporterBase\n\n        void noMatchingTestCases(std::string const& s) override;\n\n        void testRunStarting(TestRunInfo const& testInfo) override;\n\n        void testGroupStarting(GroupInfo const& groupInfo) override;\n\n        void testCaseStarting(TestCaseInfo const& testInfo) override;\n\n        void sectionStarting(SectionInfo const& sectionInfo) override;\n\n        void assertionStarting(AssertionInfo const&) override;\n\n        bool assertionEnded(AssertionStats const& assertionStats) override;\n\n        void sectionEnded(SectionStats const& sectionStats) override;\n\n        void testCaseEnded(TestCaseStats const& testCaseStats) override;\n\n        void testGroupEnded(TestGroupStats const& testGroupStats) override;\n\n        void testRunEnded(TestRunStats const& testRunStats) override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting(BenchmarkInfo const&) override;\n        void benchmarkEnded(BenchmarkStats<> const&) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    private:\n        Timer m_testCaseTimer;\n        XmlWriter m_xml;\n        int m_sectionDepth = 0;\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_xml.h\n\n// end catch_external_interfaces.h\n#endif\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n// start catch_benchmarking_all.hpp\n\n// A proxy header that includes all of the benchmarking headers to allow\n// concise include of the benchmarking features. You should prefer the\n// individual includes in standard use.\n\n// start catch_benchmark.hpp\n\n // Benchmark\n\n// start catch_chronometer.hpp\n\n// User-facing chronometer\n\n\n// start catch_clock.hpp\n\n// Clocks\n\n\n#include <chrono>\n#include <ratio>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Clock>\n        using ClockDuration = typename Clock::duration;\n        template <typename Clock>\n        using FloatDuration = std::chrono::duration<double, typename Clock::period>;\n\n        template <typename Clock>\n        using TimePoint = typename Clock::time_point;\n\n        using default_clock = std::chrono::steady_clock;\n\n        template <typename Clock>\n        struct now {\n            TimePoint<Clock> operator()() const {\n                return Clock::now();\n            }\n        };\n\n        using fp_seconds = std::chrono::duration<double, std::ratio<1>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_clock.hpp\n// start catch_optimizer.hpp\n\n // Hinting the optimizer\n\n\n#if defined(_MSC_VER)\n#   include <atomic> // atomic_thread_fence\n#endif\n\nnamespace Catch {\n    namespace Benchmark {\n#if defined(__GNUC__) || defined(__clang__)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            asm volatile(\"\" : : \"g\"(p) : \"memory\");\n        }\n        inline void keep_memory() {\n            asm volatile(\"\" : : : \"memory\");\n        }\n\n        namespace Detail {\n            inline void optimizer_barrier() { keep_memory(); }\n        } // namespace Detail\n#elif defined(_MSC_VER)\n\n#pragma optimize(\"\", off)\n        template <typename T>\n        inline void keep_memory(T* p) {\n            // thanks @milleniumbug\n            *reinterpret_cast<char volatile*>(p) = *reinterpret_cast<char const volatile*>(p);\n        }\n        // TODO equivalent keep_memory()\n#pragma optimize(\"\", on)\n\n        namespace Detail {\n            inline void optimizer_barrier() {\n                std::atomic_thread_fence(std::memory_order_seq_cst);\n            }\n        } // namespace Detail\n\n#endif\n\n        template <typename T>\n        inline void deoptimize_value(T&& x) {\n            keep_memory(&x);\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<!std::is_same<void, decltype(fn(args...))>::value>::type {\n            deoptimize_value(std::forward<Fn>(fn) (std::forward<Args...>(args...)));\n        }\n\n        template <typename Fn, typename... Args>\n        inline auto invoke_deoptimized(Fn&& fn, Args&&... args) -> typename std::enable_if<std::is_same<void, decltype(fn(args...))>::value>::type {\n            std::forward<Fn>(fn) (std::forward<Args...>(args...));\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_optimizer.hpp\n// start catch_complete_invoke.hpp\n\n// Invoke with a special case for void\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            struct CompleteType { using type = T; };\n            template <>\n            struct CompleteType<void> { struct type {}; };\n\n            template <typename T>\n            using CompleteType_t = typename CompleteType<T>::type;\n\n            template <typename Result>\n            struct CompleteInvoker {\n                template <typename Fun, typename... Args>\n                static Result invoke(Fun&& fun, Args&&... args) {\n                    return std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                }\n            };\n            template <>\n            struct CompleteInvoker<void> {\n                template <typename Fun, typename... Args>\n                static CompleteType_t<void> invoke(Fun&& fun, Args&&... args) {\n                    std::forward<Fun>(fun)(std::forward<Args>(args)...);\n                    return {};\n                }\n            };\n\n            // invoke and not return void :(\n            template <typename Fun, typename... Args>\n            CompleteType_t<FunctionReturnType<Fun, Args...>> complete_invoke(Fun&& fun, Args&&... args) {\n                return CompleteInvoker<FunctionReturnType<Fun, Args...>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...);\n            }\n\n            const std::string benchmarkErrorMsg = \"a benchmark failed to run successfully\";\n        } // namespace Detail\n\n        template <typename Fun>\n        Detail::CompleteType_t<FunctionReturnType<Fun>> user_code(Fun&& fun) {\n            CATCH_TRY{\n                return Detail::complete_invoke(std::forward<Fun>(fun));\n            } CATCH_CATCH_ALL{\n                getResultCapture().benchmarkFailed(translateActiveException());\n                CATCH_RUNTIME_ERROR(Detail::benchmarkErrorMsg);\n            }\n        }\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_complete_invoke.hpp\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            struct ChronometerConcept {\n                virtual void start() = 0;\n                virtual void finish() = 0;\n                virtual ~ChronometerConcept() = default;\n            };\n            template <typename Clock>\n            struct ChronometerModel final : public ChronometerConcept {\n                void start() override { started = Clock::now(); }\n                void finish() override { finished = Clock::now(); }\n\n                ClockDuration<Clock> elapsed() const { return finished - started; }\n\n                TimePoint<Clock> started;\n                TimePoint<Clock> finished;\n            };\n        } // namespace Detail\n\n        struct Chronometer {\n        public:\n            template <typename Fun>\n            void measure(Fun&& fun) { measure(std::forward<Fun>(fun), is_callable<Fun(int)>()); }\n\n            int runs() const { return k; }\n\n            Chronometer(Detail::ChronometerConcept& meter, int k)\n                : impl(&meter)\n                , k(k) {}\n\n        private:\n            template <typename Fun>\n            void measure(Fun&& fun, std::false_type) {\n                measure([&fun](int) { return fun(); }, std::true_type());\n            }\n\n            template <typename Fun>\n            void measure(Fun&& fun, std::true_type) {\n                Detail::optimizer_barrier();\n                impl->start();\n                for (int i = 0; i < k; ++i) invoke_deoptimized(fun, i);\n                impl->finish();\n                Detail::optimizer_barrier();\n            }\n\n            Detail::ChronometerConcept* impl;\n            int k;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_chronometer.hpp\n// start catch_environment.hpp\n\n// Environment information\n\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct EnvironmentEstimate {\n            Duration mean;\n            OutlierClassification outliers;\n\n            template <typename Duration2>\n            operator EnvironmentEstimate<Duration2>() const {\n                return { mean, outliers };\n            }\n        };\n        template <typename Clock>\n        struct Environment {\n            using clock_type = Clock;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_resolution;\n            EnvironmentEstimate<FloatDuration<Clock>> clock_cost;\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_environment.hpp\n// start catch_execution_plan.hpp\n\n // Execution plan\n\n\n// start catch_benchmark_function.hpp\n\n // Dumb std::function implementation for consistent call overhead\n\n\n#include <cassert>\n#include <type_traits>\n#include <utility>\n#include <memory>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T>\n            using Decay = typename std::decay<T>::type;\n            template <typename T, typename U>\n            struct is_related\n                : std::is_same<Decay<T>, Decay<U>> {};\n\n            /// We need to reinvent std::function because every piece of code that might add overhead\n            /// in a measurement context needs to have consistent performance characteristics so that we\n            /// can account for it in the measurement.\n            /// Implementations of std::function with optimizations that aren't always applicable, like\n            /// small buffer optimizations, are not uncommon.\n            /// This is effectively an implementation of std::function without any such optimizations;\n            /// it may be slow, but it is consistently slow.\n            struct BenchmarkFunction {\n            private:\n                struct callable {\n                    virtual void call(Chronometer meter) const = 0;\n                    virtual callable* clone() const = 0;\n                    virtual ~callable() = default;\n                };\n                template <typename Fun>\n                struct model : public callable {\n                    model(Fun&& fun) : fun(std::move(fun)) {}\n                    model(Fun const& fun) : fun(fun) {}\n\n                    model<Fun>* clone() const override { return new model<Fun>(*this); }\n\n                    void call(Chronometer meter) const override {\n                        call(meter, is_callable<Fun(Chronometer)>());\n                    }\n                    void call(Chronometer meter, std::true_type) const {\n                        fun(meter);\n                    }\n                    void call(Chronometer meter, std::false_type) const {\n                        meter.measure(fun);\n                    }\n\n                    Fun fun;\n                };\n\n                struct do_nothing { void operator()() const {} };\n\n                template <typename T>\n                BenchmarkFunction(model<T>* c) : f(c) {}\n\n            public:\n                BenchmarkFunction()\n                    : f(new model<do_nothing>{ {} }) {}\n\n                template <typename Fun,\n                    typename std::enable_if<!is_related<Fun, BenchmarkFunction>::value, int>::type = 0>\n                    BenchmarkFunction(Fun&& fun)\n                    : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {}\n\n                BenchmarkFunction(BenchmarkFunction&& that)\n                    : f(std::move(that.f)) {}\n\n                BenchmarkFunction(BenchmarkFunction const& that)\n                    : f(that.f->clone()) {}\n\n                BenchmarkFunction& operator=(BenchmarkFunction&& that) {\n                    f = std::move(that.f);\n                    return *this;\n                }\n\n                BenchmarkFunction& operator=(BenchmarkFunction const& that) {\n                    f.reset(that.f->clone());\n                    return *this;\n                }\n\n                void operator()(Chronometer meter) const { f->call(meter); }\n\n            private:\n                std::unique_ptr<callable> f;\n            };\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_benchmark_function.hpp\n// start catch_repeat.hpp\n\n// repeat algorithm\n\n\n#include <type_traits>\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Fun>\n            struct repeater {\n                void operator()(int k) const {\n                    for (int i = 0; i < k; ++i) {\n                        fun();\n                    }\n                }\n                Fun fun;\n            };\n            template <typename Fun>\n            repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) {\n                return { std::forward<Fun>(fun) };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_repeat.hpp\n// start catch_run_for_at_least.hpp\n\n// Run a function for a minimum amount of time\n\n\n// start catch_measure.hpp\n\n// Measure\n\n\n// start catch_timing.hpp\n\n// Timing\n\n\n#include <tuple>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration, typename Result>\n        struct Timing {\n            Duration elapsed;\n            Result result;\n            int iterations;\n        };\n        template <typename Clock, typename Func, typename... Args>\n        using TimingOf = Timing<ClockDuration<Clock>, Detail::CompleteType_t<FunctionReturnType<Func, Args...>>>;\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_timing.hpp\n#include <utility>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun, typename... Args>\n            TimingOf<Clock, Fun, Args...> measure(Fun&& fun, Args&&... args) {\n                auto start = Clock::now();\n                auto&& r = Detail::complete_invoke(fun, std::forward<Args>(args)...);\n                auto end = Clock::now();\n                auto delta = end - start;\n                return { delta, std::forward<decltype(r)>(r), 1 };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_measure.hpp\n#include <utility>\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, int> measure_one(Fun&& fun, int iters, std::false_type) {\n                return Detail::measure<Clock>(fun, iters);\n            }\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, Chronometer> measure_one(Fun&& fun, int iters, std::true_type) {\n                Detail::ChronometerModel<Clock> meter;\n                auto&& result = Detail::complete_invoke(fun, Chronometer(meter, iters));\n\n                return { meter.elapsed(), std::move(result), iters };\n            }\n\n            template <typename Clock, typename Fun>\n            using run_for_at_least_argument_t = typename std::conditional<is_callable<Fun(Chronometer)>::value, Chronometer, int>::type;\n\n            struct optimized_away_error : std::exception {\n                const char* what() const noexcept override {\n                    return \"could not measure benchmark, maybe it was optimized away\";\n                }\n            };\n\n            template <typename Clock, typename Fun>\n            TimingOf<Clock, Fun, run_for_at_least_argument_t<Clock, Fun>> run_for_at_least(ClockDuration<Clock> how_long, int seed, Fun&& fun) {\n                auto iters = seed;\n                while (iters < (1 << 30)) {\n                    auto&& Timing = measure_one<Clock>(fun, iters, is_callable<Fun(Chronometer)>());\n\n                    if (Timing.elapsed >= how_long) {\n                        return { Timing.elapsed, std::move(Timing.result), iters };\n                    }\n                    iters *= 2;\n                }\n                Catch::throw_exception(optimized_away_error{});\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_run_for_at_least.hpp\n#include <algorithm>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct ExecutionPlan {\n            int iterations_per_sample;\n            Duration estimated_duration;\n            Detail::BenchmarkFunction benchmark;\n            Duration warmup_time;\n            int warmup_iterations;\n\n            template <typename Duration2>\n            operator ExecutionPlan<Duration2>() const {\n                return { iterations_per_sample, estimated_duration, benchmark, warmup_time, warmup_iterations };\n            }\n\n            template <typename Clock>\n            std::vector<FloatDuration<Clock>> run(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                // warmup a bit\n                Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_iterations, Detail::repeat(now<Clock>{}));\n\n                std::vector<FloatDuration<Clock>> times;\n                times.reserve(cfg.benchmarkSamples());\n                std::generate_n(std::back_inserter(times), cfg.benchmarkSamples(), [this, env] {\n                    Detail::ChronometerModel<Clock> model;\n                    this->benchmark(Chronometer(model, iterations_per_sample));\n                    auto sample_time = model.elapsed() - env.clock_cost.mean;\n                    if (sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero();\n                    return sample_time / iterations_per_sample;\n                });\n                return times;\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_execution_plan.hpp\n// start catch_estimate_clock.hpp\n\n // Environment measurement\n\n\n// start catch_stats.hpp\n\n// Statistical analysis tools\n\n\n#include <algorithm>\n#include <functional>\n#include <vector>\n#include <iterator>\n#include <numeric>\n#include <tuple>\n#include <cmath>\n#include <utility>\n#include <cstddef>\n#include <random>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            using sample = std::vector<double>;\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);\n\n            template <typename Iterator>\n            OutlierClassification classify_outliers(Iterator first, Iterator last) {\n                std::vector<double> copy(first, last);\n\n                auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());\n                auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());\n                auto iqr = q3 - q1;\n                auto los = q1 - (iqr * 3.);\n                auto lom = q1 - (iqr * 1.5);\n                auto him = q3 + (iqr * 1.5);\n                auto his = q3 + (iqr * 3.);\n\n                OutlierClassification o;\n                for (; first != last; ++first) {\n                    auto&& t = *first;\n                    if (t < los) ++o.low_severe;\n                    else if (t < lom) ++o.low_mild;\n                    else if (t > his) ++o.high_severe;\n                    else if (t > him) ++o.high_mild;\n                    ++o.samples_seen;\n                }\n                return o;\n            }\n\n            template <typename Iterator>\n            double mean(Iterator first, Iterator last) {\n                auto count = last - first;\n                double sum = std::accumulate(first, last, 0.);\n                return sum / count;\n            }\n\n            template <typename URng, typename Iterator, typename Estimator>\n            sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {\n                auto n = last - first;\n                std::uniform_int_distribution<decltype(n)> dist(0, n - 1);\n\n                sample out;\n                out.reserve(resamples);\n                std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {\n                    std::vector<double> resampled;\n                    resampled.reserve(n);\n                    std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });\n                    return estimator(resampled.begin(), resampled.end());\n                });\n                std::sort(out.begin(), out.end());\n                return out;\n            }\n\n            template <typename Estimator, typename Iterator>\n            sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {\n                auto n = last - first;\n                auto second = std::next(first);\n                sample results;\n                results.reserve(n);\n\n                for (auto it = first; it != last; ++it) {\n                    std::iter_swap(it, first);\n                    results.push_back(estimator(second, last));\n                }\n\n                return results;\n            }\n\n            inline double normal_cdf(double x) {\n                return std::erfc(-x / std::sqrt(2.0)) / 2.0;\n            }\n\n            double erfc_inv(double x);\n\n            double normal_quantile(double p);\n\n            template <typename Iterator, typename Estimator>\n            Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {\n                auto n_samples = last - first;\n\n                double point = estimator(first, last);\n                // Degenerate case with a single sample\n                if (n_samples == 1) return { point, point, point, confidence_level };\n\n                sample jack = jackknife(estimator, first, last);\n                double jack_mean = mean(jack.begin(), jack.end());\n                double sum_squares, sum_cubes;\n                std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {\n                    auto d = jack_mean - x;\n                    auto d2 = d * d;\n                    auto d3 = d2 * d;\n                    return { sqcb.first + d2, sqcb.second + d3 };\n                });\n\n                double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));\n                int n = static_cast<int>(resample.size());\n                double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;\n                // degenerate case with uniform samples\n                if (prob_n == 0) return { point, point, point, confidence_level };\n\n                double bias = normal_quantile(prob_n);\n                double z1 = normal_quantile((1. - confidence_level) / 2.);\n\n                auto cumn = [n](double x) -> int {\n                    return std::lround(normal_cdf(x) * n); };\n                auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };\n                double b1 = bias + z1;\n                double b2 = bias - z1;\n                double a1 = a(b1);\n                double a2 = a(b2);\n                auto lo = (std::max)(cumn(a1), 0);\n                auto hi = (std::min)(cumn(a2), n - 1);\n\n                return { point, resample[lo], resample[hi], confidence_level };\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);\n\n            struct bootstrap_analysis {\n                Estimate<double> mean;\n                Estimate<double> standard_deviation;\n                double outlier_variance;\n            };\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_stats.hpp\n#include <algorithm>\n#include <iterator>\n#include <tuple>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Clock>\n            std::vector<double> resolution(int k) {\n                std::vector<TimePoint<Clock>> times;\n                times.reserve(k + 1);\n                std::generate_n(std::back_inserter(times), k + 1, now<Clock>{});\n\n                std::vector<double> deltas;\n                deltas.reserve(k);\n                std::transform(std::next(times.begin()), times.end(), times.begin(),\n                    std::back_inserter(deltas),\n                    [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); });\n\n                return deltas;\n            }\n\n            const auto warmup_iterations = 10000;\n            const auto warmup_time = std::chrono::milliseconds(100);\n            const auto minimum_ticks = 1000;\n            const auto warmup_seed = 10000;\n            const auto clock_resolution_estimation_time = std::chrono::milliseconds(500);\n            const auto clock_cost_estimation_time_limit = std::chrono::seconds(1);\n            const auto clock_cost_estimation_tick_limit = 100000;\n            const auto clock_cost_estimation_time = std::chrono::milliseconds(10);\n            const auto clock_cost_estimation_iterations = 10000;\n\n            template <typename Clock>\n            int warmup() {\n                return run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>)\n                    .iterations;\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) {\n                auto r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>)\n                    .result;\n                return {\n                    FloatDuration<Clock>(mean(r.begin(), r.end())),\n                    classify_outliers(r.begin(), r.end()),\n                };\n            }\n            template <typename Clock>\n            EnvironmentEstimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) {\n                auto time_limit = (std::min)(\n                    resolution * clock_cost_estimation_tick_limit,\n                    FloatDuration<Clock>(clock_cost_estimation_time_limit));\n                auto time_clock = [](int k) {\n                    return Detail::measure<Clock>([k] {\n                        for (int i = 0; i < k; ++i) {\n                            volatile auto ignored = Clock::now();\n                            (void)ignored;\n                        }\n                    }).elapsed;\n                };\n                time_clock(1);\n                int iters = clock_cost_estimation_iterations;\n                auto&& r = run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(clock_cost_estimation_time), iters, time_clock);\n                std::vector<double> times;\n                int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed));\n                times.reserve(nsamples);\n                std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r] {\n                    return static_cast<double>((time_clock(r.iterations) / r.iterations).count());\n                });\n                return {\n                    FloatDuration<Clock>(mean(times.begin(), times.end())),\n                    classify_outliers(times.begin(), times.end()),\n                };\n            }\n\n            template <typename Clock>\n            Environment<FloatDuration<Clock>> measure_environment() {\n                static Environment<FloatDuration<Clock>>* env = nullptr;\n                if (env) {\n                    return *env;\n                }\n\n                auto iters = Detail::warmup<Clock>();\n                auto resolution = Detail::estimate_clock_resolution<Clock>(iters);\n                auto cost = Detail::estimate_clock_cost<Clock>(resolution.mean);\n\n                env = new Environment<FloatDuration<Clock>>{ resolution, cost };\n                return *env;\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_estimate_clock.hpp\n// start catch_analyse.hpp\n\n // Run and analyse one benchmark\n\n\n// start catch_sample_analysis.hpp\n\n// Benchmark results\n\n\n#include <algorithm>\n#include <vector>\n#include <string>\n#include <iterator>\n\nnamespace Catch {\n    namespace Benchmark {\n        template <typename Duration>\n        struct SampleAnalysis {\n            std::vector<Duration> samples;\n            Estimate<Duration> mean;\n            Estimate<Duration> standard_deviation;\n            OutlierClassification outliers;\n            double outlier_variance;\n\n            template <typename Duration2>\n            operator SampleAnalysis<Duration2>() const {\n                std::vector<Duration2> samples2;\n                samples2.reserve(samples.size());\n                std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); });\n                return {\n                    std::move(samples2),\n                    mean,\n                    standard_deviation,\n                    outliers,\n                    outlier_variance,\n                };\n            }\n        };\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_sample_analysis.hpp\n#include <algorithm>\n#include <iterator>\n#include <vector>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename Duration, typename Iterator>\n            SampleAnalysis<Duration> analyse(const IConfig &cfg, Environment<Duration>, Iterator first, Iterator last) {\n                if (!cfg.benchmarkNoAnalysis()) {\n                    std::vector<double> samples;\n                    samples.reserve(last - first);\n                    std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); });\n\n                    auto analysis = Catch::Benchmark::Detail::analyse_samples(cfg.benchmarkConfidenceInterval(), cfg.benchmarkResamples(), samples.begin(), samples.end());\n                    auto outliers = Catch::Benchmark::Detail::classify_outliers(samples.begin(), samples.end());\n\n                    auto wrap_estimate = [](Estimate<double> e) {\n                        return Estimate<Duration> {\n                            Duration(e.point),\n                                Duration(e.lower_bound),\n                                Duration(e.upper_bound),\n                                e.confidence_interval,\n                        };\n                    };\n                    std::vector<Duration> samples2;\n                    samples2.reserve(samples.size());\n                    std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); });\n                    return {\n                        std::move(samples2),\n                        wrap_estimate(analysis.mean),\n                        wrap_estimate(analysis.standard_deviation),\n                        outliers,\n                        analysis.outlier_variance,\n                    };\n                } else {\n                    std::vector<Duration> samples;\n                    samples.reserve(last - first);\n\n                    Duration mean = Duration(0);\n                    int i = 0;\n                    for (auto it = first; it < last; ++it, ++i) {\n                        samples.push_back(Duration(*it));\n                        mean += Duration(*it);\n                    }\n                    mean /= i;\n\n                    return {\n                        std::move(samples),\n                        Estimate<Duration>{mean, mean, mean, 0.0},\n                        Estimate<Duration>{Duration(0), Duration(0), Duration(0), 0.0},\n                        OutlierClassification{},\n                        0.0\n                    };\n                }\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n// end catch_analyse.hpp\n#include <algorithm>\n#include <functional>\n#include <string>\n#include <vector>\n#include <cmath>\n\nnamespace Catch {\n    namespace Benchmark {\n        struct Benchmark {\n            Benchmark(std::string &&name)\n                : name(std::move(name)) {}\n\n            template <class FUN>\n            Benchmark(std::string &&name, FUN &&func)\n                : fun(std::move(func)), name(std::move(name)) {}\n\n            template <typename Clock>\n            ExecutionPlan<FloatDuration<Clock>> prepare(const IConfig &cfg, Environment<FloatDuration<Clock>> env) const {\n                auto min_time = env.clock_resolution.mean * Detail::minimum_ticks;\n                auto run_time = std::max(min_time, std::chrono::duration_cast<decltype(min_time)>(cfg.benchmarkWarmupTime()));\n                auto&& test = Detail::run_for_at_least<Clock>(std::chrono::duration_cast<ClockDuration<Clock>>(run_time), 1, fun);\n                int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed));\n                return { new_iters, test.elapsed / test.iterations * new_iters * cfg.benchmarkSamples(), fun, std::chrono::duration_cast<FloatDuration<Clock>>(cfg.benchmarkWarmupTime()), Detail::warmup_iterations };\n            }\n\n            template <typename Clock = default_clock>\n            void run() {\n                IConfigPtr cfg = getCurrentContext().getConfig();\n\n                auto env = Detail::measure_environment<Clock>();\n\n                getResultCapture().benchmarkPreparing(name);\n                CATCH_TRY{\n                    auto plan = user_code([&] {\n                        return prepare<Clock>(*cfg, env);\n                    });\n\n                    BenchmarkInfo info {\n                        name,\n                        plan.estimated_duration.count(),\n                        plan.iterations_per_sample,\n                        cfg->benchmarkSamples(),\n                        cfg->benchmarkResamples(),\n                        env.clock_resolution.mean.count(),\n                        env.clock_cost.mean.count()\n                    };\n\n                    getResultCapture().benchmarkStarting(info);\n\n                    auto samples = user_code([&] {\n                        return plan.template run<Clock>(*cfg, env);\n                    });\n\n                    auto analysis = Detail::analyse(*cfg, env, samples.begin(), samples.end());\n                    BenchmarkStats<FloatDuration<Clock>> stats{ info, analysis.samples, analysis.mean, analysis.standard_deviation, analysis.outliers, analysis.outlier_variance };\n                    getResultCapture().benchmarkEnded(stats);\n\n                } CATCH_CATCH_ALL{\n                    if (translateActiveException() != Detail::benchmarkErrorMsg) // benchmark errors have been reported, otherwise rethrow.\n                        std::rethrow_exception(std::current_exception());\n                }\n            }\n\n            // sets lambda to be used in fun *and* executes benchmark!\n            template <typename Fun,\n                typename std::enable_if<!Detail::is_related<Fun, Benchmark>::value, int>::type = 0>\n                Benchmark & operator=(Fun func) {\n                fun = Detail::BenchmarkFunction(func);\n                run();\n                return *this;\n            }\n\n            explicit operator bool() {\n                return true;\n            }\n\n        private:\n            Detail::BenchmarkFunction fun;\n            std::string name;\n        };\n    }\n} // namespace Catch\n\n#define INTERNAL_CATCH_GET_1_ARG(arg1, arg2, ...) arg1\n#define INTERNAL_CATCH_GET_2_ARG(arg1, arg2, ...) arg2\n\n#define INTERNAL_CATCH_BENCHMARK(BenchmarkName, name, benchmarkIndex)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&](int benchmarkIndex)\n\n#define INTERNAL_CATCH_BENCHMARK_ADVANCED(BenchmarkName, name)\\\n    if( Catch::Benchmark::Benchmark BenchmarkName{name} ) \\\n        BenchmarkName = [&]\n\n// end catch_benchmark.hpp\n// start catch_constructor.hpp\n\n// Constructor and destructor helpers\n\n\n#include <type_traits>\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n            template <typename T, bool Destruct>\n            struct ObjectStorage\n            {\n                using TStorage = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;\n\n                ObjectStorage() : data() {}\n\n                ObjectStorage(const ObjectStorage& other)\n                {\n                    new(&data) T(other.stored_object());\n                }\n\n                ObjectStorage(ObjectStorage&& other)\n                {\n                    new(&data) T(std::move(other.stored_object()));\n                }\n\n                ~ObjectStorage() { destruct_on_exit<T>(); }\n\n                template <typename... Args>\n                void construct(Args&&... args)\n                {\n                    new (&data) T(std::forward<Args>(args)...);\n                }\n\n                template <bool AllowManualDestruction = !Destruct>\n                typename std::enable_if<AllowManualDestruction>::type destruct()\n                {\n                    stored_object().~T();\n                }\n\n            private:\n                // If this is a constructor benchmark, destruct the underlying object\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); }\n                // Otherwise, don't\n                template <typename U>\n                void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { }\n\n                T& stored_object() {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                T const& stored_object() const {\n                    return *static_cast<T*>(static_cast<void*>(&data));\n                }\n\n                TStorage data;\n            };\n        }\n\n        template <typename T>\n        using storage_for = Detail::ObjectStorage<T, true>;\n\n        template <typename T>\n        using destructable_object = Detail::ObjectStorage<T, false>;\n    }\n}\n\n// end catch_constructor.hpp\n// end catch_benchmarking_all.hpp\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n#ifdef CATCH_IMPL\n// start catch_impl.hpp\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#endif\n\n// Keep these here for external reporters\n// start catch_test_case_tracker.h\n\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    struct NameAndLocation {\n        std::string name;\n        SourceLineInfo location;\n\n        NameAndLocation( std::string const& _name, SourceLineInfo const& _location );\n        friend bool operator==(NameAndLocation const& lhs, NameAndLocation const& rhs) {\n            return lhs.name == rhs.name\n                && lhs.location == rhs.location;\n        }\n    };\n\n    class ITracker;\n\n    using ITrackerPtr = std::shared_ptr<ITracker>;\n\n    class  ITracker {\n        NameAndLocation m_nameAndLocation;\n\n    public:\n        ITracker(NameAndLocation const& nameAndLoc) :\n            m_nameAndLocation(nameAndLoc)\n        {}\n\n        // static queries\n        NameAndLocation const& nameAndLocation() const {\n            return m_nameAndLocation;\n        }\n\n        virtual ~ITracker();\n\n        // dynamic queries\n        virtual bool isComplete() const = 0; // Successfully completed or failed\n        virtual bool isSuccessfullyCompleted() const = 0;\n        virtual bool isOpen() const = 0; // Started but not complete\n        virtual bool hasChildren() const = 0;\n        virtual bool hasStarted() const = 0;\n\n        virtual ITracker& parent() = 0;\n\n        // actions\n        virtual void close() = 0; // Successfully complete\n        virtual void fail() = 0;\n        virtual void markAsNeedingAnotherRun() = 0;\n\n        virtual void addChild( ITrackerPtr const& child ) = 0;\n        virtual ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) = 0;\n        virtual void openChild() = 0;\n\n        // Debug/ checking\n        virtual bool isSectionTracker() const = 0;\n        virtual bool isGeneratorTracker() const = 0;\n    };\n\n    class TrackerContext {\n\n        enum RunState {\n            NotStarted,\n            Executing,\n            CompletedCycle\n        };\n\n        ITrackerPtr m_rootTracker;\n        ITracker* m_currentTracker = nullptr;\n        RunState m_runState = NotStarted;\n\n    public:\n\n        ITracker& startRun();\n        void endRun();\n\n        void startCycle();\n        void completeCycle();\n\n        bool completedCycle() const;\n        ITracker& currentTracker();\n        void setCurrentTracker( ITracker* tracker );\n    };\n\n    class TrackerBase : public ITracker {\n    protected:\n        enum CycleState {\n            NotStarted,\n            Executing,\n            ExecutingChildren,\n            NeedsAnotherRun,\n            CompletedSuccessfully,\n            Failed\n        };\n\n        using Children = std::vector<ITrackerPtr>;\n        TrackerContext& m_ctx;\n        ITracker* m_parent;\n        Children m_children;\n        CycleState m_runState = NotStarted;\n\n    public:\n        TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isComplete() const override;\n        bool isSuccessfullyCompleted() const override;\n        bool isOpen() const override;\n        bool hasChildren() const override;\n        bool hasStarted() const override {\n            return m_runState != NotStarted;\n        }\n\n        void addChild( ITrackerPtr const& child ) override;\n\n        ITrackerPtr findChild( NameAndLocation const& nameAndLocation ) override;\n        ITracker& parent() override;\n\n        void openChild() override;\n\n        bool isSectionTracker() const override;\n        bool isGeneratorTracker() const override;\n\n        void open();\n\n        void close() override;\n        void fail() override;\n        void markAsNeedingAnotherRun() override;\n\n    private:\n        void moveToParent();\n        void moveToThis();\n    };\n\n    class SectionTracker : public TrackerBase {\n        std::vector<std::string> m_filters;\n        std::string m_trimmed_name;\n    public:\n        SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent );\n\n        bool isSectionTracker() const override;\n\n        bool isComplete() const override;\n\n        static SectionTracker& acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation );\n\n        void tryOpen();\n\n        void addInitialFilters( std::vector<std::string> const& filters );\n        void addNextFilters( std::vector<std::string> const& filters );\n        //! Returns filters active in this tracker\n        std::vector<std::string> const& getFilters() const;\n        //! Returns whitespace-trimmed name of the tracked section\n        std::string const& trimmedName() const;\n    };\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n// end catch_test_case_tracker.h\n\n// start catch_leak_detector.h\n\nnamespace Catch {\n\n    struct LeakDetector {\n        LeakDetector();\n        ~LeakDetector();\n    };\n\n}\n// end catch_leak_detector.h\n// Cpp files will be included in the single-header file here\n// start catch_stats.cpp\n\n// Statistical analysis tools\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n\n#include <cassert>\n#include <random>\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n#include <future>\n#endif\n\nnamespace {\n    double erf_inv(double x) {\n        // Code accompanying the article \"Approximating the erfinv function\" in GPU Computing Gems, Volume 2\n        double w, p;\n\n        w = -log((1.0 - x) * (1.0 + x));\n\n        if (w < 6.250000) {\n            w = w - 3.125000;\n            p = -3.6444120640178196996e-21;\n            p = -1.685059138182016589e-19 + p * w;\n            p = 1.2858480715256400167e-18 + p * w;\n            p = 1.115787767802518096e-17 + p * w;\n            p = -1.333171662854620906e-16 + p * w;\n            p = 2.0972767875968561637e-17 + p * w;\n            p = 6.6376381343583238325e-15 + p * w;\n            p = -4.0545662729752068639e-14 + p * w;\n            p = -8.1519341976054721522e-14 + p * w;\n            p = 2.6335093153082322977e-12 + p * w;\n            p = -1.2975133253453532498e-11 + p * w;\n            p = -5.4154120542946279317e-11 + p * w;\n            p = 1.051212273321532285e-09 + p * w;\n            p = -4.1126339803469836976e-09 + p * w;\n            p = -2.9070369957882005086e-08 + p * w;\n            p = 4.2347877827932403518e-07 + p * w;\n            p = -1.3654692000834678645e-06 + p * w;\n            p = -1.3882523362786468719e-05 + p * w;\n            p = 0.0001867342080340571352 + p * w;\n            p = -0.00074070253416626697512 + p * w;\n            p = -0.0060336708714301490533 + p * w;\n            p = 0.24015818242558961693 + p * w;\n            p = 1.6536545626831027356 + p * w;\n        } else if (w < 16.000000) {\n            w = sqrt(w) - 3.250000;\n            p = 2.2137376921775787049e-09;\n            p = 9.0756561938885390979e-08 + p * w;\n            p = -2.7517406297064545428e-07 + p * w;\n            p = 1.8239629214389227755e-08 + p * w;\n            p = 1.5027403968909827627e-06 + p * w;\n            p = -4.013867526981545969e-06 + p * w;\n            p = 2.9234449089955446044e-06 + p * w;\n            p = 1.2475304481671778723e-05 + p * w;\n            p = -4.7318229009055733981e-05 + p * w;\n            p = 6.8284851459573175448e-05 + p * w;\n            p = 2.4031110387097893999e-05 + p * w;\n            p = -0.0003550375203628474796 + p * w;\n            p = 0.00095328937973738049703 + p * w;\n            p = -0.0016882755560235047313 + p * w;\n            p = 0.0024914420961078508066 + p * w;\n            p = -0.0037512085075692412107 + p * w;\n            p = 0.005370914553590063617 + p * w;\n            p = 1.0052589676941592334 + p * w;\n            p = 3.0838856104922207635 + p * w;\n        } else {\n            w = sqrt(w) - 5.000000;\n            p = -2.7109920616438573243e-11;\n            p = -2.5556418169965252055e-10 + p * w;\n            p = 1.5076572693500548083e-09 + p * w;\n            p = -3.7894654401267369937e-09 + p * w;\n            p = 7.6157012080783393804e-09 + p * w;\n            p = -1.4960026627149240478e-08 + p * w;\n            p = 2.9147953450901080826e-08 + p * w;\n            p = -6.7711997758452339498e-08 + p * w;\n            p = 2.2900482228026654717e-07 + p * w;\n            p = -9.9298272942317002539e-07 + p * w;\n            p = 4.5260625972231537039e-06 + p * w;\n            p = -1.9681778105531670567e-05 + p * w;\n            p = 7.5995277030017761139e-05 + p * w;\n            p = -0.00021503011930044477347 + p * w;\n            p = -0.00013871931833623122026 + p * w;\n            p = 1.0103004648645343977 + p * w;\n            p = 4.8499064014085844221 + p * w;\n        }\n        return p * x;\n    }\n\n    double standard_deviation(std::vector<double>::iterator first, std::vector<double>::iterator last) {\n        auto m = Catch::Benchmark::Detail::mean(first, last);\n        double variance = std::accumulate(first, last, 0., [m](double a, double b) {\n            double diff = b - m;\n            return a + diff * diff;\n            }) / (last - first);\n            return std::sqrt(variance);\n    }\n\n}\n\nnamespace Catch {\n    namespace Benchmark {\n        namespace Detail {\n\n            double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                auto count = last - first;\n                double idx = (count - 1) * k / static_cast<double>(q);\n                int j = static_cast<int>(idx);\n                double g = idx - j;\n                std::nth_element(first, first + j, last);\n                auto xj = first[j];\n                if (g == 0) return xj;\n\n                auto xj1 = *std::min_element(first + (j + 1), last);\n                return xj + g * (xj1 - xj);\n            }\n\n            double erfc_inv(double x) {\n                return erf_inv(1.0 - x);\n            }\n\n            double normal_quantile(double p) {\n                static const double ROOT_TWO = std::sqrt(2.0);\n\n                double result = 0.0;\n                assert(p >= 0 && p <= 1);\n                if (p < 0 || p > 1) {\n                    return result;\n                }\n\n                result = -erfc_inv(2.0 * p);\n                // result *= normal distribution standard deviation (1.0) * sqrt(2)\n                result *= /*sd * */ ROOT_TWO;\n                // result += normal disttribution mean (0)\n                return result;\n            }\n\n            double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n) {\n                double sb = stddev.point;\n                double mn = mean.point / n;\n                double mg_min = mn / 2.;\n                double sg = (std::min)(mg_min / 4., sb / std::sqrt(n));\n                double sg2 = sg * sg;\n                double sb2 = sb * sb;\n\n                auto c_max = [n, mn, sb2, sg2](double x) -> double {\n                    double k = mn - x;\n                    double d = k * k;\n                    double nd = n * d;\n                    double k0 = -n * nd;\n                    double k1 = sb2 - n * sg2 + nd;\n                    double det = k1 * k1 - 4 * sg2 * k0;\n                    return (int)(-2. * k0 / (k1 + std::sqrt(det)));\n                };\n\n                auto var_out = [n, sb2, sg2](double c) {\n                    double nc = n - c;\n                    return (nc / n) * (sb2 - nc * sg2);\n                };\n\n                return (std::min)(var_out(1), var_out((std::min)(c_max(0.), c_max(mg_min)))) / sb2;\n            }\n\n            bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last) {\n                CATCH_INTERNAL_START_WARNINGS_SUPPRESSION\n                CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS\n                static std::random_device entropy;\n                CATCH_INTERNAL_STOP_WARNINGS_SUPPRESSION\n\n                auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++\n\n                auto mean = &Detail::mean<std::vector<double>::iterator>;\n                auto stddev = &standard_deviation;\n\n#if defined(CATCH_CONFIG_USE_ASYNC)\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    return std::async(std::launch::async, [=] {\n                        std::mt19937 rng(seed);\n                        auto resampled = resample(rng, n_resamples, first, last, f);\n                        return bootstrap(confidence_level, first, last, resampled, f);\n                    });\n                };\n\n                auto mean_future = Estimate(mean);\n                auto stddev_future = Estimate(stddev);\n\n                auto mean_estimate = mean_future.get();\n                auto stddev_estimate = stddev_future.get();\n#else\n                auto Estimate = [=](double(*f)(std::vector<double>::iterator, std::vector<double>::iterator)) {\n                    auto seed = entropy();\n                    std::mt19937 rng(seed);\n                    auto resampled = resample(rng, n_resamples, first, last, f);\n                    return bootstrap(confidence_level, first, last, resampled, f);\n                };\n\n                auto mean_estimate = Estimate(mean);\n                auto stddev_estimate = Estimate(stddev);\n#endif // CATCH_USE_ASYNC\n\n                double outlier_variance = Detail::outlier_variance(mean_estimate, stddev_estimate, n);\n\n                return { mean_estimate, stddev_estimate, outlier_variance };\n            }\n        } // namespace Detail\n    } // namespace Benchmark\n} // namespace Catch\n\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n// end catch_stats.cpp\n// start catch_approx.cpp\n\n#include <cmath>\n#include <limits>\n\nnamespace {\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\n}\n\nnamespace Catch {\nnamespace Detail {\n\n    Approx::Approx ( double value )\n    :   m_epsilon( std::numeric_limits<float>::epsilon()*100 ),\n        m_margin( 0.0 ),\n        m_scale( 0.0 ),\n        m_value( value )\n    {}\n\n    Approx Approx::custom() {\n        return Approx( 0 );\n    }\n\n    Approx Approx::operator-() const {\n        auto temp(*this);\n        temp.m_value = -temp.m_value;\n        return temp;\n    }\n\n    std::string Approx::toString() const {\n        ReusableStringStream rss;\n        rss << \"Approx( \" << ::Catch::Detail::stringify( m_value ) << \" )\";\n        return rss.str();\n    }\n\n    bool Approx::equalityComparisonImpl(const double other) const {\n        // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value\n        // Thanks to Richard Harris for his help refining the scaled margin value\n        return marginComparison(m_value, other, m_margin)\n            || marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(std::isinf(m_value)? 0 : m_value)));\n    }\n\n    void Approx::setMargin(double newMargin) {\n        CATCH_ENFORCE(newMargin >= 0,\n            \"Invalid Approx::margin: \" << newMargin << '.'\n            << \" Approx::Margin has to be non-negative.\");\n        m_margin = newMargin;\n    }\n\n    void Approx::setEpsilon(double newEpsilon) {\n        CATCH_ENFORCE(newEpsilon >= 0 && newEpsilon <= 1.0,\n            \"Invalid Approx::epsilon: \" << newEpsilon << '.'\n            << \" Approx::epsilon has to be in [0, 1]\");\n        m_epsilon = newEpsilon;\n    }\n\n} // end namespace Detail\n\nnamespace literals {\n    Detail::Approx operator \"\" _a(long double val) {\n        return Detail::Approx(val);\n    }\n    Detail::Approx operator \"\" _a(unsigned long long val) {\n        return Detail::Approx(val);\n    }\n} // end namespace literals\n\nstd::string StringMaker<Catch::Detail::Approx>::convert(Catch::Detail::Approx const& value) {\n    return value.toString();\n}\n\n} // end namespace Catch\n// end catch_approx.cpp\n// start catch_assertionhandler.cpp\n\n// start catch_debugger.h\n\nnamespace Catch {\n    bool isDebuggerActive();\n}\n\n#ifdef CATCH_PLATFORM_MAC\n\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP() __asm__(\"int $3\\n\" : : ) /* NOLINT */\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd4200000\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_IPHONE)\n\n    // use inline assembler\n    #if defined(__i386__) || defined(__x86_64__)\n        #define CATCH_TRAP()  __asm__(\"int $3\")\n    #elif defined(__aarch64__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xd4200000\")\n    #elif defined(__arm__) && !defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xe7f001f0\")\n    #elif defined(__arm__) &&  defined(__thumb__)\n        #define CATCH_TRAP()  __asm__(\".inst 0xde01\")\n    #endif\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    // If we can use inline assembler, do it because this allows us to break\n    // directly at the location of the failing check instead of breaking inside\n    // raise() called from it, i.e. one stack frame below.\n    #if defined(__GNUC__) && (defined(__i386) || defined(__x86_64))\n        #define CATCH_TRAP() asm volatile (\"int $3\") /* NOLINT */\n    #else // Fall back to the generic way.\n        #include <signal.h>\n\n        #define CATCH_TRAP() raise(SIGTRAP)\n    #endif\n#elif defined(_MSC_VER)\n    #define CATCH_TRAP() __debugbreak()\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) void __stdcall DebugBreak();\n    #define CATCH_TRAP() DebugBreak()\n#endif\n\n#ifndef CATCH_BREAK_INTO_DEBUGGER\n    #ifdef CATCH_TRAP\n        #define CATCH_BREAK_INTO_DEBUGGER() []{ if( Catch::isDebuggerActive() ) { CATCH_TRAP(); } }()\n    #else\n        #define CATCH_BREAK_INTO_DEBUGGER() []{}()\n    #endif\n#endif\n\n// end catch_debugger.h\n// start catch_run_context.h\n\n// start catch_fatal_condition.h\n\n#include <cassert>\n\nnamespace Catch {\n\n    // Wrapper for platform-specific fatal error (signals/SEH) handlers\n    //\n    // Tries to be cooperative with other handlers, and not step over\n    // other handlers. This means that unknown structured exceptions\n    // are passed on, previous signal handlers are called, and so on.\n    //\n    // Can only be instantiated once, and assumes that once a signal\n    // is caught, the binary will end up terminating. Thus, there\n    class FatalConditionHandler {\n        bool m_started = false;\n\n        // Install/disengage implementation for specific platform.\n        // Should be if-defed to work on current platform, can assume\n        // engage-disengage 1:1 pairing.\n        void engage_platform();\n        void disengage_platform();\n    public:\n        // Should also have platform-specific implementations as needed\n        FatalConditionHandler();\n        ~FatalConditionHandler();\n\n        void engage() {\n            assert(!m_started && \"Handler cannot be installed twice.\");\n            m_started = true;\n            engage_platform();\n        }\n\n        void disengage() {\n            assert(m_started && \"Handler cannot be uninstalled without being installed first\");\n            m_started = false;\n            disengage_platform();\n        }\n    };\n\n    //! Simple RAII guard for (dis)engaging the FatalConditionHandler\n    class FatalConditionHandlerGuard {\n        FatalConditionHandler* m_handler;\n    public:\n        FatalConditionHandlerGuard(FatalConditionHandler* handler):\n            m_handler(handler) {\n            m_handler->engage();\n        }\n        ~FatalConditionHandlerGuard() {\n            m_handler->disengage();\n        }\n    };\n\n} // end namespace Catch\n\n// end catch_fatal_condition.h\n#include <string>\n\nnamespace Catch {\n\n    struct IMutableContext;\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class RunContext : public IResultCapture, public IRunner {\n\n    public:\n        RunContext( RunContext const& ) = delete;\n        RunContext& operator =( RunContext const& ) = delete;\n\n        explicit RunContext( IConfigPtr const& _config, IStreamingReporterPtr&& reporter );\n\n        ~RunContext() override;\n\n        void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount );\n        void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount );\n\n        Totals runTest(TestCase const& testCase);\n\n        IConfigPtr config() const;\n        IStreamingReporter& reporter() const;\n\n    public: // IResultCapture\n\n        // Assertion handlers\n        void handleExpr\n                (   AssertionInfo const& info,\n                    ITransientExpression const& expr,\n                    AssertionReaction& reaction ) override;\n        void handleMessage\n                (   AssertionInfo const& info,\n                    ResultWas::OfType resultType,\n                    StringRef const& message,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedExceptionNotThrown\n                (   AssertionInfo const& info,\n                    AssertionReaction& reaction ) override;\n        void handleUnexpectedInflightException\n                (   AssertionInfo const& info,\n                    std::string const& message,\n                    AssertionReaction& reaction ) override;\n        void handleIncomplete\n                (   AssertionInfo const& info ) override;\n        void handleNonExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    AssertionReaction &reaction ) override;\n\n        bool sectionStarted( SectionInfo const& sectionInfo, Counts& assertions ) override;\n\n        void sectionEnded( SectionEndInfo const& endInfo ) override;\n        void sectionEndedEarly( SectionEndInfo const& endInfo ) override;\n\n        auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& override;\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing( std::string const& name ) override;\n        void benchmarkStarting( BenchmarkInfo const& info ) override;\n        void benchmarkEnded( BenchmarkStats<> const& stats ) override;\n        void benchmarkFailed( std::string const& error ) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void pushScopedMessage( MessageInfo const& message ) override;\n        void popScopedMessage( MessageInfo const& message ) override;\n\n        void emplaceUnscopedMessage( MessageBuilder const& builder ) override;\n\n        std::string getCurrentTestName() const override;\n\n        const AssertionResult* getLastResult() const override;\n\n        void exceptionEarlyReported() override;\n\n        void handleFatalErrorCondition( StringRef message ) override;\n\n        bool lastAssertionPassed() override;\n\n        void assertionPassed() override;\n\n    public:\n        // !TBD We need to do this another way!\n        bool aborting() const final;\n\n    private:\n\n        void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr );\n        void invokeActiveTestCase();\n\n        void resetAssertionInfo();\n        bool testForMissingAssertions( Counts& assertions );\n\n        void assertionEnded( AssertionResult const& result );\n        void reportExpr\n                (   AssertionInfo const &info,\n                    ResultWas::OfType resultType,\n                    ITransientExpression const *expr,\n                    bool negated );\n\n        void populateReaction( AssertionReaction& reaction );\n\n    private:\n\n        void handleUnfinishedSections();\n\n        TestRunInfo m_runInfo;\n        IMutableContext& m_context;\n        TestCase const* m_activeTestCase = nullptr;\n        ITracker* m_testCaseTracker = nullptr;\n        Option<AssertionResult> m_lastResult;\n\n        IConfigPtr m_config;\n        Totals m_totals;\n        IStreamingReporterPtr m_reporter;\n        std::vector<MessageInfo> m_messages;\n        std::vector<ScopedMessage> m_messageScopes; /* Keeps owners of so-called unscoped messages. */\n        AssertionInfo m_lastAssertionInfo;\n        std::vector<SectionEndInfo> m_unfinishedSections;\n        std::vector<ITracker*> m_activeSections;\n        TrackerContext m_trackerContext;\n        FatalConditionHandler m_fatalConditionhandler;\n        bool m_lastAssertionPassed = false;\n        bool m_shouldReportUnexpected = true;\n        bool m_includeSuccessfulResults;\n    };\n\n    void seedRng(IConfig const& config);\n    unsigned int rngSeed();\n} // end namespace Catch\n\n// end catch_run_context.h\nnamespace Catch {\n\n    namespace {\n        auto operator <<( std::ostream& os, ITransientExpression const& expr ) -> std::ostream& {\n            expr.streamReconstructedExpression( os );\n            return os;\n        }\n    }\n\n    LazyExpression::LazyExpression( bool isNegated )\n    :   m_isNegated( isNegated )\n    {}\n\n    LazyExpression::LazyExpression( LazyExpression const& other ) : m_isNegated( other.m_isNegated ) {}\n\n    LazyExpression::operator bool() const {\n        return m_transientExpression != nullptr;\n    }\n\n    auto operator << ( std::ostream& os, LazyExpression const& lazyExpr ) -> std::ostream& {\n        if( lazyExpr.m_isNegated )\n            os << \"!\";\n\n        if( lazyExpr ) {\n            if( lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression() )\n                os << \"(\" << *lazyExpr.m_transientExpression << \")\";\n            else\n                os << *lazyExpr.m_transientExpression;\n        }\n        else {\n            os << \"{** error - unchecked empty expression requested **}\";\n        }\n        return os;\n    }\n\n    AssertionHandler::AssertionHandler\n        (   StringRef const& macroName,\n            SourceLineInfo const& lineInfo,\n            StringRef capturedExpression,\n            ResultDisposition::Flags resultDisposition )\n    :   m_assertionInfo{ macroName, lineInfo, capturedExpression, resultDisposition },\n        m_resultCapture( getResultCapture() )\n    {}\n\n    void AssertionHandler::handleExpr( ITransientExpression const& expr ) {\n        m_resultCapture.handleExpr( m_assertionInfo, expr, m_reaction );\n    }\n    void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const& message) {\n        m_resultCapture.handleMessage( m_assertionInfo, resultType, message, m_reaction );\n    }\n\n    auto AssertionHandler::allowThrows() const -> bool {\n        return getCurrentContext().getConfig()->allowThrows();\n    }\n\n    void AssertionHandler::complete() {\n        setCompleted();\n        if( m_reaction.shouldDebugBreak ) {\n\n            // If you find your debugger stopping you here then go one level up on the\n            // call-stack for the code that caused it (typically a failed assertion)\n\n            // (To go back to the test and change execution, jump over the throw, next)\n            CATCH_BREAK_INTO_DEBUGGER();\n        }\n        if (m_reaction.shouldThrow) {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n            throw Catch::TestFailureException();\n#else\n            CATCH_ERROR( \"Test failure requires aborting test!\" );\n#endif\n        }\n    }\n    void AssertionHandler::setCompleted() {\n        m_completed = true;\n    }\n\n    void AssertionHandler::handleUnexpectedInflightException() {\n        m_resultCapture.handleUnexpectedInflightException( m_assertionInfo, Catch::translateActiveException(), m_reaction );\n    }\n\n    void AssertionHandler::handleExceptionThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n    void AssertionHandler::handleExceptionNotThrownAsExpected() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    void AssertionHandler::handleUnexpectedExceptionNotThrown() {\n        m_resultCapture.handleUnexpectedExceptionNotThrown( m_assertionInfo, m_reaction );\n    }\n\n    void AssertionHandler::handleThrowingCallSkipped() {\n        m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction);\n    }\n\n    // This is the overload that takes a string and infers the Equals matcher from it\n    // The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp\n    void handleExceptionMatchExpr( AssertionHandler& handler, std::string const& str, StringRef const& matcherString  ) {\n        handleExceptionMatchExpr( handler, Matchers::Equals( str ), matcherString );\n    }\n\n} // namespace Catch\n// end catch_assertionhandler.cpp\n// start catch_assertionresult.cpp\n\nnamespace Catch {\n    AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const & _lazyExpression):\n        lazyExpression(_lazyExpression),\n        resultType(_resultType) {}\n\n    std::string AssertionResultData::reconstructExpression() const {\n\n        if( reconstructedExpression.empty() ) {\n            if( lazyExpression ) {\n                ReusableStringStream rss;\n                rss << lazyExpression;\n                reconstructedExpression = rss.str();\n            }\n        }\n        return reconstructedExpression;\n    }\n\n    AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data )\n    :   m_info( info ),\n        m_resultData( data )\n    {}\n\n    // Result was a success\n    bool AssertionResult::succeeded() const {\n        return Catch::isOk( m_resultData.resultType );\n    }\n\n    // Result was a success, or failure is suppressed\n    bool AssertionResult::isOk() const {\n        return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition );\n    }\n\n    ResultWas::OfType AssertionResult::getResultType() const {\n        return m_resultData.resultType;\n    }\n\n    bool AssertionResult::hasExpression() const {\n        return !m_info.capturedExpression.empty();\n    }\n\n    bool AssertionResult::hasMessage() const {\n        return !m_resultData.message.empty();\n    }\n\n    std::string AssertionResult::getExpression() const {\n        // Possibly overallocating by 3 characters should be basically free\n        std::string expr; expr.reserve(m_info.capturedExpression.size() + 3);\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += \"!(\";\n        }\n        expr += m_info.capturedExpression;\n        if (isFalseTest(m_info.resultDisposition)) {\n            expr += ')';\n        }\n        return expr;\n    }\n\n    std::string AssertionResult::getExpressionInMacro() const {\n        std::string expr;\n        if( m_info.macroName.empty() )\n            expr = static_cast<std::string>(m_info.capturedExpression);\n        else {\n            expr.reserve( m_info.macroName.size() + m_info.capturedExpression.size() + 4 );\n            expr += m_info.macroName;\n            expr += \"( \";\n            expr += m_info.capturedExpression;\n            expr += \" )\";\n        }\n        return expr;\n    }\n\n    bool AssertionResult::hasExpandedExpression() const {\n        return hasExpression() && getExpandedExpression() != getExpression();\n    }\n\n    std::string AssertionResult::getExpandedExpression() const {\n        std::string expr = m_resultData.reconstructExpression();\n        return expr.empty()\n                ? getExpression()\n                : expr;\n    }\n\n    std::string AssertionResult::getMessage() const {\n        return m_resultData.message;\n    }\n    SourceLineInfo AssertionResult::getSourceInfo() const {\n        return m_info.lineInfo;\n    }\n\n    StringRef AssertionResult::getTestMacroName() const {\n        return m_info.macroName;\n    }\n\n} // end namespace Catch\n// end catch_assertionresult.cpp\n// start catch_capture_matchers.cpp\n\nnamespace Catch {\n\n    using StringMatcher = Matchers::Impl::MatcherBase<std::string>;\n\n    // This is the general overload that takes a any string matcher\n    // There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers\n    // the Equals matcher (so the header does not mention matchers)\n    void handleExceptionMatchExpr( AssertionHandler& handler, StringMatcher const& matcher, StringRef const& matcherString  ) {\n        std::string exceptionMessage = Catch::translateActiveException();\n        MatchExpr<std::string, StringMatcher const&> expr( exceptionMessage, matcher, matcherString );\n        handler.handleExpr( expr );\n    }\n\n} // namespace Catch\n// end catch_capture_matchers.cpp\n// start catch_commandline.cpp\n\n// start catch_commandline.h\n\n// start catch_clara.h\n\n// Use Catch's value for console width (store Clara's off to the side, if present)\n#ifdef CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#endif\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH-1\n\n#ifdef __clang__\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wweak-vtables\"\n#pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#pragma clang diagnostic ignored \"-Wshadow\"\n#endif\n\n// start clara.hpp\n// Copyright 2017 Two Blue Cubes Ltd. All rights reserved.\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// See https://github.com/philsquared/Clara for more details\n\n// Clara v1.1.5\n\n\n#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80\n#endif\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n#ifndef CLARA_CONFIG_OPTIONAL_TYPE\n#ifdef __has_include\n#if __has_include(<optional>) && __cplusplus >= 201703L\n#include <optional>\n#define CLARA_CONFIG_OPTIONAL_TYPE std::optional\n#endif\n#endif\n#endif\n\n// ----------- #included from clara_textflow.hpp -----------\n\n// TextFlowCpp\n//\n// A single-header library for wrapping and laying out basic text, by Phil Nash\n//\n// Distributed under the Boost Software License, Version 1.0. (See accompanying\n// file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n//\n// This project is hosted at https://github.com/philsquared/textflowcpp\n\n\n#include <cassert>\n#include <ostream>\n#include <sstream>\n#include <vector>\n\n#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80\n#endif\n\nnamespace Catch {\nnamespace clara {\nnamespace TextFlow {\n\ninline auto isWhitespace(char c) -> bool {\n\tstatic std::string chars = \" \\t\\n\\r\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableBefore(char c) -> bool {\n\tstatic std::string chars = \"[({<|\";\n\treturn chars.find(c) != std::string::npos;\n}\ninline auto isBreakableAfter(char c) -> bool {\n\tstatic std::string chars = \"])}>.,:;*+-=&/\\\\\";\n\treturn chars.find(c) != std::string::npos;\n}\n\nclass Columns;\n\nclass Column {\n\tstd::vector<std::string> m_strings;\n\tsize_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH;\n\tsize_t m_indent = 0;\n\tsize_t m_initialIndent = std::string::npos;\n\npublic:\n\tclass iterator {\n\t\tfriend Column;\n\n\t\tColumn const& m_column;\n\t\tsize_t m_stringIndex = 0;\n\t\tsize_t m_pos = 0;\n\n\t\tsize_t m_len = 0;\n\t\tsize_t m_end = 0;\n\t\tbool m_suffix = false;\n\n\t\titerator(Column const& column, size_t stringIndex)\n\t\t\t: m_column(column),\n\t\t\tm_stringIndex(stringIndex) {}\n\n\t\tauto line() const -> std::string const& { return m_column.m_strings[m_stringIndex]; }\n\n\t\tauto isBoundary(size_t at) const -> bool {\n\t\t\tassert(at > 0);\n\t\t\tassert(at <= line().size());\n\n\t\t\treturn at == line().size() ||\n\t\t\t\t(isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) ||\n\t\t\t\tisBreakableBefore(line()[at]) ||\n\t\t\t\tisBreakableAfter(line()[at - 1]);\n\t\t}\n\n\t\tvoid calcLength() {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\n\t\t\tm_suffix = false;\n\t\t\tauto width = m_column.m_width - indent();\n\t\t\tm_end = m_pos;\n\t\t\tif (line()[m_pos] == '\\n') {\n\t\t\t\t++m_end;\n\t\t\t}\n\t\t\twhile (m_end < line().size() && line()[m_end] != '\\n')\n\t\t\t\t++m_end;\n\n\t\t\tif (m_end < m_pos + width) {\n\t\t\t\tm_len = m_end - m_pos;\n\t\t\t} else {\n\t\t\t\tsize_t len = width;\n\t\t\t\twhile (len > 0 && !isBoundary(m_pos + len))\n\t\t\t\t\t--len;\n\t\t\t\twhile (len > 0 && isWhitespace(line()[m_pos + len - 1]))\n\t\t\t\t\t--len;\n\n\t\t\t\tif (len > 0) {\n\t\t\t\t\tm_len = len;\n\t\t\t\t} else {\n\t\t\t\t\tm_suffix = true;\n\t\t\t\t\tm_len = width - 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tauto indent() const -> size_t {\n\t\t\tauto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos;\n\t\t\treturn initial == std::string::npos ? m_column.m_indent : initial;\n\t\t}\n\n\t\tauto addIndentAndSuffix(std::string const &plain) const -> std::string {\n\t\t\treturn std::string(indent(), ' ') + (m_suffix ? plain + \"-\" : plain);\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Column const& column) : m_column(column) {\n\t\t\tassert(m_column.m_width > m_column.m_indent);\n\t\t\tassert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent);\n\t\t\tcalcLength();\n\t\t\tif (m_len == 0)\n\t\t\t\tm_stringIndex++; // Empty string\n\t\t}\n\n\t\tauto operator *() const -> std::string {\n\t\t\tassert(m_stringIndex < m_column.m_strings.size());\n\t\t\tassert(m_pos <= m_end);\n\t\t\treturn addIndentAndSuffix(line().substr(m_pos, m_len));\n\t\t}\n\n\t\tauto operator ++() -> iterator& {\n\t\t\tm_pos += m_len;\n\t\t\tif (m_pos < line().size() && line()[m_pos] == '\\n')\n\t\t\t\tm_pos += 1;\n\t\t\telse\n\t\t\t\twhile (m_pos < line().size() && isWhitespace(line()[m_pos]))\n\t\t\t\t\t++m_pos;\n\n\t\t\tif (m_pos == line().size()) {\n\t\t\t\tm_pos = 0;\n\t\t\t\t++m_stringIndex;\n\t\t\t}\n\t\t\tif (m_stringIndex < m_column.m_strings.size())\n\t\t\t\tcalcLength();\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn\n\t\t\t\tm_pos == other.m_pos &&\n\t\t\t\tm_stringIndex == other.m_stringIndex &&\n\t\t\t\t&m_column == &other.m_column;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn !operator==(other);\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\texplicit Column(std::string const& text) { m_strings.push_back(text); }\n\n\tauto width(size_t newWidth) -> Column& {\n\t\tassert(newWidth > 0);\n\t\tm_width = newWidth;\n\t\treturn *this;\n\t}\n\tauto indent(size_t newIndent) -> Column& {\n\t\tm_indent = newIndent;\n\t\treturn *this;\n\t}\n\tauto initialIndent(size_t newIndent) -> Column& {\n\t\tm_initialIndent = newIndent;\n\t\treturn *this;\n\t}\n\n\tauto width() const -> size_t { return m_width; }\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, m_strings.size() }; }\n\n\tinline friend std::ostream& operator << (std::ostream& os, Column const& col) {\n\t\tbool first = true;\n\t\tfor (auto line : col) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto operator + (Column const& other)->Columns;\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\nclass Spacer : public Column {\n\npublic:\n\texplicit Spacer(size_t spaceWidth) : Column(\"\") {\n\t\twidth(spaceWidth);\n\t}\n};\n\nclass Columns {\n\tstd::vector<Column> m_columns;\n\npublic:\n\n\tclass iterator {\n\t\tfriend Columns;\n\t\tstruct EndTag {};\n\n\t\tstd::vector<Column> const& m_columns;\n\t\tstd::vector<Column::iterator> m_iterators;\n\t\tsize_t m_activeIterators;\n\n\t\titerator(Columns const& columns, EndTag)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(0) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.end());\n\t\t}\n\n\tpublic:\n\t\tusing difference_type = std::ptrdiff_t;\n\t\tusing value_type = std::string;\n\t\tusing pointer = value_type * ;\n\t\tusing reference = value_type & ;\n\t\tusing iterator_category = std::forward_iterator_tag;\n\n\t\texplicit iterator(Columns const& columns)\n\t\t\t: m_columns(columns.m_columns),\n\t\t\tm_activeIterators(m_columns.size()) {\n\t\t\tm_iterators.reserve(m_columns.size());\n\n\t\t\tfor (auto const& col : m_columns)\n\t\t\t\tm_iterators.push_back(col.begin());\n\t\t}\n\n\t\tauto operator ==(iterator const& other) const -> bool {\n\t\t\treturn m_iterators == other.m_iterators;\n\t\t}\n\t\tauto operator !=(iterator const& other) const -> bool {\n\t\t\treturn m_iterators != other.m_iterators;\n\t\t}\n\t\tauto operator *() const -> std::string {\n\t\t\tstd::string row, padding;\n\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tauto width = m_columns[i].width();\n\t\t\t\tif (m_iterators[i] != m_columns[i].end()) {\n\t\t\t\t\tstd::string col = *m_iterators[i];\n\t\t\t\t\trow += padding + col;\n\t\t\t\t\tif (col.size() < width)\n\t\t\t\t\t\tpadding = std::string(width - col.size(), ' ');\n\t\t\t\t\telse\n\t\t\t\t\t\tpadding = \"\";\n\t\t\t\t} else {\n\t\t\t\t\tpadding += std::string(width, ' ');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn row;\n\t\t}\n\t\tauto operator ++() -> iterator& {\n\t\t\tfor (size_t i = 0; i < m_columns.size(); ++i) {\n\t\t\t\tif (m_iterators[i] != m_columns[i].end())\n\t\t\t\t\t++m_iterators[i];\n\t\t\t}\n\t\t\treturn *this;\n\t\t}\n\t\tauto operator ++(int) -> iterator {\n\t\t\titerator prev(*this);\n\t\t\toperator++();\n\t\t\treturn prev;\n\t\t}\n\t};\n\tusing const_iterator = iterator;\n\n\tauto begin() const -> iterator { return iterator(*this); }\n\tauto end() const -> iterator { return { *this, iterator::EndTag() }; }\n\n\tauto operator += (Column const& col) -> Columns& {\n\t\tm_columns.push_back(col);\n\t\treturn *this;\n\t}\n\tauto operator + (Column const& col) -> Columns {\n\t\tColumns combined = *this;\n\t\tcombined += col;\n\t\treturn combined;\n\t}\n\n\tinline friend std::ostream& operator << (std::ostream& os, Columns const& cols) {\n\n\t\tbool first = true;\n\t\tfor (auto line : cols) {\n\t\t\tif (first)\n\t\t\t\tfirst = false;\n\t\t\telse\n\t\t\t\tos << \"\\n\";\n\t\t\tos << line;\n\t\t}\n\t\treturn os;\n\t}\n\n\tauto toString() const -> std::string {\n\t\tstd::ostringstream oss;\n\t\toss << *this;\n\t\treturn oss.str();\n\t}\n};\n\ninline auto Column::operator + (Column const& other) -> Columns {\n\tColumns cols;\n\tcols += *this;\n\tcols += other;\n\treturn cols;\n}\n}\n\n}\n}\n\n// ----------- end of #include from clara_textflow.hpp -----------\n// ........... back in clara.hpp\n\n#include <cctype>\n#include <string>\n#include <memory>\n#include <set>\n#include <algorithm>\n\n#if !defined(CATCH_PLATFORM_WINDOWS) && ( defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) )\n#define CATCH_PLATFORM_WINDOWS\n#endif\n\nnamespace Catch { namespace clara {\nnamespace detail {\n\n    // Traits for extracting arg and return type of lambdas (for single argument lambdas)\n    template<typename L>\n    struct UnaryLambdaTraits : UnaryLambdaTraits<decltype( &L::operator() )> {};\n\n    template<typename ClassT, typename ReturnT, typename... Args>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( Args... ) const> {\n        static const bool isValid = false;\n    };\n\n    template<typename ClassT, typename ReturnT, typename ArgT>\n    struct UnaryLambdaTraits<ReturnT( ClassT::* )( ArgT ) const> {\n        static const bool isValid = true;\n        using ArgType = typename std::remove_const<typename std::remove_reference<ArgT>::type>::type;\n        using ReturnType = ReturnT;\n    };\n\n    class TokenStream;\n\n    // Transport for raw args (copied from main args, or supplied via init list for testing)\n    class Args {\n        friend TokenStream;\n        std::string m_exeName;\n        std::vector<std::string> m_args;\n\n    public:\n        Args( int argc, char const* const* argv )\n            : m_exeName(argv[0]),\n              m_args(argv + 1, argv + argc) {}\n\n        Args( std::initializer_list<std::string> args )\n        :   m_exeName( *args.begin() ),\n            m_args( args.begin()+1, args.end() )\n        {}\n\n        auto exeName() const -> std::string {\n            return m_exeName;\n        }\n    };\n\n    // Wraps a token coming from a token stream. These may not directly correspond to strings as a single string\n    // may encode an option + its argument if the : or = form is used\n    enum class TokenType {\n        Option, Argument\n    };\n    struct Token {\n        TokenType type;\n        std::string token;\n    };\n\n    inline auto isOptPrefix( char c ) -> bool {\n        return c == '-'\n#ifdef CATCH_PLATFORM_WINDOWS\n            || c == '/'\n#endif\n        ;\n    }\n\n    // Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled\n    class TokenStream {\n        using Iterator = std::vector<std::string>::const_iterator;\n        Iterator it;\n        Iterator itEnd;\n        std::vector<Token> m_tokenBuffer;\n\n        void loadBuffer() {\n            m_tokenBuffer.resize( 0 );\n\n            // Skip any empty strings\n            while( it != itEnd && it->empty() )\n                ++it;\n\n            if( it != itEnd ) {\n                auto const &next = *it;\n                if( isOptPrefix( next[0] ) ) {\n                    auto delimiterPos = next.find_first_of( \" :=\" );\n                    if( delimiterPos != std::string::npos ) {\n                        m_tokenBuffer.push_back( { TokenType::Option, next.substr( 0, delimiterPos ) } );\n                        m_tokenBuffer.push_back( { TokenType::Argument, next.substr( delimiterPos + 1 ) } );\n                    } else {\n                        if( next[1] != '-' && next.size() > 2 ) {\n                            std::string opt = \"- \";\n                            for( size_t i = 1; i < next.size(); ++i ) {\n                                opt[1] = next[i];\n                                m_tokenBuffer.push_back( { TokenType::Option, opt } );\n                            }\n                        } else {\n                            m_tokenBuffer.push_back( { TokenType::Option, next } );\n                        }\n                    }\n                } else {\n                    m_tokenBuffer.push_back( { TokenType::Argument, next } );\n                }\n            }\n        }\n\n    public:\n        explicit TokenStream( Args const &args ) : TokenStream( args.m_args.begin(), args.m_args.end() ) {}\n\n        TokenStream( Iterator it, Iterator itEnd ) : it( it ), itEnd( itEnd ) {\n            loadBuffer();\n        }\n\n        explicit operator bool() const {\n            return !m_tokenBuffer.empty() || it != itEnd;\n        }\n\n        auto count() const -> size_t { return m_tokenBuffer.size() + (itEnd - it); }\n\n        auto operator*() const -> Token {\n            assert( !m_tokenBuffer.empty() );\n            return m_tokenBuffer.front();\n        }\n\n        auto operator->() const -> Token const * {\n            assert( !m_tokenBuffer.empty() );\n            return &m_tokenBuffer.front();\n        }\n\n        auto operator++() -> TokenStream & {\n            if( m_tokenBuffer.size() >= 2 ) {\n                m_tokenBuffer.erase( m_tokenBuffer.begin() );\n            } else {\n                if( it != itEnd )\n                    ++it;\n                loadBuffer();\n            }\n            return *this;\n        }\n    };\n\n    class ResultBase {\n    public:\n        enum Type {\n            Ok, LogicError, RuntimeError\n        };\n\n    protected:\n        ResultBase( Type type ) : m_type( type ) {}\n        virtual ~ResultBase() = default;\n\n        virtual void enforceOk() const = 0;\n\n        Type m_type;\n    };\n\n    template<typename T>\n    class ResultValueBase : public ResultBase {\n    public:\n        auto value() const -> T const & {\n            enforceOk();\n            return m_value;\n        }\n\n    protected:\n        ResultValueBase( Type type ) : ResultBase( type ) {}\n\n        ResultValueBase( ResultValueBase const &other ) : ResultBase( other ) {\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n        }\n\n        ResultValueBase( Type, T const &value ) : ResultBase( Ok ) {\n            new( &m_value ) T( value );\n        }\n\n        auto operator=( ResultValueBase const &other ) -> ResultValueBase & {\n            if( m_type == ResultBase::Ok )\n                m_value.~T();\n            ResultBase::operator=(other);\n            if( m_type == ResultBase::Ok )\n                new( &m_value ) T( other.m_value );\n            return *this;\n        }\n\n        ~ResultValueBase() override {\n            if( m_type == Ok )\n                m_value.~T();\n        }\n\n        union {\n            T m_value;\n        };\n    };\n\n    template<>\n    class ResultValueBase<void> : public ResultBase {\n    protected:\n        using ResultBase::ResultBase;\n    };\n\n    template<typename T = void>\n    class BasicResult : public ResultValueBase<T> {\n    public:\n        template<typename U>\n        explicit BasicResult( BasicResult<U> const &other )\n        :   ResultValueBase<T>( other.type() ),\n            m_errorMessage( other.errorMessage() )\n        {\n            assert( type() != ResultBase::Ok );\n        }\n\n        template<typename U>\n        static auto ok( U const &value ) -> BasicResult { return { ResultBase::Ok, value }; }\n        static auto ok() -> BasicResult { return { ResultBase::Ok }; }\n        static auto logicError( std::string const &message ) -> BasicResult { return { ResultBase::LogicError, message }; }\n        static auto runtimeError( std::string const &message ) -> BasicResult { return { ResultBase::RuntimeError, message }; }\n\n        explicit operator bool() const { return m_type == ResultBase::Ok; }\n        auto type() const -> ResultBase::Type { return m_type; }\n        auto errorMessage() const -> std::string { return m_errorMessage; }\n\n    protected:\n        void enforceOk() const override {\n\n            // Errors shouldn't reach this point, but if they do\n            // the actual error message will be in m_errorMessage\n            assert( m_type != ResultBase::LogicError );\n            assert( m_type != ResultBase::RuntimeError );\n            if( m_type != ResultBase::Ok )\n                std::abort();\n        }\n\n        std::string m_errorMessage; // Only populated if resultType is an error\n\n        BasicResult( ResultBase::Type type, std::string const &message )\n        :   ResultValueBase<T>(type),\n            m_errorMessage(message)\n        {\n            assert( m_type != ResultBase::Ok );\n        }\n\n        using ResultValueBase<T>::ResultValueBase;\n        using ResultBase::m_type;\n    };\n\n    enum class ParseResultType {\n        Matched, NoMatch, ShortCircuitAll, ShortCircuitSame\n    };\n\n    class ParseState {\n    public:\n\n        ParseState( ParseResultType type, TokenStream const &remainingTokens )\n        : m_type(type),\n          m_remainingTokens( remainingTokens )\n        {}\n\n        auto type() const -> ParseResultType { return m_type; }\n        auto remainingTokens() const -> TokenStream { return m_remainingTokens; }\n\n    private:\n        ParseResultType m_type;\n        TokenStream m_remainingTokens;\n    };\n\n    using Result = BasicResult<void>;\n    using ParserResult = BasicResult<ParseResultType>;\n    using InternalParseResult = BasicResult<ParseState>;\n\n    struct HelpColumns {\n        std::string left;\n        std::string right;\n    };\n\n    template<typename T>\n    inline auto convertInto( std::string const &source, T& target ) -> ParserResult {\n        std::stringstream ss;\n        ss << source;\n        ss >> target;\n        if( ss.fail() )\n            return ParserResult::runtimeError( \"Unable to convert '\" + source + \"' to destination type\" );\n        else\n            return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, std::string& target ) -> ParserResult {\n        target = source;\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n    inline auto convertInto( std::string const &source, bool &target ) -> ParserResult {\n        std::string srcLC = source;\n        std::transform( srcLC.begin(), srcLC.end(), srcLC.begin(), []( unsigned char c ) { return static_cast<char>( std::tolower(c) ); } );\n        if (srcLC == \"y\" || srcLC == \"1\" || srcLC == \"true\" || srcLC == \"yes\" || srcLC == \"on\")\n            target = true;\n        else if (srcLC == \"n\" || srcLC == \"0\" || srcLC == \"false\" || srcLC == \"no\" || srcLC == \"off\")\n            target = false;\n        else\n            return ParserResult::runtimeError( \"Expected a boolean value but did not recognise: '\" + source + \"'\" );\n        return ParserResult::ok( ParseResultType::Matched );\n    }\n#ifdef CLARA_CONFIG_OPTIONAL_TYPE\n    template<typename T>\n    inline auto convertInto( std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE<T>& target ) -> ParserResult {\n        T temp;\n        auto result = convertInto( source, temp );\n        if( result )\n            target = std::move(temp);\n        return result;\n    }\n#endif // CLARA_CONFIG_OPTIONAL_TYPE\n\n    struct NonCopyable {\n        NonCopyable() = default;\n        NonCopyable( NonCopyable const & ) = delete;\n        NonCopyable( NonCopyable && ) = delete;\n        NonCopyable &operator=( NonCopyable const & ) = delete;\n        NonCopyable &operator=( NonCopyable && ) = delete;\n    };\n\n    struct BoundRef : NonCopyable {\n        virtual ~BoundRef() = default;\n        virtual auto isContainer() const -> bool { return false; }\n        virtual auto isFlag() const -> bool { return false; }\n    };\n    struct BoundValueRefBase : BoundRef {\n        virtual auto setValue( std::string const &arg ) -> ParserResult = 0;\n    };\n    struct BoundFlagRefBase : BoundRef {\n        virtual auto setFlag( bool flag ) -> ParserResult = 0;\n        virtual auto isFlag() const -> bool { return true; }\n    };\n\n    template<typename T>\n    struct BoundValueRef : BoundValueRefBase {\n        T &m_ref;\n\n        explicit BoundValueRef( T &ref ) : m_ref( ref ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return convertInto( arg, m_ref );\n        }\n    };\n\n    template<typename T>\n    struct BoundValueRef<std::vector<T>> : BoundValueRefBase {\n        std::vector<T> &m_ref;\n\n        explicit BoundValueRef( std::vector<T> &ref ) : m_ref( ref ) {}\n\n        auto isContainer() const -> bool override { return true; }\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            T temp;\n            auto result = convertInto( arg, temp );\n            if( result )\n                m_ref.push_back( temp );\n            return result;\n        }\n    };\n\n    struct BoundFlagRef : BoundFlagRefBase {\n        bool &m_ref;\n\n        explicit BoundFlagRef( bool &ref ) : m_ref( ref ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            m_ref = flag;\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ReturnType>\n    struct LambdaInvoker {\n        static_assert( std::is_same<ReturnType, ParserResult>::value, \"Lambda must return void or clara::ParserResult\" );\n\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            return lambda( arg );\n        }\n    };\n\n    template<>\n    struct LambdaInvoker<void> {\n        template<typename L, typename ArgType>\n        static auto invoke( L const &lambda, ArgType const &arg ) -> ParserResult {\n            lambda( arg );\n            return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    template<typename ArgType, typename L>\n    inline auto invokeLambda( L const &lambda, std::string const &arg ) -> ParserResult {\n        ArgType temp{};\n        auto result = convertInto( arg, temp );\n        return !result\n           ? result\n           : LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( lambda, temp );\n    }\n\n    template<typename L>\n    struct BoundLambda : BoundValueRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        explicit BoundLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setValue( std::string const &arg ) -> ParserResult override {\n            return invokeLambda<typename UnaryLambdaTraits<L>::ArgType>( m_lambda, arg );\n        }\n    };\n\n    template<typename L>\n    struct BoundFlagLambda : BoundFlagRefBase {\n        L m_lambda;\n\n        static_assert( UnaryLambdaTraits<L>::isValid, \"Supplied lambda must take exactly one argument\" );\n        static_assert( std::is_same<typename UnaryLambdaTraits<L>::ArgType, bool>::value, \"flags must be boolean\" );\n\n        explicit BoundFlagLambda( L const &lambda ) : m_lambda( lambda ) {}\n\n        auto setFlag( bool flag ) -> ParserResult override {\n            return LambdaInvoker<typename UnaryLambdaTraits<L>::ReturnType>::invoke( m_lambda, flag );\n        }\n    };\n\n    enum class Optionality { Optional, Required };\n\n    struct Parser;\n\n    class ParserBase {\n    public:\n        virtual ~ParserBase() = default;\n        virtual auto validate() const -> Result { return Result::ok(); }\n        virtual auto parse( std::string const& exeName, TokenStream const &tokens) const -> InternalParseResult  = 0;\n        virtual auto cardinality() const -> size_t { return 1; }\n\n        auto parse( Args const &args ) const -> InternalParseResult {\n            return parse( args.exeName(), TokenStream( args ) );\n        }\n    };\n\n    template<typename DerivedT>\n    class ComposableParserImpl : public ParserBase {\n    public:\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser;\n\n\t\ttemplate<typename T>\n        auto operator+( T const &other ) const -> Parser;\n    };\n\n    // Common code and state for Args and Opts\n    template<typename DerivedT>\n    class ParserRefImpl : public ComposableParserImpl<DerivedT> {\n    protected:\n        Optionality m_optionality = Optionality::Optional;\n        std::shared_ptr<BoundRef> m_ref;\n        std::string m_hint;\n        std::string m_description;\n\n        explicit ParserRefImpl( std::shared_ptr<BoundRef> const &ref ) : m_ref( ref ) {}\n\n    public:\n        template<typename T>\n        ParserRefImpl( T &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundValueRef<T>>( ref ) ),\n            m_hint( hint )\n        {}\n\n        template<typename LambdaT>\n        ParserRefImpl( LambdaT const &ref, std::string const &hint )\n        :   m_ref( std::make_shared<BoundLambda<LambdaT>>( ref ) ),\n            m_hint(hint)\n        {}\n\n        auto operator()( std::string const &description ) -> DerivedT & {\n            m_description = description;\n            return static_cast<DerivedT &>( *this );\n        }\n\n        auto optional() -> DerivedT & {\n            m_optionality = Optionality::Optional;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto required() -> DerivedT & {\n            m_optionality = Optionality::Required;\n            return static_cast<DerivedT &>( *this );\n        };\n\n        auto isOptional() const -> bool {\n            return m_optionality == Optionality::Optional;\n        }\n\n        auto cardinality() const -> size_t override {\n            if( m_ref->isContainer() )\n                return 0;\n            else\n                return 1;\n        }\n\n        auto hint() const -> std::string { return m_hint; }\n    };\n\n    class ExeName : public ComposableParserImpl<ExeName> {\n        std::shared_ptr<std::string> m_name;\n        std::shared_ptr<BoundValueRefBase> m_ref;\n\n        template<typename LambdaT>\n        static auto makeRef(LambdaT const &lambda) -> std::shared_ptr<BoundValueRefBase> {\n            return std::make_shared<BoundLambda<LambdaT>>( lambda) ;\n        }\n\n    public:\n        ExeName() : m_name( std::make_shared<std::string>( \"<executable>\" ) ) {}\n\n        explicit ExeName( std::string &ref ) : ExeName() {\n            m_ref = std::make_shared<BoundValueRef<std::string>>( ref );\n        }\n\n        template<typename LambdaT>\n        explicit ExeName( LambdaT const& lambda ) : ExeName() {\n            m_ref = std::make_shared<BoundLambda<LambdaT>>( lambda );\n        }\n\n        // The exe name is not parsed out of the normal tokens, but is handled specially\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n        }\n\n        auto name() const -> std::string { return *m_name; }\n        auto set( std::string const& newName ) -> ParserResult {\n\n            auto lastSlash = newName.find_last_of( \"\\\\/\" );\n            auto filename = ( lastSlash == std::string::npos )\n                    ? newName\n                    : newName.substr( lastSlash+1 );\n\n            *m_name = filename;\n            if( m_ref )\n                return m_ref->setValue( filename );\n            else\n                return ParserResult::ok( ParseResultType::Matched );\n        }\n    };\n\n    class Arg : public ParserRefImpl<Arg> {\n    public:\n        using ParserRefImpl::ParserRefImpl;\n\n        auto parse( std::string const &, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            auto const &token = *remainingTokens;\n            if( token.type != TokenType::Argument )\n                return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n\n            assert( !m_ref->isFlag() );\n            auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n\n            auto result = valueRef->setValue( remainingTokens->token );\n            if( !result )\n                return InternalParseResult( result );\n            else\n                return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n        }\n    };\n\n    inline auto normaliseOpt( std::string const &optName ) -> std::string {\n#ifdef CATCH_PLATFORM_WINDOWS\n        if( optName[0] == '/' )\n            return \"-\" + optName.substr( 1 );\n        else\n#endif\n            return optName;\n    }\n\n    class Opt : public ParserRefImpl<Opt> {\n    protected:\n        std::vector<std::string> m_optNames;\n\n    public:\n        template<typename LambdaT>\n        explicit Opt( LambdaT const &ref ) : ParserRefImpl( std::make_shared<BoundFlagLambda<LambdaT>>( ref ) ) {}\n\n        explicit Opt( bool &ref ) : ParserRefImpl( std::make_shared<BoundFlagRef>( ref ) ) {}\n\n        template<typename LambdaT>\n        Opt( LambdaT const &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        template<typename T>\n        Opt( T &ref, std::string const &hint ) : ParserRefImpl( ref, hint ) {}\n\n        auto operator[]( std::string const &optName ) -> Opt & {\n            m_optNames.push_back( optName );\n            return *this;\n        }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::ostringstream oss;\n            bool first = true;\n            for( auto const &opt : m_optNames ) {\n                if (first)\n                    first = false;\n                else\n                    oss << \", \";\n                oss << opt;\n            }\n            if( !m_hint.empty() )\n                oss << \" <\" << m_hint << \">\";\n            return { { oss.str(), m_description } };\n        }\n\n        auto isMatch( std::string const &optToken ) const -> bool {\n            auto normalisedToken = normaliseOpt( optToken );\n            for( auto const &name : m_optNames ) {\n                if( normaliseOpt( name ) == normalisedToken )\n                    return true;\n            }\n            return false;\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const&, TokenStream const &tokens ) const -> InternalParseResult override {\n            auto validationResult = validate();\n            if( !validationResult )\n                return InternalParseResult( validationResult );\n\n            auto remainingTokens = tokens;\n            if( remainingTokens && remainingTokens->type == TokenType::Option ) {\n                auto const &token = *remainingTokens;\n                if( isMatch(token.token ) ) {\n                    if( m_ref->isFlag() ) {\n                        auto flagRef = static_cast<detail::BoundFlagRefBase*>( m_ref.get() );\n                        auto result = flagRef->setFlag( true );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    } else {\n                        auto valueRef = static_cast<detail::BoundValueRefBase*>( m_ref.get() );\n                        ++remainingTokens;\n                        if( !remainingTokens )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto const &argToken = *remainingTokens;\n                        if( argToken.type != TokenType::Argument )\n                            return InternalParseResult::runtimeError( \"Expected argument following \" + token.token );\n                        auto result = valueRef->setValue( argToken.token );\n                        if( !result )\n                            return InternalParseResult( result );\n                        if( result.value() == ParseResultType::ShortCircuitAll )\n                            return InternalParseResult::ok( ParseState( result.value(), remainingTokens ) );\n                    }\n                    return InternalParseResult::ok( ParseState( ParseResultType::Matched, ++remainingTokens ) );\n                }\n            }\n            return InternalParseResult::ok( ParseState( ParseResultType::NoMatch, remainingTokens ) );\n        }\n\n        auto validate() const -> Result override {\n            if( m_optNames.empty() )\n                return Result::logicError( \"No options supplied to Opt\" );\n            for( auto const &name : m_optNames ) {\n                if( name.empty() )\n                    return Result::logicError( \"Option name cannot be empty\" );\n#ifdef CATCH_PLATFORM_WINDOWS\n                if( name[0] != '-' && name[0] != '/' )\n                    return Result::logicError( \"Option name must begin with '-' or '/'\" );\n#else\n                if( name[0] != '-' )\n                    return Result::logicError( \"Option name must begin with '-'\" );\n#endif\n            }\n            return ParserRefImpl::validate();\n        }\n    };\n\n    struct Help : Opt {\n        Help( bool &showHelpFlag )\n        :   Opt([&]( bool flag ) {\n                showHelpFlag = flag;\n                return ParserResult::ok( ParseResultType::ShortCircuitAll );\n            })\n        {\n            static_cast<Opt &>( *this )\n                    (\"display usage information\")\n                    [\"-?\"][\"-h\"][\"--help\"]\n                    .optional();\n        }\n    };\n\n    struct Parser : ParserBase {\n\n        mutable ExeName m_exeName;\n        std::vector<Opt> m_options;\n        std::vector<Arg> m_args;\n\n        auto operator|=( ExeName const &exeName ) -> Parser & {\n            m_exeName = exeName;\n            return *this;\n        }\n\n        auto operator|=( Arg const &arg ) -> Parser & {\n            m_args.push_back(arg);\n            return *this;\n        }\n\n        auto operator|=( Opt const &opt ) -> Parser & {\n            m_options.push_back(opt);\n            return *this;\n        }\n\n        auto operator|=( Parser const &other ) -> Parser & {\n            m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end());\n            m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end());\n            return *this;\n        }\n\n        template<typename T>\n        auto operator|( T const &other ) const -> Parser {\n            return Parser( *this ) |= other;\n        }\n\n        // Forward deprecated interface with '+' instead of '|'\n        template<typename T>\n        auto operator+=( T const &other ) -> Parser & { return operator|=( other ); }\n        template<typename T>\n        auto operator+( T const &other ) const -> Parser { return operator|( other ); }\n\n        auto getHelpColumns() const -> std::vector<HelpColumns> {\n            std::vector<HelpColumns> cols;\n            for (auto const &o : m_options) {\n                auto childCols = o.getHelpColumns();\n                cols.insert( cols.end(), childCols.begin(), childCols.end() );\n            }\n            return cols;\n        }\n\n        void writeToStream( std::ostream &os ) const {\n            if (!m_exeName.name().empty()) {\n                os << \"usage:\\n\" << \"  \" << m_exeName.name() << \" \";\n                bool required = true, first = true;\n                for( auto const &arg : m_args ) {\n                    if (first)\n                        first = false;\n                    else\n                        os << \" \";\n                    if( arg.isOptional() && required ) {\n                        os << \"[\";\n                        required = false;\n                    }\n                    os << \"<\" << arg.hint() << \">\";\n                    if( arg.cardinality() == 0 )\n                        os << \" ... \";\n                }\n                if( !required )\n                    os << \"]\";\n                if( !m_options.empty() )\n                    os << \" options\";\n                os << \"\\n\\nwhere options are:\" << std::endl;\n            }\n\n            auto rows = getHelpColumns();\n            size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH;\n            size_t optWidth = 0;\n            for( auto const &cols : rows )\n                optWidth = (std::max)(optWidth, cols.left.size() + 2);\n\n            optWidth = (std::min)(optWidth, consoleWidth/2);\n\n            for( auto const &cols : rows ) {\n                auto row =\n                        TextFlow::Column( cols.left ).width( optWidth ).indent( 2 ) +\n                        TextFlow::Spacer(4) +\n                        TextFlow::Column( cols.right ).width( consoleWidth - 7 - optWidth );\n                os << row << std::endl;\n            }\n        }\n\n        friend auto operator<<( std::ostream &os, Parser const &parser ) -> std::ostream& {\n            parser.writeToStream( os );\n            return os;\n        }\n\n        auto validate() const -> Result override {\n            for( auto const &opt : m_options ) {\n                auto result = opt.validate();\n                if( !result )\n                    return result;\n            }\n            for( auto const &arg : m_args ) {\n                auto result = arg.validate();\n                if( !result )\n                    return result;\n            }\n            return Result::ok();\n        }\n\n        using ParserBase::parse;\n\n        auto parse( std::string const& exeName, TokenStream const &tokens ) const -> InternalParseResult override {\n\n            struct ParserInfo {\n                ParserBase const* parser = nullptr;\n                size_t count = 0;\n            };\n            const size_t totalParsers = m_options.size() + m_args.size();\n            assert( totalParsers < 512 );\n            // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do\n            ParserInfo parseInfos[512];\n\n            {\n                size_t i = 0;\n                for (auto const &opt : m_options) parseInfos[i++].parser = &opt;\n                for (auto const &arg : m_args) parseInfos[i++].parser = &arg;\n            }\n\n            m_exeName.set( exeName );\n\n            auto result = InternalParseResult::ok( ParseState( ParseResultType::NoMatch, tokens ) );\n            while( result.value().remainingTokens() ) {\n                bool tokenParsed = false;\n\n                for( size_t i = 0; i < totalParsers; ++i ) {\n                    auto&  parseInfo = parseInfos[i];\n                    if( parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality() ) {\n                        result = parseInfo.parser->parse(exeName, result.value().remainingTokens());\n                        if (!result)\n                            return result;\n                        if (result.value().type() != ParseResultType::NoMatch) {\n                            tokenParsed = true;\n                            ++parseInfo.count;\n                            break;\n                        }\n                    }\n                }\n\n                if( result.value().type() == ParseResultType::ShortCircuitAll )\n                    return result;\n                if( !tokenParsed )\n                    return InternalParseResult::runtimeError( \"Unrecognised token: \" + result.value().remainingTokens()->token );\n            }\n            // !TBD Check missing required options\n            return result;\n        }\n    };\n\n    template<typename DerivedT>\n    template<typename T>\n    auto ComposableParserImpl<DerivedT>::operator|( T const &other ) const -> Parser {\n        return Parser() | static_cast<DerivedT const &>( *this ) | other;\n    }\n} // namespace detail\n\n// A Combined parser\nusing detail::Parser;\n\n// A parser for options\nusing detail::Opt;\n\n// A parser for arguments\nusing detail::Arg;\n\n// Wrapper for argc, argv from main()\nusing detail::Args;\n\n// Specifies the name of the executable\nusing detail::ExeName;\n\n// Convenience wrapper for option parser that specifies the help option\nusing detail::Help;\n\n// enum of result types from a parse\nusing detail::ParseResultType;\n\n// Result type for parser operation\nusing detail::ParserResult;\n\n}} // namespace Catch::clara\n\n// end clara.hpp\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// Restore Clara's value for console width, if present\n#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH\n#endif\n\n// end catch_clara.h\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config );\n\n} // end namespace Catch\n\n// end catch_commandline.h\n#include <fstream>\n#include <ctime>\n\nnamespace Catch {\n\n    clara::Parser makeCommandLineParser( ConfigData& config ) {\n\n        using namespace clara;\n\n        auto const setWarning = [&]( std::string const& warning ) {\n                auto warningSet = [&]() {\n                    if( warning == \"NoAssertions\" )\n                        return WarnAbout::NoAssertions;\n\n                    if ( warning == \"NoTests\" )\n                        return WarnAbout::NoTests;\n\n                    return WarnAbout::Nothing;\n                }();\n\n                if (warningSet == WarnAbout::Nothing)\n                    return ParserResult::runtimeError( \"Unrecognised warning: '\" + warning + \"'\" );\n                config.warnings = static_cast<WarnAbout::What>( config.warnings | warningSet );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const loadTestNamesFromFile = [&]( std::string const& filename ) {\n                std::ifstream f( filename.c_str() );\n                if( !f.is_open() )\n                    return ParserResult::runtimeError( \"Unable to load input file: '\" + filename + \"'\" );\n\n                std::string line;\n                while( std::getline( f, line ) ) {\n                    line = trim(line);\n                    if( !line.empty() && !startsWith( line, '#' ) ) {\n                        if( !startsWith( line, '\"' ) )\n                            line = '\"' + line + '\"';\n                        config.testsOrTags.push_back( line );\n                        config.testsOrTags.emplace_back( \",\" );\n                    }\n                }\n                //Remove comma in the end\n                if(!config.testsOrTags.empty())\n                    config.testsOrTags.erase( config.testsOrTags.end()-1 );\n\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setTestOrder = [&]( std::string const& order ) {\n                if( startsWith( \"declared\", order ) )\n                    config.runOrder = RunTests::InDeclarationOrder;\n                else if( startsWith( \"lexical\", order ) )\n                    config.runOrder = RunTests::InLexicographicalOrder;\n                else if( startsWith( \"random\", order ) )\n                    config.runOrder = RunTests::InRandomOrder;\n                else\n                    return clara::ParserResult::runtimeError( \"Unrecognised ordering: '\" + order + \"'\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setRngSeed = [&]( std::string const& seed ) {\n                if( seed != \"time\" )\n                    return clara::detail::convertInto( seed, config.rngSeed );\n                config.rngSeed = static_cast<unsigned int>( std::time(nullptr) );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setColourUsage = [&]( std::string const& useColour ) {\n                    auto mode = toLower( useColour );\n\n                    if( mode == \"yes\" )\n                        config.useColour = UseColour::Yes;\n                    else if( mode == \"no\" )\n                        config.useColour = UseColour::No;\n                    else if( mode == \"auto\" )\n                        config.useColour = UseColour::Auto;\n                    else\n                        return ParserResult::runtimeError( \"colour mode must be one of: auto, yes or no. '\" + useColour + \"' not recognised\" );\n                return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setWaitForKeypress = [&]( std::string const& keypress ) {\n                auto keypressLc = toLower( keypress );\n                if (keypressLc == \"never\")\n                    config.waitForKeypress = WaitForKeypress::Never;\n                else if( keypressLc == \"start\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStart;\n                else if( keypressLc == \"exit\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeExit;\n                else if( keypressLc == \"both\" )\n                    config.waitForKeypress = WaitForKeypress::BeforeStartAndExit;\n                else\n                    return ParserResult::runtimeError( \"keypress argument must be one of: never, start, exit or both. '\" + keypress + \"' not recognised\" );\n            return ParserResult::ok( ParseResultType::Matched );\n            };\n        auto const setVerbosity = [&]( std::string const& verbosity ) {\n            auto lcVerbosity = toLower( verbosity );\n            if( lcVerbosity == \"quiet\" )\n                config.verbosity = Verbosity::Quiet;\n            else if( lcVerbosity == \"normal\" )\n                config.verbosity = Verbosity::Normal;\n            else if( lcVerbosity == \"high\" )\n                config.verbosity = Verbosity::High;\n            else\n                return ParserResult::runtimeError( \"Unrecognised verbosity, '\" + verbosity + \"'\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n        auto const setReporter = [&]( std::string const& reporter ) {\n            IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n\n            auto lcReporter = toLower( reporter );\n            auto result = factories.find( lcReporter );\n\n            if( factories.end() != result )\n                config.reporterName = lcReporter;\n            else\n                return ParserResult::runtimeError( \"Unrecognized reporter, '\" + reporter + \"'. Check available with --list-reporters\" );\n            return ParserResult::ok( ParseResultType::Matched );\n        };\n\n        auto cli\n            = ExeName( config.processName )\n            | Help( config.showHelp )\n            | Opt( config.listTests )\n                [\"-l\"][\"--list-tests\"]\n                ( \"list all/matching test cases\" )\n            | Opt( config.listTags )\n                [\"-t\"][\"--list-tags\"]\n                ( \"list all/matching tags\" )\n            | Opt( config.showSuccessfulTests )\n                [\"-s\"][\"--success\"]\n                ( \"include successful tests in output\" )\n            | Opt( config.shouldDebugBreak )\n                [\"-b\"][\"--break\"]\n                ( \"break into debugger on failure\" )\n            | Opt( config.noThrow )\n                [\"-e\"][\"--nothrow\"]\n                ( \"skip exception tests\" )\n            | Opt( config.showInvisibles )\n                [\"-i\"][\"--invisibles\"]\n                ( \"show invisibles (tabs, newlines)\" )\n            | Opt( config.outputFilename, \"filename\" )\n                [\"-o\"][\"--out\"]\n                ( \"output filename\" )\n            | Opt( setReporter, \"name\" )\n                [\"-r\"][\"--reporter\"]\n                ( \"reporter to use (defaults to console)\" )\n            | Opt( config.name, \"name\" )\n                [\"-n\"][\"--name\"]\n                ( \"suite name\" )\n            | Opt( [&]( bool ){ config.abortAfter = 1; } )\n                [\"-a\"][\"--abort\"]\n                ( \"abort at first failure\" )\n            | Opt( [&]( int x ){ config.abortAfter = x; }, \"no. failures\" )\n                [\"-x\"][\"--abortx\"]\n                ( \"abort after x failures\" )\n            | Opt( setWarning, \"warning name\" )\n                [\"-w\"][\"--warn\"]\n                ( \"enable warnings\" )\n            | Opt( [&]( bool flag ) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, \"yes|no\" )\n                [\"-d\"][\"--durations\"]\n                ( \"show test durations\" )\n            | Opt( config.minDuration, \"seconds\" )\n                [\"-D\"][\"--min-duration\"]\n                ( \"show test durations for tests taking at least the given number of seconds\" )\n            | Opt( loadTestNamesFromFile, \"filename\" )\n                [\"-f\"][\"--input-file\"]\n                ( \"load test names to run from a file\" )\n            | Opt( config.filenamesAsTags )\n                [\"-#\"][\"--filenames-as-tags\"]\n                ( \"adds a tag for the filename\" )\n            | Opt( config.sectionsToRun, \"section name\" )\n                [\"-c\"][\"--section\"]\n                ( \"specify section to run\" )\n            | Opt( setVerbosity, \"quiet|normal|high\" )\n                [\"-v\"][\"--verbosity\"]\n                ( \"set output verbosity\" )\n            | Opt( config.listTestNamesOnly )\n                [\"--list-test-names-only\"]\n                ( \"list all/matching test cases names only\" )\n            | Opt( config.listReporters )\n                [\"--list-reporters\"]\n                ( \"list all reporters\" )\n            | Opt( setTestOrder, \"decl|lex|rand\" )\n                [\"--order\"]\n                ( \"test case order (defaults to decl)\" )\n            | Opt( setRngSeed, \"'time'|number\" )\n                [\"--rng-seed\"]\n                ( \"set a specific seed for random numbers\" )\n            | Opt( setColourUsage, \"yes|no\" )\n                [\"--use-colour\"]\n                ( \"should output be colourised\" )\n            | Opt( config.libIdentify )\n                [\"--libidentify\"]\n                ( \"report name and version according to libidentify standard\" )\n            | Opt( setWaitForKeypress, \"never|start|exit|both\" )\n                [\"--wait-for-keypress\"]\n                ( \"waits for a keypress before exiting\" )\n            | Opt( config.benchmarkSamples, \"samples\" )\n                [\"--benchmark-samples\"]\n                ( \"number of samples to collect (default: 100)\" )\n            | Opt( config.benchmarkResamples, \"resamples\" )\n                [\"--benchmark-resamples\"]\n                ( \"number of resamples for the bootstrap (default: 100000)\" )\n            | Opt( config.benchmarkConfidenceInterval, \"confidence interval\" )\n                [\"--benchmark-confidence-interval\"]\n                ( \"confidence interval for the bootstrap (between 0 and 1, default: 0.95)\" )\n            | Opt( config.benchmarkNoAnalysis )\n                [\"--benchmark-no-analysis\"]\n                ( \"perform only measurements; do not perform any analysis\" )\n            | Opt( config.benchmarkWarmupTime, \"benchmarkWarmupTime\" )\n                [\"--benchmark-warmup-time\"]\n                ( \"amount of time in milliseconds spent on warming up each test (default: 100)\" )\n            | Arg( config.testsOrTags, \"test name|pattern|tags\" )\n                ( \"which test or tests to use\" );\n\n        return cli;\n    }\n\n} // end namespace Catch\n// end catch_commandline.cpp\n// start catch_common.cpp\n\n#include <cstring>\n#include <ostream>\n\nnamespace Catch {\n\n    bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const noexcept {\n        return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0);\n    }\n    bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const noexcept {\n        // We can assume that the same file will usually have the same pointer.\n        // Thus, if the pointers are the same, there is no point in calling the strcmp\n        return line < other.line || ( line == other.line && file != other.file && (std::strcmp(file, other.file) < 0));\n    }\n\n    std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) {\n#ifndef __GNUG__\n        os << info.file << '(' << info.line << ')';\n#else\n        os << info.file << ':' << info.line;\n#endif\n        return os;\n    }\n\n    std::string StreamEndStop::operator+() const {\n        return std::string();\n    }\n\n    NonCopyable::NonCopyable() = default;\n    NonCopyable::~NonCopyable() = default;\n\n}\n// end catch_common.cpp\n// start catch_config.cpp\n\nnamespace Catch {\n\n    Config::Config( ConfigData const& data )\n    :   m_data( data ),\n        m_stream( openStream() )\n    {\n        // We need to trim filter specs to avoid trouble with superfluous\n        // whitespace (esp. important for bdd macros, as those are manually\n        // aligned with whitespace).\n\n        for (auto& elem : m_data.testsOrTags) {\n            elem = trim(elem);\n        }\n        for (auto& elem : m_data.sectionsToRun) {\n            elem = trim(elem);\n        }\n\n        TestSpecParser parser(ITagAliasRegistry::get());\n        if (!m_data.testsOrTags.empty()) {\n            m_hasTestFilters = true;\n            for (auto const& testOrTags : m_data.testsOrTags) {\n                parser.parse(testOrTags);\n            }\n        }\n        m_testSpec = parser.testSpec();\n    }\n\n    std::string const& Config::getFilename() const {\n        return m_data.outputFilename ;\n    }\n\n    bool Config::listTests() const          { return m_data.listTests; }\n    bool Config::listTestNamesOnly() const  { return m_data.listTestNamesOnly; }\n    bool Config::listTags() const           { return m_data.listTags; }\n    bool Config::listReporters() const      { return m_data.listReporters; }\n\n    std::string Config::getProcessName() const { return m_data.processName; }\n    std::string const& Config::getReporterName() const { return m_data.reporterName; }\n\n    std::vector<std::string> const& Config::getTestsOrTags() const { return m_data.testsOrTags; }\n    std::vector<std::string> const& Config::getSectionsToRun() const { return m_data.sectionsToRun; }\n\n    TestSpec const& Config::testSpec() const { return m_testSpec; }\n    bool Config::hasTestFilters() const { return m_hasTestFilters; }\n\n    bool Config::showHelp() const { return m_data.showHelp; }\n\n    // IConfig interface\n    bool Config::allowThrows() const                   { return !m_data.noThrow; }\n    std::ostream& Config::stream() const               { return m_stream->stream(); }\n    std::string Config::name() const                   { return m_data.name.empty() ? m_data.processName : m_data.name; }\n    bool Config::includeSuccessfulResults() const      { return m_data.showSuccessfulTests; }\n    bool Config::warnAboutMissingAssertions() const    { return !!(m_data.warnings & WarnAbout::NoAssertions); }\n    bool Config::warnAboutNoTests() const              { return !!(m_data.warnings & WarnAbout::NoTests); }\n    ShowDurations::OrNot Config::showDurations() const { return m_data.showDurations; }\n    double Config::minDuration() const                 { return m_data.minDuration; }\n    RunTests::InWhatOrder Config::runOrder() const     { return m_data.runOrder; }\n    unsigned int Config::rngSeed() const               { return m_data.rngSeed; }\n    UseColour::YesOrNo Config::useColour() const       { return m_data.useColour; }\n    bool Config::shouldDebugBreak() const              { return m_data.shouldDebugBreak; }\n    int Config::abortAfter() const                     { return m_data.abortAfter; }\n    bool Config::showInvisibles() const                { return m_data.showInvisibles; }\n    Verbosity Config::verbosity() const                { return m_data.verbosity; }\n\n    bool Config::benchmarkNoAnalysis() const                      { return m_data.benchmarkNoAnalysis; }\n    int Config::benchmarkSamples() const                          { return m_data.benchmarkSamples; }\n    double Config::benchmarkConfidenceInterval() const            { return m_data.benchmarkConfidenceInterval; }\n    unsigned int Config::benchmarkResamples() const               { return m_data.benchmarkResamples; }\n    std::chrono::milliseconds Config::benchmarkWarmupTime() const { return std::chrono::milliseconds(m_data.benchmarkWarmupTime); }\n\n    IStream const* Config::openStream() {\n        return Catch::makeStream(m_data.outputFilename);\n    }\n\n} // end namespace Catch\n// end catch_config.cpp\n// start catch_console_colour.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\n// start catch_errno_guard.h\n\nnamespace Catch {\n\n    class ErrnoGuard {\n    public:\n        ErrnoGuard();\n        ~ErrnoGuard();\n    private:\n        int m_oldErrno;\n    };\n\n}\n\n// end catch_errno_guard.h\n// start catch_windows_h_proxy.h\n\n\n#if defined(CATCH_PLATFORM_WINDOWS)\n\n#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX)\n#  define CATCH_DEFINED_NOMINMAX\n#  define NOMINMAX\n#endif\n#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN)\n#  define CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  define WIN32_LEAN_AND_MEAN\n#endif\n\n#ifdef __AFXDLL\n#include <AfxWin.h>\n#else\n#include <windows.h>\n#endif\n\n#ifdef CATCH_DEFINED_NOMINMAX\n#  undef NOMINMAX\n#endif\n#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN\n#  undef WIN32_LEAN_AND_MEAN\n#endif\n\n#endif // defined(CATCH_PLATFORM_WINDOWS)\n\n// end catch_windows_h_proxy.h\n#include <sstream>\n\nnamespace Catch {\n    namespace {\n\n        struct IColourImpl {\n            virtual ~IColourImpl() = default;\n            virtual void use( Colour::Code _colourCode ) = 0;\n        };\n\n        struct NoColourImpl : IColourImpl {\n            void use( Colour::Code ) override {}\n\n            static IColourImpl* instance() {\n                static NoColourImpl s_instance;\n                return &s_instance;\n            }\n        };\n\n    } // anon namespace\n} // namespace Catch\n\n#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI )\n#   ifdef CATCH_PLATFORM_WINDOWS\n#       define CATCH_CONFIG_COLOUR_WINDOWS\n#   else\n#       define CATCH_CONFIG_COLOUR_ANSI\n#   endif\n#endif\n\n#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) /////////////////////////////////////////\n\nnamespace Catch {\nnamespace {\n\n    class Win32ColourImpl : public IColourImpl {\n    public:\n        Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) )\n        {\n            CONSOLE_SCREEN_BUFFER_INFO csbiInfo;\n            GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo );\n            originalForegroundAttributes = csbiInfo.wAttributes & ~( BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY );\n            originalBackgroundAttributes = csbiInfo.wAttributes & ~( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY );\n        }\n\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:      return setTextAttribute( originalForegroundAttributes );\n                case Colour::White:     return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::Red:       return setTextAttribute( FOREGROUND_RED );\n                case Colour::Green:     return setTextAttribute( FOREGROUND_GREEN );\n                case Colour::Blue:      return setTextAttribute( FOREGROUND_BLUE );\n                case Colour::Cyan:      return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN );\n                case Colour::Yellow:    return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN );\n                case Colour::Grey:      return setTextAttribute( 0 );\n\n                case Colour::LightGrey:     return setTextAttribute( FOREGROUND_INTENSITY );\n                case Colour::BrightRed:     return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED );\n                case Colour::BrightGreen:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN );\n                case Colour::BrightWhite:   return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE );\n                case Colour::BrightYellow:  return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n\n                default:\n                    CATCH_ERROR( \"Unknown colour requested\" );\n            }\n        }\n\n    private:\n        void setTextAttribute( WORD _textAttribute ) {\n            SetConsoleTextAttribute( stdoutHandle, _textAttribute | originalBackgroundAttributes );\n        }\n        HANDLE stdoutHandle;\n        WORD originalForegroundAttributes;\n        WORD originalBackgroundAttributes;\n    };\n\n    IColourImpl* platformColourInstance() {\n        static Win32ColourImpl s_instance;\n\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = UseColour::Yes;\n        return colourMode == UseColour::Yes\n            ? &s_instance\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#elif defined( CATCH_CONFIG_COLOUR_ANSI ) //////////////////////////////////////\n\n#include <unistd.h>\n\nnamespace Catch {\nnamespace {\n\n    // use POSIX/ ANSI console terminal codes\n    // Thanks to Adam Strzelecki for original contribution\n    // (http://github.com/nanoant)\n    // https://github.com/philsquared/Catch/pull/131\n    class PosixColourImpl : public IColourImpl {\n    public:\n        void use( Colour::Code _colourCode ) override {\n            switch( _colourCode ) {\n                case Colour::None:\n                case Colour::White:     return setColour( \"[0m\" );\n                case Colour::Red:       return setColour( \"[0;31m\" );\n                case Colour::Green:     return setColour( \"[0;32m\" );\n                case Colour::Blue:      return setColour( \"[0;34m\" );\n                case Colour::Cyan:      return setColour( \"[0;36m\" );\n                case Colour::Yellow:    return setColour( \"[0;33m\" );\n                case Colour::Grey:      return setColour( \"[1;30m\" );\n\n                case Colour::LightGrey:     return setColour( \"[0;37m\" );\n                case Colour::BrightRed:     return setColour( \"[1;31m\" );\n                case Colour::BrightGreen:   return setColour( \"[1;32m\" );\n                case Colour::BrightWhite:   return setColour( \"[1;37m\" );\n                case Colour::BrightYellow:  return setColour( \"[1;33m\" );\n\n                case Colour::Bright: CATCH_INTERNAL_ERROR( \"not a colour\" );\n                default: CATCH_INTERNAL_ERROR( \"Unknown colour requested\" );\n            }\n        }\n        static IColourImpl* instance() {\n            static PosixColourImpl s_instance;\n            return &s_instance;\n        }\n\n    private:\n        void setColour( const char* _escapeCode ) {\n            getCurrentContext().getConfig()->stream()\n                << '\\033' << _escapeCode;\n        }\n    };\n\n    bool useColourOnPlatform() {\n        return\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n            !isDebuggerActive() &&\n#endif\n#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__))\n            isatty(STDOUT_FILENO)\n#else\n            false\n#endif\n            ;\n    }\n    IColourImpl* platformColourInstance() {\n        ErrnoGuard guard;\n        IConfigPtr config = getCurrentContext().getConfig();\n        UseColour::YesOrNo colourMode = config\n            ? config->useColour()\n            : UseColour::Auto;\n        if( colourMode == UseColour::Auto )\n            colourMode = useColourOnPlatform()\n                ? UseColour::Yes\n                : UseColour::No;\n        return colourMode == UseColour::Yes\n            ? PosixColourImpl::instance()\n            : NoColourImpl::instance();\n    }\n\n} // end anon namespace\n} // end namespace Catch\n\n#else  // not Windows or ANSI ///////////////////////////////////////////////\n\nnamespace Catch {\n\n    static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); }\n\n} // end namespace Catch\n\n#endif // Windows/ ANSI/ None\n\nnamespace Catch {\n\n    Colour::Colour( Code _colourCode ) { use( _colourCode ); }\n    Colour::Colour( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved = true;\n    }\n    Colour& Colour::operator=( Colour&& other ) noexcept {\n        m_moved = other.m_moved;\n        other.m_moved  = true;\n        return *this;\n    }\n\n    Colour::~Colour(){ if( !m_moved ) use( None ); }\n\n    void Colour::use( Code _colourCode ) {\n        static IColourImpl* impl = platformColourInstance();\n        // Strictly speaking, this cannot possibly happen.\n        // However, under some conditions it does happen (see #1626),\n        // and this change is small enough that we can let practicality\n        // triumph over purity in this case.\n        if (impl != nullptr) {\n            impl->use( _colourCode );\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, Colour const& ) {\n        return os;\n    }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_console_colour.cpp\n// start catch_context.cpp\n\nnamespace Catch {\n\n    class Context : public IMutableContext, NonCopyable {\n\n    public: // IContext\n        IResultCapture* getResultCapture() override {\n            return m_resultCapture;\n        }\n        IRunner* getRunner() override {\n            return m_runner;\n        }\n\n        IConfigPtr const& getConfig() const override {\n            return m_config;\n        }\n\n        ~Context() override;\n\n    public: // IMutableContext\n        void setResultCapture( IResultCapture* resultCapture ) override {\n            m_resultCapture = resultCapture;\n        }\n        void setRunner( IRunner* runner ) override {\n            m_runner = runner;\n        }\n        void setConfig( IConfigPtr const& config ) override {\n            m_config = config;\n        }\n\n        friend IMutableContext& getCurrentMutableContext();\n\n    private:\n        IConfigPtr m_config;\n        IRunner* m_runner = nullptr;\n        IResultCapture* m_resultCapture = nullptr;\n    };\n\n    IMutableContext *IMutableContext::currentContext = nullptr;\n\n    void IMutableContext::createContext()\n    {\n        currentContext = new Context();\n    }\n\n    void cleanUpContext() {\n        delete IMutableContext::currentContext;\n        IMutableContext::currentContext = nullptr;\n    }\n    IContext::~IContext() = default;\n    IMutableContext::~IMutableContext() = default;\n    Context::~Context() = default;\n\n    SimplePcg32& rng() {\n        static SimplePcg32 s_rng;\n        return s_rng;\n    }\n\n}\n// end catch_context.cpp\n// start catch_debug_console.cpp\n\n// start catch_debug_console.h\n\n#include <string>\n\nnamespace Catch {\n    void writeToDebugConsole( std::string const& text );\n}\n\n// end catch_debug_console.h\n#if defined(CATCH_CONFIG_ANDROID_LOGWRITE)\n#include <android/log.h>\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            __android_log_write( ANDROID_LOG_DEBUG, \"Catch\", text.c_str() );\n        }\n    }\n\n#elif defined(CATCH_PLATFORM_WINDOWS)\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            ::OutputDebugStringA( text.c_str() );\n        }\n    }\n\n#else\n\n    namespace Catch {\n        void writeToDebugConsole( std::string const& text ) {\n            // !TBD: Need a version for Mac/ XCode and other IDEs\n            Catch::cout() << text;\n        }\n    }\n\n#endif // Platform\n// end catch_debug_console.cpp\n// start catch_debugger.cpp\n\n#if defined(CATCH_PLATFORM_MAC) || defined(CATCH_PLATFORM_IPHONE)\n\n#  include <cassert>\n#  include <sys/types.h>\n#  include <unistd.h>\n#  include <cstddef>\n#  include <ostream>\n\n#ifdef __apple_build_version__\n    // These headers will only compile with AppleClang (XCode)\n    // For other compilers (Clang, GCC, ... ) we need to exclude them\n#  include <sys/sysctl.h>\n#endif\n\n    namespace Catch {\n        #ifdef __apple_build_version__\n        // The following function is taken directly from the following technical note:\n        // https://developer.apple.com/library/archive/qa/qa1361/_index.html\n\n        // Returns true if the current process is being debugged (either\n        // running under the debugger or has a debugger attached post facto).\n        bool isDebuggerActive(){\n            int                 mib[4];\n            struct kinfo_proc   info;\n            std::size_t         size;\n\n            // Initialize the flags so that, if sysctl fails for some bizarre\n            // reason, we get a predictable result.\n\n            info.kp_proc.p_flag = 0;\n\n            // Initialize mib, which tells sysctl the info we want, in this case\n            // we're looking for information about a specific process ID.\n\n            mib[0] = CTL_KERN;\n            mib[1] = KERN_PROC;\n            mib[2] = KERN_PROC_PID;\n            mib[3] = getpid();\n\n            // Call sysctl.\n\n            size = sizeof(info);\n            if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0 ) {\n                Catch::cerr() << \"\\n** Call to sysctl failed - unable to determine if debugger is active **\\n\" << std::endl;\n                return false;\n            }\n\n            // We're being debugged if the P_TRACED flag is set.\n\n            return ( (info.kp_proc.p_flag & P_TRACED) != 0 );\n        }\n        #else\n        bool isDebuggerActive() {\n            // We need to find another way to determine this for non-appleclang compilers on macOS\n            return false;\n        }\n        #endif\n    } // namespace Catch\n\n#elif defined(CATCH_PLATFORM_LINUX)\n    #include <fstream>\n    #include <string>\n\n    namespace Catch{\n        // The standard POSIX way of detecting a debugger is to attempt to\n        // ptrace() the process, but this needs to be done from a child and not\n        // this process itself to still allow attaching to this process later\n        // if wanted, so is rather heavy. Under Linux we have the PID of the\n        // \"debugger\" (which doesn't need to be gdb, of course, it could also\n        // be strace, for example) in /proc/$PID/status, so just get it from\n        // there instead.\n        bool isDebuggerActive(){\n            // Libstdc++ has a bug, where std::ifstream sets errno to 0\n            // This way our users can properly assert over errno values\n            ErrnoGuard guard;\n            std::ifstream in(\"/proc/self/status\");\n            for( std::string line; std::getline(in, line); ) {\n                static const int PREFIX_LEN = 11;\n                if( line.compare(0, PREFIX_LEN, \"TracerPid:\\t\") == 0 ) {\n                    // We're traced if the PID is not 0 and no other PID starts\n                    // with 0 digit, so it's enough to check for just a single\n                    // character.\n                    return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0';\n                }\n            }\n\n            return false;\n        }\n    } // namespace Catch\n#elif defined(_MSC_VER)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#elif defined(__MINGW32__)\n    extern \"C\" __declspec(dllimport) int __stdcall IsDebuggerPresent();\n    namespace Catch {\n        bool isDebuggerActive() {\n            return IsDebuggerPresent() != 0;\n        }\n    }\n#else\n    namespace Catch {\n       bool isDebuggerActive() { return false; }\n    }\n#endif // Platform\n// end catch_debugger.cpp\n// start catch_decomposer.cpp\n\nnamespace Catch {\n\n    ITransientExpression::~ITransientExpression() = default;\n\n    void formatReconstructedExpression( std::ostream &os, std::string const& lhs, StringRef op, std::string const& rhs ) {\n        if( lhs.size() + rhs.size() < 40 &&\n                lhs.find('\\n') == std::string::npos &&\n                rhs.find('\\n') == std::string::npos )\n            os << lhs << \" \" << op << \" \" << rhs;\n        else\n            os << lhs << \"\\n\" << op << \"\\n\" << rhs;\n    }\n}\n// end catch_decomposer.cpp\n// start catch_enforce.cpp\n\n#include <stdexcept>\n\nnamespace Catch {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS) && !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS_CUSTOM_HANDLER)\n    [[noreturn]]\n    void throw_exception(std::exception const& e) {\n        Catch::cerr() << \"Catch will terminate because it needed to throw an exception.\\n\"\n                      << \"The message was: \" << e.what() << '\\n';\n        std::terminate();\n    }\n#endif\n\n    [[noreturn]]\n    void throw_logic_error(std::string const& msg) {\n        throw_exception(std::logic_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_domain_error(std::string const& msg) {\n        throw_exception(std::domain_error(msg));\n    }\n\n    [[noreturn]]\n    void throw_runtime_error(std::string const& msg) {\n        throw_exception(std::runtime_error(msg));\n    }\n\n} // namespace Catch;\n// end catch_enforce.cpp\n// start catch_enum_values_registry.cpp\n// start catch_enum_values_registry.h\n\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    namespace Detail {\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values );\n\n        class EnumValuesRegistry : public IMutableEnumValuesRegistry {\n\n            std::vector<std::unique_ptr<EnumInfo>> m_enumInfos;\n\n            EnumInfo const& registerEnum( StringRef enumName, StringRef allEnums, std::vector<int> const& values) override;\n        };\n\n        std::vector<StringRef> parseEnums( StringRef enums );\n\n    } // Detail\n\n} // Catch\n\n// end catch_enum_values_registry.h\n\n#include <map>\n#include <cassert>\n\nnamespace Catch {\n\n    IMutableEnumValuesRegistry::~IMutableEnumValuesRegistry() {}\n\n    namespace Detail {\n\n        namespace {\n            // Extracts the actual name part of an enum instance\n            // In other words, it returns the Blue part of Bikeshed::Colour::Blue\n            StringRef extractInstanceName(StringRef enumInstance) {\n                // Find last occurrence of \":\"\n                size_t name_start = enumInstance.size();\n                while (name_start > 0 && enumInstance[name_start - 1] != ':') {\n                    --name_start;\n                }\n                return enumInstance.substr(name_start, enumInstance.size() - name_start);\n            }\n        }\n\n        std::vector<StringRef> parseEnums( StringRef enums ) {\n            auto enumValues = splitStringRef( enums, ',' );\n            std::vector<StringRef> parsed;\n            parsed.reserve( enumValues.size() );\n            for( auto const& enumValue : enumValues ) {\n                parsed.push_back(trim(extractInstanceName(enumValue)));\n            }\n            return parsed;\n        }\n\n        EnumInfo::~EnumInfo() {}\n\n        StringRef EnumInfo::lookup( int value ) const {\n            for( auto const& valueToName : m_values ) {\n                if( valueToName.first == value )\n                    return valueToName.second;\n            }\n            return \"{** unexpected enum value **}\"_sr;\n        }\n\n        std::unique_ptr<EnumInfo> makeEnumInfo( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            std::unique_ptr<EnumInfo> enumInfo( new EnumInfo );\n            enumInfo->m_name = enumName;\n            enumInfo->m_values.reserve( values.size() );\n\n            const auto valueNames = Catch::Detail::parseEnums( allValueNames );\n            assert( valueNames.size() == values.size() );\n            std::size_t i = 0;\n            for( auto value : values )\n                enumInfo->m_values.emplace_back(value, valueNames[i++]);\n\n            return enumInfo;\n        }\n\n        EnumInfo const& EnumValuesRegistry::registerEnum( StringRef enumName, StringRef allValueNames, std::vector<int> const& values ) {\n            m_enumInfos.push_back(makeEnumInfo(enumName, allValueNames, values));\n            return *m_enumInfos.back();\n        }\n\n    } // Detail\n} // Catch\n\n// end catch_enum_values_registry.cpp\n// start catch_errno_guard.cpp\n\n#include <cerrno>\n\nnamespace Catch {\n        ErrnoGuard::ErrnoGuard():m_oldErrno(errno){}\n        ErrnoGuard::~ErrnoGuard() { errno = m_oldErrno; }\n}\n// end catch_errno_guard.cpp\n// start catch_exception_translator_registry.cpp\n\n// start catch_exception_translator_registry.h\n\n#include <vector>\n#include <string>\n#include <memory>\n\nnamespace Catch {\n\n    class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry {\n    public:\n        ~ExceptionTranslatorRegistry();\n        virtual void registerTranslator( const IExceptionTranslator* translator );\n        std::string translateActiveException() const override;\n        std::string tryTranslators() const;\n\n    private:\n        std::vector<std::unique_ptr<IExceptionTranslator const>> m_translators;\n    };\n}\n\n// end catch_exception_translator_registry.h\n#ifdef __OBJC__\n#import \"Foundation/Foundation.h\"\n#endif\n\nnamespace Catch {\n\n    ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() {\n    }\n\n    void ExceptionTranslatorRegistry::registerTranslator( const IExceptionTranslator* translator ) {\n        m_translators.push_back( std::unique_ptr<const IExceptionTranslator>( translator ) );\n    }\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        try {\n#ifdef __OBJC__\n            // In Objective-C try objective-c exceptions first\n            @try {\n                return tryTranslators();\n            }\n            @catch (NSException *exception) {\n                return Catch::Detail::stringify( [exception description] );\n            }\n#else\n            // Compiling a mixed mode project with MSVC means that CLR\n            // exceptions will be caught in (...) as well. However, these\n            // do not fill-in std::current_exception and thus lead to crash\n            // when attempting rethrow.\n            // /EHa switch also causes structured exceptions to be caught\n            // here, but they fill-in current_exception properly, so\n            // at worst the output should be a little weird, instead of\n            // causing a crash.\n            if (std::current_exception() == nullptr) {\n                return \"Non C++ exception. Possibly a CLR exception.\";\n            }\n            return tryTranslators();\n#endif\n        }\n        catch( TestFailureException& ) {\n            std::rethrow_exception(std::current_exception());\n        }\n        catch( std::exception& ex ) {\n            return ex.what();\n        }\n        catch( std::string& msg ) {\n            return msg;\n        }\n        catch( const char* msg ) {\n            return msg;\n        }\n        catch(...) {\n            return \"Unknown exception\";\n        }\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        if (m_translators.empty()) {\n            std::rethrow_exception(std::current_exception());\n        } else {\n            return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end());\n        }\n    }\n\n#else // ^^ Exceptions are enabled // Exceptions are disabled vv\n    std::string ExceptionTranslatorRegistry::translateActiveException() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to translate active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n\n    std::string ExceptionTranslatorRegistry::tryTranslators() const {\n        CATCH_INTERNAL_ERROR(\"Attempted to use exception translators under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n    }\n#endif\n\n}\n// end catch_exception_translator_registry.cpp\n// start catch_fatal_condition.cpp\n\n#include <algorithm>\n\n#if !defined( CATCH_CONFIG_WINDOWS_SEH ) && !defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace Catch {\n\n    // If neither SEH nor signal handling is required, the handler impls\n    // do not have to do anything, and can be empty.\n    void FatalConditionHandler::engage_platform() {}\n    void FatalConditionHandler::disengage_platform() {}\n    FatalConditionHandler::FatalConditionHandler() = default;\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n} // end namespace Catch\n\n#endif // !CATCH_CONFIG_WINDOWS_SEH && !CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) && defined( CATCH_CONFIG_POSIX_SIGNALS )\n#error \"Inconsistent configuration: Windows' SEH handling and POSIX signals cannot be enabled at the same time\"\n#endif // CATCH_CONFIG_WINDOWS_SEH && CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH ) || defined( CATCH_CONFIG_POSIX_SIGNALS )\n\nnamespace {\n    //! Signals fatal error message to the run context\n    void reportFatal( char const * const message ) {\n        Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition( message );\n    }\n\n    //! Minimal size Catch2 needs for its own fatal error handling.\n    //! Picked anecdotally, so it might not be sufficient on all\n    //! platforms, and for all configurations.\n    constexpr std::size_t minStackSizeForErrors = 32 * 1024;\n} // end unnamed namespace\n\n#endif // CATCH_CONFIG_WINDOWS_SEH || CATCH_CONFIG_POSIX_SIGNALS\n\n#if defined( CATCH_CONFIG_WINDOWS_SEH )\n\nnamespace Catch {\n\n    struct SignalDefs { DWORD id; const char* name; };\n\n    // There is no 1-1 mapping between signals and windows exceptions.\n    // Windows can easily distinguish between SO and SigSegV,\n    // but SigInt, SigTerm, etc are handled differently.\n    static SignalDefs signalDefs[] = {\n        { static_cast<DWORD>(EXCEPTION_ILLEGAL_INSTRUCTION),  \"SIGILL - Illegal instruction signal\" },\n        { static_cast<DWORD>(EXCEPTION_STACK_OVERFLOW), \"SIGSEGV - Stack overflow\" },\n        { static_cast<DWORD>(EXCEPTION_ACCESS_VIOLATION), \"SIGSEGV - Segmentation violation signal\" },\n        { static_cast<DWORD>(EXCEPTION_INT_DIVIDE_BY_ZERO), \"Divide by zero error\" },\n    };\n\n    static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) {\n        for (auto const& def : signalDefs) {\n            if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) {\n                reportFatal(def.name);\n            }\n        }\n        // If its not an exception we care about, pass it along.\n        // This stops us from eating debugger breaks etc.\n        return EXCEPTION_CONTINUE_SEARCH;\n    }\n\n    // Since we do not support multiple instantiations, we put these\n    // into global variables and rely on cleaning them up in outlined\n    // constructors/destructors\n    static PVOID exceptionHandlerHandle = nullptr;\n\n    // For MSVC, we reserve part of the stack memory for handling\n    // memory overflow structured exception.\n    FatalConditionHandler::FatalConditionHandler() {\n        ULONG guaranteeSize = static_cast<ULONG>(minStackSizeForErrors);\n        if (!SetThreadStackGuarantee(&guaranteeSize)) {\n            // We do not want to fully error out, because needing\n            // the stack reserve should be rare enough anyway.\n            Catch::cerr()\n                << \"Failed to reserve piece of stack.\"\n                << \" Stack overflows will not be reported successfully.\";\n        }\n    }\n\n    // We do not attempt to unset the stack guarantee, because\n    // Windows does not support lowering the stack size guarantee.\n    FatalConditionHandler::~FatalConditionHandler() = default;\n\n    void FatalConditionHandler::engage_platform() {\n        // Register as first handler in current chain\n        exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException);\n        if (!exceptionHandlerHandle) {\n            CATCH_RUNTIME_ERROR(\"Could not register vectored exception handler\");\n        }\n    }\n\n    void FatalConditionHandler::disengage_platform() {\n        if (!RemoveVectoredExceptionHandler(exceptionHandlerHandle)) {\n            CATCH_RUNTIME_ERROR(\"Could not unregister vectored exception handler\");\n        }\n        exceptionHandlerHandle = nullptr;\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_WINDOWS_SEH\n\n#if defined( CATCH_CONFIG_POSIX_SIGNALS )\n\n#include <signal.h>\n\nnamespace Catch {\n\n    struct SignalDefs {\n        int id;\n        const char* name;\n    };\n\n    static SignalDefs signalDefs[] = {\n        { SIGINT,  \"SIGINT - Terminal interrupt signal\" },\n        { SIGILL,  \"SIGILL - Illegal instruction signal\" },\n        { SIGFPE,  \"SIGFPE - Floating point error signal\" },\n        { SIGSEGV, \"SIGSEGV - Segmentation violation signal\" },\n        { SIGTERM, \"SIGTERM - Termination request signal\" },\n        { SIGABRT, \"SIGABRT - Abort (abnormal termination) signal\" }\n    };\n\n// Older GCCs trigger -Wmissing-field-initializers for T foo = {}\n// which is zero initialization, but not explicit. We want to avoid\n// that.\n#if defined(__GNUC__)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wmissing-field-initializers\"\n#endif\n\n    static char* altStackMem = nullptr;\n    static std::size_t altStackSize = 0;\n    static stack_t oldSigStack{};\n    static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]{};\n\n    static void restorePreviousSignalHandlers() {\n        // We set signal handlers back to the previous ones. Hopefully\n        // nobody overwrote them in the meantime, and doesn't expect\n        // their signal handlers to live past ours given that they\n        // installed them after ours..\n        for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &oldSigActions[i], nullptr);\n        }\n        // Return the old stack\n        sigaltstack(&oldSigStack, nullptr);\n    }\n\n    static void handleSignal( int sig ) {\n        char const * name = \"<unknown signal>\";\n        for (auto const& def : signalDefs) {\n            if (sig == def.id) {\n                name = def.name;\n                break;\n            }\n        }\n        // We need to restore previous signal handlers and let them do\n        // their thing, so that the users can have the debugger break\n        // when a signal is raised, and so on.\n        restorePreviousSignalHandlers();\n        reportFatal( name );\n        raise( sig );\n    }\n\n    FatalConditionHandler::FatalConditionHandler() {\n        assert(!altStackMem && \"Cannot initialize POSIX signal handler when one already exists\");\n        if (altStackSize == 0) {\n            altStackSize = std::max(static_cast<size_t>(SIGSTKSZ), minStackSizeForErrors);\n        }\n        altStackMem = new char[altStackSize]();\n    }\n\n    FatalConditionHandler::~FatalConditionHandler() {\n        delete[] altStackMem;\n        // We signal that another instance can be constructed by zeroing\n        // out the pointer.\n        altStackMem = nullptr;\n    }\n\n    void FatalConditionHandler::engage_platform() {\n        stack_t sigStack;\n        sigStack.ss_sp = altStackMem;\n        sigStack.ss_size = altStackSize;\n        sigStack.ss_flags = 0;\n        sigaltstack(&sigStack, &oldSigStack);\n        struct sigaction sa = { };\n\n        sa.sa_handler = handleSignal;\n        sa.sa_flags = SA_ONSTACK;\n        for (std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i) {\n            sigaction(signalDefs[i].id, &sa, &oldSigActions[i]);\n        }\n    }\n\n#if defined(__GNUC__)\n#    pragma GCC diagnostic pop\n#endif\n\n    void FatalConditionHandler::disengage_platform() {\n        restorePreviousSignalHandlers();\n    }\n\n} // end namespace Catch\n\n#endif // CATCH_CONFIG_POSIX_SIGNALS\n// end catch_fatal_condition.cpp\n// start catch_generators.cpp\n\n#include <limits>\n#include <set>\n\nnamespace Catch {\n\nIGeneratorTracker::~IGeneratorTracker() {}\n\nconst char* GeneratorException::what() const noexcept {\n    return m_msg;\n}\n\nnamespace Generators {\n\n    GeneratorUntypedBase::~GeneratorUntypedBase() {}\n\n    auto acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        return getResultCapture().acquireGeneratorTracker( generatorName, lineInfo );\n    }\n\n} // namespace Generators\n} // namespace Catch\n// end catch_generators.cpp\n// start catch_interfaces_capture.cpp\n\nnamespace Catch {\n    IResultCapture::~IResultCapture() = default;\n}\n// end catch_interfaces_capture.cpp\n// start catch_interfaces_config.cpp\n\nnamespace Catch {\n    IConfig::~IConfig() = default;\n}\n// end catch_interfaces_config.cpp\n// start catch_interfaces_exception.cpp\n\nnamespace Catch {\n    IExceptionTranslator::~IExceptionTranslator() = default;\n    IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default;\n}\n// end catch_interfaces_exception.cpp\n// start catch_interfaces_registry_hub.cpp\n\nnamespace Catch {\n    IRegistryHub::~IRegistryHub() = default;\n    IMutableRegistryHub::~IMutableRegistryHub() = default;\n}\n// end catch_interfaces_registry_hub.cpp\n// start catch_interfaces_reporter.cpp\n\n// start catch_reporter_listening.h\n\nnamespace Catch {\n\n    class ListeningReporter : public IStreamingReporter {\n        using Reporters = std::vector<IStreamingReporterPtr>;\n        Reporters m_listeners;\n        IStreamingReporterPtr m_reporter = nullptr;\n        ReporterPreferences m_preferences;\n\n    public:\n        ListeningReporter();\n\n        void addListener( IStreamingReporterPtr&& listener );\n        void addReporter( IStreamingReporterPtr&& reporter );\n\n    public: // IStreamingReporter\n\n        ReporterPreferences getPreferences() const override;\n\n        void noMatchingTestCases( std::string const& spec ) override;\n\n        void reportInvalidArguments(std::string const&arg) override;\n\n        static std::set<Verbosity> getSupportedVerbosities();\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n        void benchmarkPreparing(std::string const& name) override;\n        void benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) override;\n        void benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) override;\n        void benchmarkFailed(std::string const&) override;\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n        void testRunStarting( TestRunInfo const& testRunInfo ) override;\n        void testGroupStarting( GroupInfo const& groupInfo ) override;\n        void testCaseStarting( TestCaseInfo const& testInfo ) override;\n        void sectionStarting( SectionInfo const& sectionInfo ) override;\n        void assertionStarting( AssertionInfo const& assertionInfo ) override;\n\n        // The return value indicates if the messages buffer should be cleared:\n        bool assertionEnded( AssertionStats const& assertionStats ) override;\n        void sectionEnded( SectionStats const& sectionStats ) override;\n        void testCaseEnded( TestCaseStats const& testCaseStats ) override;\n        void testGroupEnded( TestGroupStats const& testGroupStats ) override;\n        void testRunEnded( TestRunStats const& testRunStats ) override;\n\n        void skipTest( TestCaseInfo const& testInfo ) override;\n        bool isMulti() const override;\n\n    };\n\n} // end namespace Catch\n\n// end catch_reporter_listening.h\nnamespace Catch {\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig )\n    :   m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {}\n\n    ReporterConfig::ReporterConfig( IConfigPtr const& _fullConfig, std::ostream& _stream )\n    :   m_stream( &_stream ), m_fullConfig( _fullConfig ) {}\n\n    std::ostream& ReporterConfig::stream() const { return *m_stream; }\n    IConfigPtr ReporterConfig::fullConfig() const { return m_fullConfig; }\n\n    TestRunInfo::TestRunInfo( std::string const& _name ) : name( _name ) {}\n\n    GroupInfo::GroupInfo(  std::string const& _name,\n                           std::size_t _groupIndex,\n                           std::size_t _groupsCount )\n    :   name( _name ),\n        groupIndex( _groupIndex ),\n        groupsCounts( _groupsCount )\n    {}\n\n     AssertionStats::AssertionStats( AssertionResult const& _assertionResult,\n                                     std::vector<MessageInfo> const& _infoMessages,\n                                     Totals const& _totals )\n    :   assertionResult( _assertionResult ),\n        infoMessages( _infoMessages ),\n        totals( _totals )\n    {\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = _assertionResult.m_resultData.lazyExpression.m_transientExpression;\n\n        if( assertionResult.hasMessage() ) {\n            // Copy message into messages list.\n            // !TBD This should have been done earlier, somewhere\n            MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() );\n            builder << assertionResult.getMessage();\n            builder.m_info.message = builder.m_stream.str();\n\n            infoMessages.push_back( builder.m_info );\n        }\n    }\n\n     AssertionStats::~AssertionStats() = default;\n\n    SectionStats::SectionStats(  SectionInfo const& _sectionInfo,\n                                 Counts const& _assertions,\n                                 double _durationInSeconds,\n                                 bool _missingAssertions )\n    :   sectionInfo( _sectionInfo ),\n        assertions( _assertions ),\n        durationInSeconds( _durationInSeconds ),\n        missingAssertions( _missingAssertions )\n    {}\n\n    SectionStats::~SectionStats() = default;\n\n    TestCaseStats::TestCaseStats(  TestCaseInfo const& _testInfo,\n                                   Totals const& _totals,\n                                   std::string const& _stdOut,\n                                   std::string const& _stdErr,\n                                   bool _aborting )\n    : testInfo( _testInfo ),\n        totals( _totals ),\n        stdOut( _stdOut ),\n        stdErr( _stdErr ),\n        aborting( _aborting )\n    {}\n\n    TestCaseStats::~TestCaseStats() = default;\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo,\n                                    Totals const& _totals,\n                                    bool _aborting )\n    :   groupInfo( _groupInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestGroupStats::TestGroupStats( GroupInfo const& _groupInfo )\n    :   groupInfo( _groupInfo ),\n        aborting( false )\n    {}\n\n    TestGroupStats::~TestGroupStats() = default;\n\n    TestRunStats::TestRunStats(   TestRunInfo const& _runInfo,\n                    Totals const& _totals,\n                    bool _aborting )\n    :   runInfo( _runInfo ),\n        totals( _totals ),\n        aborting( _aborting )\n    {}\n\n    TestRunStats::~TestRunStats() = default;\n\n    void IStreamingReporter::fatalErrorEncountered( StringRef ) {}\n    bool IStreamingReporter::isMulti() const { return false; }\n\n    IReporterFactory::~IReporterFactory() = default;\n    IReporterRegistry::~IReporterRegistry() = default;\n\n} // end namespace Catch\n// end catch_interfaces_reporter.cpp\n// start catch_interfaces_runner.cpp\n\nnamespace Catch {\n    IRunner::~IRunner() = default;\n}\n// end catch_interfaces_runner.cpp\n// start catch_interfaces_testcase.cpp\n\nnamespace Catch {\n    ITestInvoker::~ITestInvoker() = default;\n    ITestCaseRegistry::~ITestCaseRegistry() = default;\n}\n// end catch_interfaces_testcase.cpp\n// start catch_leak_detector.cpp\n\n#ifdef CATCH_CONFIG_WINDOWS_CRTDBG\n#include <crtdbg.h>\n\nnamespace Catch {\n\n    LeakDetector::LeakDetector() {\n        int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);\n        flag |= _CRTDBG_LEAK_CHECK_DF;\n        flag |= _CRTDBG_ALLOC_MEM_DF;\n        _CrtSetDbgFlag(flag);\n        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);\n        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);\n        // Change this to leaking allocation's number to break there\n        _CrtSetBreakAlloc(-1);\n    }\n}\n\n#else\n\n    Catch::LeakDetector::LeakDetector() {}\n\n#endif\n\nCatch::LeakDetector::~LeakDetector() {\n    Catch::cleanUp();\n}\n// end catch_leak_detector.cpp\n// start catch_list.cpp\n\n// start catch_list.h\n\n#include <set>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config );\n\n    std::size_t listTestsNamesOnly( Config const& config );\n\n    struct TagInfo {\n        void add( std::string const& spelling );\n        std::string all() const;\n\n        std::set<std::string> spellings;\n        std::size_t count = 0;\n    };\n\n    std::size_t listTags( Config const& config );\n\n    std::size_t listReporters();\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config );\n\n} // end namespace Catch\n\n// end catch_list.h\n// start catch_text.h\n\nnamespace Catch {\n    using namespace clara::TextFlow;\n}\n\n// end catch_text.h\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    std::size_t listTests( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available test cases:\\n\";\n        }\n\n        auto matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            Colour::Code colour = testCaseInfo.isHidden()\n                ? Colour::SecondaryText\n                : Colour::None;\n            Colour colourGuard( colour );\n\n            Catch::cout() << Column( testCaseInfo.name ).initialIndent( 2 ).indent( 4 ) << \"\\n\";\n            if( config.verbosity() >= Verbosity::High ) {\n                Catch::cout() << Column( Catch::Detail::stringify( testCaseInfo.lineInfo ) ).indent(4) << std::endl;\n                std::string description = testCaseInfo.description;\n                if( description.empty() )\n                    description = \"(NO DESCRIPTION)\";\n                Catch::cout() << Column( description ).indent(4) << std::endl;\n            }\n            if( !testCaseInfo.tags.empty() )\n                Catch::cout() << Column( testCaseInfo.tagsAsString() ).indent( 6 ) << \"\\n\";\n        }\n\n        if( !config.hasTestFilters() )\n            Catch::cout() << pluralise( matchedTestCases.size(), \"test case\" ) << '\\n' << std::endl;\n        else\n            Catch::cout() << pluralise( matchedTestCases.size(), \"matching test case\" ) << '\\n' << std::endl;\n        return matchedTestCases.size();\n    }\n\n    std::size_t listTestsNamesOnly( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        std::size_t matchedTests = 0;\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCaseInfo : matchedTestCases ) {\n            matchedTests++;\n            if( startsWith( testCaseInfo.name, '#' ) )\n               Catch::cout() << '\"' << testCaseInfo.name << '\"';\n            else\n               Catch::cout() << testCaseInfo.name;\n            if ( config.verbosity() >= Verbosity::High )\n                Catch::cout() << \"\\t@\" << testCaseInfo.lineInfo;\n            Catch::cout() << std::endl;\n        }\n        return matchedTests;\n    }\n\n    void TagInfo::add( std::string const& spelling ) {\n        ++count;\n        spellings.insert( spelling );\n    }\n\n    std::string TagInfo::all() const {\n        size_t size = 0;\n        for (auto const& spelling : spellings) {\n            // Add 2 for the brackes\n            size += spelling.size() + 2;\n        }\n\n        std::string out; out.reserve(size);\n        for (auto const& spelling : spellings) {\n            out += '[';\n            out += spelling;\n            out += ']';\n        }\n        return out;\n    }\n\n    std::size_t listTags( Config const& config ) {\n        TestSpec const& testSpec = config.testSpec();\n        if( config.hasTestFilters() )\n            Catch::cout() << \"Tags for matching test cases:\\n\";\n        else {\n            Catch::cout() << \"All available tags:\\n\";\n        }\n\n        std::map<std::string, TagInfo> tagCounts;\n\n        std::vector<TestCase> matchedTestCases = filterTests( getAllTestCasesSorted( config ), testSpec, config );\n        for( auto const& testCase : matchedTestCases ) {\n            for( auto const& tagName : testCase.getTestCaseInfo().tags ) {\n                std::string lcaseTagName = toLower( tagName );\n                auto countIt = tagCounts.find( lcaseTagName );\n                if( countIt == tagCounts.end() )\n                    countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first;\n                countIt->second.add( tagName );\n            }\n        }\n\n        for( auto const& tagCount : tagCounts ) {\n            ReusableStringStream rss;\n            rss << \"  \" << std::setw(2) << tagCount.second.count << \"  \";\n            auto str = rss.str();\n            auto wrapper = Column( tagCount.second.all() )\n                                                    .initialIndent( 0 )\n                                                    .indent( str.size() )\n                                                    .width( CATCH_CONFIG_CONSOLE_WIDTH-10 );\n            Catch::cout() << str << wrapper << '\\n';\n        }\n        Catch::cout() << pluralise( tagCounts.size(), \"tag\" ) << '\\n' << std::endl;\n        return tagCounts.size();\n    }\n\n    std::size_t listReporters() {\n        Catch::cout() << \"Available reporters:\\n\";\n        IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories();\n        std::size_t maxNameLen = 0;\n        for( auto const& factoryKvp : factories )\n            maxNameLen = (std::max)( maxNameLen, factoryKvp.first.size() );\n\n        for( auto const& factoryKvp : factories ) {\n            Catch::cout()\n                    << Column( factoryKvp.first + \":\" )\n                            .indent(2)\n                            .width( 5+maxNameLen )\n                    +  Column( factoryKvp.second->getDescription() )\n                            .initialIndent(0)\n                            .indent(2)\n                            .width( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 )\n                    << \"\\n\";\n        }\n        Catch::cout() << std::endl;\n        return factories.size();\n    }\n\n    Option<std::size_t> list( std::shared_ptr<Config> const& config ) {\n        Option<std::size_t> listedCount;\n        getCurrentMutableContext().setConfig( config );\n        if( config->listTests() )\n            listedCount = listedCount.valueOr(0) + listTests( *config );\n        if( config->listTestNamesOnly() )\n            listedCount = listedCount.valueOr(0) + listTestsNamesOnly( *config );\n        if( config->listTags() )\n            listedCount = listedCount.valueOr(0) + listTags( *config );\n        if( config->listReporters() )\n            listedCount = listedCount.valueOr(0) + listReporters();\n        return listedCount;\n    }\n\n} // end namespace Catch\n// end catch_list.cpp\n// start catch_matchers.cpp\n\nnamespace Catch {\nnamespace Matchers {\n    namespace Impl {\n\n        std::string MatcherUntypedBase::toString() const {\n            if( m_cachedToString.empty() )\n                m_cachedToString = describe();\n            return m_cachedToString;\n        }\n\n        MatcherUntypedBase::~MatcherUntypedBase() = default;\n\n    } // namespace Impl\n} // namespace Matchers\n\nusing namespace Matchers;\nusing Matchers::Impl::MatcherBase;\n\n} // namespace Catch\n// end catch_matchers.cpp\n// start catch_matchers_exception.cpp\n\nnamespace Catch {\nnamespace Matchers {\nnamespace Exception {\n\nbool ExceptionMessageMatcher::match(std::exception const& ex) const {\n    return ex.what() == m_message;\n}\n\nstd::string ExceptionMessageMatcher::describe() const {\n    return \"exception message matches \\\"\" + m_message + \"\\\"\";\n}\n\n}\nException::ExceptionMessageMatcher Message(std::string const& message) {\n    return Exception::ExceptionMessageMatcher(message);\n}\n\n// namespace Exception\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_exception.cpp\n// start catch_matchers_floating.cpp\n\n// start catch_polyfills.hpp\n\nnamespace Catch {\n    bool isnan(float f);\n    bool isnan(double d);\n}\n\n// end catch_polyfills.hpp\n// start catch_to_string.hpp\n\n#include <string>\n\nnamespace Catch {\n    template <typename T>\n    std::string to_string(T const& t) {\n#if defined(CATCH_CONFIG_CPP11_TO_STRING)\n        return std::to_string(t);\n#else\n        ReusableStringStream rss;\n        rss << t;\n        return rss.str();\n#endif\n    }\n} // end namespace Catch\n\n// end catch_to_string.hpp\n#include <algorithm>\n#include <cmath>\n#include <cstdlib>\n#include <cstdint>\n#include <cstring>\n#include <sstream>\n#include <type_traits>\n#include <iomanip>\n#include <limits>\n\nnamespace Catch {\nnamespace {\n\n    int32_t convert(float f) {\n        static_assert(sizeof(float) == sizeof(int32_t), \"Important ULP matcher assumption violated\");\n        int32_t i;\n        std::memcpy(&i, &f, sizeof(f));\n        return i;\n    }\n\n    int64_t convert(double d) {\n        static_assert(sizeof(double) == sizeof(int64_t), \"Important ULP matcher assumption violated\");\n        int64_t i;\n        std::memcpy(&i, &d, sizeof(d));\n        return i;\n    }\n\n    template <typename FP>\n    bool almostEqualUlps(FP lhs, FP rhs, uint64_t maxUlpDiff) {\n        // Comparison with NaN should always be false.\n        // This way we can rule it out before getting into the ugly details\n        if (Catch::isnan(lhs) || Catch::isnan(rhs)) {\n            return false;\n        }\n\n        auto lc = convert(lhs);\n        auto rc = convert(rhs);\n\n        if ((lc < 0) != (rc < 0)) {\n            // Potentially we can have +0 and -0\n            return lhs == rhs;\n        }\n\n        // static cast as a workaround for IBM XLC\n        auto ulpDiff = std::abs(static_cast<FP>(lc - rc));\n        return static_cast<uint64_t>(ulpDiff) <= maxUlpDiff;\n    }\n\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n\n    float nextafter(float x, float y) {\n        return ::nextafterf(x, y);\n    }\n\n    double nextafter(double x, double y) {\n        return ::nextafter(x, y);\n    }\n\n#endif // ^^^ CATCH_CONFIG_GLOBAL_NEXTAFTER ^^^\n\ntemplate <typename FP>\nFP step(FP start, FP direction, uint64_t steps) {\n    for (uint64_t i = 0; i < steps; ++i) {\n#if defined(CATCH_CONFIG_GLOBAL_NEXTAFTER)\n        start = Catch::nextafter(start, direction);\n#else\n        start = std::nextafter(start, direction);\n#endif\n    }\n    return start;\n}\n\n// Performs equivalent check of std::fabs(lhs - rhs) <= margin\n// But without the subtraction to allow for INFINITY in comparison\nbool marginComparison(double lhs, double rhs, double margin) {\n    return (lhs + margin >= rhs) && (rhs + margin >= lhs);\n}\n\ntemplate <typename FloatingPoint>\nvoid write(std::ostream& out, FloatingPoint num) {\n    out << std::scientific\n        << std::setprecision(std::numeric_limits<FloatingPoint>::max_digits10 - 1)\n        << num;\n}\n\n} // end anonymous namespace\n\nnamespace Matchers {\nnamespace Floating {\n\n    enum class FloatingPointKind : uint8_t {\n        Float,\n        Double\n    };\n\n    WithinAbsMatcher::WithinAbsMatcher(double target, double margin)\n        :m_target{ target }, m_margin{ margin } {\n        CATCH_ENFORCE(margin >= 0, \"Invalid margin: \" << margin << '.'\n            << \" Margin has to be non-negative.\");\n    }\n\n    // Performs equivalent check of std::fabs(lhs - rhs) <= margin\n    // But without the subtraction to allow for INFINITY in comparison\n    bool WithinAbsMatcher::match(double const& matchee) const {\n        return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee);\n    }\n\n    std::string WithinAbsMatcher::describe() const {\n        return \"is within \" + ::Catch::Detail::stringify(m_margin) + \" of \" + ::Catch::Detail::stringify(m_target);\n    }\n\n    WithinUlpsMatcher::WithinUlpsMatcher(double target, uint64_t ulps, FloatingPointKind baseType)\n        :m_target{ target }, m_ulps{ ulps }, m_type{ baseType } {\n        CATCH_ENFORCE(m_type == FloatingPointKind::Double\n                   || m_ulps < (std::numeric_limits<uint32_t>::max)(),\n            \"Provided ULP is impossibly large for a float comparison.\");\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic push\n// Clang <3.5 reports on the default branch in the switch below\n#pragma clang diagnostic ignored \"-Wunreachable-code\"\n#endif\n\n    bool WithinUlpsMatcher::match(double const& matchee) const {\n        switch (m_type) {\n        case FloatingPointKind::Float:\n            return almostEqualUlps<float>(static_cast<float>(matchee), static_cast<float>(m_target), m_ulps);\n        case FloatingPointKind::Double:\n            return almostEqualUlps<double>(matchee, m_target, m_ulps);\n        default:\n            CATCH_INTERNAL_ERROR( \"Unknown FloatingPointKind value\" );\n        }\n    }\n\n#if defined(__clang__)\n#pragma clang diagnostic pop\n#endif\n\n    std::string WithinUlpsMatcher::describe() const {\n        std::stringstream ret;\n\n        ret << \"is within \" << m_ulps << \" ULPs of \";\n\n        if (m_type == FloatingPointKind::Float) {\n            write(ret, static_cast<float>(m_target));\n            ret << 'f';\n        } else {\n            write(ret, m_target);\n        }\n\n        ret << \" ([\";\n        if (m_type == FloatingPointKind::Double) {\n            write(ret, step(m_target, static_cast<double>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(m_target, static_cast<double>( INFINITY), m_ulps));\n        } else {\n            // We have to cast INFINITY to float because of MinGW, see #1782\n            write(ret, step(static_cast<float>(m_target), static_cast<float>(-INFINITY), m_ulps));\n            ret << \", \";\n            write(ret, step(static_cast<float>(m_target), static_cast<float>( INFINITY), m_ulps));\n        }\n        ret << \"])\";\n\n        return ret.str();\n    }\n\n    WithinRelMatcher::WithinRelMatcher(double target, double epsilon):\n        m_target(target),\n        m_epsilon(epsilon){\n        CATCH_ENFORCE(m_epsilon >= 0., \"Relative comparison with epsilon <  0 does not make sense.\");\n        CATCH_ENFORCE(m_epsilon  < 1., \"Relative comparison with epsilon >= 1 does not make sense.\");\n    }\n\n    bool WithinRelMatcher::match(double const& matchee) const {\n        const auto relMargin = m_epsilon * (std::max)(std::fabs(matchee), std::fabs(m_target));\n        return marginComparison(matchee, m_target,\n                                std::isinf(relMargin)? 0 : relMargin);\n    }\n\n    std::string WithinRelMatcher::describe() const {\n        Catch::ReusableStringStream sstr;\n        sstr << \"and \" << m_target << \" are within \" << m_epsilon * 100. << \"% of each other\";\n        return sstr.str();\n    }\n\n}// namespace Floating\n\nFloating::WithinUlpsMatcher WithinULP(double target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double);\n}\n\nFloating::WithinUlpsMatcher WithinULP(float target, uint64_t maxUlpDiff) {\n    return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float);\n}\n\nFloating::WithinAbsMatcher WithinAbs(double target, double margin) {\n    return Floating::WithinAbsMatcher(target, margin);\n}\n\nFloating::WithinRelMatcher WithinRel(double target, double eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(double target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<double>::epsilon() * 100);\n}\n\nFloating::WithinRelMatcher WithinRel(float target, float eps) {\n    return Floating::WithinRelMatcher(target, eps);\n}\n\nFloating::WithinRelMatcher WithinRel(float target) {\n    return Floating::WithinRelMatcher(target, std::numeric_limits<float>::epsilon() * 100);\n}\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_floating.cpp\n// start catch_matchers_generic.cpp\n\nstd::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string& desc) {\n    if (desc.empty()) {\n        return \"matches undescribed predicate\";\n    } else {\n        return \"matches predicate: \\\"\" + desc + '\"';\n    }\n}\n// end catch_matchers_generic.cpp\n// start catch_matchers_string.cpp\n\n#include <regex>\n\nnamespace Catch {\nnamespace Matchers {\n\n    namespace StdString {\n\n        CasedString::CasedString( std::string const& str, CaseSensitive::Choice caseSensitivity )\n        :   m_caseSensitivity( caseSensitivity ),\n            m_str( adjustString( str ) )\n        {}\n        std::string CasedString::adjustString( std::string const& str ) const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? toLower( str )\n                   : str;\n        }\n        std::string CasedString::caseSensitivitySuffix() const {\n            return m_caseSensitivity == CaseSensitive::No\n                   ? \" (case insensitive)\"\n                   : std::string();\n        }\n\n        StringMatcherBase::StringMatcherBase( std::string const& operation, CasedString const& comparator )\n        : m_comparator( comparator ),\n          m_operation( operation ) {\n        }\n\n        std::string StringMatcherBase::describe() const {\n            std::string description;\n            description.reserve(5 + m_operation.size() + m_comparator.m_str.size() +\n                                        m_comparator.caseSensitivitySuffix().size());\n            description += m_operation;\n            description += \": \\\"\";\n            description += m_comparator.m_str;\n            description += \"\\\"\";\n            description += m_comparator.caseSensitivitySuffix();\n            return description;\n        }\n\n        EqualsMatcher::EqualsMatcher( CasedString const& comparator ) : StringMatcherBase( \"equals\", comparator ) {}\n\n        bool EqualsMatcher::match( std::string const& source ) const {\n            return m_comparator.adjustString( source ) == m_comparator.m_str;\n        }\n\n        ContainsMatcher::ContainsMatcher( CasedString const& comparator ) : StringMatcherBase( \"contains\", comparator ) {}\n\n        bool ContainsMatcher::match( std::string const& source ) const {\n            return contains( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        StartsWithMatcher::StartsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"starts with\", comparator ) {}\n\n        bool StartsWithMatcher::match( std::string const& source ) const {\n            return startsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        EndsWithMatcher::EndsWithMatcher( CasedString const& comparator ) : StringMatcherBase( \"ends with\", comparator ) {}\n\n        bool EndsWithMatcher::match( std::string const& source ) const {\n            return endsWith( m_comparator.adjustString( source ), m_comparator.m_str );\n        }\n\n        RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity): m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) {}\n\n        bool RegexMatcher::match(std::string const& matchee) const {\n            auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway\n            if (m_caseSensitivity == CaseSensitive::Choice::No) {\n                flags |= std::regex::icase;\n            }\n            auto reg = std::regex(m_regex, flags);\n            return std::regex_match(matchee, reg);\n        }\n\n        std::string RegexMatcher::describe() const {\n            return \"matches \" + ::Catch::Detail::stringify(m_regex) + ((m_caseSensitivity == CaseSensitive::Choice::Yes)? \" case sensitively\" : \" case insensitively\");\n        }\n\n    } // namespace StdString\n\n    StdString::EqualsMatcher Equals( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EqualsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::ContainsMatcher Contains( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::ContainsMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::EndsWithMatcher EndsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::EndsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n    StdString::StartsWithMatcher StartsWith( std::string const& str, CaseSensitive::Choice caseSensitivity ) {\n        return StdString::StartsWithMatcher( StdString::CasedString( str, caseSensitivity) );\n    }\n\n    StdString::RegexMatcher Matches(std::string const& regex, CaseSensitive::Choice caseSensitivity) {\n        return StdString::RegexMatcher(regex, caseSensitivity);\n    }\n\n} // namespace Matchers\n} // namespace Catch\n// end catch_matchers_string.cpp\n// start catch_message.cpp\n\n// start catch_uncaught_exceptions.h\n\nnamespace Catch {\n    bool uncaught_exceptions();\n} // end namespace Catch\n\n// end catch_uncaught_exceptions.h\n#include <cassert>\n#include <stack>\n\nnamespace Catch {\n\n    MessageInfo::MessageInfo(   StringRef const& _macroName,\n                                SourceLineInfo const& _lineInfo,\n                                ResultWas::OfType _type )\n    :   macroName( _macroName ),\n        lineInfo( _lineInfo ),\n        type( _type ),\n        sequence( ++globalCount )\n    {}\n\n    bool MessageInfo::operator==( MessageInfo const& other ) const {\n        return sequence == other.sequence;\n    }\n\n    bool MessageInfo::operator<( MessageInfo const& other ) const {\n        return sequence < other.sequence;\n    }\n\n    // This may need protecting if threading support is added\n    unsigned int MessageInfo::globalCount = 0;\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    Catch::MessageBuilder::MessageBuilder( StringRef const& macroName,\n                                           SourceLineInfo const& lineInfo,\n                                           ResultWas::OfType type )\n        :m_info(macroName, lineInfo, type) {}\n\n    ////////////////////////////////////////////////////////////////////////////\n\n    ScopedMessage::ScopedMessage( MessageBuilder const& builder )\n    : m_info( builder.m_info ), m_moved()\n    {\n        m_info.message = builder.m_stream.str();\n        getResultCapture().pushScopedMessage( m_info );\n    }\n\n    ScopedMessage::ScopedMessage( ScopedMessage&& old )\n    : m_info( old.m_info ), m_moved()\n    {\n        old.m_moved = true;\n    }\n\n    ScopedMessage::~ScopedMessage() {\n        if ( !uncaught_exceptions() && !m_moved ){\n            getResultCapture().popScopedMessage(m_info);\n        }\n    }\n\n    Capturer::Capturer( StringRef macroName, SourceLineInfo const& lineInfo, ResultWas::OfType resultType, StringRef names ) {\n        auto trimmed = [&] (size_t start, size_t end) {\n            while (names[start] == ',' || isspace(static_cast<unsigned char>(names[start]))) {\n                ++start;\n            }\n            while (names[end] == ',' || isspace(static_cast<unsigned char>(names[end]))) {\n                --end;\n            }\n            return names.substr(start, end - start + 1);\n        };\n        auto skipq = [&] (size_t start, char quote) {\n            for (auto i = start + 1; i < names.size() ; ++i) {\n                if (names[i] == quote)\n                    return i;\n                if (names[i] == '\\\\')\n                    ++i;\n            }\n            CATCH_INTERNAL_ERROR(\"CAPTURE parsing encountered unmatched quote\");\n        };\n\n        size_t start = 0;\n        std::stack<char> openings;\n        for (size_t pos = 0; pos < names.size(); ++pos) {\n            char c = names[pos];\n            switch (c) {\n            case '[':\n            case '{':\n            case '(':\n            // It is basically impossible to disambiguate between\n            // comparison and start of template args in this context\n//            case '<':\n                openings.push(c);\n                break;\n            case ']':\n            case '}':\n            case ')':\n//           case '>':\n                openings.pop();\n                break;\n            case '\"':\n            case '\\'':\n                pos = skipq(pos, c);\n                break;\n            case ',':\n                if (start != pos && openings.empty()) {\n                    m_messages.emplace_back(macroName, lineInfo, resultType);\n                    m_messages.back().message = static_cast<std::string>(trimmed(start, pos));\n                    m_messages.back().message += \" := \";\n                    start = pos;\n                }\n            }\n        }\n        assert(openings.empty() && \"Mismatched openings\");\n        m_messages.emplace_back(macroName, lineInfo, resultType);\n        m_messages.back().message = static_cast<std::string>(trimmed(start, names.size() - 1));\n        m_messages.back().message += \" := \";\n    }\n    Capturer::~Capturer() {\n        if ( !uncaught_exceptions() ){\n            assert( m_captured == m_messages.size() );\n            for( size_t i = 0; i < m_captured; ++i  )\n                m_resultCapture.popScopedMessage( m_messages[i] );\n        }\n    }\n\n    void Capturer::captureValue( size_t index, std::string const& value ) {\n        assert( index < m_messages.size() );\n        m_messages[index].message += value;\n        m_resultCapture.pushScopedMessage( m_messages[index] );\n        m_captured++;\n    }\n\n} // end namespace Catch\n// end catch_message.cpp\n// start catch_output_redirect.cpp\n\n// start catch_output_redirect.h\n#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n\n#include <cstdio>\n#include <iosfwd>\n#include <string>\n\nnamespace Catch {\n\n    class RedirectedStream {\n        std::ostream& m_originalStream;\n        std::ostream& m_redirectionStream;\n        std::streambuf* m_prevBuf;\n\n    public:\n        RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream );\n        ~RedirectedStream();\n    };\n\n    class RedirectedStdOut {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cout;\n    public:\n        RedirectedStdOut();\n        auto str() const -> std::string;\n    };\n\n    // StdErr has two constituent streams in C++, std::cerr and std::clog\n    // This means that we need to redirect 2 streams into 1 to keep proper\n    // order of writes\n    class RedirectedStdErr {\n        ReusableStringStream m_rss;\n        RedirectedStream m_cerr;\n        RedirectedStream m_clog;\n    public:\n        RedirectedStdErr();\n        auto str() const -> std::string;\n    };\n\n    class RedirectedStreams {\n    public:\n        RedirectedStreams(RedirectedStreams const&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams const&) = delete;\n        RedirectedStreams(RedirectedStreams&&) = delete;\n        RedirectedStreams& operator=(RedirectedStreams&&) = delete;\n\n        RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr);\n        ~RedirectedStreams();\n    private:\n        std::string& m_redirectedCout;\n        std::string& m_redirectedCerr;\n        RedirectedStdOut m_redirectedStdOut;\n        RedirectedStdErr m_redirectedStdErr;\n    };\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n    // Windows's implementation of std::tmpfile is terrible (it tries\n    // to create a file inside system folder, thus requiring elevated\n    // privileges for the binary), so we have to use tmpnam(_s) and\n    // create the file ourselves there.\n    class TempFile {\n    public:\n        TempFile(TempFile const&) = delete;\n        TempFile& operator=(TempFile const&) = delete;\n        TempFile(TempFile&&) = delete;\n        TempFile& operator=(TempFile&&) = delete;\n\n        TempFile();\n        ~TempFile();\n\n        std::FILE* getFile();\n        std::string getContents();\n\n    private:\n        std::FILE* m_file = nullptr;\n    #if defined(_MSC_VER)\n        char m_buffer[L_tmpnam] = { 0 };\n    #endif\n    };\n\n    class OutputRedirect {\n    public:\n        OutputRedirect(OutputRedirect const&) = delete;\n        OutputRedirect& operator=(OutputRedirect const&) = delete;\n        OutputRedirect(OutputRedirect&&) = delete;\n        OutputRedirect& operator=(OutputRedirect&&) = delete;\n\n        OutputRedirect(std::string& stdout_dest, std::string& stderr_dest);\n        ~OutputRedirect();\n\n    private:\n        int m_originalStdout = -1;\n        int m_originalStderr = -1;\n        TempFile m_stdoutFile;\n        TempFile m_stderrFile;\n        std::string& m_stdoutDest;\n        std::string& m_stderrDest;\n    };\n\n#endif\n\n} // end namespace Catch\n\n#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H\n// end catch_output_redirect.h\n#include <cstdio>\n#include <cstring>\n#include <fstream>\n#include <sstream>\n#include <stdexcept>\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #include <io.h>      //_dup and _dup2\n    #define dup _dup\n    #define dup2 _dup2\n    #define fileno _fileno\n    #else\n    #include <unistd.h>  // dup and dup2\n    #endif\n#endif\n\nnamespace Catch {\n\n    RedirectedStream::RedirectedStream( std::ostream& originalStream, std::ostream& redirectionStream )\n    :   m_originalStream( originalStream ),\n        m_redirectionStream( redirectionStream ),\n        m_prevBuf( m_originalStream.rdbuf() )\n    {\n        m_originalStream.rdbuf( m_redirectionStream.rdbuf() );\n    }\n\n    RedirectedStream::~RedirectedStream() {\n        m_originalStream.rdbuf( m_prevBuf );\n    }\n\n    RedirectedStdOut::RedirectedStdOut() : m_cout( Catch::cout(), m_rss.get() ) {}\n    auto RedirectedStdOut::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStdErr::RedirectedStdErr()\n    :   m_cerr( Catch::cerr(), m_rss.get() ),\n        m_clog( Catch::clog(), m_rss.get() )\n    {}\n    auto RedirectedStdErr::str() const -> std::string { return m_rss.str(); }\n\n    RedirectedStreams::RedirectedStreams(std::string& redirectedCout, std::string& redirectedCerr)\n    :   m_redirectedCout(redirectedCout),\n        m_redirectedCerr(redirectedCerr)\n    {}\n\n    RedirectedStreams::~RedirectedStreams() {\n        m_redirectedCout += m_redirectedStdOut.str();\n        m_redirectedCerr += m_redirectedStdErr.str();\n    }\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n\n#if defined(_MSC_VER)\n    TempFile::TempFile() {\n        if (tmpnam_s(m_buffer)) {\n            CATCH_RUNTIME_ERROR(\"Could not get a temp filename\");\n        }\n        if (fopen_s(&m_file, m_buffer, \"w+\")) {\n            char buffer[100];\n            if (strerror_s(buffer, errno)) {\n                CATCH_RUNTIME_ERROR(\"Could not translate errno to a string\");\n            }\n            CATCH_RUNTIME_ERROR(\"Could not open the temp file: '\" << m_buffer << \"' because: \" << buffer);\n        }\n    }\n#else\n    TempFile::TempFile() {\n        m_file = std::tmpfile();\n        if (!m_file) {\n            CATCH_RUNTIME_ERROR(\"Could not create a temp file.\");\n        }\n    }\n\n#endif\n\n    TempFile::~TempFile() {\n         // TBD: What to do about errors here?\n         std::fclose(m_file);\n         // We manually create the file on Windows only, on Linux\n         // it will be autodeleted\n#if defined(_MSC_VER)\n         std::remove(m_buffer);\n#endif\n    }\n\n    FILE* TempFile::getFile() {\n        return m_file;\n    }\n\n    std::string TempFile::getContents() {\n        std::stringstream sstr;\n        char buffer[100] = {};\n        std::rewind(m_file);\n        while (std::fgets(buffer, sizeof(buffer), m_file)) {\n            sstr << buffer;\n        }\n        return sstr.str();\n    }\n\n    OutputRedirect::OutputRedirect(std::string& stdout_dest, std::string& stderr_dest) :\n        m_originalStdout(dup(1)),\n        m_originalStderr(dup(2)),\n        m_stdoutDest(stdout_dest),\n        m_stderrDest(stderr_dest) {\n        dup2(fileno(m_stdoutFile.getFile()), 1);\n        dup2(fileno(m_stderrFile.getFile()), 2);\n    }\n\n    OutputRedirect::~OutputRedirect() {\n        Catch::cout() << std::flush;\n        fflush(stdout);\n        // Since we support overriding these streams, we flush cerr\n        // even though std::cerr is unbuffered\n        Catch::cerr() << std::flush;\n        Catch::clog() << std::flush;\n        fflush(stderr);\n\n        dup2(m_originalStdout, 1);\n        dup2(m_originalStderr, 2);\n\n        m_stdoutDest += m_stdoutFile.getContents();\n        m_stderrDest += m_stderrFile.getContents();\n    }\n\n#endif // CATCH_CONFIG_NEW_CAPTURE\n\n} // namespace Catch\n\n#if defined(CATCH_CONFIG_NEW_CAPTURE)\n    #if defined(_MSC_VER)\n    #undef dup\n    #undef dup2\n    #undef fileno\n    #endif\n#endif\n// end catch_output_redirect.cpp\n// start catch_polyfills.cpp\n\n#include <cmath>\n\nnamespace Catch {\n\n#if !defined(CATCH_CONFIG_POLYFILL_ISNAN)\n    bool isnan(float f) {\n        return std::isnan(f);\n    }\n    bool isnan(double d) {\n        return std::isnan(d);\n    }\n#else\n    // For now we only use this for embarcadero\n    bool isnan(float f) {\n        return std::_isnan(f);\n    }\n    bool isnan(double d) {\n        return std::_isnan(d);\n    }\n#endif\n\n} // end namespace Catch\n// end catch_polyfills.cpp\n// start catch_random_number_generator.cpp\n\nnamespace Catch {\n\nnamespace {\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4146) // we negate uint32 during the rotate\n#endif\n        // Safe rotr implementation thanks to John Regehr\n        uint32_t rotate_right(uint32_t val, uint32_t count) {\n            const uint32_t mask = 31;\n            count &= mask;\n            return (val >> count) | (val << (-count & mask));\n        }\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n}\n\n    SimplePcg32::SimplePcg32(result_type seed_) {\n        seed(seed_);\n    }\n\n    void SimplePcg32::seed(result_type seed_) {\n        m_state = 0;\n        (*this)();\n        m_state += seed_;\n        (*this)();\n    }\n\n    void SimplePcg32::discard(uint64_t skip) {\n        // We could implement this to run in O(log n) steps, but this\n        // should suffice for our use case.\n        for (uint64_t s = 0; s < skip; ++s) {\n            static_cast<void>((*this)());\n        }\n    }\n\n    SimplePcg32::result_type SimplePcg32::operator()() {\n        // prepare the output value\n        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);\n        const auto output = rotate_right(xorshifted, m_state >> 59u);\n\n        // advance state\n        m_state = m_state * 6364136223846793005ULL + s_inc;\n\n        return output;\n    }\n\n    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state == rhs.m_state;\n    }\n\n    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {\n        return lhs.m_state != rhs.m_state;\n    }\n}\n// end catch_random_number_generator.cpp\n// start catch_registry_hub.cpp\n\n// start catch_test_case_registry_impl.h\n\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <ios>\n\nnamespace Catch {\n\n    class TestCase;\n    struct IConfig;\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases );\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config );\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config );\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions );\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config );\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config );\n\n    class TestRegistry : public ITestCaseRegistry {\n    public:\n        virtual ~TestRegistry() = default;\n\n        virtual void registerTest( TestCase const& testCase );\n\n        std::vector<TestCase> const& getAllTests() const override;\n        std::vector<TestCase> const& getAllTestsSorted( IConfig const& config ) const override;\n\n    private:\n        std::vector<TestCase> m_functions;\n        mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder;\n        mutable std::vector<TestCase> m_sortedFunctions;\n        std::size_t m_unnamedCount = 0;\n        std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised\n    };\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    class TestInvokerAsFunction : public ITestInvoker {\n        void(*m_testAsFunction)();\n    public:\n        TestInvokerAsFunction( void(*testAsFunction)() ) noexcept;\n\n        void invoke() const override;\n    };\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName );\n\n    ///////////////////////////////////////////////////////////////////////////\n\n} // end namespace Catch\n\n// end catch_test_case_registry_impl.h\n// start catch_reporter_registry.h\n\n#include <map>\n\nnamespace Catch {\n\n    class ReporterRegistry : public IReporterRegistry {\n\n    public:\n\n        ~ReporterRegistry() override;\n\n        IStreamingReporterPtr create( std::string const& name, IConfigPtr const& config ) const override;\n\n        void registerReporter( std::string const& name, IReporterFactoryPtr const& factory );\n        void registerListener( IReporterFactoryPtr const& factory );\n\n        FactoryMap const& getFactories() const override;\n        Listeners const& getListeners() const override;\n\n    private:\n        FactoryMap m_factories;\n        Listeners m_listeners;\n    };\n}\n\n// end catch_reporter_registry.h\n// start catch_tag_alias_registry.h\n\n// start catch_tag_alias.h\n\n#include <string>\n\nnamespace Catch {\n\n    struct TagAlias {\n        TagAlias(std::string const& _tag, SourceLineInfo _lineInfo);\n\n        std::string tag;\n        SourceLineInfo lineInfo;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias.h\n#include <map>\n\nnamespace Catch {\n\n    class TagAliasRegistry : public ITagAliasRegistry {\n    public:\n        ~TagAliasRegistry() override;\n        TagAlias const* find( std::string const& alias ) const override;\n        std::string expandAliases( std::string const& unexpandedTestSpec ) const override;\n        void add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo );\n\n    private:\n        std::map<std::string, TagAlias> m_registry;\n    };\n\n} // end namespace Catch\n\n// end catch_tag_alias_registry.h\n// start catch_startup_exception_registry.h\n\n#include <vector>\n#include <exception>\n\nnamespace Catch {\n\n    class StartupExceptionRegistry {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n    public:\n        void add(std::exception_ptr const& exception) noexcept;\n        std::vector<std::exception_ptr> const& getExceptions() const noexcept;\n    private:\n        std::vector<std::exception_ptr> m_exceptions;\n#endif\n    };\n\n} // end namespace Catch\n\n// end catch_startup_exception_registry.h\n// start catch_singletons.hpp\n\nnamespace Catch {\n\n    struct ISingleton {\n        virtual ~ISingleton();\n    };\n\n    void addSingleton( ISingleton* singleton );\n    void cleanupSingletons();\n\n    template<typename SingletonImplT, typename InterfaceT = SingletonImplT, typename MutableInterfaceT = InterfaceT>\n    class Singleton : SingletonImplT, public ISingleton {\n\n        static auto getInternal() -> Singleton* {\n            static Singleton* s_instance = nullptr;\n            if( !s_instance ) {\n                s_instance = new Singleton;\n                addSingleton( s_instance );\n            }\n            return s_instance;\n        }\n\n    public:\n        static auto get() -> InterfaceT const& {\n            return *getInternal();\n        }\n        static auto getMutable() -> MutableInterfaceT& {\n            return *getInternal();\n        }\n    };\n\n} // namespace Catch\n\n// end catch_singletons.hpp\nnamespace Catch {\n\n    namespace {\n\n        class RegistryHub : public IRegistryHub, public IMutableRegistryHub,\n                            private NonCopyable {\n\n        public: // IRegistryHub\n            RegistryHub() = default;\n            IReporterRegistry const& getReporterRegistry() const override {\n                return m_reporterRegistry;\n            }\n            ITestCaseRegistry const& getTestCaseRegistry() const override {\n                return m_testCaseRegistry;\n            }\n            IExceptionTranslatorRegistry const& getExceptionTranslatorRegistry() const override {\n                return m_exceptionTranslatorRegistry;\n            }\n            ITagAliasRegistry const& getTagAliasRegistry() const override {\n                return m_tagAliasRegistry;\n            }\n            StartupExceptionRegistry const& getStartupExceptionRegistry() const override {\n                return m_exceptionRegistry;\n            }\n\n        public: // IMutableRegistryHub\n            void registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerReporter( name, factory );\n            }\n            void registerListener( IReporterFactoryPtr const& factory ) override {\n                m_reporterRegistry.registerListener( factory );\n            }\n            void registerTest( TestCase const& testInfo ) override {\n                m_testCaseRegistry.registerTest( testInfo );\n            }\n            void registerTranslator( const IExceptionTranslator* translator ) override {\n                m_exceptionTranslatorRegistry.registerTranslator( translator );\n            }\n            void registerTagAlias( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) override {\n                m_tagAliasRegistry.add( alias, tag, lineInfo );\n            }\n            void registerStartupException() noexcept override {\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n                m_exceptionRegistry.add(std::current_exception());\n#else\n                CATCH_INTERNAL_ERROR(\"Attempted to register active exception under CATCH_CONFIG_DISABLE_EXCEPTIONS!\");\n#endif\n            }\n            IMutableEnumValuesRegistry& getMutableEnumValuesRegistry() override {\n                return m_enumValuesRegistry;\n            }\n\n        private:\n            TestRegistry m_testCaseRegistry;\n            ReporterRegistry m_reporterRegistry;\n            ExceptionTranslatorRegistry m_exceptionTranslatorRegistry;\n            TagAliasRegistry m_tagAliasRegistry;\n            StartupExceptionRegistry m_exceptionRegistry;\n            Detail::EnumValuesRegistry m_enumValuesRegistry;\n        };\n    }\n\n    using RegistryHubSingleton = Singleton<RegistryHub, IRegistryHub, IMutableRegistryHub>;\n\n    IRegistryHub const& getRegistryHub() {\n        return RegistryHubSingleton::get();\n    }\n    IMutableRegistryHub& getMutableRegistryHub() {\n        return RegistryHubSingleton::getMutable();\n    }\n    void cleanUp() {\n        cleanupSingletons();\n        cleanUpContext();\n    }\n    std::string translateActiveException() {\n        return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException();\n    }\n\n} // end namespace Catch\n// end catch_registry_hub.cpp\n// start catch_reporter_registry.cpp\n\nnamespace Catch {\n\n    ReporterRegistry::~ReporterRegistry() = default;\n\n    IStreamingReporterPtr ReporterRegistry::create( std::string const& name, IConfigPtr const& config ) const {\n        auto it =  m_factories.find( name );\n        if( it == m_factories.end() )\n            return nullptr;\n        return it->second->create( ReporterConfig( config ) );\n    }\n\n    void ReporterRegistry::registerReporter( std::string const& name, IReporterFactoryPtr const& factory ) {\n        m_factories.emplace(name, factory);\n    }\n    void ReporterRegistry::registerListener( IReporterFactoryPtr const& factory ) {\n        m_listeners.push_back( factory );\n    }\n\n    IReporterRegistry::FactoryMap const& ReporterRegistry::getFactories() const {\n        return m_factories;\n    }\n    IReporterRegistry::Listeners const& ReporterRegistry::getListeners() const {\n        return m_listeners;\n    }\n\n}\n// end catch_reporter_registry.cpp\n// start catch_result_type.cpp\n\nnamespace Catch {\n\n    bool isOk( ResultWas::OfType resultType ) {\n        return ( resultType & ResultWas::FailureBit ) == 0;\n    }\n    bool isJustInfo( int flags ) {\n        return flags == ResultWas::Info;\n    }\n\n    ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) {\n        return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) );\n    }\n\n    bool shouldContinueOnFailure( int flags )    { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; }\n    bool shouldSuppressFailure( int flags )      { return ( flags & ResultDisposition::SuppressFail ) != 0; }\n\n} // end namespace Catch\n// end catch_result_type.cpp\n// start catch_run_context.cpp\n\n#include <cassert>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace Generators {\n        struct GeneratorTracker : TestCaseTracking::TrackerBase, IGeneratorTracker {\n            GeneratorBasePtr m_generator;\n\n            GeneratorTracker( TestCaseTracking::NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n            :   TrackerBase( nameAndLocation, ctx, parent )\n            {}\n            ~GeneratorTracker();\n\n            static GeneratorTracker& acquire( TrackerContext& ctx, TestCaseTracking::NameAndLocation const& nameAndLocation ) {\n                std::shared_ptr<GeneratorTracker> tracker;\n\n                ITracker& currentTracker = ctx.currentTracker();\n                // Under specific circumstances, the generator we want\n                // to acquire is also the current tracker. If this is\n                // the case, we have to avoid looking through current\n                // tracker's children, and instead return the current\n                // tracker.\n                // A case where this check is important is e.g.\n                //     for (int i = 0; i < 5; ++i) {\n                //         int n = GENERATE(1, 2);\n                //     }\n                //\n                // without it, the code above creates 5 nested generators.\n                if (currentTracker.nameAndLocation() == nameAndLocation) {\n                    auto thisTracker = currentTracker.parent().findChild(nameAndLocation);\n                    assert(thisTracker);\n                    assert(thisTracker->isGeneratorTracker());\n                    tracker = std::static_pointer_cast<GeneratorTracker>(thisTracker);\n                } else if ( TestCaseTracking::ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n                    assert( childTracker );\n                    assert( childTracker->isGeneratorTracker() );\n                    tracker = std::static_pointer_cast<GeneratorTracker>( childTracker );\n                } else {\n                    tracker = std::make_shared<GeneratorTracker>( nameAndLocation, ctx, &currentTracker );\n                    currentTracker.addChild( tracker );\n                }\n\n                if( !tracker->isComplete() ) {\n                    tracker->open();\n                }\n\n                return *tracker;\n            }\n\n            // TrackerBase interface\n            bool isGeneratorTracker() const override { return true; }\n            auto hasGenerator() const -> bool override {\n                return !!m_generator;\n            }\n            void close() override {\n                TrackerBase::close();\n                // If a generator has a child (it is followed by a section)\n                // and none of its children have started, then we must wait\n                // until later to start consuming its values.\n                // This catches cases where `GENERATE` is placed between two\n                // `SECTION`s.\n                // **The check for m_children.empty cannot be removed**.\n                // doing so would break `GENERATE` _not_ followed by `SECTION`s.\n                const bool should_wait_for_child = [&]() {\n                    // No children -> nobody to wait for\n                    if ( m_children.empty() ) {\n                        return false;\n                    }\n                    // If at least one child started executing, don't wait\n                    if ( std::find_if(\n                             m_children.begin(),\n                             m_children.end(),\n                             []( TestCaseTracking::ITrackerPtr tracker ) {\n                                 return tracker->hasStarted();\n                             } ) != m_children.end() ) {\n                        return false;\n                    }\n\n                    // No children have started. We need to check if they _can_\n                    // start, and thus we should wait for them, or they cannot\n                    // start (due to filters), and we shouldn't wait for them\n                    auto* parent = m_parent;\n                    // This is safe: there is always at least one section\n                    // tracker in a test case tracking tree\n                    while ( !parent->isSectionTracker() ) {\n                        parent = &( parent->parent() );\n                    }\n                    assert( parent &&\n                            \"Missing root (test case) level section\" );\n\n                    auto const& parentSection =\n                        static_cast<SectionTracker&>( *parent );\n                    auto const& filters = parentSection.getFilters();\n                    // No filters -> no restrictions on running sections\n                    if ( filters.empty() ) {\n                        return true;\n                    }\n\n                    for ( auto const& child : m_children ) {\n                        if ( child->isSectionTracker() &&\n                             std::find( filters.begin(),\n                                        filters.end(),\n                                        static_cast<SectionTracker&>( *child )\n                                            .trimmedName() ) !=\n                                 filters.end() ) {\n                            return true;\n                        }\n                    }\n                    return false;\n                }();\n\n                // This check is a bit tricky, because m_generator->next()\n                // has a side-effect, where it consumes generator's current\n                // value, but we do not want to invoke the side-effect if\n                // this generator is still waiting for any child to start.\n                if ( should_wait_for_child ||\n                     ( m_runState == CompletedSuccessfully &&\n                       m_generator->next() ) ) {\n                    m_children.clear();\n                    m_runState = Executing;\n                }\n            }\n\n            // IGeneratorTracker interface\n            auto getGenerator() const -> GeneratorBasePtr const& override {\n                return m_generator;\n            }\n            void setGenerator( GeneratorBasePtr&& generator ) override {\n                m_generator = std::move( generator );\n            }\n        };\n        GeneratorTracker::~GeneratorTracker() {}\n    }\n\n    RunContext::RunContext(IConfigPtr const& _config, IStreamingReporterPtr&& reporter)\n    :   m_runInfo(_config->name()),\n        m_context(getCurrentMutableContext()),\n        m_config(_config),\n        m_reporter(std::move(reporter)),\n        m_lastAssertionInfo{ StringRef(), SourceLineInfo(\"\",0), StringRef(), ResultDisposition::Normal },\n        m_includeSuccessfulResults( m_config->includeSuccessfulResults() || m_reporter->getPreferences().shouldReportAllAssertions )\n    {\n        m_context.setRunner(this);\n        m_context.setConfig(m_config);\n        m_context.setResultCapture(this);\n        m_reporter->testRunStarting(m_runInfo);\n    }\n\n    RunContext::~RunContext() {\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting()));\n    }\n\n    void RunContext::testGroupStarting(std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount));\n    }\n\n    void RunContext::testGroupEnded(std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount) {\n        m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting()));\n    }\n\n    Totals RunContext::runTest(TestCase const& testCase) {\n        Totals prevTotals = m_totals;\n\n        std::string redirectedCout;\n        std::string redirectedCerr;\n\n        auto const& testInfo = testCase.getTestCaseInfo();\n\n        m_reporter->testCaseStarting(testInfo);\n\n        m_activeTestCase = &testCase;\n\n        ITracker& rootTracker = m_trackerContext.startRun();\n        assert(rootTracker.isSectionTracker());\n        static_cast<SectionTracker&>(rootTracker).addInitialFilters(m_config->getSectionsToRun());\n        do {\n            m_trackerContext.startCycle();\n            m_testCaseTracker = &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo));\n            runCurrentTest(redirectedCout, redirectedCerr);\n        } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting());\n\n        Totals deltaTotals = m_totals.delta(prevTotals);\n        if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) {\n            deltaTotals.assertions.failed++;\n            deltaTotals.testCases.passed--;\n            deltaTotals.testCases.failed++;\n        }\n        m_totals.testCases += deltaTotals.testCases;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  redirectedCout,\n                                  redirectedCerr,\n                                  aborting()));\n\n        m_activeTestCase = nullptr;\n        m_testCaseTracker = nullptr;\n\n        return deltaTotals;\n    }\n\n    IConfigPtr RunContext::config() const {\n        return m_config;\n    }\n\n    IStreamingReporter& RunContext::reporter() const {\n        return *m_reporter;\n    }\n\n    void RunContext::assertionEnded(AssertionResult const & result) {\n        if (result.getResultType() == ResultWas::Ok) {\n            m_totals.assertions.passed++;\n            m_lastAssertionPassed = true;\n        } else if (!result.isOk()) {\n            m_lastAssertionPassed = false;\n            if( m_activeTestCase->getTestCaseInfo().okToFail() )\n                m_totals.assertions.failedButOk++;\n            else\n                m_totals.assertions.failed++;\n        }\n        else {\n            m_lastAssertionPassed = true;\n        }\n\n        // We have no use for the return value (whether messages should be cleared), because messages were made scoped\n        // and should be let to clear themselves out.\n        static_cast<void>(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals)));\n\n        if (result.getResultType() != ResultWas::Warning)\n            m_messageScopes.clear();\n\n        // Reset working state\n        resetAssertionInfo();\n        m_lastResult = result;\n    }\n    void RunContext::resetAssertionInfo() {\n        m_lastAssertionInfo.macroName = StringRef();\n        m_lastAssertionInfo.capturedExpression = \"{Unknown expression after the reported line}\"_sr;\n    }\n\n    bool RunContext::sectionStarted(SectionInfo const & sectionInfo, Counts & assertions) {\n        ITracker& sectionTracker = SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo));\n        if (!sectionTracker.isOpen())\n            return false;\n        m_activeSections.push_back(&sectionTracker);\n\n        m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo;\n\n        m_reporter->sectionStarting(sectionInfo);\n\n        assertions = m_totals.assertions;\n\n        return true;\n    }\n    auto RunContext::acquireGeneratorTracker( StringRef generatorName, SourceLineInfo const& lineInfo ) -> IGeneratorTracker& {\n        using namespace Generators;\n        GeneratorTracker& tracker = GeneratorTracker::acquire(m_trackerContext,\n                                                              TestCaseTracking::NameAndLocation( static_cast<std::string>(generatorName), lineInfo ) );\n        m_lastAssertionInfo.lineInfo = lineInfo;\n        return tracker;\n    }\n\n    bool RunContext::testForMissingAssertions(Counts& assertions) {\n        if (assertions.total() != 0)\n            return false;\n        if (!m_config->warnAboutMissingAssertions())\n            return false;\n        if (m_trackerContext.currentTracker().hasChildren())\n            return false;\n        m_totals.assertions.failed++;\n        assertions.failed++;\n        return true;\n    }\n\n    void RunContext::sectionEnded(SectionEndInfo const & endInfo) {\n        Counts assertions = m_totals.assertions - endInfo.prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        if (!m_activeSections.empty()) {\n            m_activeSections.back()->close();\n            m_activeSections.pop_back();\n        }\n\n        m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions));\n        m_messages.clear();\n        m_messageScopes.clear();\n    }\n\n    void RunContext::sectionEndedEarly(SectionEndInfo const & endInfo) {\n        if (m_unfinishedSections.empty())\n            m_activeSections.back()->fail();\n        else\n            m_activeSections.back()->close();\n        m_activeSections.pop_back();\n\n        m_unfinishedSections.push_back(endInfo);\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void RunContext::benchmarkPreparing(std::string const& name) {\n        m_reporter->benchmarkPreparing(name);\n    }\n    void RunContext::benchmarkStarting( BenchmarkInfo const& info ) {\n        m_reporter->benchmarkStarting( info );\n    }\n    void RunContext::benchmarkEnded( BenchmarkStats<> const& stats ) {\n        m_reporter->benchmarkEnded( stats );\n    }\n    void RunContext::benchmarkFailed(std::string const & error) {\n        m_reporter->benchmarkFailed(error);\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void RunContext::pushScopedMessage(MessageInfo const & message) {\n        m_messages.push_back(message);\n    }\n\n    void RunContext::popScopedMessage(MessageInfo const & message) {\n        m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end());\n    }\n\n    void RunContext::emplaceUnscopedMessage( MessageBuilder const& builder ) {\n        m_messageScopes.emplace_back( builder );\n    }\n\n    std::string RunContext::getCurrentTestName() const {\n        return m_activeTestCase\n            ? m_activeTestCase->getTestCaseInfo().name\n            : std::string();\n    }\n\n    const AssertionResult * RunContext::getLastResult() const {\n        return &(*m_lastResult);\n    }\n\n    void RunContext::exceptionEarlyReported() {\n        m_shouldReportUnexpected = false;\n    }\n\n    void RunContext::handleFatalErrorCondition( StringRef message ) {\n        // First notify reporter that bad things happened\n        m_reporter->fatalErrorEncountered(message);\n\n        // Don't rebuild the result -- the stringification itself can cause more fatal errors\n        // Instead, fake a result data.\n        AssertionResultData tempResult( ResultWas::FatalErrorCondition, { false } );\n        tempResult.message = static_cast<std::string>(message);\n        AssertionResult result(m_lastAssertionInfo, tempResult);\n\n        assertionEnded(result);\n\n        handleUnfinishedSections();\n\n        // Recreate section for test case (as we will lose the one that was in scope)\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n\n        Counts assertions;\n        assertions.failed = 1;\n        SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false);\n        m_reporter->sectionEnded(testCaseSectionStats);\n\n        auto const& testInfo = m_activeTestCase->getTestCaseInfo();\n\n        Totals deltaTotals;\n        deltaTotals.testCases.failed = 1;\n        deltaTotals.assertions.failed = 1;\n        m_reporter->testCaseEnded(TestCaseStats(testInfo,\n                                  deltaTotals,\n                                  std::string(),\n                                  std::string(),\n                                  false));\n        m_totals.testCases.failed++;\n        testGroupEnded(std::string(), m_totals, 1, 1);\n        m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false));\n    }\n\n    bool RunContext::lastAssertionPassed() {\n         return m_lastAssertionPassed;\n    }\n\n    void RunContext::assertionPassed() {\n        m_lastAssertionPassed = true;\n        ++m_totals.assertions.passed;\n        resetAssertionInfo();\n        m_messageScopes.clear();\n    }\n\n    bool RunContext::aborting() const {\n        return m_totals.assertions.failed >= static_cast<std::size_t>(m_config->abortAfter());\n    }\n\n    void RunContext::runCurrentTest(std::string & redirectedCout, std::string & redirectedCerr) {\n        auto const& testCaseInfo = m_activeTestCase->getTestCaseInfo();\n        SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name);\n        m_reporter->sectionStarting(testCaseSection);\n        Counts prevAssertions = m_totals.assertions;\n        double duration = 0;\n        m_shouldReportUnexpected = true;\n        m_lastAssertionInfo = { \"TEST_CASE\"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal };\n\n        seedRng(*m_config);\n\n        Timer timer;\n        CATCH_TRY {\n            if (m_reporter->getPreferences().shouldRedirectStdOut) {\n#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT)\n                RedirectedStreams redirectedStreams(redirectedCout, redirectedCerr);\n\n                timer.start();\n                invokeActiveTestCase();\n#else\n                OutputRedirect r(redirectedCout, redirectedCerr);\n                timer.start();\n                invokeActiveTestCase();\n#endif\n            } else {\n                timer.start();\n                invokeActiveTestCase();\n            }\n            duration = timer.getElapsedSeconds();\n        } CATCH_CATCH_ANON (TestFailureException&) {\n            // This just means the test was aborted due to failure\n        } CATCH_CATCH_ALL {\n            // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions\n            // are reported without translation at the point of origin.\n            if( m_shouldReportUnexpected ) {\n                AssertionReaction dummyReaction;\n                handleUnexpectedInflightException( m_lastAssertionInfo, translateActiveException(), dummyReaction );\n            }\n        }\n        Counts assertions = m_totals.assertions - prevAssertions;\n        bool missingAssertions = testForMissingAssertions(assertions);\n\n        m_testCaseTracker->close();\n        handleUnfinishedSections();\n        m_messages.clear();\n        m_messageScopes.clear();\n\n        SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions);\n        m_reporter->sectionEnded(testCaseSectionStats);\n    }\n\n    void RunContext::invokeActiveTestCase() {\n        FatalConditionHandlerGuard _(&m_fatalConditionhandler);\n        m_activeTestCase->invoke();\n    }\n\n    void RunContext::handleUnfinishedSections() {\n        // If sections ended prematurely due to an exception we stored their\n        // infos here so we can tear them down outside the unwind process.\n        for (auto it = m_unfinishedSections.rbegin(),\n             itEnd = m_unfinishedSections.rend();\n             it != itEnd;\n             ++it)\n            sectionEnded(*it);\n        m_unfinishedSections.clear();\n    }\n\n    void RunContext::handleExpr(\n        AssertionInfo const& info,\n        ITransientExpression const& expr,\n        AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        bool negated = isFalseTest( info.resultDisposition );\n        bool result = expr.getResult() != negated;\n\n        if( result ) {\n            if (!m_includeSuccessfulResults) {\n                assertionPassed();\n            }\n            else {\n                reportExpr(info, ResultWas::Ok, &expr, negated);\n            }\n        }\n        else {\n            reportExpr(info, ResultWas::ExpressionFailed, &expr, negated );\n            populateReaction( reaction );\n        }\n    }\n    void RunContext::reportExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            ITransientExpression const *expr,\n            bool negated ) {\n\n        m_lastAssertionInfo = info;\n        AssertionResultData data( resultType, LazyExpression( negated ) );\n\n        AssertionResult assertionResult{ info, data };\n        assertionResult.m_resultData.lazyExpression.m_transientExpression = expr;\n\n        assertionEnded( assertionResult );\n    }\n\n    void RunContext::handleMessage(\n            AssertionInfo const& info,\n            ResultWas::OfType resultType,\n            StringRef const& message,\n            AssertionReaction& reaction\n    ) {\n        m_reporter->assertionStarting( info );\n\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        data.message = static_cast<std::string>(message);\n        AssertionResult assertionResult{ m_lastAssertionInfo, data };\n        assertionEnded( assertionResult );\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n    void RunContext::handleUnexpectedExceptionNotThrown(\n            AssertionInfo const& info,\n            AssertionReaction& reaction\n    ) {\n        handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction);\n    }\n\n    void RunContext::handleUnexpectedInflightException(\n            AssertionInfo const& info,\n            std::string const& message,\n            AssertionReaction& reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = message;\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n        populateReaction( reaction );\n    }\n\n    void RunContext::populateReaction( AssertionReaction& reaction ) {\n        reaction.shouldDebugBreak = m_config->shouldDebugBreak();\n        reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal);\n    }\n\n    void RunContext::handleIncomplete(\n            AssertionInfo const& info\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( ResultWas::ThrewException, LazyExpression( false ) );\n        data.message = \"Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE\";\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n    }\n    void RunContext::handleNonExpr(\n            AssertionInfo const &info,\n            ResultWas::OfType resultType,\n            AssertionReaction &reaction\n    ) {\n        m_lastAssertionInfo = info;\n\n        AssertionResultData data( resultType, LazyExpression( false ) );\n        AssertionResult assertionResult{ info, data };\n        assertionEnded( assertionResult );\n\n        if( !assertionResult.isOk() )\n            populateReaction( reaction );\n    }\n\n    IResultCapture& getResultCapture() {\n        if (auto* capture = getCurrentContext().getResultCapture())\n            return *capture;\n        else\n            CATCH_INTERNAL_ERROR(\"No result capture instance\");\n    }\n\n    void seedRng(IConfig const& config) {\n        if (config.rngSeed() != 0) {\n            std::srand(config.rngSeed());\n            rng().seed(config.rngSeed());\n        }\n    }\n\n    unsigned int rngSeed() {\n        return getCurrentContext().getConfig()->rngSeed();\n    }\n\n}\n// end catch_run_context.cpp\n// start catch_section.cpp\n\nnamespace Catch {\n\n    Section::Section( SectionInfo const& info )\n    :   m_info( info ),\n        m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) )\n    {\n        m_timer.start();\n    }\n\n    Section::~Section() {\n        if( m_sectionIncluded ) {\n            SectionEndInfo endInfo{ m_info, m_assertions, m_timer.getElapsedSeconds() };\n            if( uncaught_exceptions() )\n                getResultCapture().sectionEndedEarly( endInfo );\n            else\n                getResultCapture().sectionEnded( endInfo );\n        }\n    }\n\n    // This indicates whether the section should be executed or not\n    Section::operator bool() const {\n        return m_sectionIncluded;\n    }\n\n} // end namespace Catch\n// end catch_section.cpp\n// start catch_section_info.cpp\n\nnamespace Catch {\n\n    SectionInfo::SectionInfo\n        (   SourceLineInfo const& _lineInfo,\n            std::string const& _name )\n    :   name( _name ),\n        lineInfo( _lineInfo )\n    {}\n\n} // end namespace Catch\n// end catch_section_info.cpp\n// start catch_session.cpp\n\n// start catch_session.h\n\n#include <memory>\n\nnamespace Catch {\n\n    class Session : NonCopyable {\n    public:\n\n        Session();\n        ~Session() override;\n\n        void showHelp() const;\n        void libIdentify();\n\n        int applyCommandLine( int argc, char const * const * argv );\n    #if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n        int applyCommandLine( int argc, wchar_t const * const * argv );\n    #endif\n\n        void useConfigData( ConfigData const& configData );\n\n        template<typename CharT>\n        int run(int argc, CharT const * const argv[]) {\n            if (m_startupExceptions)\n                return 1;\n            int returnCode = applyCommandLine(argc, argv);\n            if (returnCode == 0)\n                returnCode = run();\n            return returnCode;\n        }\n\n        int run();\n\n        clara::Parser const& cli() const;\n        void cli( clara::Parser const& newParser );\n        ConfigData& configData();\n        Config& config();\n    private:\n        int runInternal();\n\n        clara::Parser m_cli;\n        ConfigData m_configData;\n        std::shared_ptr<Config> m_config;\n        bool m_startupExceptions = false;\n    };\n\n} // end namespace Catch\n\n// end catch_session.h\n// start catch_version.h\n\n#include <iosfwd>\n\nnamespace Catch {\n\n    // Versioning information\n    struct Version {\n        Version( Version const& ) = delete;\n        Version& operator=( Version const& ) = delete;\n        Version(    unsigned int _majorVersion,\n                    unsigned int _minorVersion,\n                    unsigned int _patchNumber,\n                    char const * const _branchName,\n                    unsigned int _buildNumber );\n\n        unsigned int const majorVersion;\n        unsigned int const minorVersion;\n        unsigned int const patchNumber;\n\n        // buildNumber is only used if branchName is not null\n        char const * const branchName;\n        unsigned int const buildNumber;\n\n        friend std::ostream& operator << ( std::ostream& os, Version const& version );\n    };\n\n    Version const& libraryVersion();\n}\n\n// end catch_version.h\n#include <cstdlib>\n#include <iomanip>\n#include <set>\n#include <iterator>\n\nnamespace Catch {\n\n    namespace {\n        const int MaxExitCode = 255;\n\n        IStreamingReporterPtr createReporter(std::string const& reporterName, IConfigPtr const& config) {\n            auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config);\n            CATCH_ENFORCE(reporter, \"No reporter registered with name: '\" << reporterName << \"'\");\n\n            return reporter;\n        }\n\n        IStreamingReporterPtr makeReporter(std::shared_ptr<Config> const& config) {\n            if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) {\n                return createReporter(config->getReporterName(), config);\n            }\n\n            // On older platforms, returning std::unique_ptr<ListeningReporter>\n            // when the return type is std::unique_ptr<IStreamingReporter>\n            // doesn't compile without a std::move call. However, this causes\n            // a warning on newer platforms. Thus, we have to work around\n            // it a bit and downcast the pointer manually.\n            auto ret = std::unique_ptr<IStreamingReporter>(new ListeningReporter);\n            auto& multi = static_cast<ListeningReporter&>(*ret);\n            auto const& listeners = Catch::getRegistryHub().getReporterRegistry().getListeners();\n            for (auto const& listener : listeners) {\n                multi.addListener(listener->create(Catch::ReporterConfig(config)));\n            }\n            multi.addReporter(createReporter(config->getReporterName(), config));\n            return ret;\n        }\n\n        class TestGroup {\n        public:\n            explicit TestGroup(std::shared_ptr<Config> const& config)\n            : m_config{config}\n            , m_context{config, makeReporter(config)}\n            {\n                auto const& allTestCases = getAllTestCasesSorted(*m_config);\n                m_matches = m_config->testSpec().matchesByFilter(allTestCases, *m_config);\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n\n                if (m_matches.empty() && invalidArgs.empty()) {\n                    for (auto const& test : allTestCases)\n                        if (!test.isHidden())\n                            m_tests.emplace(&test);\n                } else {\n                    for (auto const& match : m_matches)\n                        m_tests.insert(match.tests.begin(), match.tests.end());\n                }\n            }\n\n            Totals execute() {\n                auto const& invalidArgs = m_config->testSpec().getInvalidArgs();\n                Totals totals;\n                m_context.testGroupStarting(m_config->name(), 1, 1);\n                for (auto const& testCase : m_tests) {\n                    if (!m_context.aborting())\n                        totals += m_context.runTest(*testCase);\n                    else\n                        m_context.reporter().skipTest(*testCase);\n                }\n\n                for (auto const& match : m_matches) {\n                    if (match.tests.empty()) {\n                        m_context.reporter().noMatchingTestCases(match.name);\n                        totals.error = -1;\n                    }\n                }\n\n                if (!invalidArgs.empty()) {\n                    for (auto const& invalidArg: invalidArgs)\n                         m_context.reporter().reportInvalidArguments(invalidArg);\n                }\n\n                m_context.testGroupEnded(m_config->name(), totals, 1, 1);\n                return totals;\n            }\n\n        private:\n            using Tests = std::set<TestCase const*>;\n\n            std::shared_ptr<Config> m_config;\n            RunContext m_context;\n            Tests m_tests;\n            TestSpec::Matches m_matches;\n        };\n\n        void applyFilenamesAsTags(Catch::IConfig const& config) {\n            auto& tests = const_cast<std::vector<TestCase>&>(getAllTestCasesSorted(config));\n            for (auto& testCase : tests) {\n                auto tags = testCase.tags;\n\n                std::string filename = testCase.lineInfo.file;\n                auto lastSlash = filename.find_last_of(\"\\\\/\");\n                if (lastSlash != std::string::npos) {\n                    filename.erase(0, lastSlash);\n                    filename[0] = '#';\n                }\n                else\n                {\n                    filename.insert(0, \"#\");\n                }\n\n                auto lastDot = filename.find_last_of('.');\n                if (lastDot != std::string::npos) {\n                    filename.erase(lastDot);\n                }\n\n                tags.push_back(std::move(filename));\n                setTags(testCase, tags);\n            }\n        }\n\n    } // anon namespace\n\n    Session::Session() {\n        static bool alreadyInstantiated = false;\n        if( alreadyInstantiated ) {\n            CATCH_TRY { CATCH_INTERNAL_ERROR( \"Only one instance of Catch::Session can ever be used\" ); }\n            CATCH_CATCH_ALL { getMutableRegistryHub().registerStartupException(); }\n        }\n\n        // There cannot be exceptions at startup in no-exception mode.\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        const auto& exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions();\n        if ( !exceptions.empty() ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n\n            m_startupExceptions = true;\n            Colour colourGuard( Colour::Red );\n            Catch::cerr() << \"Errors occurred during startup!\" << '\\n';\n            // iterate over all exceptions and notify user\n            for ( const auto& ex_ptr : exceptions ) {\n                try {\n                    std::rethrow_exception(ex_ptr);\n                } catch ( std::exception const& ex ) {\n                    Catch::cerr() << Column( ex.what() ).indent(2) << '\\n';\n                }\n            }\n        }\n#endif\n\n        alreadyInstantiated = true;\n        m_cli = makeCommandLineParser( m_configData );\n    }\n    Session::~Session() {\n        Catch::cleanUp();\n    }\n\n    void Session::showHelp() const {\n        Catch::cout()\n                << \"\\nCatch v\" << libraryVersion() << \"\\n\"\n                << m_cli << std::endl\n                << \"For more detailed usage please see the project docs\\n\" << std::endl;\n    }\n    void Session::libIdentify() {\n        Catch::cout()\n                << std::left << std::setw(16) << \"description: \" << \"A Catch2 test executable\\n\"\n                << std::left << std::setw(16) << \"category: \" << \"testframework\\n\"\n                << std::left << std::setw(16) << \"framework: \" << \"Catch Test\\n\"\n                << std::left << std::setw(16) << \"version: \" << libraryVersion() << std::endl;\n    }\n\n    int Session::applyCommandLine( int argc, char const * const * argv ) {\n        if( m_startupExceptions )\n            return 1;\n\n        auto result = m_cli.parse( clara::Args( argc, argv ) );\n        if( !result ) {\n            config();\n            getCurrentMutableContext().setConfig(m_config);\n            Catch::cerr()\n                << Colour( Colour::Red )\n                << \"\\nError(s) in input:\\n\"\n                << Column( result.errorMessage() ).indent( 2 )\n                << \"\\n\\n\";\n            Catch::cerr() << \"Run with -? for usage\\n\" << std::endl;\n            return MaxExitCode;\n        }\n\n        if( m_configData.showHelp )\n            showHelp();\n        if( m_configData.libIdentify )\n            libIdentify();\n        m_config.reset();\n        return 0;\n    }\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(_WIN32) && defined(UNICODE)\n    int Session::applyCommandLine( int argc, wchar_t const * const * argv ) {\n\n        char **utf8Argv = new char *[ argc ];\n\n        for ( int i = 0; i < argc; ++i ) {\n            int bufSize = WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, nullptr, 0, nullptr, nullptr );\n\n            utf8Argv[ i ] = new char[ bufSize ];\n\n            WideCharToMultiByte( CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, nullptr, nullptr );\n        }\n\n        int returnCode = applyCommandLine( argc, utf8Argv );\n\n        for ( int i = 0; i < argc; ++i )\n            delete [] utf8Argv[ i ];\n\n        delete [] utf8Argv;\n\n        return returnCode;\n    }\n#endif\n\n    void Session::useConfigData( ConfigData const& configData ) {\n        m_configData = configData;\n        m_config.reset();\n    }\n\n    int Session::run() {\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeStart ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before starting\" << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        int exitCode = runInternal();\n        if( ( m_configData.waitForKeypress & WaitForKeypress::BeforeExit ) != 0 ) {\n            Catch::cout() << \"...waiting for enter/ return before exiting, with code: \" << exitCode << std::endl;\n            static_cast<void>(std::getchar());\n        }\n        return exitCode;\n    }\n\n    clara::Parser const& Session::cli() const {\n        return m_cli;\n    }\n    void Session::cli( clara::Parser const& newParser ) {\n        m_cli = newParser;\n    }\n    ConfigData& Session::configData() {\n        return m_configData;\n    }\n    Config& Session::config() {\n        if( !m_config )\n            m_config = std::make_shared<Config>( m_configData );\n        return *m_config;\n    }\n\n    int Session::runInternal() {\n        if( m_startupExceptions )\n            return 1;\n\n        if (m_configData.showHelp || m_configData.libIdentify) {\n            return 0;\n        }\n\n        CATCH_TRY {\n            config(); // Force config to be constructed\n\n            seedRng( *m_config );\n\n            if( m_configData.filenamesAsTags )\n                applyFilenamesAsTags( *m_config );\n\n            // Handle list request\n            if( Option<std::size_t> listed = list( m_config ) )\n                return static_cast<int>( *listed );\n\n            TestGroup tests { m_config };\n            auto const totals = tests.execute();\n\n            if( m_config->warnAboutNoTests() && totals.error == -1 )\n                return 2;\n\n            // Note that on unices only the lower 8 bits are usually used, clamping\n            // the return value to 255 prevents false negative when some multiple\n            // of 256 tests has failed\n            return (std::min) (MaxExitCode, (std::max) (totals.error, static_cast<int>(totals.assertions.failed)));\n        }\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        catch( std::exception& ex ) {\n            Catch::cerr() << ex.what() << std::endl;\n            return MaxExitCode;\n        }\n#endif\n    }\n\n} // end namespace Catch\n// end catch_session.cpp\n// start catch_singletons.cpp\n\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        static auto getSingletons() -> std::vector<ISingleton*>*& {\n            static std::vector<ISingleton*>* g_singletons = nullptr;\n            if( !g_singletons )\n                g_singletons = new std::vector<ISingleton*>();\n            return g_singletons;\n        }\n    }\n\n    ISingleton::~ISingleton() {}\n\n    void addSingleton(ISingleton* singleton ) {\n        getSingletons()->push_back( singleton );\n    }\n    void cleanupSingletons() {\n        auto& singletons = getSingletons();\n        for( auto singleton : *singletons )\n            delete singleton;\n        delete singletons;\n        singletons = nullptr;\n    }\n\n} // namespace Catch\n// end catch_singletons.cpp\n// start catch_startup_exception_registry.cpp\n\n#if !defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\nnamespace Catch {\nvoid StartupExceptionRegistry::add( std::exception_ptr const& exception ) noexcept {\n        CATCH_TRY {\n            m_exceptions.push_back(exception);\n        } CATCH_CATCH_ALL {\n            // If we run out of memory during start-up there's really not a lot more we can do about it\n            std::terminate();\n        }\n    }\n\n    std::vector<std::exception_ptr> const& StartupExceptionRegistry::getExceptions() const noexcept {\n        return m_exceptions;\n    }\n\n} // end namespace Catch\n#endif\n// end catch_startup_exception_registry.cpp\n// start catch_stream.cpp\n\n#include <cstdio>\n#include <iostream>\n#include <fstream>\n#include <sstream>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    Catch::IStream::~IStream() = default;\n\n    namespace Detail { namespace {\n        template<typename WriterF, std::size_t bufferSize=256>\n        class StreamBufImpl : public std::streambuf {\n            char data[bufferSize];\n            WriterF m_writer;\n\n        public:\n            StreamBufImpl() {\n                setp( data, data + sizeof(data) );\n            }\n\n            ~StreamBufImpl() noexcept {\n                StreamBufImpl::sync();\n            }\n\n        private:\n            int overflow( int c ) override {\n                sync();\n\n                if( c != EOF ) {\n                    if( pbase() == epptr() )\n                        m_writer( std::string( 1, static_cast<char>( c ) ) );\n                    else\n                        sputc( static_cast<char>( c ) );\n                }\n                return 0;\n            }\n\n            int sync() override {\n                if( pbase() != pptr() ) {\n                    m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) );\n                    setp( pbase(), epptr() );\n                }\n                return 0;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        struct OutputDebugWriter {\n\n            void operator()( std::string const&str ) {\n                writeToDebugConsole( str );\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class FileStream : public IStream {\n            mutable std::ofstream m_ofs;\n        public:\n            FileStream( StringRef filename ) {\n                m_ofs.open( filename.c_str() );\n                CATCH_ENFORCE( !m_ofs.fail(), \"Unable to open file: '\" << filename << \"'\" );\n            }\n            ~FileStream() override = default;\n        public: // IStream\n            std::ostream& stream() const override {\n                return m_ofs;\n            }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class CoutStream : public IStream {\n            mutable std::ostream m_os;\n        public:\n            // Store the streambuf from cout up-front because\n            // cout may get redirected when running tests\n            CoutStream() : m_os( Catch::cout().rdbuf() ) {}\n            ~CoutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n        ///////////////////////////////////////////////////////////////////////////\n\n        class DebugOutStream : public IStream {\n            std::unique_ptr<StreamBufImpl<OutputDebugWriter>> m_streamBuf;\n            mutable std::ostream m_os;\n        public:\n            DebugOutStream()\n            :   m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ),\n                m_os( m_streamBuf.get() )\n            {}\n\n            ~DebugOutStream() override = default;\n\n        public: // IStream\n            std::ostream& stream() const override { return m_os; }\n        };\n\n    }} // namespace anon::detail\n\n    ///////////////////////////////////////////////////////////////////////////\n\n    auto makeStream( StringRef const &filename ) -> IStream const* {\n        if( filename.empty() )\n            return new Detail::CoutStream();\n        else if( filename[0] == '%' ) {\n            if( filename == \"%debug\" )\n                return new Detail::DebugOutStream();\n            else\n                CATCH_ERROR( \"Unrecognised stream: '\" << filename << \"'\" );\n        }\n        else\n            return new Detail::FileStream( filename );\n    }\n\n    // This class encapsulates the idea of a pool of ostringstreams that can be reused.\n    struct StringStreams {\n        std::vector<std::unique_ptr<std::ostringstream>> m_streams;\n        std::vector<std::size_t> m_unused;\n        std::ostringstream m_referenceStream; // Used for copy state/ flags from\n\n        auto add() -> std::size_t {\n            if( m_unused.empty() ) {\n                m_streams.push_back( std::unique_ptr<std::ostringstream>( new std::ostringstream ) );\n                return m_streams.size()-1;\n            }\n            else {\n                auto index = m_unused.back();\n                m_unused.pop_back();\n                return index;\n            }\n        }\n\n        void release( std::size_t index ) {\n            m_streams[index]->copyfmt( m_referenceStream ); // Restore initial flags and other state\n            m_unused.push_back(index);\n        }\n    };\n\n    ReusableStringStream::ReusableStringStream()\n    :   m_index( Singleton<StringStreams>::getMutable().add() ),\n        m_oss( Singleton<StringStreams>::getMutable().m_streams[m_index].get() )\n    {}\n\n    ReusableStringStream::~ReusableStringStream() {\n        static_cast<std::ostringstream*>( m_oss )->str(\"\");\n        m_oss->clear();\n        Singleton<StringStreams>::getMutable().release( m_index );\n    }\n\n    auto ReusableStringStream::str() const -> std::string {\n        return static_cast<std::ostringstream*>( m_oss )->str();\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n\n#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions\n    std::ostream& cout() { return std::cout; }\n    std::ostream& cerr() { return std::cerr; }\n    std::ostream& clog() { return std::clog; }\n#endif\n}\n// end catch_stream.cpp\n// start catch_string_manip.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cctype>\n#include <vector>\n\nnamespace Catch {\n\n    namespace {\n        char toLowerCh(char c) {\n            return static_cast<char>( std::tolower( static_cast<unsigned char>(c) ) );\n        }\n    }\n\n    bool startsWith( std::string const& s, std::string const& prefix ) {\n        return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin());\n    }\n    bool startsWith( std::string const& s, char prefix ) {\n        return !s.empty() && s[0] == prefix;\n    }\n    bool endsWith( std::string const& s, std::string const& suffix ) {\n        return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());\n    }\n    bool endsWith( std::string const& s, char suffix ) {\n        return !s.empty() && s[s.size()-1] == suffix;\n    }\n    bool contains( std::string const& s, std::string const& infix ) {\n        return s.find( infix ) != std::string::npos;\n    }\n    void toLowerInPlace( std::string& s ) {\n        std::transform( s.begin(), s.end(), s.begin(), toLowerCh );\n    }\n    std::string toLower( std::string const& s ) {\n        std::string lc = s;\n        toLowerInPlace( lc );\n        return lc;\n    }\n    std::string trim( std::string const& str ) {\n        static char const* whitespaceChars = \"\\n\\r\\t \";\n        std::string::size_type start = str.find_first_not_of( whitespaceChars );\n        std::string::size_type end = str.find_last_not_of( whitespaceChars );\n\n        return start != std::string::npos ? str.substr( start, 1+end-start ) : std::string();\n    }\n\n    StringRef trim(StringRef ref) {\n        const auto is_ws = [](char c) {\n            return c == ' ' || c == '\\t' || c == '\\n' || c == '\\r';\n        };\n        size_t real_begin = 0;\n        while (real_begin < ref.size() && is_ws(ref[real_begin])) { ++real_begin; }\n        size_t real_end = ref.size();\n        while (real_end > real_begin && is_ws(ref[real_end - 1])) { --real_end; }\n\n        return ref.substr(real_begin, real_end - real_begin);\n    }\n\n    bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) {\n        bool replaced = false;\n        std::size_t i = str.find( replaceThis );\n        while( i != std::string::npos ) {\n            replaced = true;\n            str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() );\n            if( i < str.size()-withThis.size() )\n                i = str.find( replaceThis, i+withThis.size() );\n            else\n                i = std::string::npos;\n        }\n        return replaced;\n    }\n\n    std::vector<StringRef> splitStringRef( StringRef str, char delimiter ) {\n        std::vector<StringRef> subStrings;\n        std::size_t start = 0;\n        for(std::size_t pos = 0; pos < str.size(); ++pos ) {\n            if( str[pos] == delimiter ) {\n                if( pos - start > 1 )\n                    subStrings.push_back( str.substr( start, pos-start ) );\n                start = pos+1;\n            }\n        }\n        if( start < str.size() )\n            subStrings.push_back( str.substr( start, str.size()-start ) );\n        return subStrings;\n    }\n\n    pluralise::pluralise( std::size_t count, std::string const& label )\n    :   m_count( count ),\n        m_label( label )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) {\n        os << pluraliser.m_count << ' ' << pluraliser.m_label;\n        if( pluraliser.m_count != 1 )\n            os << 's';\n        return os;\n    }\n\n}\n// end catch_string_manip.cpp\n// start catch_stringref.cpp\n\n#include <algorithm>\n#include <ostream>\n#include <cstring>\n#include <cstdint>\n\nnamespace Catch {\n    StringRef::StringRef( char const* rawChars ) noexcept\n    : StringRef( rawChars, static_cast<StringRef::size_type>(std::strlen(rawChars) ) )\n    {}\n\n    auto StringRef::c_str() const -> char const* {\n        CATCH_ENFORCE(isNullTerminated(), \"Called StringRef::c_str() on a non-null-terminated instance\");\n        return m_start;\n    }\n    auto StringRef::data() const noexcept -> char const* {\n        return m_start;\n    }\n\n    auto StringRef::substr( size_type start, size_type size ) const noexcept -> StringRef {\n        if (start < m_size) {\n            return StringRef(m_start + start, (std::min)(m_size - start, size));\n        } else {\n            return StringRef();\n        }\n    }\n    auto StringRef::operator == ( StringRef const& other ) const noexcept -> bool {\n        return m_size == other.m_size\n            && (std::memcmp( m_start, other.m_start, m_size ) == 0);\n    }\n\n    auto operator << ( std::ostream& os, StringRef const& str ) -> std::ostream& {\n        return os.write(str.data(), str.size());\n    }\n\n    auto operator+=( std::string& lhs, StringRef const& rhs ) -> std::string& {\n        lhs.append(rhs.data(), rhs.size());\n        return lhs;\n    }\n\n} // namespace Catch\n// end catch_stringref.cpp\n// start catch_tag_alias.cpp\n\nnamespace Catch {\n    TagAlias::TagAlias(std::string const & _tag, SourceLineInfo _lineInfo): tag(_tag), lineInfo(_lineInfo) {}\n}\n// end catch_tag_alias.cpp\n// start catch_tag_alias_autoregistrar.cpp\n\nnamespace Catch {\n\n    RegistrarForTagAliases::RegistrarForTagAliases(char const* alias, char const* tag, SourceLineInfo const& lineInfo) {\n        CATCH_TRY {\n            getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo);\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n}\n// end catch_tag_alias_autoregistrar.cpp\n// start catch_tag_alias_registry.cpp\n\n#include <sstream>\n\nnamespace Catch {\n\n    TagAliasRegistry::~TagAliasRegistry() {}\n\n    TagAlias const* TagAliasRegistry::find( std::string const& alias ) const {\n        auto it = m_registry.find( alias );\n        if( it != m_registry.end() )\n            return &(it->second);\n        else\n            return nullptr;\n    }\n\n    std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const {\n        std::string expandedTestSpec = unexpandedTestSpec;\n        for( auto const& registryKvp : m_registry ) {\n            std::size_t pos = expandedTestSpec.find( registryKvp.first );\n            if( pos != std::string::npos ) {\n                expandedTestSpec =  expandedTestSpec.substr( 0, pos ) +\n                                    registryKvp.second.tag +\n                                    expandedTestSpec.substr( pos + registryKvp.first.size() );\n            }\n        }\n        return expandedTestSpec;\n    }\n\n    void TagAliasRegistry::add( std::string const& alias, std::string const& tag, SourceLineInfo const& lineInfo ) {\n        CATCH_ENFORCE( startsWith(alias, \"[@\") && endsWith(alias, ']'),\n                      \"error: tag alias, '\" << alias << \"' is not of the form [@alias name].\\n\" << lineInfo );\n\n        CATCH_ENFORCE( m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second,\n                      \"error: tag alias, '\" << alias << \"' already registered.\\n\"\n                      << \"\\tFirst seen at: \" << find(alias)->lineInfo << \"\\n\"\n                      << \"\\tRedefined at: \" << lineInfo );\n    }\n\n    ITagAliasRegistry::~ITagAliasRegistry() {}\n\n    ITagAliasRegistry const& ITagAliasRegistry::get() {\n        return getRegistryHub().getTagAliasRegistry();\n    }\n\n} // end namespace Catch\n// end catch_tag_alias_registry.cpp\n// start catch_test_case_info.cpp\n\n#include <cctype>\n#include <exception>\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) {\n            if( startsWith( tag, '.' ) ||\n                tag == \"!hide\" )\n                return TestCaseInfo::IsHidden;\n            else if( tag == \"!throws\" )\n                return TestCaseInfo::Throws;\n            else if( tag == \"!shouldfail\" )\n                return TestCaseInfo::ShouldFail;\n            else if( tag == \"!mayfail\" )\n                return TestCaseInfo::MayFail;\n            else if( tag == \"!nonportable\" )\n                return TestCaseInfo::NonPortable;\n            else if( tag == \"!benchmark\" )\n                return static_cast<TestCaseInfo::SpecialProperties>( TestCaseInfo::Benchmark | TestCaseInfo::IsHidden );\n            else\n                return TestCaseInfo::None;\n        }\n        bool isReservedTag( std::string const& tag ) {\n            return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !std::isalnum( static_cast<unsigned char>(tag[0]) );\n        }\n        void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) {\n            CATCH_ENFORCE( !isReservedTag(tag),\n                          \"Tag name: [\" << tag << \"] is not allowed.\\n\"\n                          << \"Tag names starting with non alphanumeric characters are reserved\\n\"\n                          << _lineInfo );\n        }\n    }\n\n    TestCase makeTestCase(  ITestInvoker* _testCase,\n                            std::string const& _className,\n                            NameAndTags const& nameAndTags,\n                            SourceLineInfo const& _lineInfo )\n    {\n        bool isHidden = false;\n\n        // Parse out tags\n        std::vector<std::string> tags;\n        std::string desc, tag;\n        bool inTag = false;\n        for (char c : nameAndTags.tags) {\n            if( !inTag ) {\n                if( c == '[' )\n                    inTag = true;\n                else\n                    desc += c;\n            }\n            else {\n                if( c == ']' ) {\n                    TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag );\n                    if( ( prop & TestCaseInfo::IsHidden ) != 0 )\n                        isHidden = true;\n                    else if( prop == TestCaseInfo::None )\n                        enforceNotReservedTag( tag, _lineInfo );\n\n                    // Merged hide tags like `[.approvals]` should be added as\n                    // `[.][approvals]`. The `[.]` is added at later point, so\n                    // we only strip the prefix\n                    if (startsWith(tag, '.') && tag.size() > 1) {\n                        tag.erase(0, 1);\n                    }\n                    tags.push_back( tag );\n                    tag.clear();\n                    inTag = false;\n                }\n                else\n                    tag += c;\n            }\n        }\n        if( isHidden ) {\n            // Add all \"hidden\" tags to make them behave identically\n            tags.insert( tags.end(), { \".\", \"!hide\" } );\n        }\n\n        TestCaseInfo info( static_cast<std::string>(nameAndTags.name), _className, desc, tags, _lineInfo );\n        return TestCase( _testCase, std::move(info) );\n    }\n\n    void setTags( TestCaseInfo& testCaseInfo, std::vector<std::string> tags ) {\n        std::sort(begin(tags), end(tags));\n        tags.erase(std::unique(begin(tags), end(tags)), end(tags));\n        testCaseInfo.lcaseTags.clear();\n\n        for( auto const& tag : tags ) {\n            std::string lcaseTag = toLower( tag );\n            testCaseInfo.properties = static_cast<TestCaseInfo::SpecialProperties>( testCaseInfo.properties | parseSpecialTag( lcaseTag ) );\n            testCaseInfo.lcaseTags.push_back( lcaseTag );\n        }\n        testCaseInfo.tags = std::move(tags);\n    }\n\n    TestCaseInfo::TestCaseInfo( std::string const& _name,\n                                std::string const& _className,\n                                std::string const& _description,\n                                std::vector<std::string> const& _tags,\n                                SourceLineInfo const& _lineInfo )\n    :   name( _name ),\n        className( _className ),\n        description( _description ),\n        lineInfo( _lineInfo ),\n        properties( None )\n    {\n        setTags( *this, _tags );\n    }\n\n    bool TestCaseInfo::isHidden() const {\n        return ( properties & IsHidden ) != 0;\n    }\n    bool TestCaseInfo::throws() const {\n        return ( properties & Throws ) != 0;\n    }\n    bool TestCaseInfo::okToFail() const {\n        return ( properties & (ShouldFail | MayFail ) ) != 0;\n    }\n    bool TestCaseInfo::expectedToFail() const {\n        return ( properties & (ShouldFail ) ) != 0;\n    }\n\n    std::string TestCaseInfo::tagsAsString() const {\n        std::string ret;\n        // '[' and ']' per tag\n        std::size_t full_size = 2 * tags.size();\n        for (const auto& tag : tags) {\n            full_size += tag.size();\n        }\n        ret.reserve(full_size);\n        for (const auto& tag : tags) {\n            ret.push_back('[');\n            ret.append(tag);\n            ret.push_back(']');\n        }\n\n        return ret;\n    }\n\n    TestCase::TestCase( ITestInvoker* testCase, TestCaseInfo&& info ) : TestCaseInfo( std::move(info) ), test( testCase ) {}\n\n    TestCase TestCase::withName( std::string const& _newName ) const {\n        TestCase other( *this );\n        other.name = _newName;\n        return other;\n    }\n\n    void TestCase::invoke() const {\n        test->invoke();\n    }\n\n    bool TestCase::operator == ( TestCase const& other ) const {\n        return  test.get() == other.test.get() &&\n                name == other.name &&\n                className == other.className;\n    }\n\n    bool TestCase::operator < ( TestCase const& other ) const {\n        return name < other.name;\n    }\n\n    TestCaseInfo const& TestCase::getTestCaseInfo() const\n    {\n        return *this;\n    }\n\n} // end namespace Catch\n// end catch_test_case_info.cpp\n// start catch_test_case_registry_impl.cpp\n\n#include <algorithm>\n#include <sstream>\n\nnamespace Catch {\n\n    namespace {\n        struct TestHasher {\n            using hash_t = uint64_t;\n\n            explicit TestHasher( hash_t hashSuffix ):\n                m_hashSuffix{ hashSuffix } {}\n\n            uint32_t operator()( TestCase const& t ) const {\n                // FNV-1a hash with multiplication fold.\n                const hash_t prime = 1099511628211u;\n                hash_t hash = 14695981039346656037u;\n                for ( const char c : t.name ) {\n                    hash ^= c;\n                    hash *= prime;\n                }\n                hash ^= m_hashSuffix;\n                hash *= prime;\n                const uint32_t low{ static_cast<uint32_t>( hash ) };\n                const uint32_t high{ static_cast<uint32_t>( hash >> 32 ) };\n                return low * high;\n            }\n\n        private:\n            hash_t m_hashSuffix;\n        };\n    } // end unnamed namespace\n\n    std::vector<TestCase> sortTests( IConfig const& config, std::vector<TestCase> const& unsortedTestCases ) {\n        switch( config.runOrder() ) {\n            case RunTests::InDeclarationOrder:\n                // already in declaration order\n                break;\n\n            case RunTests::InLexicographicalOrder: {\n                std::vector<TestCase> sorted = unsortedTestCases;\n                std::sort( sorted.begin(), sorted.end() );\n                return sorted;\n            }\n\n            case RunTests::InRandomOrder: {\n                seedRng( config );\n                TestHasher h{ config.rngSeed() };\n\n                using hashedTest = std::pair<TestHasher::hash_t, TestCase const*>;\n                std::vector<hashedTest> indexed_tests;\n                indexed_tests.reserve( unsortedTestCases.size() );\n\n                for (auto const& testCase : unsortedTestCases) {\n                    indexed_tests.emplace_back(h(testCase), &testCase);\n                }\n\n                std::sort(indexed_tests.begin(), indexed_tests.end(),\n                          [](hashedTest const& lhs, hashedTest const& rhs) {\n                          if (lhs.first == rhs.first) {\n                              return lhs.second->name < rhs.second->name;\n                          }\n                          return lhs.first < rhs.first;\n                });\n\n                std::vector<TestCase> sorted;\n                sorted.reserve( indexed_tests.size() );\n\n                for (auto const& hashed : indexed_tests) {\n                    sorted.emplace_back(*hashed.second);\n                }\n\n                return sorted;\n            }\n        }\n        return unsortedTestCases;\n    }\n\n    bool isThrowSafe( TestCase const& testCase, IConfig const& config ) {\n        return !testCase.throws() || config.allowThrows();\n    }\n\n    bool matchTest( TestCase const& testCase, TestSpec const& testSpec, IConfig const& config ) {\n        return testSpec.matches( testCase ) && isThrowSafe( testCase, config );\n    }\n\n    void enforceNoDuplicateTestCases( std::vector<TestCase> const& functions ) {\n        std::set<TestCase> seenFunctions;\n        for( auto const& function : functions ) {\n            auto prev = seenFunctions.insert( function );\n            CATCH_ENFORCE( prev.second,\n                    \"error: TEST_CASE( \\\"\" << function.name << \"\\\" ) already defined.\\n\"\n                    << \"\\tFirst seen at \" << prev.first->getTestCaseInfo().lineInfo << \"\\n\"\n                    << \"\\tRedefined at \" << function.getTestCaseInfo().lineInfo );\n        }\n    }\n\n    std::vector<TestCase> filterTests( std::vector<TestCase> const& testCases, TestSpec const& testSpec, IConfig const& config ) {\n        std::vector<TestCase> filtered;\n        filtered.reserve( testCases.size() );\n        for (auto const& testCase : testCases) {\n            if ((!testSpec.hasFilters() && !testCase.isHidden()) ||\n                (testSpec.hasFilters() && matchTest(testCase, testSpec, config))) {\n                filtered.push_back(testCase);\n            }\n        }\n        return filtered;\n    }\n    std::vector<TestCase> const& getAllTestCasesSorted( IConfig const& config ) {\n        return getRegistryHub().getTestCaseRegistry().getAllTestsSorted( config );\n    }\n\n    void TestRegistry::registerTest( TestCase const& testCase ) {\n        std::string name = testCase.getTestCaseInfo().name;\n        if( name.empty() ) {\n            ReusableStringStream rss;\n            rss << \"Anonymous test case \" << ++m_unnamedCount;\n            return registerTest( testCase.withName( rss.str() ) );\n        }\n        m_functions.push_back( testCase );\n    }\n\n    std::vector<TestCase> const& TestRegistry::getAllTests() const {\n        return m_functions;\n    }\n    std::vector<TestCase> const& TestRegistry::getAllTestsSorted( IConfig const& config ) const {\n        if( m_sortedFunctions.empty() )\n            enforceNoDuplicateTestCases( m_functions );\n\n        if(  m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty() ) {\n            m_sortedFunctions = sortTests( config, m_functions );\n            m_currentSortOrder = config.runOrder();\n        }\n        return m_sortedFunctions;\n    }\n\n    ///////////////////////////////////////////////////////////////////////////\n    TestInvokerAsFunction::TestInvokerAsFunction( void(*testAsFunction)() ) noexcept : m_testAsFunction( testAsFunction ) {}\n\n    void TestInvokerAsFunction::invoke() const {\n        m_testAsFunction();\n    }\n\n    std::string extractClassName( StringRef const& classOrQualifiedMethodName ) {\n        std::string className(classOrQualifiedMethodName);\n        if( startsWith( className, '&' ) )\n        {\n            std::size_t lastColons = className.rfind( \"::\" );\n            std::size_t penultimateColons = className.rfind( \"::\", lastColons-1 );\n            if( penultimateColons == std::string::npos )\n                penultimateColons = 1;\n            className = className.substr( penultimateColons, lastColons-penultimateColons );\n        }\n        return className;\n    }\n\n} // end namespace Catch\n// end catch_test_case_registry_impl.cpp\n// start catch_test_case_tracker.cpp\n\n#include <algorithm>\n#include <cassert>\n#include <stdexcept>\n#include <memory>\n#include <sstream>\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#endif\n\nnamespace Catch {\nnamespace TestCaseTracking {\n\n    NameAndLocation::NameAndLocation( std::string const& _name, SourceLineInfo const& _location )\n    :   name( _name ),\n        location( _location )\n    {}\n\n    ITracker::~ITracker() = default;\n\n    ITracker& TrackerContext::startRun() {\n        m_rootTracker = std::make_shared<SectionTracker>( NameAndLocation( \"{root}\", CATCH_INTERNAL_LINEINFO ), *this, nullptr );\n        m_currentTracker = nullptr;\n        m_runState = Executing;\n        return *m_rootTracker;\n    }\n\n    void TrackerContext::endRun() {\n        m_rootTracker.reset();\n        m_currentTracker = nullptr;\n        m_runState = NotStarted;\n    }\n\n    void TrackerContext::startCycle() {\n        m_currentTracker = m_rootTracker.get();\n        m_runState = Executing;\n    }\n    void TrackerContext::completeCycle() {\n        m_runState = CompletedCycle;\n    }\n\n    bool TrackerContext::completedCycle() const {\n        return m_runState == CompletedCycle;\n    }\n    ITracker& TrackerContext::currentTracker() {\n        return *m_currentTracker;\n    }\n    void TrackerContext::setCurrentTracker( ITracker* tracker ) {\n        m_currentTracker = tracker;\n    }\n\n    TrackerBase::TrackerBase( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent ):\n        ITracker(nameAndLocation),\n        m_ctx( ctx ),\n        m_parent( parent )\n    {}\n\n    bool TrackerBase::isComplete() const {\n        return m_runState == CompletedSuccessfully || m_runState == Failed;\n    }\n    bool TrackerBase::isSuccessfullyCompleted() const {\n        return m_runState == CompletedSuccessfully;\n    }\n    bool TrackerBase::isOpen() const {\n        return m_runState != NotStarted && !isComplete();\n    }\n    bool TrackerBase::hasChildren() const {\n        return !m_children.empty();\n    }\n\n    void TrackerBase::addChild( ITrackerPtr const& child ) {\n        m_children.push_back( child );\n    }\n\n    ITrackerPtr TrackerBase::findChild( NameAndLocation const& nameAndLocation ) {\n        auto it = std::find_if( m_children.begin(), m_children.end(),\n            [&nameAndLocation]( ITrackerPtr const& tracker ){\n                return\n                    tracker->nameAndLocation().location == nameAndLocation.location &&\n                    tracker->nameAndLocation().name == nameAndLocation.name;\n            } );\n        return( it != m_children.end() )\n            ? *it\n            : nullptr;\n    }\n    ITracker& TrackerBase::parent() {\n        assert( m_parent ); // Should always be non-null except for root\n        return *m_parent;\n    }\n\n    void TrackerBase::openChild() {\n        if( m_runState != ExecutingChildren ) {\n            m_runState = ExecutingChildren;\n            if( m_parent )\n                m_parent->openChild();\n        }\n    }\n\n    bool TrackerBase::isSectionTracker() const { return false; }\n    bool TrackerBase::isGeneratorTracker() const { return false; }\n\n    void TrackerBase::open() {\n        m_runState = Executing;\n        moveToThis();\n        if( m_parent )\n            m_parent->openChild();\n    }\n\n    void TrackerBase::close() {\n\n        // Close any still open children (e.g. generators)\n        while( &m_ctx.currentTracker() != this )\n            m_ctx.currentTracker().close();\n\n        switch( m_runState ) {\n            case NeedsAnotherRun:\n                break;\n\n            case Executing:\n                m_runState = CompletedSuccessfully;\n                break;\n            case ExecutingChildren:\n                if( std::all_of(m_children.begin(), m_children.end(), [](ITrackerPtr const& t){ return t->isComplete(); }) )\n                    m_runState = CompletedSuccessfully;\n                break;\n\n            case NotStarted:\n            case CompletedSuccessfully:\n            case Failed:\n                CATCH_INTERNAL_ERROR( \"Illogical state: \" << m_runState );\n\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown state: \" << m_runState );\n        }\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::fail() {\n        m_runState = Failed;\n        if( m_parent )\n            m_parent->markAsNeedingAnotherRun();\n        moveToParent();\n        m_ctx.completeCycle();\n    }\n    void TrackerBase::markAsNeedingAnotherRun() {\n        m_runState = NeedsAnotherRun;\n    }\n\n    void TrackerBase::moveToParent() {\n        assert( m_parent );\n        m_ctx.setCurrentTracker( m_parent );\n    }\n    void TrackerBase::moveToThis() {\n        m_ctx.setCurrentTracker( this );\n    }\n\n    SectionTracker::SectionTracker( NameAndLocation const& nameAndLocation, TrackerContext& ctx, ITracker* parent )\n    :   TrackerBase( nameAndLocation, ctx, parent ),\n        m_trimmed_name(trim(nameAndLocation.name))\n    {\n        if( parent ) {\n            while( !parent->isSectionTracker() )\n                parent = &parent->parent();\n\n            SectionTracker& parentSection = static_cast<SectionTracker&>( *parent );\n            addNextFilters( parentSection.m_filters );\n        }\n    }\n\n    bool SectionTracker::isComplete() const {\n        bool complete = true;\n\n        if (m_filters.empty()\n            || m_filters[0] == \"\"\n            || std::find(m_filters.begin(), m_filters.end(), m_trimmed_name) != m_filters.end()) {\n            complete = TrackerBase::isComplete();\n        }\n        return complete;\n    }\n\n    bool SectionTracker::isSectionTracker() const { return true; }\n\n    SectionTracker& SectionTracker::acquire( TrackerContext& ctx, NameAndLocation const& nameAndLocation ) {\n        std::shared_ptr<SectionTracker> section;\n\n        ITracker& currentTracker = ctx.currentTracker();\n        if( ITrackerPtr childTracker = currentTracker.findChild( nameAndLocation ) ) {\n            assert( childTracker );\n            assert( childTracker->isSectionTracker() );\n            section = std::static_pointer_cast<SectionTracker>( childTracker );\n        }\n        else {\n            section = std::make_shared<SectionTracker>( nameAndLocation, ctx, &currentTracker );\n            currentTracker.addChild( section );\n        }\n        if( !ctx.completedCycle() )\n            section->tryOpen();\n        return *section;\n    }\n\n    void SectionTracker::tryOpen() {\n        if( !isComplete() )\n            open();\n    }\n\n    void SectionTracker::addInitialFilters( std::vector<std::string> const& filters ) {\n        if( !filters.empty() ) {\n            m_filters.reserve( m_filters.size() + filters.size() + 2 );\n            m_filters.emplace_back(\"\"); // Root - should never be consulted\n            m_filters.emplace_back(\"\"); // Test Case - not a section filter\n            m_filters.insert( m_filters.end(), filters.begin(), filters.end() );\n        }\n    }\n    void SectionTracker::addNextFilters( std::vector<std::string> const& filters ) {\n        if( filters.size() > 1 )\n            m_filters.insert( m_filters.end(), filters.begin()+1, filters.end() );\n    }\n\n    std::vector<std::string> const& SectionTracker::getFilters() const {\n        return m_filters;\n    }\n\n    std::string const& SectionTracker::trimmedName() const {\n        return m_trimmed_name;\n    }\n\n} // namespace TestCaseTracking\n\nusing TestCaseTracking::ITracker;\nusing TestCaseTracking::TrackerContext;\nusing TestCaseTracking::SectionTracker;\n\n} // namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n// end catch_test_case_tracker.cpp\n// start catch_test_registry.cpp\n\nnamespace Catch {\n\n    auto makeTestInvoker( void(*testAsFunction)() ) noexcept -> ITestInvoker* {\n        return new(std::nothrow) TestInvokerAsFunction( testAsFunction );\n    }\n\n    NameAndTags::NameAndTags( StringRef const& name_ , StringRef const& tags_ ) noexcept : name( name_ ), tags( tags_ ) {}\n\n    AutoReg::AutoReg( ITestInvoker* invoker, SourceLineInfo const& lineInfo, StringRef const& classOrMethod, NameAndTags const& nameAndTags ) noexcept {\n        CATCH_TRY {\n            getMutableRegistryHub()\n                    .registerTest(\n                        makeTestCase(\n                            invoker,\n                            extractClassName( classOrMethod ),\n                            nameAndTags,\n                            lineInfo));\n        } CATCH_CATCH_ALL {\n            // Do not throw when constructing global objects, instead register the exception to be processed later\n            getMutableRegistryHub().registerStartupException();\n        }\n    }\n\n    AutoReg::~AutoReg() = default;\n}\n// end catch_test_registry.cpp\n// start catch_test_spec.cpp\n\n#include <algorithm>\n#include <string>\n#include <vector>\n#include <memory>\n\nnamespace Catch {\n\n    TestSpec::Pattern::Pattern( std::string const& name )\n    : m_name( name )\n    {}\n\n    TestSpec::Pattern::~Pattern() = default;\n\n    std::string const& TestSpec::Pattern::name() const {\n        return m_name;\n    }\n\n    TestSpec::NamePattern::NamePattern( std::string const& name, std::string const& filterString )\n    : Pattern( filterString )\n    , m_wildcardPattern( toLower( name ), CaseSensitive::No )\n    {}\n\n    bool TestSpec::NamePattern::matches( TestCaseInfo const& testCase ) const {\n        return m_wildcardPattern.matches( testCase.name );\n    }\n\n    TestSpec::TagPattern::TagPattern( std::string const& tag, std::string const& filterString )\n    : Pattern( filterString )\n    , m_tag( toLower( tag ) )\n    {}\n\n    bool TestSpec::TagPattern::matches( TestCaseInfo const& testCase ) const {\n        return std::find(begin(testCase.lcaseTags),\n                         end(testCase.lcaseTags),\n                         m_tag) != end(testCase.lcaseTags);\n    }\n\n    TestSpec::ExcludedPattern::ExcludedPattern( PatternPtr const& underlyingPattern )\n    : Pattern( underlyingPattern->name() )\n    , m_underlyingPattern( underlyingPattern )\n    {}\n\n    bool TestSpec::ExcludedPattern::matches( TestCaseInfo const& testCase ) const {\n        return !m_underlyingPattern->matches( testCase );\n    }\n\n    bool TestSpec::Filter::matches( TestCaseInfo const& testCase ) const {\n        return std::all_of( m_patterns.begin(), m_patterns.end(), [&]( PatternPtr const& p ){ return p->matches( testCase ); } );\n    }\n\n    std::string TestSpec::Filter::name() const {\n        std::string name;\n        for( auto const& p : m_patterns )\n            name += p->name();\n        return name;\n    }\n\n    bool TestSpec::hasFilters() const {\n        return !m_filters.empty();\n    }\n\n    bool TestSpec::matches( TestCaseInfo const& testCase ) const {\n        return std::any_of( m_filters.begin(), m_filters.end(), [&]( Filter const& f ){ return f.matches( testCase ); } );\n    }\n\n    TestSpec::Matches TestSpec::matchesByFilter( std::vector<TestCase> const& testCases, IConfig const& config ) const\n    {\n        Matches matches( m_filters.size() );\n        std::transform( m_filters.begin(), m_filters.end(), matches.begin(), [&]( Filter const& filter ){\n            std::vector<TestCase const*> currentMatches;\n            for( auto const& test : testCases )\n                if( isThrowSafe( test, config ) && filter.matches( test ) )\n                    currentMatches.emplace_back( &test );\n            return FilterMatch{ filter.name(), currentMatches };\n        } );\n        return matches;\n    }\n\n    const TestSpec::vectorStrings& TestSpec::getInvalidArgs() const{\n        return  (m_invalidArgs);\n    }\n\n}\n// end catch_test_spec.cpp\n// start catch_test_spec_parser.cpp\n\nnamespace Catch {\n\n    TestSpecParser::TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {}\n\n    TestSpecParser& TestSpecParser::parse( std::string const& arg ) {\n        m_mode = None;\n        m_exclusion = false;\n        m_arg = m_tagAliases->expandAliases( arg );\n        m_escapeChars.clear();\n        m_substring.reserve(m_arg.size());\n        m_patternName.reserve(m_arg.size());\n        m_realPatternPos = 0;\n\n        for( m_pos = 0; m_pos < m_arg.size(); ++m_pos )\n          //if visitChar fails\n           if( !visitChar( m_arg[m_pos] ) ){\n               m_testSpec.m_invalidArgs.push_back(arg);\n               break;\n           }\n        endMode();\n        return *this;\n    }\n    TestSpec TestSpecParser::testSpec() {\n        addFilter();\n        return m_testSpec;\n    }\n    bool TestSpecParser::visitChar( char c ) {\n        if( (m_mode != EscapedName) && (c == '\\\\') ) {\n            escape();\n            addCharToPattern(c);\n            return true;\n        }else if((m_mode != EscapedName) && (c == ',') )  {\n            return separate();\n        }\n\n        switch( m_mode ) {\n        case None:\n            if( processNoneChar( c ) )\n                return true;\n            break;\n        case Name:\n            processNameChar( c );\n            break;\n        case EscapedName:\n            endMode();\n            addCharToPattern(c);\n            return true;\n        default:\n        case Tag:\n        case QuotedName:\n            if( processOtherChar( c ) )\n                return true;\n            break;\n        }\n\n        m_substring += c;\n        if( !isControlChar( c ) ) {\n            m_patternName += c;\n            m_realPatternPos++;\n        }\n        return true;\n    }\n    // Two of the processing methods return true to signal the caller to return\n    // without adding the given character to the current pattern strings\n    bool TestSpecParser::processNoneChar( char c ) {\n        switch( c ) {\n        case ' ':\n            return true;\n        case '~':\n            m_exclusion = true;\n            return false;\n        case '[':\n            startNewMode( Tag );\n            return false;\n        case '\"':\n            startNewMode( QuotedName );\n            return false;\n        default:\n            startNewMode( Name );\n            return false;\n        }\n    }\n    void TestSpecParser::processNameChar( char c ) {\n        if( c == '[' ) {\n            if( m_substring == \"exclude:\" )\n                m_exclusion = true;\n            else\n                endMode();\n            startNewMode( Tag );\n        }\n    }\n    bool TestSpecParser::processOtherChar( char c ) {\n        if( !isControlChar( c ) )\n            return false;\n        m_substring += c;\n        endMode();\n        return true;\n    }\n    void TestSpecParser::startNewMode( Mode mode ) {\n        m_mode = mode;\n    }\n    void TestSpecParser::endMode() {\n        switch( m_mode ) {\n        case Name:\n        case QuotedName:\n            return addNamePattern();\n        case Tag:\n            return addTagPattern();\n        case EscapedName:\n            revertBackToLastMode();\n            return;\n        case None:\n        default:\n            return startNewMode( None );\n        }\n    }\n    void TestSpecParser::escape() {\n        saveLastMode();\n        m_mode = EscapedName;\n        m_escapeChars.push_back(m_realPatternPos);\n    }\n    bool TestSpecParser::isControlChar( char c ) const {\n        switch( m_mode ) {\n            default:\n                return false;\n            case None:\n                return c == '~';\n            case Name:\n                return c == '[';\n            case EscapedName:\n                return true;\n            case QuotedName:\n                return c == '\"';\n            case Tag:\n                return c == '[' || c == ']';\n        }\n    }\n\n    void TestSpecParser::addFilter() {\n        if( !m_currentFilter.m_patterns.empty() ) {\n            m_testSpec.m_filters.push_back( m_currentFilter );\n            m_currentFilter = TestSpec::Filter();\n        }\n    }\n\n    void TestSpecParser::saveLastMode() {\n      lastMode = m_mode;\n    }\n\n    void TestSpecParser::revertBackToLastMode() {\n      m_mode = lastMode;\n    }\n\n    bool TestSpecParser::separate() {\n      if( (m_mode==QuotedName) || (m_mode==Tag) ){\n         //invalid argument, signal failure to previous scope.\n         m_mode = None;\n         m_pos = m_arg.size();\n         m_substring.clear();\n         m_patternName.clear();\n         m_realPatternPos = 0;\n         return false;\n      }\n      endMode();\n      addFilter();\n      return true; //success\n    }\n\n    std::string TestSpecParser::preprocessPattern() {\n        std::string token = m_patternName;\n        for (std::size_t i = 0; i < m_escapeChars.size(); ++i)\n            token = token.substr(0, m_escapeChars[i] - i) + token.substr(m_escapeChars[i] - i + 1);\n        m_escapeChars.clear();\n        if (startsWith(token, \"exclude:\")) {\n            m_exclusion = true;\n            token = token.substr(8);\n        }\n\n        m_patternName.clear();\n        m_realPatternPos = 0;\n\n        return token;\n    }\n\n    void TestSpecParser::addNamePattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::NamePattern>(token, m_substring);\n            if (m_exclusion)\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    void TestSpecParser::addTagPattern() {\n        auto token = preprocessPattern();\n\n        if (!token.empty()) {\n            // If the tag pattern is the \"hide and tag\" shorthand (e.g. [.foo])\n            // we have to create a separate hide tag and shorten the real one\n            if (token.size() > 1 && token[0] == '.') {\n                token.erase(token.begin());\n                TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(\".\", m_substring);\n                if (m_exclusion) {\n                    pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n                }\n                m_currentFilter.m_patterns.push_back(pattern);\n            }\n\n            TestSpec::PatternPtr pattern = std::make_shared<TestSpec::TagPattern>(token, m_substring);\n\n            if (m_exclusion) {\n                pattern = std::make_shared<TestSpec::ExcludedPattern>(pattern);\n            }\n            m_currentFilter.m_patterns.push_back(pattern);\n        }\n        m_substring.clear();\n        m_exclusion = false;\n        m_mode = None;\n    }\n\n    TestSpec parseTestSpec( std::string const& arg ) {\n        return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec();\n    }\n\n} // namespace Catch\n// end catch_test_spec_parser.cpp\n// start catch_timer.cpp\n\n#include <chrono>\n\nstatic const uint64_t nanosecondsInSecond = 1000000000;\n\nnamespace Catch {\n\n    auto getCurrentNanosecondsSinceEpoch() -> uint64_t {\n        return std::chrono::duration_cast<std::chrono::nanoseconds>( std::chrono::high_resolution_clock::now().time_since_epoch() ).count();\n    }\n\n    namespace {\n        auto estimateClockResolution() -> uint64_t {\n            uint64_t sum = 0;\n            static const uint64_t iterations = 1000000;\n\n            auto startTime = getCurrentNanosecondsSinceEpoch();\n\n            for( std::size_t i = 0; i < iterations; ++i ) {\n\n                uint64_t ticks;\n                uint64_t baseTicks = getCurrentNanosecondsSinceEpoch();\n                do {\n                    ticks = getCurrentNanosecondsSinceEpoch();\n                } while( ticks == baseTicks );\n\n                auto delta = ticks - baseTicks;\n                sum += delta;\n\n                // If we have been calibrating for over 3 seconds -- the clock\n                // is terrible and we should move on.\n                // TBD: How to signal that the measured resolution is probably wrong?\n                if (ticks > startTime + 3 * nanosecondsInSecond) {\n                    return sum / ( i + 1u );\n                }\n            }\n\n            // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers\n            // - and potentially do more iterations if there's a high variance.\n            return sum/iterations;\n        }\n    }\n    auto getEstimatedClockResolution() -> uint64_t {\n        static auto s_resolution = estimateClockResolution();\n        return s_resolution;\n    }\n\n    void Timer::start() {\n       m_nanoseconds = getCurrentNanosecondsSinceEpoch();\n    }\n    auto Timer::getElapsedNanoseconds() const -> uint64_t {\n        return getCurrentNanosecondsSinceEpoch() - m_nanoseconds;\n    }\n    auto Timer::getElapsedMicroseconds() const -> uint64_t {\n        return getElapsedNanoseconds()/1000;\n    }\n    auto Timer::getElapsedMilliseconds() const -> unsigned int {\n        return static_cast<unsigned int>(getElapsedMicroseconds()/1000);\n    }\n    auto Timer::getElapsedSeconds() const -> double {\n        return getElapsedMicroseconds()/1000000.0;\n    }\n\n} // namespace Catch\n// end catch_timer.cpp\n// start catch_tostring.cpp\n\n#if defined(__clang__)\n#    pragma clang diagnostic push\n#    pragma clang diagnostic ignored \"-Wexit-time-destructors\"\n#    pragma clang diagnostic ignored \"-Wglobal-constructors\"\n#endif\n\n// Enable specific decls locally\n#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER)\n#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER\n#endif\n\n#include <cmath>\n#include <iomanip>\n\nnamespace Catch {\n\nnamespace Detail {\n\n    const std::string unprintableString = \"{?}\";\n\n    namespace {\n        const int hexThreshold = 255;\n\n        struct Endianness {\n            enum Arch { Big, Little };\n\n            static Arch which() {\n                int one = 1;\n                // If the lowest byte we read is non-zero, we can assume\n                // that little endian format is used.\n                auto value = *reinterpret_cast<char*>(&one);\n                return value ? Little : Big;\n            }\n        };\n    }\n\n    std::string rawMemoryToString( const void *object, std::size_t size ) {\n        // Reverse order for little endian architectures\n        int i = 0, end = static_cast<int>( size ), inc = 1;\n        if( Endianness::which() == Endianness::Little ) {\n            i = end-1;\n            end = inc = -1;\n        }\n\n        unsigned char const *bytes = static_cast<unsigned char const *>(object);\n        ReusableStringStream rss;\n        rss << \"0x\" << std::setfill('0') << std::hex;\n        for( ; i != end; i += inc )\n             rss << std::setw(2) << static_cast<unsigned>(bytes[i]);\n       return rss.str();\n    }\n}\n\ntemplate<typename T>\nstd::string fpToString( T value, int precision ) {\n    if (Catch::isnan(value)) {\n        return \"nan\";\n    }\n\n    ReusableStringStream rss;\n    rss << std::setprecision( precision )\n        << std::fixed\n        << value;\n    std::string d = rss.str();\n    std::size_t i = d.find_last_not_of( '0' );\n    if( i != std::string::npos && i != d.size()-1 ) {\n        if( d[i] == '.' )\n            i++;\n        d = d.substr( 0, i+1 );\n    }\n    return d;\n}\n\n//// ======================================================= ////\n//\n//   Out-of-line defs for full specialization of StringMaker\n//\n//// ======================================================= ////\n\nstd::string StringMaker<std::string>::convert(const std::string& str) {\n    if (!getCurrentContext().getConfig()->showInvisibles()) {\n        return '\"' + str + '\"';\n    }\n\n    std::string s(\"\\\"\");\n    for (char c : str) {\n        switch (c) {\n        case '\\n':\n            s.append(\"\\\\n\");\n            break;\n        case '\\t':\n            s.append(\"\\\\t\");\n            break;\n        default:\n            s.push_back(c);\n            break;\n        }\n    }\n    s.append(\"\\\"\");\n    return s;\n}\n\n#ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::string_view>::convert(std::string_view str) {\n    return ::Catch::Detail::stringify(std::string{ str });\n}\n#endif\n\nstd::string StringMaker<char const*>::convert(char const* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<char*>::convert(char* str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::string{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n\n#ifdef CATCH_CONFIG_WCHAR\nstd::string StringMaker<std::wstring>::convert(const std::wstring& wstr) {\n    std::string s;\n    s.reserve(wstr.size());\n    for (auto c : wstr) {\n        s += (c <= 0xff) ? static_cast<char>(c) : '?';\n    }\n    return ::Catch::Detail::stringify(s);\n}\n\n# ifdef CATCH_CONFIG_CPP17_STRING_VIEW\nstd::string StringMaker<std::wstring_view>::convert(std::wstring_view str) {\n    return StringMaker<std::wstring>::convert(std::wstring(str));\n}\n# endif\n\nstd::string StringMaker<wchar_t const*>::convert(wchar_t const * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\nstd::string StringMaker<wchar_t *>::convert(wchar_t * str) {\n    if (str) {\n        return ::Catch::Detail::stringify(std::wstring{ str });\n    } else {\n        return{ \"{null string}\" };\n    }\n}\n#endif\n\n#if defined(CATCH_CONFIG_CPP17_BYTE)\n#include <cstddef>\nstd::string StringMaker<std::byte>::convert(std::byte value) {\n    return ::Catch::Detail::stringify(std::to_integer<unsigned long long>(value));\n}\n#endif // defined(CATCH_CONFIG_CPP17_BYTE)\n\nstd::string StringMaker<int>::convert(int value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long>::convert(long value) {\n    return ::Catch::Detail::stringify(static_cast<long long>(value));\n}\nstd::string StringMaker<long long>::convert(long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<unsigned int>::convert(unsigned int value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long>::convert(unsigned long value) {\n    return ::Catch::Detail::stringify(static_cast<unsigned long long>(value));\n}\nstd::string StringMaker<unsigned long long>::convert(unsigned long long value) {\n    ReusableStringStream rss;\n    rss << value;\n    if (value > Detail::hexThreshold) {\n        rss << \" (0x\" << std::hex << value << ')';\n    }\n    return rss.str();\n}\n\nstd::string StringMaker<bool>::convert(bool b) {\n    return b ? \"true\" : \"false\";\n}\n\nstd::string StringMaker<signed char>::convert(signed char value) {\n    if (value == '\\r') {\n        return \"'\\\\r'\";\n    } else if (value == '\\f') {\n        return \"'\\\\f'\";\n    } else if (value == '\\n') {\n        return \"'\\\\n'\";\n    } else if (value == '\\t') {\n        return \"'\\\\t'\";\n    } else if ('\\0' <= value && value < ' ') {\n        return ::Catch::Detail::stringify(static_cast<unsigned int>(value));\n    } else {\n        char chstr[] = \"' '\";\n        chstr[1] = value;\n        return chstr;\n    }\n}\nstd::string StringMaker<char>::convert(char c) {\n    return ::Catch::Detail::stringify(static_cast<signed char>(c));\n}\nstd::string StringMaker<unsigned char>::convert(unsigned char c) {\n    return ::Catch::Detail::stringify(static_cast<char>(c));\n}\n\nstd::string StringMaker<std::nullptr_t>::convert(std::nullptr_t) {\n    return \"nullptr\";\n}\n\nint StringMaker<float>::precision = 5;\n\nstd::string StringMaker<float>::convert(float value) {\n    return fpToString(value, precision) + 'f';\n}\n\nint StringMaker<double>::precision = 10;\n\nstd::string StringMaker<double>::convert(double value) {\n    return fpToString(value, precision);\n}\n\nstd::string ratio_string<std::atto>::symbol() { return \"a\"; }\nstd::string ratio_string<std::femto>::symbol() { return \"f\"; }\nstd::string ratio_string<std::pico>::symbol() { return \"p\"; }\nstd::string ratio_string<std::nano>::symbol() { return \"n\"; }\nstd::string ratio_string<std::micro>::symbol() { return \"u\"; }\nstd::string ratio_string<std::milli>::symbol() { return \"m\"; }\n\n} // end namespace Catch\n\n#if defined(__clang__)\n#    pragma clang diagnostic pop\n#endif\n\n// end catch_tostring.cpp\n// start catch_totals.cpp\n\nnamespace Catch {\n\n    Counts Counts::operator - ( Counts const& other ) const {\n        Counts diff;\n        diff.passed = passed - other.passed;\n        diff.failed = failed - other.failed;\n        diff.failedButOk = failedButOk - other.failedButOk;\n        return diff;\n    }\n\n    Counts& Counts::operator += ( Counts const& other ) {\n        passed += other.passed;\n        failed += other.failed;\n        failedButOk += other.failedButOk;\n        return *this;\n    }\n\n    std::size_t Counts::total() const {\n        return passed + failed + failedButOk;\n    }\n    bool Counts::allPassed() const {\n        return failed == 0 && failedButOk == 0;\n    }\n    bool Counts::allOk() const {\n        return failed == 0;\n    }\n\n    Totals Totals::operator - ( Totals const& other ) const {\n        Totals diff;\n        diff.assertions = assertions - other.assertions;\n        diff.testCases = testCases - other.testCases;\n        return diff;\n    }\n\n    Totals& Totals::operator += ( Totals const& other ) {\n        assertions += other.assertions;\n        testCases += other.testCases;\n        return *this;\n    }\n\n    Totals Totals::delta( Totals const& prevTotals ) const {\n        Totals diff = *this - prevTotals;\n        if( diff.assertions.failed > 0 )\n            ++diff.testCases.failed;\n        else if( diff.assertions.failedButOk > 0 )\n            ++diff.testCases.failedButOk;\n        else\n            ++diff.testCases.passed;\n        return diff;\n    }\n\n}\n// end catch_totals.cpp\n// start catch_uncaught_exceptions.cpp\n\n// start catch_config_uncaught_exceptions.hpp\n\n//              Copyright Catch2 Authors\n// Distributed under the Boost Software License, Version 1.0.\n//   (See accompanying file LICENSE_1_0.txt or copy at\n//        https://www.boost.org/LICENSE_1_0.txt)\n\n// SPDX-License-Identifier: BSL-1.0\n\n#ifndef CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n#define CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n\n#if defined(_MSC_VER)\n#  if _MSC_VER >= 1900 // Visual Studio 2015 or newer\n#    define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#  endif\n#endif\n\n#include <exception>\n\n#if defined(__cpp_lib_uncaught_exceptions) \\\n    && !defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif // __cpp_lib_uncaught_exceptions\n\n#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) \\\n    && !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n\n#  define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS\n#endif\n\n#endif // CATCH_CONFIG_UNCAUGHT_EXCEPTIONS_HPP\n// end catch_config_uncaught_exceptions.hpp\n#include <exception>\n\nnamespace Catch {\n    bool uncaught_exceptions() {\n#if defined(CATCH_CONFIG_DISABLE_EXCEPTIONS)\n        return false;\n#elif defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS)\n        return std::uncaught_exceptions() > 0;\n#else\n        return std::uncaught_exception();\n#endif\n  }\n} // end namespace Catch\n// end catch_uncaught_exceptions.cpp\n// start catch_version.cpp\n\n#include <ostream>\n\nnamespace Catch {\n\n    Version::Version\n        (   unsigned int _majorVersion,\n            unsigned int _minorVersion,\n            unsigned int _patchNumber,\n            char const * const _branchName,\n            unsigned int _buildNumber )\n    :   majorVersion( _majorVersion ),\n        minorVersion( _minorVersion ),\n        patchNumber( _patchNumber ),\n        branchName( _branchName ),\n        buildNumber( _buildNumber )\n    {}\n\n    std::ostream& operator << ( std::ostream& os, Version const& version ) {\n        os  << version.majorVersion << '.'\n            << version.minorVersion << '.'\n            << version.patchNumber;\n        // branchName is never null -> 0th char is \\0 if it is empty\n        if (version.branchName[0]) {\n            os << '-' << version.branchName\n               << '.' << version.buildNumber;\n        }\n        return os;\n    }\n\n    Version const& libraryVersion() {\n        static Version version( 2, 13, 9, \"\", 0 );\n        return version;\n    }\n\n}\n// end catch_version.cpp\n// start catch_wildcard_pattern.cpp\n\nnamespace Catch {\n\n    WildcardPattern::WildcardPattern( std::string const& pattern,\n                                      CaseSensitive::Choice caseSensitivity )\n    :   m_caseSensitivity( caseSensitivity ),\n        m_pattern( normaliseString( pattern ) )\n    {\n        if( startsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 1 );\n            m_wildcard = WildcardAtStart;\n        }\n        if( endsWith( m_pattern, '*' ) ) {\n            m_pattern = m_pattern.substr( 0, m_pattern.size()-1 );\n            m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd );\n        }\n    }\n\n    bool WildcardPattern::matches( std::string const& str ) const {\n        switch( m_wildcard ) {\n            case NoWildcard:\n                return m_pattern == normaliseString( str );\n            case WildcardAtStart:\n                return endsWith( normaliseString( str ), m_pattern );\n            case WildcardAtEnd:\n                return startsWith( normaliseString( str ), m_pattern );\n            case WildcardAtBothEnds:\n                return contains( normaliseString( str ), m_pattern );\n            default:\n                CATCH_INTERNAL_ERROR( \"Unknown enum\" );\n        }\n    }\n\n    std::string WildcardPattern::normaliseString( std::string const& str ) const {\n        return trim( m_caseSensitivity == CaseSensitive::No ? toLower( str ) : str );\n    }\n}\n// end catch_wildcard_pattern.cpp\n// start catch_xmlwriter.cpp\n\n#include <iomanip>\n#include <type_traits>\n\nnamespace Catch {\n\nnamespace {\n\n    size_t trailingBytes(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return 2;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return 3;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return 4;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    uint32_t headerValue(unsigned char c) {\n        if ((c & 0xE0) == 0xC0) {\n            return c & 0x1F;\n        }\n        if ((c & 0xF0) == 0xE0) {\n            return c & 0x0F;\n        }\n        if ((c & 0xF8) == 0xF0) {\n            return c & 0x07;\n        }\n        CATCH_INTERNAL_ERROR(\"Invalid multibyte utf-8 start byte encountered\");\n    }\n\n    void hexEscapeChar(std::ostream& os, unsigned char c) {\n        std::ios_base::fmtflags f(os.flags());\n        os << \"\\\\x\"\n            << std::uppercase << std::hex << std::setfill('0') << std::setw(2)\n            << static_cast<int>(c);\n        os.flags(f);\n    }\n\n    bool shouldNewline(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Newline));\n    }\n\n    bool shouldIndent(XmlFormatting fmt) {\n        return !!(static_cast<std::underlying_type<XmlFormatting>::type>(fmt & XmlFormatting::Indent));\n    }\n\n} // anonymous namespace\n\n    XmlFormatting operator | (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) |\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlFormatting operator & (XmlFormatting lhs, XmlFormatting rhs) {\n        return static_cast<XmlFormatting>(\n            static_cast<std::underlying_type<XmlFormatting>::type>(lhs) &\n            static_cast<std::underlying_type<XmlFormatting>::type>(rhs)\n        );\n    }\n\n    XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat )\n    :   m_str( str ),\n        m_forWhat( forWhat )\n    {}\n\n    void XmlEncode::encodeTo( std::ostream& os ) const {\n        // Apostrophe escaping not necessary if we always use \" to write attributes\n        // (see: http://www.w3.org/TR/xml/#syntax)\n\n        for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {\n            unsigned char c = m_str[idx];\n            switch (c) {\n            case '<':   os << \"&lt;\"; break;\n            case '&':   os << \"&amp;\"; break;\n\n            case '>':\n                // See: http://www.w3.org/TR/xml/#syntax\n                if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']')\n                    os << \"&gt;\";\n                else\n                    os << c;\n                break;\n\n            case '\\\"':\n                if (m_forWhat == ForAttributes)\n                    os << \"&quot;\";\n                else\n                    os << c;\n                break;\n\n            default:\n                // Check for control characters and invalid utf-8\n\n                // Escape control characters in standard ascii\n                // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0\n                if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // Plain ASCII: Write it to stream\n                if (c < 0x7F) {\n                    os << c;\n                    break;\n                }\n\n                // UTF-8 territory\n                // Check if the encoding is valid and if it is not, hex escape bytes.\n                // Important: We do not check the exact decoded values for validity, only the encoding format\n                // First check that this bytes is a valid lead byte:\n                // This means that it is not encoded as 1111 1XXX\n                // Or as 10XX XXXX\n                if (c <  0xC0 ||\n                    c >= 0xF8) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                auto encBytes = trailingBytes(c);\n                // Are there enough bytes left to avoid accessing out-of-bounds memory?\n                if (idx + encBytes - 1 >= m_str.size()) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n                // The header is valid, check data\n                // The next encBytes bytes must together be a valid utf-8\n                // This means: bitpattern 10XX XXXX and the extracted value is sane (ish)\n                bool valid = true;\n                uint32_t value = headerValue(c);\n                for (std::size_t n = 1; n < encBytes; ++n) {\n                    unsigned char nc = m_str[idx + n];\n                    valid &= ((nc & 0xC0) == 0x80);\n                    value = (value << 6) | (nc & 0x3F);\n                }\n\n                if (\n                    // Wrong bit pattern of following bytes\n                    (!valid) ||\n                    // Overlong encodings\n                    (value < 0x80) ||\n                    (0x80 <= value && value < 0x800   && encBytes > 2) ||\n                    (0x800 < value && value < 0x10000 && encBytes > 3) ||\n                    // Encoded value out of range\n                    (value >= 0x110000)\n                    ) {\n                    hexEscapeChar(os, c);\n                    break;\n                }\n\n                // If we got here, this is in fact a valid(ish) utf-8 sequence\n                for (std::size_t n = 0; n < encBytes; ++n) {\n                    os << m_str[idx + n];\n                }\n                idx += encBytes - 1;\n                break;\n            }\n        }\n    }\n\n    std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) {\n        xmlEncode.encodeTo( os );\n        return os;\n    }\n\n    XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer, XmlFormatting fmt )\n    :   m_writer( writer ),\n        m_fmt(fmt)\n    {}\n\n    XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) noexcept\n    :   m_writer( other.m_writer ),\n        m_fmt(other.m_fmt)\n    {\n        other.m_writer = nullptr;\n        other.m_fmt = XmlFormatting::None;\n    }\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) noexcept {\n        if ( m_writer ) {\n            m_writer->endElement();\n        }\n        m_writer = other.m_writer;\n        other.m_writer = nullptr;\n        m_fmt = other.m_fmt;\n        other.m_fmt = XmlFormatting::None;\n        return *this;\n    }\n\n    XmlWriter::ScopedElement::~ScopedElement() {\n        if (m_writer) {\n            m_writer->endElement(m_fmt);\n        }\n    }\n\n    XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, XmlFormatting fmt ) {\n        m_writer->writeText( text, fmt );\n        return *this;\n    }\n\n    XmlWriter::XmlWriter( std::ostream& os ) : m_os( os )\n    {\n        writeDeclaration();\n    }\n\n    XmlWriter::~XmlWriter() {\n        while (!m_tags.empty()) {\n            endElement();\n        }\n        newlineIfNecessary();\n    }\n\n    XmlWriter& XmlWriter::startElement( std::string const& name, XmlFormatting fmt ) {\n        ensureTagClosed();\n        newlineIfNecessary();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n            m_indent += \"  \";\n        }\n        m_os << '<' << name;\n        m_tags.push_back( name );\n        m_tagIsOpen = true;\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name, XmlFormatting fmt ) {\n        ScopedElement scoped( this, fmt );\n        startElement( name, fmt );\n        return scoped;\n    }\n\n    XmlWriter& XmlWriter::endElement(XmlFormatting fmt) {\n        m_indent = m_indent.substr(0, m_indent.size() - 2);\n\n        if( m_tagIsOpen ) {\n            m_os << \"/>\";\n            m_tagIsOpen = false;\n        } else {\n            newlineIfNecessary();\n            if (shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << \"</\" << m_tags.back() << \">\";\n        }\n        m_os << std::flush;\n        applyFormatting(fmt);\n        m_tags.pop_back();\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) {\n        if( !name.empty() && !attribute.empty() )\n            m_os << ' ' << name << \"=\\\"\" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) {\n        m_os << ' ' << name << \"=\\\"\" << ( attribute ? \"true\" : \"false\" ) << '\"';\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeText( std::string const& text, XmlFormatting fmt) {\n        if( !text.empty() ){\n            bool tagWasOpen = m_tagIsOpen;\n            ensureTagClosed();\n            if (tagWasOpen && shouldIndent(fmt)) {\n                m_os << m_indent;\n            }\n            m_os << XmlEncode( text );\n            applyFormatting(fmt);\n        }\n        return *this;\n    }\n\n    XmlWriter& XmlWriter::writeComment( std::string const& text, XmlFormatting fmt) {\n        ensureTagClosed();\n        if (shouldIndent(fmt)) {\n            m_os << m_indent;\n        }\n        m_os << \"<!--\" << text << \"-->\";\n        applyFormatting(fmt);\n        return *this;\n    }\n\n    void XmlWriter::writeStylesheetRef( std::string const& url ) {\n        m_os << \"<?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"\" << url << \"\\\"?>\\n\";\n    }\n\n    XmlWriter& XmlWriter::writeBlankLine() {\n        ensureTagClosed();\n        m_os << '\\n';\n        return *this;\n    }\n\n    void XmlWriter::ensureTagClosed() {\n        if( m_tagIsOpen ) {\n            m_os << '>' << std::flush;\n            newlineIfNecessary();\n            m_tagIsOpen = false;\n        }\n    }\n\n    void XmlWriter::applyFormatting(XmlFormatting fmt) {\n        m_needsNewline = shouldNewline(fmt);\n    }\n\n    void XmlWriter::writeDeclaration() {\n        m_os << \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n\";\n    }\n\n    void XmlWriter::newlineIfNecessary() {\n        if( m_needsNewline ) {\n            m_os << std::endl;\n            m_needsNewline = false;\n        }\n    }\n}\n// end catch_xmlwriter.cpp\n// start catch_reporter_bases.cpp\n\n#include <cstring>\n#include <cfloat>\n#include <cstdio>\n#include <cassert>\n#include <memory>\n\nnamespace Catch {\n    void prepareExpandedExpression(AssertionResult& result) {\n        result.getExpandedExpression();\n    }\n\n    // Because formatting using c++ streams is stateful, drop down to C is required\n    // Alternatively we could use stringstream, but its performance is... not good.\n    std::string getFormattedDuration( double duration ) {\n        // Max exponent + 1 is required to represent the whole part\n        // + 1 for decimal point\n        // + 3 for the 3 decimal places\n        // + 1 for null terminator\n        const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1;\n        char buffer[maxDoubleSize];\n\n        // Save previous errno, to prevent sprintf from overwriting it\n        ErrnoGuard guard;\n#ifdef _MSC_VER\n        sprintf_s(buffer, \"%.3f\", duration);\n#else\n        std::sprintf(buffer, \"%.3f\", duration);\n#endif\n        return std::string(buffer);\n    }\n\n    bool shouldShowDuration( IConfig const& config, double duration ) {\n        if ( config.showDurations() == ShowDurations::Always ) {\n            return true;\n        }\n        if ( config.showDurations() == ShowDurations::Never ) {\n            return false;\n        }\n        const double min = config.minDuration();\n        return min >= 0 && duration >= min;\n    }\n\n    std::string serializeFilters( std::vector<std::string> const& container ) {\n        ReusableStringStream oss;\n        bool first = true;\n        for (auto&& filter : container)\n        {\n            if (!first)\n                oss << ' ';\n            else\n                first = false;\n\n            oss << filter;\n        }\n        return oss.str();\n    }\n\n    TestEventListenerBase::TestEventListenerBase(ReporterConfig const & _config)\n        :StreamingReporterBase(_config) {}\n\n    std::set<Verbosity> TestEventListenerBase::getSupportedVerbosities() {\n        return { Verbosity::Quiet, Verbosity::Normal, Verbosity::High };\n    }\n\n    void TestEventListenerBase::assertionStarting(AssertionInfo const &) {}\n\n    bool TestEventListenerBase::assertionEnded(AssertionStats const &) {\n        return false;\n    }\n\n} // end namespace Catch\n// end catch_reporter_bases.cpp\n// start catch_reporter_compact.cpp\n\nnamespace {\n\n#ifdef CATCH_PLATFORM_MAC\n    const char* failedString() { return \"FAILED\"; }\n    const char* passedString() { return \"PASSED\"; }\n#else\n    const char* failedString() { return \"failed\"; }\n    const char* passedString() { return \"passed\"; }\n#endif\n\n    // Colour::LightGrey\n    Catch::Colour::Code dimColour() { return Catch::Colour::FileName; }\n\n    std::string bothOrAll( std::size_t count ) {\n        return count == 1 ? std::string() :\n               count == 2 ? \"both \" : \"all \" ;\n    }\n\n} // anon namespace\n\nnamespace Catch {\nnamespace {\n// Colour, message variants:\n// - white: No tests ran.\n// -   red: Failed [both/all] N test cases, failed [both/all] M assertions.\n// - white: Passed [both/all] N test cases (no assertions).\n// -   red: Failed N tests cases, failed M assertions.\n// - green: Passed [both/all] N tests cases with M assertions.\nvoid printTotals(std::ostream& out, const Totals& totals) {\n    if (totals.testCases.total() == 0) {\n        out << \"No tests ran.\";\n    } else if (totals.testCases.failed == totals.testCases.total()) {\n        Colour colour(Colour::ResultError);\n        const std::string qualify_assertions_failed =\n            totals.assertions.failed == totals.assertions.total() ?\n            bothOrAll(totals.assertions.failed) : std::string();\n        out <<\n            \"Failed \" << bothOrAll(totals.testCases.failed)\n            << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << qualify_assertions_failed <<\n            pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else if (totals.assertions.total() == 0) {\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.total())\n            << pluralise(totals.testCases.total(), \"test case\")\n            << \" (no assertions).\";\n    } else if (totals.assertions.failed) {\n        Colour colour(Colour::ResultError);\n        out <<\n            \"Failed \" << pluralise(totals.testCases.failed, \"test case\") << \", \"\n            \"failed \" << pluralise(totals.assertions.failed, \"assertion\") << '.';\n    } else {\n        Colour colour(Colour::ResultSuccess);\n        out <<\n            \"Passed \" << bothOrAll(totals.testCases.passed)\n            << pluralise(totals.testCases.passed, \"test case\") <<\n            \" with \" << pluralise(totals.assertions.passed, \"assertion\") << '.';\n    }\n}\n\n// Implementation of CompactReporter formatting\nclass AssertionPrinter {\npublic:\n    AssertionPrinter& operator= (AssertionPrinter const&) = delete;\n    AssertionPrinter(AssertionPrinter const&) = delete;\n    AssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream)\n        , result(_stats.assertionResult)\n        , messages(_stats.infoMessages)\n        , itMessage(_stats.infoMessages.begin())\n        , printInfoMessages(_printInfoMessages) {}\n\n    void print() {\n        printSourceInfo();\n\n        itMessage = messages.begin();\n\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            printResultType(Colour::ResultSuccess, passedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            if (!result.hasExpression())\n                printRemainingMessages(Colour::None);\n            else\n                printRemainingMessages();\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk())\n                printResultType(Colour::ResultSuccess, failedString() + std::string(\" - but was ok\"));\n            else\n                printResultType(Colour::Error, failedString());\n            printOriginalExpression();\n            printReconstructedExpression();\n            printRemainingMessages();\n            break;\n        case ResultWas::ThrewException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"unexpected exception with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::FatalErrorCondition:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"fatal error condition with message:\");\n            printMessage();\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::DidntThrowException:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"expected exception, got none\");\n            printExpressionWas();\n            printRemainingMessages();\n            break;\n        case ResultWas::Info:\n            printResultType(Colour::None, \"info\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::Warning:\n            printResultType(Colour::None, \"warning\");\n            printMessage();\n            printRemainingMessages();\n            break;\n        case ResultWas::ExplicitFailure:\n            printResultType(Colour::Error, failedString());\n            printIssue(\"explicitly\");\n            printRemainingMessages(Colour::None);\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            printResultType(Colour::Error, \"** internal error **\");\n            break;\n        }\n    }\n\nprivate:\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << ':';\n    }\n\n    void printResultType(Colour::Code colour, std::string const& passOrFail) const {\n        if (!passOrFail.empty()) {\n            {\n                Colour colourGuard(colour);\n                stream << ' ' << passOrFail;\n            }\n            stream << ':';\n        }\n    }\n\n    void printIssue(std::string const& issue) const {\n        stream << ' ' << issue;\n    }\n\n    void printExpressionWas() {\n        if (result.hasExpression()) {\n            stream << ';';\n            {\n                Colour colour(dimColour());\n                stream << \" expression was:\";\n            }\n            printOriginalExpression();\n        }\n    }\n\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            stream << ' ' << result.getExpression();\n        }\n    }\n\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            {\n                Colour colour(dimColour());\n                stream << \" for: \";\n            }\n            stream << result.getExpandedExpression();\n        }\n    }\n\n    void printMessage() {\n        if (itMessage != messages.end()) {\n            stream << \" '\" << itMessage->message << '\\'';\n            ++itMessage;\n        }\n    }\n\n    void printRemainingMessages(Colour::Code colour = dimColour()) {\n        if (itMessage == messages.end())\n            return;\n\n        const auto itEnd = messages.cend();\n        const auto N = static_cast<std::size_t>(std::distance(itMessage, itEnd));\n\n        {\n            Colour colourGuard(colour);\n            stream << \" with \" << pluralise(N, \"message\") << ':';\n        }\n\n        while (itMessage != itEnd) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || itMessage->type != ResultWas::Info) {\n                printMessage();\n                if (itMessage != itEnd) {\n                    Colour colourGuard(dimColour());\n                    stream << \" and\";\n                }\n                continue;\n            }\n            ++itMessage;\n        }\n    }\n\nprivate:\n    std::ostream& stream;\n    AssertionResult const& result;\n    std::vector<MessageInfo> messages;\n    std::vector<MessageInfo>::const_iterator itMessage;\n    bool printInfoMessages;\n};\n\n} // anon namespace\n\n        std::string CompactReporter::getDescription() {\n            return \"Reports test results on a single line, suitable for IDEs\";\n        }\n\n        void CompactReporter::noMatchingTestCases( std::string const& spec ) {\n            stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n        }\n\n        void CompactReporter::assertionStarting( AssertionInfo const& ) {}\n\n        bool CompactReporter::assertionEnded( AssertionStats const& _assertionStats ) {\n            AssertionResult const& result = _assertionStats.assertionResult;\n\n            bool printInfoMessages = true;\n\n            // Drop out if result was successful and we're not printing those\n            if( !m_config->includeSuccessfulResults() && result.isOk() ) {\n                if( result.getResultType() != ResultWas::Warning )\n                    return false;\n                printInfoMessages = false;\n            }\n\n            AssertionPrinter printer( stream, _assertionStats, printInfoMessages );\n            printer.print();\n\n            stream << std::endl;\n            return true;\n        }\n\n        void CompactReporter::sectionEnded(SectionStats const& _sectionStats) {\n            double dur = _sectionStats.durationInSeconds;\n            if ( shouldShowDuration( *m_config, dur ) ) {\n                stream << getFormattedDuration( dur ) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n            }\n        }\n\n        void CompactReporter::testRunEnded( TestRunStats const& _testRunStats ) {\n            printTotals( stream, _testRunStats.totals );\n            stream << '\\n' << std::endl;\n            StreamingReporterBase::testRunEnded( _testRunStats );\n        }\n\n        CompactReporter::~CompactReporter() {}\n\n    CATCH_REGISTER_REPORTER( \"compact\", CompactReporter )\n\n} // end namespace Catch\n// end catch_reporter_compact.cpp\n// start catch_reporter_console.cpp\n\n#include <cfloat>\n#include <cstdio>\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n // Note that 4062 (not all labels are handled and default is missing) is enabled\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic push\n// For simplicity, benchmarking-only helpers are always enabled\n#  pragma clang diagnostic ignored \"-Wunused-function\"\n#endif\n\nnamespace Catch {\n\nnamespace {\n\n// Formatter impl for ConsoleReporter\nclass ConsoleAssertionPrinter {\npublic:\n    ConsoleAssertionPrinter& operator= (ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(ConsoleAssertionPrinter const&) = delete;\n    ConsoleAssertionPrinter(std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages)\n        : stream(_stream),\n        stats(_stats),\n        result(_stats.assertionResult),\n        colour(Colour::None),\n        message(result.getMessage()),\n        messages(_stats.infoMessages),\n        printInfoMessages(_printInfoMessages) {\n        switch (result.getResultType()) {\n        case ResultWas::Ok:\n            colour = Colour::Success;\n            passOrFail = \"PASSED\";\n            //if( result.hasMessage() )\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ExpressionFailed:\n            if (result.isOk()) {\n                colour = Colour::Success;\n                passOrFail = \"FAILED - but was ok\";\n            } else {\n                colour = Colour::Error;\n                passOrFail = \"FAILED\";\n            }\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"with messages\";\n            break;\n        case ResultWas::ThrewException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to unexpected exception with \";\n            if (_stats.infoMessages.size() == 1)\n                messageLabel += \"message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel += \"messages\";\n            break;\n        case ResultWas::FatalErrorCondition:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"due to a fatal error condition\";\n            break;\n        case ResultWas::DidntThrowException:\n            colour = Colour::Error;\n            passOrFail = \"FAILED\";\n            messageLabel = \"because no exception was thrown where one was expected\";\n            break;\n        case ResultWas::Info:\n            messageLabel = \"info\";\n            break;\n        case ResultWas::Warning:\n            messageLabel = \"warning\";\n            break;\n        case ResultWas::ExplicitFailure:\n            passOrFail = \"FAILED\";\n            colour = Colour::Error;\n            if (_stats.infoMessages.size() == 1)\n                messageLabel = \"explicitly with message\";\n            if (_stats.infoMessages.size() > 1)\n                messageLabel = \"explicitly with messages\";\n            break;\n            // These cases are here to prevent compiler warnings\n        case ResultWas::Unknown:\n        case ResultWas::FailureBit:\n        case ResultWas::Exception:\n            passOrFail = \"** internal error **\";\n            colour = Colour::Error;\n            break;\n        }\n    }\n\n    void print() const {\n        printSourceInfo();\n        if (stats.totals.assertions.total() > 0) {\n            printResultType();\n            printOriginalExpression();\n            printReconstructedExpression();\n        } else {\n            stream << '\\n';\n        }\n        printMessage();\n    }\n\nprivate:\n    void printResultType() const {\n        if (!passOrFail.empty()) {\n            Colour colourGuard(colour);\n            stream << passOrFail << \":\\n\";\n        }\n    }\n    void printOriginalExpression() const {\n        if (result.hasExpression()) {\n            Colour colourGuard(Colour::OriginalExpression);\n            stream << \"  \";\n            stream << result.getExpressionInMacro();\n            stream << '\\n';\n        }\n    }\n    void printReconstructedExpression() const {\n        if (result.hasExpandedExpression()) {\n            stream << \"with expansion:\\n\";\n            Colour colourGuard(Colour::ReconstructedExpression);\n            stream << Column(result.getExpandedExpression()).indent(2) << '\\n';\n        }\n    }\n    void printMessage() const {\n        if (!messageLabel.empty())\n            stream << messageLabel << ':' << '\\n';\n        for (auto const& msg : messages) {\n            // If this assertion is a warning ignore any INFO messages\n            if (printInfoMessages || msg.type != ResultWas::Info)\n                stream << Column(msg.message).indent(2) << '\\n';\n        }\n    }\n    void printSourceInfo() const {\n        Colour colourGuard(Colour::FileName);\n        stream << result.getSourceInfo() << \": \";\n    }\n\n    std::ostream& stream;\n    AssertionStats const& stats;\n    AssertionResult const& result;\n    Colour::Code colour;\n    std::string passOrFail;\n    std::string messageLabel;\n    std::string message;\n    std::vector<MessageInfo> messages;\n    bool printInfoMessages;\n};\n\nstd::size_t makeRatio(std::size_t number, std::size_t total) {\n    std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0;\n    return (ratio == 0 && number > 0) ? 1 : ratio;\n}\n\nstd::size_t& findMax(std::size_t& i, std::size_t& j, std::size_t& k) {\n    if (i > j && i > k)\n        return i;\n    else if (j > k)\n        return j;\n    else\n        return k;\n}\n\nstruct ColumnInfo {\n    enum Justification { Left, Right };\n    std::string name;\n    int width;\n    Justification justification;\n};\nstruct ColumnBreak {};\nstruct RowBreak {};\n\nclass Duration {\n    enum class Unit {\n        Auto,\n        Nanoseconds,\n        Microseconds,\n        Milliseconds,\n        Seconds,\n        Minutes\n    };\n    static const uint64_t s_nanosecondsInAMicrosecond = 1000;\n    static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond;\n    static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond;\n    static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond;\n\n    double m_inNanoseconds;\n    Unit m_units;\n\npublic:\n    explicit Duration(double inNanoseconds, Unit units = Unit::Auto)\n        : m_inNanoseconds(inNanoseconds),\n        m_units(units) {\n        if (m_units == Unit::Auto) {\n            if (m_inNanoseconds < s_nanosecondsInAMicrosecond)\n                m_units = Unit::Nanoseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMillisecond)\n                m_units = Unit::Microseconds;\n            else if (m_inNanoseconds < s_nanosecondsInASecond)\n                m_units = Unit::Milliseconds;\n            else if (m_inNanoseconds < s_nanosecondsInAMinute)\n                m_units = Unit::Seconds;\n            else\n                m_units = Unit::Minutes;\n        }\n\n    }\n\n    auto value() const -> double {\n        switch (m_units) {\n        case Unit::Microseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMicrosecond);\n        case Unit::Milliseconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMillisecond);\n        case Unit::Seconds:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInASecond);\n        case Unit::Minutes:\n            return m_inNanoseconds / static_cast<double>(s_nanosecondsInAMinute);\n        default:\n            return m_inNanoseconds;\n        }\n    }\n    auto unitsAsString() const -> std::string {\n        switch (m_units) {\n        case Unit::Nanoseconds:\n            return \"ns\";\n        case Unit::Microseconds:\n            return \"us\";\n        case Unit::Milliseconds:\n            return \"ms\";\n        case Unit::Seconds:\n            return \"s\";\n        case Unit::Minutes:\n            return \"m\";\n        default:\n            return \"** internal error **\";\n        }\n\n    }\n    friend auto operator << (std::ostream& os, Duration const& duration) -> std::ostream& {\n        return os << duration.value() << ' ' << duration.unitsAsString();\n    }\n};\n} // end anon namespace\n\nclass TablePrinter {\n    std::ostream& m_os;\n    std::vector<ColumnInfo> m_columnInfos;\n    std::ostringstream m_oss;\n    int m_currentColumn = -1;\n    bool m_isOpen = false;\n\npublic:\n    TablePrinter( std::ostream& os, std::vector<ColumnInfo> columnInfos )\n    :   m_os( os ),\n        m_columnInfos( std::move( columnInfos ) ) {}\n\n    auto columnInfos() const -> std::vector<ColumnInfo> const& {\n        return m_columnInfos;\n    }\n\n    void open() {\n        if (!m_isOpen) {\n            m_isOpen = true;\n            *this << RowBreak();\n\n\t\t\tColumns headerCols;\n\t\t\tSpacer spacer(2);\n\t\t\tfor (auto const& info : m_columnInfos) {\n\t\t\t\theaderCols += Column(info.name).width(static_cast<std::size_t>(info.width - 2));\n\t\t\t\theaderCols += spacer;\n\t\t\t}\n\t\t\tm_os << headerCols << '\\n';\n\n            m_os << Catch::getLineOfChars<'-'>() << '\\n';\n        }\n    }\n    void close() {\n        if (m_isOpen) {\n            *this << RowBreak();\n            m_os << std::endl;\n            m_isOpen = false;\n        }\n    }\n\n    template<typename T>\n    friend TablePrinter& operator << (TablePrinter& tp, T const& value) {\n        tp.m_oss << value;\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, ColumnBreak) {\n        auto colStr = tp.m_oss.str();\n        const auto strSize = colStr.size();\n        tp.m_oss.str(\"\");\n        tp.open();\n        if (tp.m_currentColumn == static_cast<int>(tp.m_columnInfos.size() - 1)) {\n            tp.m_currentColumn = -1;\n            tp.m_os << '\\n';\n        }\n        tp.m_currentColumn++;\n\n        auto colInfo = tp.m_columnInfos[tp.m_currentColumn];\n        auto padding = (strSize + 1 < static_cast<std::size_t>(colInfo.width))\n            ? std::string(colInfo.width - (strSize + 1), ' ')\n            : std::string();\n        if (colInfo.justification == ColumnInfo::Left)\n            tp.m_os << colStr << padding << ' ';\n        else\n            tp.m_os << padding << colStr << ' ';\n        return tp;\n    }\n\n    friend TablePrinter& operator << (TablePrinter& tp, RowBreak) {\n        if (tp.m_currentColumn > 0) {\n            tp.m_os << '\\n';\n            tp.m_currentColumn = -1;\n        }\n        return tp;\n    }\n};\n\nConsoleReporter::ConsoleReporter(ReporterConfig const& config)\n    : StreamingReporterBase(config),\n    m_tablePrinter(new TablePrinter(config.stream(),\n        [&config]() -> std::vector<ColumnInfo> {\n        if (config.fullConfig()->benchmarkNoAnalysis())\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"     samples\", 14, ColumnInfo::Right },\n                { \"  iterations\", 14, ColumnInfo::Right },\n                { \"        mean\", 14, ColumnInfo::Right }\n            };\n        }\n        else\n        {\n            return{\n                { \"benchmark name\", CATCH_CONFIG_CONSOLE_WIDTH - 43, ColumnInfo::Left },\n                { \"samples      mean       std dev\", 14, ColumnInfo::Right },\n                { \"iterations   low mean   low std dev\", 14, ColumnInfo::Right },\n                { \"estimated    high mean  high std dev\", 14, ColumnInfo::Right }\n            };\n        }\n    }())) {}\nConsoleReporter::~ConsoleReporter() = default;\n\nstd::string ConsoleReporter::getDescription() {\n    return \"Reports test results as plain lines of text\";\n}\n\nvoid ConsoleReporter::noMatchingTestCases(std::string const& spec) {\n    stream << \"No test cases matched '\" << spec << '\\'' << std::endl;\n}\n\nvoid ConsoleReporter::reportInvalidArguments(std::string const&arg){\n    stream << \"Invalid Filter: \" << arg << std::endl;\n}\n\nvoid ConsoleReporter::assertionStarting(AssertionInfo const&) {}\n\nbool ConsoleReporter::assertionEnded(AssertionStats const& _assertionStats) {\n    AssertionResult const& result = _assertionStats.assertionResult;\n\n    bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n    // Drop out if result was successful but we're not printing them.\n    if (!includeResults && result.getResultType() != ResultWas::Warning)\n        return false;\n\n    lazyPrint();\n\n    ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults);\n    printer.print();\n    stream << std::endl;\n    return true;\n}\n\nvoid ConsoleReporter::sectionStarting(SectionInfo const& _sectionInfo) {\n    m_tablePrinter->close();\n    m_headerPrinted = false;\n    StreamingReporterBase::sectionStarting(_sectionInfo);\n}\nvoid ConsoleReporter::sectionEnded(SectionStats const& _sectionStats) {\n    m_tablePrinter->close();\n    if (_sectionStats.missingAssertions) {\n        lazyPrint();\n        Colour colour(Colour::ResultError);\n        if (m_sectionStack.size() > 1)\n            stream << \"\\nNo assertions in section\";\n        else\n            stream << \"\\nNo assertions in test case\";\n        stream << \" '\" << _sectionStats.sectionInfo.name << \"'\\n\" << std::endl;\n    }\n    double dur = _sectionStats.durationInSeconds;\n    if (shouldShowDuration(*m_config, dur)) {\n        stream << getFormattedDuration(dur) << \" s: \" << _sectionStats.sectionInfo.name << std::endl;\n    }\n    if (m_headerPrinted) {\n        m_headerPrinted = false;\n    }\n    StreamingReporterBase::sectionEnded(_sectionStats);\n}\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\nvoid ConsoleReporter::benchmarkPreparing(std::string const& name) {\n\tlazyPrintWithoutClosingBenchmarkTable();\n\n\tauto nameCol = Column(name).width(static_cast<std::size_t>(m_tablePrinter->columnInfos()[0].width - 2));\n\n\tbool firstLine = true;\n\tfor (auto line : nameCol) {\n\t\tif (!firstLine)\n\t\t\t(*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak();\n\t\telse\n\t\t\tfirstLine = false;\n\n\t\t(*m_tablePrinter) << line << ColumnBreak();\n\t}\n}\n\nvoid ConsoleReporter::benchmarkStarting(BenchmarkInfo const& info) {\n    (*m_tablePrinter) << info.samples << ColumnBreak()\n        << info.iterations << ColumnBreak();\n    if (!m_config->benchmarkNoAnalysis())\n        (*m_tablePrinter) << Duration(info.estimatedDuration) << ColumnBreak();\n}\nvoid ConsoleReporter::benchmarkEnded(BenchmarkStats<> const& stats) {\n    if (m_config->benchmarkNoAnalysis())\n    {\n        (*m_tablePrinter) << Duration(stats.mean.point.count()) << ColumnBreak();\n    }\n    else\n    {\n        (*m_tablePrinter) << ColumnBreak()\n            << Duration(stats.mean.point.count()) << ColumnBreak()\n            << Duration(stats.mean.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.mean.upper_bound.count()) << ColumnBreak() << ColumnBreak()\n            << Duration(stats.standardDeviation.point.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.lower_bound.count()) << ColumnBreak()\n            << Duration(stats.standardDeviation.upper_bound.count()) << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak() << ColumnBreak();\n    }\n}\n\nvoid ConsoleReporter::benchmarkFailed(std::string const& error) {\n\tColour colour(Colour::Red);\n    (*m_tablePrinter)\n        << \"Benchmark failed (\" << error << ')'\n        << ColumnBreak() << RowBreak();\n}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nvoid ConsoleReporter::testCaseEnded(TestCaseStats const& _testCaseStats) {\n    m_tablePrinter->close();\n    StreamingReporterBase::testCaseEnded(_testCaseStats);\n    m_headerPrinted = false;\n}\nvoid ConsoleReporter::testGroupEnded(TestGroupStats const& _testGroupStats) {\n    if (currentGroupInfo.used) {\n        printSummaryDivider();\n        stream << \"Summary for group '\" << _testGroupStats.groupInfo.name << \"':\\n\";\n        printTotals(_testGroupStats.totals);\n        stream << '\\n' << std::endl;\n    }\n    StreamingReporterBase::testGroupEnded(_testGroupStats);\n}\nvoid ConsoleReporter::testRunEnded(TestRunStats const& _testRunStats) {\n    printTotalsDivider(_testRunStats.totals);\n    printTotals(_testRunStats.totals);\n    stream << std::endl;\n    StreamingReporterBase::testRunEnded(_testRunStats);\n}\nvoid ConsoleReporter::testRunStarting(TestRunInfo const& _testInfo) {\n    StreamingReporterBase::testRunStarting(_testInfo);\n    printTestFilters();\n}\n\nvoid ConsoleReporter::lazyPrint() {\n\n    m_tablePrinter->close();\n    lazyPrintWithoutClosingBenchmarkTable();\n}\n\nvoid ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() {\n\n    if (!currentTestRunInfo.used)\n        lazyPrintRunInfo();\n    if (!currentGroupInfo.used)\n        lazyPrintGroupInfo();\n\n    if (!m_headerPrinted) {\n        printTestCaseAndSectionHeader();\n        m_headerPrinted = true;\n    }\n}\nvoid ConsoleReporter::lazyPrintRunInfo() {\n    stream << '\\n' << getLineOfChars<'~'>() << '\\n';\n    Colour colour(Colour::SecondaryText);\n    stream << currentTestRunInfo->name\n        << \" is a Catch v\" << libraryVersion() << \" host application.\\n\"\n        << \"Run with -? for options\\n\\n\";\n\n    if (m_config->rngSeed() != 0)\n        stream << \"Randomness seeded to: \" << m_config->rngSeed() << \"\\n\\n\";\n\n    currentTestRunInfo.used = true;\n}\nvoid ConsoleReporter::lazyPrintGroupInfo() {\n    if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) {\n        printClosedHeader(\"Group: \" + currentGroupInfo->name);\n        currentGroupInfo.used = true;\n    }\n}\nvoid ConsoleReporter::printTestCaseAndSectionHeader() {\n    assert(!m_sectionStack.empty());\n    printOpenHeader(currentTestCaseInfo->name);\n\n    if (m_sectionStack.size() > 1) {\n        Colour colourGuard(Colour::Headers);\n\n        auto\n            it = m_sectionStack.begin() + 1, // Skip first section (test case)\n            itEnd = m_sectionStack.end();\n        for (; it != itEnd; ++it)\n            printHeaderString(it->name, 2);\n    }\n\n    SourceLineInfo lineInfo = m_sectionStack.back().lineInfo;\n\n    stream << getLineOfChars<'-'>() << '\\n';\n    Colour colourGuard(Colour::FileName);\n    stream << lineInfo << '\\n';\n    stream << getLineOfChars<'.'>() << '\\n' << std::endl;\n}\n\nvoid ConsoleReporter::printClosedHeader(std::string const& _name) {\n    printOpenHeader(_name);\n    stream << getLineOfChars<'.'>() << '\\n';\n}\nvoid ConsoleReporter::printOpenHeader(std::string const& _name) {\n    stream << getLineOfChars<'-'>() << '\\n';\n    {\n        Colour colourGuard(Colour::Headers);\n        printHeaderString(_name);\n    }\n}\n\n// if string has a : in first line will set indent to follow it on\n// subsequent lines\nvoid ConsoleReporter::printHeaderString(std::string const& _string, std::size_t indent) {\n    std::size_t i = _string.find(\": \");\n    if (i != std::string::npos)\n        i += 2;\n    else\n        i = 0;\n    stream << Column(_string).indent(indent + i).initialIndent(indent) << '\\n';\n}\n\nstruct SummaryColumn {\n\n    SummaryColumn( std::string _label, Colour::Code _colour )\n    :   label( std::move( _label ) ),\n        colour( _colour ) {}\n    SummaryColumn addRow( std::size_t count ) {\n        ReusableStringStream rss;\n        rss << count;\n        std::string row = rss.str();\n        for (auto& oldRow : rows) {\n            while (oldRow.size() < row.size())\n                oldRow = ' ' + oldRow;\n            while (oldRow.size() > row.size())\n                row = ' ' + row;\n        }\n        rows.push_back(row);\n        return *this;\n    }\n\n    std::string label;\n    Colour::Code colour;\n    std::vector<std::string> rows;\n\n};\n\nvoid ConsoleReporter::printTotals( Totals const& totals ) {\n    if (totals.testCases.total() == 0) {\n        stream << Colour(Colour::Warning) << \"No tests ran\\n\";\n    } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) {\n        stream << Colour(Colour::ResultSuccess) << \"All tests passed\";\n        stream << \" (\"\n            << pluralise(totals.assertions.passed, \"assertion\") << \" in \"\n            << pluralise(totals.testCases.passed, \"test case\") << ')'\n            << '\\n';\n    } else {\n\n        std::vector<SummaryColumn> columns;\n        columns.push_back(SummaryColumn(\"\", Colour::None)\n                          .addRow(totals.testCases.total())\n                          .addRow(totals.assertions.total()));\n        columns.push_back(SummaryColumn(\"passed\", Colour::Success)\n                          .addRow(totals.testCases.passed)\n                          .addRow(totals.assertions.passed));\n        columns.push_back(SummaryColumn(\"failed\", Colour::ResultError)\n                          .addRow(totals.testCases.failed)\n                          .addRow(totals.assertions.failed));\n        columns.push_back(SummaryColumn(\"failed as expected\", Colour::ResultExpectedFailure)\n                          .addRow(totals.testCases.failedButOk)\n                          .addRow(totals.assertions.failedButOk));\n\n        printSummaryRow(\"test cases\", columns, 0);\n        printSummaryRow(\"assertions\", columns, 1);\n    }\n}\nvoid ConsoleReporter::printSummaryRow(std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row) {\n    for (auto col : cols) {\n        std::string value = col.rows[row];\n        if (col.label.empty()) {\n            stream << label << \": \";\n            if (value != \"0\")\n                stream << value;\n            else\n                stream << Colour(Colour::Warning) << \"- none -\";\n        } else if (value != \"0\") {\n            stream << Colour(Colour::LightGrey) << \" | \";\n            stream << Colour(col.colour)\n                << value << ' ' << col.label;\n        }\n    }\n    stream << '\\n';\n}\n\nvoid ConsoleReporter::printTotalsDivider(Totals const& totals) {\n    if (totals.testCases.total() > 0) {\n        std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total());\n        std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total());\n        std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total());\n        while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)++;\n        while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1)\n            findMax(failedRatio, failedButOkRatio, passedRatio)--;\n\n        stream << Colour(Colour::Error) << std::string(failedRatio, '=');\n        stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '=');\n        if (totals.testCases.allPassed())\n            stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '=');\n        else\n            stream << Colour(Colour::Success) << std::string(passedRatio, '=');\n    } else {\n        stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '=');\n    }\n    stream << '\\n';\n}\nvoid ConsoleReporter::printSummaryDivider() {\n    stream << getLineOfChars<'-'>() << '\\n';\n}\n\nvoid ConsoleReporter::printTestFilters() {\n    if (m_config->testSpec().hasFilters()) {\n        Colour guard(Colour::BrightYellow);\n        stream << \"Filters: \" << serializeFilters(m_config->getTestsOrTags()) << '\\n';\n    }\n}\n\nCATCH_REGISTER_REPORTER(\"console\", ConsoleReporter)\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n\n#if defined(__clang__)\n#  pragma clang diagnostic pop\n#endif\n// end catch_reporter_console.cpp\n// start catch_reporter_junit.cpp\n\n#include <cassert>\n#include <sstream>\n#include <ctime>\n#include <algorithm>\n#include <iomanip>\n\nnamespace Catch {\n\n    namespace {\n        std::string getCurrentTimestamp() {\n            // Beware, this is not reentrant because of backward compatibility issues\n            // Also, UTC only, again because of backward compatibility (%z is C++11)\n            time_t rawtime;\n            std::time(&rawtime);\n            auto const timeStampSize = sizeof(\"2017-01-16T17:06:45Z\");\n\n#ifdef _MSC_VER\n            std::tm timeInfo = {};\n            gmtime_s(&timeInfo, &rawtime);\n#else\n            std::tm* timeInfo;\n            timeInfo = std::gmtime(&rawtime);\n#endif\n\n            char timeStamp[timeStampSize];\n            const char * const fmt = \"%Y-%m-%dT%H:%M:%SZ\";\n\n#ifdef _MSC_VER\n            std::strftime(timeStamp, timeStampSize, fmt, &timeInfo);\n#else\n            std::strftime(timeStamp, timeStampSize, fmt, timeInfo);\n#endif\n            return std::string(timeStamp, timeStampSize-1);\n        }\n\n        std::string fileNameTag(const std::vector<std::string> &tags) {\n            auto it = std::find_if(begin(tags),\n                                   end(tags),\n                                   [] (std::string const& tag) {return tag.front() == '#'; });\n            if (it != tags.end())\n                return it->substr(1);\n            return std::string();\n        }\n\n        // Formats the duration in seconds to 3 decimal places.\n        // This is done because some genius defined Maven Surefire schema\n        // in a way that only accepts 3 decimal places, and tools like\n        // Jenkins use that schema for validation JUnit reporter output.\n        std::string formatDuration( double seconds ) {\n            ReusableStringStream rss;\n            rss << std::fixed << std::setprecision( 3 ) << seconds;\n            return rss.str();\n        }\n\n    } // anonymous namespace\n\n    JunitReporter::JunitReporter( ReporterConfig const& _config )\n        :   CumulativeReporterBase( _config ),\n            xml( _config.stream() )\n        {\n            m_reporterPrefs.shouldRedirectStdOut = true;\n            m_reporterPrefs.shouldReportAllAssertions = true;\n        }\n\n    JunitReporter::~JunitReporter() {}\n\n    std::string JunitReporter::getDescription() {\n        return \"Reports test results in an XML format that looks like Ant's junitreport target\";\n    }\n\n    void JunitReporter::noMatchingTestCases( std::string const& /*spec*/ ) {}\n\n    void JunitReporter::testRunStarting( TestRunInfo const& runInfo )  {\n        CumulativeReporterBase::testRunStarting( runInfo );\n        xml.startElement( \"testsuites\" );\n    }\n\n    void JunitReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        suiteTimer.start();\n        stdOutForSuite.clear();\n        stdErrForSuite.clear();\n        unexpectedExceptions = 0;\n        CumulativeReporterBase::testGroupStarting( groupInfo );\n    }\n\n    void JunitReporter::testCaseStarting( TestCaseInfo const& testCaseInfo ) {\n        m_okToFail = testCaseInfo.okToFail();\n    }\n\n    bool JunitReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail )\n            unexpectedExceptions++;\n        return CumulativeReporterBase::assertionEnded( assertionStats );\n    }\n\n    void JunitReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        stdOutForSuite += testCaseStats.stdOut;\n        stdErrForSuite += testCaseStats.stdErr;\n        CumulativeReporterBase::testCaseEnded( testCaseStats );\n    }\n\n    void JunitReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        double suiteTime = suiteTimer.getElapsedSeconds();\n        CumulativeReporterBase::testGroupEnded( testGroupStats );\n        writeGroup( *m_testGroups.back(), suiteTime );\n    }\n\n    void JunitReporter::testRunEndedCumulative() {\n        xml.endElement();\n    }\n\n    void JunitReporter::writeGroup( TestGroupNode const& groupNode, double suiteTime ) {\n        XmlWriter::ScopedElement e = xml.scopedElement( \"testsuite\" );\n\n        TestGroupStats const& stats = groupNode.value;\n        xml.writeAttribute( \"name\", stats.groupInfo.name );\n        xml.writeAttribute( \"errors\", unexpectedExceptions );\n        xml.writeAttribute( \"failures\", stats.totals.assertions.failed-unexpectedExceptions );\n        xml.writeAttribute( \"tests\", stats.totals.assertions.total() );\n        xml.writeAttribute( \"hostname\", \"tbd\" ); // !TBD\n        if( m_config->showDurations() == ShowDurations::Never )\n            xml.writeAttribute( \"time\", \"\" );\n        else\n            xml.writeAttribute( \"time\", formatDuration( suiteTime ) );\n        xml.writeAttribute( \"timestamp\", getCurrentTimestamp() );\n\n        // Write properties if there are any\n        if (m_config->hasTestFilters() || m_config->rngSeed() != 0) {\n            auto properties = xml.scopedElement(\"properties\");\n            if (m_config->hasTestFilters()) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"filters\")\n                    .writeAttribute(\"value\", serializeFilters(m_config->getTestsOrTags()));\n            }\n            if (m_config->rngSeed() != 0) {\n                xml.scopedElement(\"property\")\n                    .writeAttribute(\"name\", \"random-seed\")\n                    .writeAttribute(\"value\", m_config->rngSeed());\n            }\n        }\n\n        // Write test cases\n        for( auto const& child : groupNode.children )\n            writeTestCase( *child );\n\n        xml.scopedElement( \"system-out\" ).writeText( trim( stdOutForSuite ), XmlFormatting::Newline );\n        xml.scopedElement( \"system-err\" ).writeText( trim( stdErrForSuite ), XmlFormatting::Newline );\n    }\n\n    void JunitReporter::writeTestCase( TestCaseNode const& testCaseNode ) {\n        TestCaseStats const& stats = testCaseNode.value;\n\n        // All test cases have exactly one section - which represents the\n        // test case itself. That section may have 0-n nested sections\n        assert( testCaseNode.children.size() == 1 );\n        SectionNode const& rootSection = *testCaseNode.children.front();\n\n        std::string className = stats.testInfo.className;\n\n        if( className.empty() ) {\n            className = fileNameTag(stats.testInfo.tags);\n            if ( className.empty() )\n                className = \"global\";\n        }\n\n        if ( !m_config->name().empty() )\n            className = m_config->name() + \".\" + className;\n\n        writeSection( className, \"\", rootSection, stats.testInfo.okToFail() );\n    }\n\n    void JunitReporter::writeSection( std::string const& className,\n                                      std::string const& rootName,\n                                      SectionNode const& sectionNode,\n                                      bool testOkToFail) {\n        std::string name = trim( sectionNode.stats.sectionInfo.name );\n        if( !rootName.empty() )\n            name = rootName + '/' + name;\n\n        if( !sectionNode.assertions.empty() ||\n            !sectionNode.stdOut.empty() ||\n            !sectionNode.stdErr.empty() ) {\n            XmlWriter::ScopedElement e = xml.scopedElement( \"testcase\" );\n            if( className.empty() ) {\n                xml.writeAttribute( \"classname\", name );\n                xml.writeAttribute( \"name\", \"root\" );\n            }\n            else {\n                xml.writeAttribute( \"classname\", className );\n                xml.writeAttribute( \"name\", name );\n            }\n            xml.writeAttribute( \"time\", formatDuration( sectionNode.stats.durationInSeconds ) );\n            // This is not ideal, but it should be enough to mimic gtest's\n            // junit output.\n            // Ideally the JUnit reporter would also handle `skipTest`\n            // events and write those out appropriately.\n            xml.writeAttribute( \"status\", \"run\" );\n\n            if (sectionNode.stats.assertions.failedButOk) {\n                xml.scopedElement(\"skipped\")\n                    .writeAttribute(\"message\", \"TEST_CASE tagged with !mayfail\");\n            }\n\n            writeAssertions( sectionNode );\n\n            if( !sectionNode.stdOut.empty() )\n                xml.scopedElement( \"system-out\" ).writeText( trim( sectionNode.stdOut ), XmlFormatting::Newline );\n            if( !sectionNode.stdErr.empty() )\n                xml.scopedElement( \"system-err\" ).writeText( trim( sectionNode.stdErr ), XmlFormatting::Newline );\n        }\n        for( auto const& childNode : sectionNode.childSections )\n            if( className.empty() )\n                writeSection( name, \"\", *childNode, testOkToFail );\n            else\n                writeSection( className, name, *childNode, testOkToFail );\n    }\n\n    void JunitReporter::writeAssertions( SectionNode const& sectionNode ) {\n        for( auto const& assertion : sectionNode.assertions )\n            writeAssertion( assertion );\n    }\n\n    void JunitReporter::writeAssertion( AssertionStats const& stats ) {\n        AssertionResult const& result = stats.assertionResult;\n        if( !result.isOk() ) {\n            std::string elementName;\n            switch( result.getResultType() ) {\n                case ResultWas::ThrewException:\n                case ResultWas::FatalErrorCondition:\n                    elementName = \"error\";\n                    break;\n                case ResultWas::ExplicitFailure:\n                case ResultWas::ExpressionFailed:\n                case ResultWas::DidntThrowException:\n                    elementName = \"failure\";\n                    break;\n\n                // We should never see these here:\n                case ResultWas::Info:\n                case ResultWas::Warning:\n                case ResultWas::Ok:\n                case ResultWas::Unknown:\n                case ResultWas::FailureBit:\n                case ResultWas::Exception:\n                    elementName = \"internalError\";\n                    break;\n            }\n\n            XmlWriter::ScopedElement e = xml.scopedElement( elementName );\n\n            xml.writeAttribute( \"message\", result.getExpression() );\n            xml.writeAttribute( \"type\", result.getTestMacroName() );\n\n            ReusableStringStream rss;\n            if (stats.totals.assertions.total() > 0) {\n                rss << \"FAILED\" << \":\\n\";\n                if (result.hasExpression()) {\n                    rss << \"  \";\n                    rss << result.getExpressionInMacro();\n                    rss << '\\n';\n                }\n                if (result.hasExpandedExpression()) {\n                    rss << \"with expansion:\\n\";\n                    rss << Column(result.getExpandedExpression()).indent(2) << '\\n';\n                }\n            } else {\n                rss << '\\n';\n            }\n\n            if( !result.getMessage().empty() )\n                rss << result.getMessage() << '\\n';\n            for( auto const& msg : stats.infoMessages )\n                if( msg.type == ResultWas::Info )\n                    rss << msg.message << '\\n';\n\n            rss << \"at \" << result.getSourceInfo();\n            xml.writeText( rss.str(), XmlFormatting::Newline );\n        }\n    }\n\n    CATCH_REGISTER_REPORTER( \"junit\", JunitReporter )\n\n} // end namespace Catch\n// end catch_reporter_junit.cpp\n// start catch_reporter_listening.cpp\n\n#include <cassert>\n\nnamespace Catch {\n\n    ListeningReporter::ListeningReporter() {\n        // We will assume that listeners will always want all assertions\n        m_preferences.shouldReportAllAssertions = true;\n    }\n\n    void ListeningReporter::addListener( IStreamingReporterPtr&& listener ) {\n        m_listeners.push_back( std::move( listener ) );\n    }\n\n    void ListeningReporter::addReporter(IStreamingReporterPtr&& reporter) {\n        assert(!m_reporter && \"Listening reporter can wrap only 1 real reporter\");\n        m_reporter = std::move( reporter );\n        m_preferences.shouldRedirectStdOut = m_reporter->getPreferences().shouldRedirectStdOut;\n    }\n\n    ReporterPreferences ListeningReporter::getPreferences() const {\n        return m_preferences;\n    }\n\n    std::set<Verbosity> ListeningReporter::getSupportedVerbosities() {\n        return std::set<Verbosity>{ };\n    }\n\n    void ListeningReporter::noMatchingTestCases( std::string const& spec ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->noMatchingTestCases( spec );\n        }\n        m_reporter->noMatchingTestCases( spec );\n    }\n\n    void ListeningReporter::reportInvalidArguments(std::string const&arg){\n        for ( auto const& listener : m_listeners ) {\n            listener->reportInvalidArguments( arg );\n        }\n        m_reporter->reportInvalidArguments( arg );\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void ListeningReporter::benchmarkPreparing( std::string const& name ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkPreparing(name);\n\t\t}\n\t\tm_reporter->benchmarkPreparing(name);\n\t}\n    void ListeningReporter::benchmarkStarting( BenchmarkInfo const& benchmarkInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkStarting( benchmarkInfo );\n        }\n        m_reporter->benchmarkStarting( benchmarkInfo );\n    }\n    void ListeningReporter::benchmarkEnded( BenchmarkStats<> const& benchmarkStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->benchmarkEnded( benchmarkStats );\n        }\n        m_reporter->benchmarkEnded( benchmarkStats );\n    }\n\n\tvoid ListeningReporter::benchmarkFailed( std::string const& error ) {\n\t\tfor (auto const& listener : m_listeners) {\n\t\t\tlistener->benchmarkFailed(error);\n\t\t}\n\t\tm_reporter->benchmarkFailed(error);\n\t}\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    void ListeningReporter::testRunStarting( TestRunInfo const& testRunInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunStarting( testRunInfo );\n        }\n        m_reporter->testRunStarting( testRunInfo );\n    }\n\n    void ListeningReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupStarting( groupInfo );\n        }\n        m_reporter->testGroupStarting( groupInfo );\n    }\n\n    void ListeningReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseStarting( testInfo );\n        }\n        m_reporter->testCaseStarting( testInfo );\n    }\n\n    void ListeningReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionStarting( sectionInfo );\n        }\n        m_reporter->sectionStarting( sectionInfo );\n    }\n\n    void ListeningReporter::assertionStarting( AssertionInfo const& assertionInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->assertionStarting( assertionInfo );\n        }\n        m_reporter->assertionStarting( assertionInfo );\n    }\n\n    // The return value indicates if the messages buffer should be cleared:\n    bool ListeningReporter::assertionEnded( AssertionStats const& assertionStats ) {\n        for( auto const& listener : m_listeners ) {\n            static_cast<void>( listener->assertionEnded( assertionStats ) );\n        }\n        return m_reporter->assertionEnded( assertionStats );\n    }\n\n    void ListeningReporter::sectionEnded( SectionStats const& sectionStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->sectionEnded( sectionStats );\n        }\n        m_reporter->sectionEnded( sectionStats );\n    }\n\n    void ListeningReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testCaseEnded( testCaseStats );\n        }\n        m_reporter->testCaseEnded( testCaseStats );\n    }\n\n    void ListeningReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testGroupEnded( testGroupStats );\n        }\n        m_reporter->testGroupEnded( testGroupStats );\n    }\n\n    void ListeningReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->testRunEnded( testRunStats );\n        }\n        m_reporter->testRunEnded( testRunStats );\n    }\n\n    void ListeningReporter::skipTest( TestCaseInfo const& testInfo ) {\n        for ( auto const& listener : m_listeners ) {\n            listener->skipTest( testInfo );\n        }\n        m_reporter->skipTest( testInfo );\n    }\n\n    bool ListeningReporter::isMulti() const {\n        return true;\n    }\n\n} // end namespace Catch\n// end catch_reporter_listening.cpp\n// start catch_reporter_xml.cpp\n\n#if defined(_MSC_VER)\n#pragma warning(push)\n#pragma warning(disable:4061) // Not all labels are EXPLICITLY handled in switch\n                              // Note that 4062 (not all labels are handled\n                              // and default is missing) is enabled\n#endif\n\nnamespace Catch {\n    XmlReporter::XmlReporter( ReporterConfig const& _config )\n    :   StreamingReporterBase( _config ),\n        m_xml(_config.stream())\n    {\n        m_reporterPrefs.shouldRedirectStdOut = true;\n        m_reporterPrefs.shouldReportAllAssertions = true;\n    }\n\n    XmlReporter::~XmlReporter() = default;\n\n    std::string XmlReporter::getDescription() {\n        return \"Reports test results as an XML document\";\n    }\n\n    std::string XmlReporter::getStylesheetRef() const {\n        return std::string();\n    }\n\n    void XmlReporter::writeSourceInfo( SourceLineInfo const& sourceInfo ) {\n        m_xml\n            .writeAttribute( \"filename\", sourceInfo.file )\n            .writeAttribute( \"line\", sourceInfo.line );\n    }\n\n    void XmlReporter::noMatchingTestCases( std::string const& s ) {\n        StreamingReporterBase::noMatchingTestCases( s );\n    }\n\n    void XmlReporter::testRunStarting( TestRunInfo const& testInfo ) {\n        StreamingReporterBase::testRunStarting( testInfo );\n        std::string stylesheetRef = getStylesheetRef();\n        if( !stylesheetRef.empty() )\n            m_xml.writeStylesheetRef( stylesheetRef );\n        m_xml.startElement( \"Catch\" );\n        if( !m_config->name().empty() )\n            m_xml.writeAttribute( \"name\", m_config->name() );\n        if (m_config->testSpec().hasFilters())\n            m_xml.writeAttribute( \"filters\", serializeFilters( m_config->getTestsOrTags() ) );\n        if( m_config->rngSeed() != 0 )\n            m_xml.scopedElement( \"Randomness\" )\n                .writeAttribute( \"seed\", m_config->rngSeed() );\n    }\n\n    void XmlReporter::testGroupStarting( GroupInfo const& groupInfo ) {\n        StreamingReporterBase::testGroupStarting( groupInfo );\n        m_xml.startElement( \"Group\" )\n            .writeAttribute( \"name\", groupInfo.name );\n    }\n\n    void XmlReporter::testCaseStarting( TestCaseInfo const& testInfo ) {\n        StreamingReporterBase::testCaseStarting(testInfo);\n        m_xml.startElement( \"TestCase\" )\n            .writeAttribute( \"name\", trim( testInfo.name ) )\n            .writeAttribute( \"description\", testInfo.description )\n            .writeAttribute( \"tags\", testInfo.tagsAsString() );\n\n        writeSourceInfo( testInfo.lineInfo );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            m_testCaseTimer.start();\n        m_xml.ensureTagClosed();\n    }\n\n    void XmlReporter::sectionStarting( SectionInfo const& sectionInfo ) {\n        StreamingReporterBase::sectionStarting( sectionInfo );\n        if( m_sectionDepth++ > 0 ) {\n            m_xml.startElement( \"Section\" )\n                .writeAttribute( \"name\", trim( sectionInfo.name ) );\n            writeSourceInfo( sectionInfo.lineInfo );\n            m_xml.ensureTagClosed();\n        }\n    }\n\n    void XmlReporter::assertionStarting( AssertionInfo const& ) { }\n\n    bool XmlReporter::assertionEnded( AssertionStats const& assertionStats ) {\n\n        AssertionResult const& result = assertionStats.assertionResult;\n\n        bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();\n\n        if( includeResults || result.getResultType() == ResultWas::Warning ) {\n            // Print any info messages in <Info> tags.\n            for( auto const& msg : assertionStats.infoMessages ) {\n                if( msg.type == ResultWas::Info && includeResults ) {\n                    m_xml.scopedElement( \"Info\" )\n                            .writeText( msg.message );\n                } else if ( msg.type == ResultWas::Warning ) {\n                    m_xml.scopedElement( \"Warning\" )\n                            .writeText( msg.message );\n                }\n            }\n        }\n\n        // Drop out if result was successful but we're not printing them.\n        if( !includeResults && result.getResultType() != ResultWas::Warning )\n            return true;\n\n        // Print the expression if there is one.\n        if( result.hasExpression() ) {\n            m_xml.startElement( \"Expression\" )\n                .writeAttribute( \"success\", result.succeeded() )\n                .writeAttribute( \"type\", result.getTestMacroName() );\n\n            writeSourceInfo( result.getSourceInfo() );\n\n            m_xml.scopedElement( \"Original\" )\n                .writeText( result.getExpression() );\n            m_xml.scopedElement( \"Expanded\" )\n                .writeText( result.getExpandedExpression() );\n        }\n\n        // And... Print a result applicable to each result type.\n        switch( result.getResultType() ) {\n            case ResultWas::ThrewException:\n                m_xml.startElement( \"Exception\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::FatalErrorCondition:\n                m_xml.startElement( \"FatalErrorCondition\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            case ResultWas::Info:\n                m_xml.scopedElement( \"Info\" )\n                    .writeText( result.getMessage() );\n                break;\n            case ResultWas::Warning:\n                // Warning will already have been written\n                break;\n            case ResultWas::ExplicitFailure:\n                m_xml.startElement( \"Failure\" );\n                writeSourceInfo( result.getSourceInfo() );\n                m_xml.writeText( result.getMessage() );\n                m_xml.endElement();\n                break;\n            default:\n                break;\n        }\n\n        if( result.hasExpression() )\n            m_xml.endElement();\n\n        return true;\n    }\n\n    void XmlReporter::sectionEnded( SectionStats const& sectionStats ) {\n        StreamingReporterBase::sectionEnded( sectionStats );\n        if( --m_sectionDepth > 0 ) {\n            XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResults\" );\n            e.writeAttribute( \"successes\", sectionStats.assertions.passed );\n            e.writeAttribute( \"failures\", sectionStats.assertions.failed );\n            e.writeAttribute( \"expectedFailures\", sectionStats.assertions.failedButOk );\n\n            if ( m_config->showDurations() == ShowDurations::Always )\n                e.writeAttribute( \"durationInSeconds\", sectionStats.durationInSeconds );\n\n            m_xml.endElement();\n        }\n    }\n\n    void XmlReporter::testCaseEnded( TestCaseStats const& testCaseStats ) {\n        StreamingReporterBase::testCaseEnded( testCaseStats );\n        XmlWriter::ScopedElement e = m_xml.scopedElement( \"OverallResult\" );\n        e.writeAttribute( \"success\", testCaseStats.totals.assertions.allOk() );\n\n        if ( m_config->showDurations() == ShowDurations::Always )\n            e.writeAttribute( \"durationInSeconds\", m_testCaseTimer.getElapsedSeconds() );\n\n        if( !testCaseStats.stdOut.empty() )\n            m_xml.scopedElement( \"StdOut\" ).writeText( trim( testCaseStats.stdOut ), XmlFormatting::Newline );\n        if( !testCaseStats.stdErr.empty() )\n            m_xml.scopedElement( \"StdErr\" ).writeText( trim( testCaseStats.stdErr ), XmlFormatting::Newline );\n\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testGroupEnded( TestGroupStats const& testGroupStats ) {\n        StreamingReporterBase::testGroupEnded( testGroupStats );\n        // TODO: Check testGroupStats.aborting and act accordingly.\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testGroupStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testGroupStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testGroupStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testGroupStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n    void XmlReporter::testRunEnded( TestRunStats const& testRunStats ) {\n        StreamingReporterBase::testRunEnded( testRunStats );\n        m_xml.scopedElement( \"OverallResults\" )\n            .writeAttribute( \"successes\", testRunStats.totals.assertions.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.assertions.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.assertions.failedButOk );\n        m_xml.scopedElement( \"OverallResultsCases\")\n            .writeAttribute( \"successes\", testRunStats.totals.testCases.passed )\n            .writeAttribute( \"failures\", testRunStats.totals.testCases.failed )\n            .writeAttribute( \"expectedFailures\", testRunStats.totals.testCases.failedButOk );\n        m_xml.endElement();\n    }\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n    void XmlReporter::benchmarkPreparing(std::string const& name) {\n        m_xml.startElement(\"BenchmarkResults\")\n            .writeAttribute(\"name\", name);\n    }\n\n    void XmlReporter::benchmarkStarting(BenchmarkInfo const &info) {\n        m_xml.writeAttribute(\"samples\", info.samples)\n            .writeAttribute(\"resamples\", info.resamples)\n            .writeAttribute(\"iterations\", info.iterations)\n            .writeAttribute(\"clockResolution\", info.clockResolution)\n            .writeAttribute(\"estimatedDuration\", info.estimatedDuration)\n            .writeComment(\"All values in nano seconds\");\n    }\n\n    void XmlReporter::benchmarkEnded(BenchmarkStats<> const& benchmarkStats) {\n        m_xml.startElement(\"mean\")\n            .writeAttribute(\"value\", benchmarkStats.mean.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.mean.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.mean.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.mean.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"standardDeviation\")\n            .writeAttribute(\"value\", benchmarkStats.standardDeviation.point.count())\n            .writeAttribute(\"lowerBound\", benchmarkStats.standardDeviation.lower_bound.count())\n            .writeAttribute(\"upperBound\", benchmarkStats.standardDeviation.upper_bound.count())\n            .writeAttribute(\"ci\", benchmarkStats.standardDeviation.confidence_interval);\n        m_xml.endElement();\n        m_xml.startElement(\"outliers\")\n            .writeAttribute(\"variance\", benchmarkStats.outlierVariance)\n            .writeAttribute(\"lowMild\", benchmarkStats.outliers.low_mild)\n            .writeAttribute(\"lowSevere\", benchmarkStats.outliers.low_severe)\n            .writeAttribute(\"highMild\", benchmarkStats.outliers.high_mild)\n            .writeAttribute(\"highSevere\", benchmarkStats.outliers.high_severe);\n        m_xml.endElement();\n        m_xml.endElement();\n    }\n\n    void XmlReporter::benchmarkFailed(std::string const &error) {\n        m_xml.scopedElement(\"failed\").\n            writeAttribute(\"message\", error);\n        m_xml.endElement();\n    }\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n    CATCH_REGISTER_REPORTER( \"xml\", XmlReporter )\n\n} // end namespace Catch\n\n#if defined(_MSC_VER)\n#pragma warning(pop)\n#endif\n// end catch_reporter_xml.cpp\n\nnamespace Catch {\n    LeakDetector leakDetector;\n}\n\n#ifdef __clang__\n#pragma clang diagnostic pop\n#endif\n\n// end catch_impl.hpp\n#endif\n\n#ifdef CATCH_CONFIG_MAIN\n// start catch_default_main.hpp\n\n#ifndef __OBJC__\n\n#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)\n// Standard C/C++ Win32 Unicode wmain entry point\nextern \"C\" int wmain (int argc, wchar_t * argv[], wchar_t * []) {\n#else\n// Standard C/C++ main entry point\nint main (int argc, char * argv[]) {\n#endif\n\n    return Catch::Session().run( argc, argv );\n}\n\n#else // __OBJC__\n\n// Objective-C entry point\nint main (int argc, char * const argv[]) {\n#if !CATCH_ARC_ENABLED\n    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];\n#endif\n\n    Catch::registerTestMethods();\n    int result = Catch::Session().run( argc, (char**)argv );\n\n#if !CATCH_ARC_ENABLED\n    [pool drain];\n#endif\n\n    return result;\n}\n\n#endif // __OBJC__\n\n// end catch_default_main.hpp\n#endif\n\n#if !defined(CATCH_CONFIG_IMPL_ONLY)\n\n#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED\n#  undef CLARA_CONFIG_MAIN\n#endif\n\n#if !defined(CATCH_CONFIG_DISABLE)\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define CATCH_REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"CATCH_REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CATCH_CHECK( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CATCH_CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CATCH_CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CATCH_CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CATCH_CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CATCH_CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CATCH_CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CATCH_CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CATCH_CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CATCH_CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CATCH_CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CATCH_CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CATCH_REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( \"CATCH_INFO\", msg )\n#define CATCH_UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"CATCH_UNSCOPED_INFO\", msg )\n#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( \"CATCH_WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CATCH_CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CATCH_CAPTURE\",__VA_ARGS__ )\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define CATCH_DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define CATCH_FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"CATCH_FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( \"CATCH_SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define CATCH_STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__ ,      #__VA_ARGS__ );     CATCH_SUCCEED( #__VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); CATCH_SUCCEED( #__VA_ARGS__ )\n#else\n#define CATCH_STATIC_REQUIRE( ... )       CATCH_REQUIRE( __VA_ARGS__ )\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) CATCH_REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n#define CATCH_GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define CATCH_AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define CATCH_WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define CATCH_AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define CATCH_THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define CATCH_AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define CATCH_BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define CATCH_BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE\", Catch::ResultDisposition::Normal, __VA_ARGS__  )\n#define REQUIRE_FALSE( ... ) INTERNAL_CATCH_TEST( \"REQUIRE_FALSE\", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n\n#define REQUIRE_THROWS( ... ) INTERNAL_CATCH_THROWS( \"REQUIRE_THROWS\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"REQUIRE_THROWS_AS\", exceptionType, Catch::ResultDisposition::Normal, expr )\n#define REQUIRE_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"REQUIRE_THROWS_WITH\", Catch::ResultDisposition::Normal, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"REQUIRE_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::Normal, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"REQUIRE_NOTHROW\", Catch::ResultDisposition::Normal, __VA_ARGS__ )\n\n#define CHECK( ... ) INTERNAL_CATCH_TEST( \"CHECK\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_FALSE( ... ) INTERNAL_CATCH_TEST( \"CHECK_FALSE\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__ )\n#define CHECKED_IF( ... ) INTERNAL_CATCH_IF( \"CHECKED_IF\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECKED_ELSE( ... ) INTERNAL_CATCH_ELSE( \"CHECKED_ELSE\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_NOFAIL( ... ) INTERNAL_CATCH_TEST( \"CHECK_NOFAIL\", Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, __VA_ARGS__ )\n\n#define CHECK_THROWS( ... )  INTERNAL_CATCH_THROWS( \"CHECK_THROWS\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( \"CHECK_THROWS_AS\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr )\n#define CHECK_THROWS_WITH( expr, matcher ) INTERNAL_CATCH_THROWS_STR_MATCHES( \"CHECK_THROWS_WITH\", Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) INTERNAL_CATCH_THROWS_MATCHES( \"CHECK_THROWS_MATCHES\", exceptionType, Catch::ResultDisposition::ContinueOnFailure, matcher, expr )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) INTERNAL_CATCH_NO_THROW( \"CHECK_NOTHROW\", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"CHECK_THAT\", matcher, Catch::ResultDisposition::ContinueOnFailure, arg )\n\n#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( \"REQUIRE_THAT\", matcher, Catch::ResultDisposition::Normal, arg )\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) INTERNAL_CATCH_INFO( \"INFO\", msg )\n#define UNSCOPED_INFO( msg ) INTERNAL_CATCH_UNSCOPED_INFO( \"UNSCOPED_INFO\", msg )\n#define WARN( msg ) INTERNAL_CATCH_MSG( \"WARN\", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg )\n#define CAPTURE( ... ) INTERNAL_CATCH_CAPTURE( INTERNAL_CATCH_UNIQUE_NAME(capturer), \"CAPTURE\",__VA_ARGS__ )\n\n#define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ )\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ )\n#define REGISTER_TEST_CASE( Function, ... ) INTERNAL_CATCH_REGISTER_TESTCASE( Function, __VA_ARGS__ )\n#define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ )\n#define DYNAMIC_SECTION( ... ) INTERNAL_CATCH_DYNAMIC_SECTION( __VA_ARGS__ )\n#define FAIL( ... ) INTERNAL_CATCH_MSG( \"FAIL\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__ )\n#define FAIL_CHECK( ... ) INTERNAL_CATCH_MSG( \"FAIL_CHECK\", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define SUCCEED( ... ) INTERNAL_CATCH_MSG( \"SUCCEED\", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__ )\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE()\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE(__VA_ARGS__)\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE( __VA_ARGS__ ) )\n#define TEMPLATE_LIST_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_LIST_TEST_CASE_METHOD( className, __VA_ARGS__ ) )\n#endif\n\n#if !defined(CATCH_CONFIG_RUNTIME_STATIC_REQUIRE)\n#define STATIC_REQUIRE( ... )       static_assert(   __VA_ARGS__,  #__VA_ARGS__ ); SUCCEED( #__VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) static_assert( !(__VA_ARGS__), \"!(\" #__VA_ARGS__ \")\" ); SUCCEED( \"!(\" #__VA_ARGS__ \")\" )\n#else\n#define STATIC_REQUIRE( ... )       REQUIRE( __VA_ARGS__ )\n#define STATIC_REQUIRE_FALSE( ... ) REQUIRE_FALSE( __VA_ARGS__ )\n#endif\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) TEST_CASE( \"Scenario: \" __VA_ARGS__ )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, \"Scenario: \" __VA_ARGS__ )\n\n#define GIVEN( desc )     INTERNAL_CATCH_DYNAMIC_SECTION( \"    Given: \" << desc )\n#define AND_GIVEN( desc ) INTERNAL_CATCH_DYNAMIC_SECTION( \"And given: \" << desc )\n#define WHEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     When: \" << desc )\n#define AND_WHEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \" And when: \" << desc )\n#define THEN( desc )      INTERNAL_CATCH_DYNAMIC_SECTION( \"     Then: \" << desc )\n#define AND_THEN( desc )  INTERNAL_CATCH_DYNAMIC_SECTION( \"      And: \" << desc )\n\n#if defined(CATCH_CONFIG_ENABLE_BENCHMARKING)\n#define BENCHMARK(...) \\\n    INTERNAL_CATCH_BENCHMARK(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), INTERNAL_CATCH_GET_1_ARG(__VA_ARGS__,,), INTERNAL_CATCH_GET_2_ARG(__VA_ARGS__,,))\n#define BENCHMARK_ADVANCED(name) \\\n    INTERNAL_CATCH_BENCHMARK_ADVANCED(INTERNAL_CATCH_UNIQUE_NAME(C_A_T_C_H_B_E_N_C_H_), name)\n#endif // CATCH_CONFIG_ENABLE_BENCHMARKING\n\nusing Catch::Detail::Approx;\n\n#else // CATCH_CONFIG_DISABLE\n\n//////\n// If this config identifier is defined then all CATCH macros are prefixed with CATCH_\n#ifdef CATCH_CONFIG_PREFIX_ALL\n\n#define CATCH_REQUIRE( ... )        (void)(0)\n#define CATCH_REQUIRE_FALSE( ... )  (void)(0)\n\n#define CATCH_REQUIRE_THROWS( ... ) (void)(0)\n#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_REQUIRE_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif// CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CATCH_CHECK( ... )         (void)(0)\n#define CATCH_CHECK_FALSE( ... )   (void)(0)\n#define CATCH_CHECKED_IF( ... )    if (__VA_ARGS__)\n#define CATCH_CHECKED_ELSE( ... )  if (!(__VA_ARGS__))\n#define CATCH_CHECK_NOFAIL( ... )  (void)(0)\n\n#define CATCH_CHECK_THROWS( ... )  (void)(0)\n#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CATCH_CHECK_THROWS_WITH( expr, matcher )     (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CATCH_CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CATCH_CHECK_THAT( arg, matcher )   (void)(0)\n\n#define CATCH_REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define CATCH_INFO( msg )          (void)(0)\n#define CATCH_UNSCOPED_INFO( msg ) (void)(0)\n#define CATCH_WARN( msg )          (void)(0)\n#define CATCH_CAPTURE( msg )       (void)(0)\n\n#define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_METHOD_AS_TEST_CASE( method, ... )\n#define CATCH_REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define CATCH_SECTION( ... )\n#define CATCH_DYNAMIC_SECTION( ... )\n#define CATCH_FAIL( ... ) (void)(0)\n#define CATCH_FAIL_CHECK( ... ) (void)(0)\n#define CATCH_SUCCEED( ... ) (void)(0)\n\n#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define CATCH_TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) CATCH_TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define CATCH_TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) CATCH_TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n// \"BDD-style\" convenience wrappers\n#define CATCH_SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n#define CATCH_GIVEN( desc )\n#define CATCH_AND_GIVEN( desc )\n#define CATCH_WHEN( desc )\n#define CATCH_AND_WHEN( desc )\n#define CATCH_THEN( desc )\n#define CATCH_AND_THEN( desc )\n\n#define CATCH_STATIC_REQUIRE( ... )       (void)(0)\n#define CATCH_STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required\n#else\n\n#define REQUIRE( ... )       (void)(0)\n#define REQUIRE_FALSE( ... ) (void)(0)\n\n#define REQUIRE_THROWS( ... ) (void)(0)\n#define REQUIRE_THROWS_AS( expr, exceptionType ) (void)(0)\n#define REQUIRE_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define REQUIRE_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define REQUIRE_NOTHROW( ... ) (void)(0)\n\n#define CHECK( ... ) (void)(0)\n#define CHECK_FALSE( ... ) (void)(0)\n#define CHECKED_IF( ... ) if (__VA_ARGS__)\n#define CHECKED_ELSE( ... ) if (!(__VA_ARGS__))\n#define CHECK_NOFAIL( ... ) (void)(0)\n\n#define CHECK_THROWS( ... )  (void)(0)\n#define CHECK_THROWS_AS( expr, exceptionType ) (void)(0)\n#define CHECK_THROWS_WITH( expr, matcher ) (void)(0)\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THROWS_MATCHES( expr, exceptionType, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n#define CHECK_NOTHROW( ... ) (void)(0)\n\n#if !defined(CATCH_CONFIG_DISABLE_MATCHERS)\n#define CHECK_THAT( arg, matcher ) (void)(0)\n\n#define REQUIRE_THAT( arg, matcher ) (void)(0)\n#endif // CATCH_CONFIG_DISABLE_MATCHERS\n\n#define INFO( msg ) (void)(0)\n#define UNSCOPED_INFO( msg ) (void)(0)\n#define WARN( msg ) (void)(0)\n#define CAPTURE( ... ) (void)(0)\n\n#define TEST_CASE( ... )  INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n#define METHOD_AS_TEST_CASE( method, ... )\n#define REGISTER_TEST_CASE( Function, ... ) (void)(0)\n#define SECTION( ... )\n#define DYNAMIC_SECTION( ... )\n#define FAIL( ... ) (void)(0)\n#define FAIL_CHECK( ... ) (void)(0)\n#define SUCCEED( ... ) (void)(0)\n#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ))\n\n#ifndef CATCH_CONFIG_TRADITIONAL_MSVC_PREPROCESSOR\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__)\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#else\n#define TEMPLATE_TEST_CASE( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_SIG( ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_SIG_NO_REGISTRATION(__VA_ARGS__) )\n#define TEMPLATE_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_TEST_CASE_METHOD_SIG( className, ... ) INTERNAL_CATCH_EXPAND_VARGS( INTERNAL_CATCH_TEMPLATE_TEST_CASE_METHOD_SIG_NO_REGISTRATION(className, __VA_ARGS__ ) )\n#define TEMPLATE_PRODUCT_TEST_CASE( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_SIG( ... ) TEMPLATE_TEST_CASE( __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#define TEMPLATE_PRODUCT_TEST_CASE_METHOD_SIG( className, ... ) TEMPLATE_TEST_CASE_METHOD( className, __VA_ARGS__ )\n#endif\n\n#define STATIC_REQUIRE( ... )       (void)(0)\n#define STATIC_REQUIRE_FALSE( ... ) (void)(0)\n\n#endif\n\n#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG( INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ), signature )\n\n// \"BDD-style\" convenience wrappers\n#define SCENARIO( ... ) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ) )\n#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME( C_A_T_C_H_T_E_S_T_ ), className )\n\n#define GIVEN( desc )\n#define AND_GIVEN( desc )\n#define WHEN( desc )\n#define AND_WHEN( desc )\n#define THEN( desc )\n#define AND_THEN( desc )\n\nusing Catch::Detail::Approx;\n\n#endif\n\n#endif // ! CATCH_CONFIG_IMPL_ONLY\n\n// start catch_reenable_warnings.h\n\n\n#ifdef __clang__\n#    ifdef __ICC // icpc defines the __clang__ macro\n#        pragma warning(pop)\n#    else\n#        pragma clang diagnostic pop\n#    endif\n#elif defined __GNUC__\n#    pragma GCC diagnostic pop\n#endif\n\n// end catch_reenable_warnings.h\n// end catch.hpp\n#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED\n\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/conftest.py",
    "content": "# -*- coding: utf-8 -*-\n\"\"\"pytest configuration\n\nExtends output capture as needed by pybind11: ignore constructors, optional unordered lines.\nAdds docstring and exceptions message sanitizers: ignore Python 2 vs 3 differences.\n\"\"\"\n\nimport contextlib\nimport difflib\nimport gc\nimport re\nimport textwrap\n\nimport pytest\n\nimport env\n\n# Early diagnostic for failed imports\nimport pybind11_tests  # noqa: F401\n\n_unicode_marker = re.compile(r\"u(\\'[^\\']*\\')\")\n_long_marker = re.compile(r\"([0-9])L\")\n_hexadecimal = re.compile(r\"0x[0-9a-fA-F]+\")\n\n# Avoid collecting Python3 only files\ncollect_ignore = []\nif env.PY2:\n    collect_ignore.append(\"test_async.py\")\n\n\ndef _strip_and_dedent(s):\n    \"\"\"For triple-quote strings\"\"\"\n    return textwrap.dedent(s.lstrip(\"\\n\").rstrip())\n\n\ndef _split_and_sort(s):\n    \"\"\"For output which does not require specific line order\"\"\"\n    return sorted(_strip_and_dedent(s).splitlines())\n\n\ndef _make_explanation(a, b):\n    \"\"\"Explanation for a failed assert -- the a and b arguments are List[str]\"\"\"\n    return [\"--- actual / +++ expected\"] + [\n        line.strip(\"\\n\") for line in difflib.ndiff(a, b)\n    ]\n\n\nclass Output(object):\n    \"\"\"Basic output post-processing and comparison\"\"\"\n\n    def __init__(self, string):\n        self.string = string\n        self.explanation = []\n\n    def __str__(self):\n        return self.string\n\n    def __eq__(self, other):\n        # Ignore constructor/destructor output which is prefixed with \"###\"\n        a = [\n            line\n            for line in self.string.strip().splitlines()\n            if not line.startswith(\"###\")\n        ]\n        b = _strip_and_dedent(other).splitlines()\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a, b)\n            return False\n\n\nclass Unordered(Output):\n    \"\"\"Custom comparison for output without strict line ordering\"\"\"\n\n    def __eq__(self, other):\n        a = _split_and_sort(self.string)\n        b = _split_and_sort(other)\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a, b)\n            return False\n\n\nclass Capture(object):\n    def __init__(self, capfd):\n        self.capfd = capfd\n        self.out = \"\"\n        self.err = \"\"\n\n    def __enter__(self):\n        self.capfd.readouterr()\n        return self\n\n    def __exit__(self, *args):\n        self.out, self.err = self.capfd.readouterr()\n\n    def __eq__(self, other):\n        a = Output(self.out)\n        b = other\n        if a == b:\n            return True\n        else:\n            self.explanation = a.explanation\n            return False\n\n    def __str__(self):\n        return self.out\n\n    def __contains__(self, item):\n        return item in self.out\n\n    @property\n    def unordered(self):\n        return Unordered(self.out)\n\n    @property\n    def stderr(self):\n        return Output(self.err)\n\n\n@pytest.fixture\ndef capture(capsys):\n    \"\"\"Extended `capsys` with context manager and custom equality operators\"\"\"\n    return Capture(capsys)\n\n\nclass SanitizedString(object):\n    def __init__(self, sanitizer):\n        self.sanitizer = sanitizer\n        self.string = \"\"\n        self.explanation = []\n\n    def __call__(self, thing):\n        self.string = self.sanitizer(thing)\n        return self\n\n    def __eq__(self, other):\n        a = self.string\n        b = _strip_and_dedent(other)\n        if a == b:\n            return True\n        else:\n            self.explanation = _make_explanation(a.splitlines(), b.splitlines())\n            return False\n\n\ndef _sanitize_general(s):\n    s = s.strip()\n    s = s.replace(\"pybind11_tests.\", \"m.\")\n    s = s.replace(\"unicode\", \"str\")\n    s = _long_marker.sub(r\"\\1\", s)\n    s = _unicode_marker.sub(r\"\\1\", s)\n    return s\n\n\ndef _sanitize_docstring(thing):\n    s = thing.__doc__\n    s = _sanitize_general(s)\n    return s\n\n\n@pytest.fixture\ndef doc():\n    \"\"\"Sanitize docstrings and add custom failure explanation\"\"\"\n    return SanitizedString(_sanitize_docstring)\n\n\ndef _sanitize_message(thing):\n    s = str(thing)\n    s = _sanitize_general(s)\n    s = _hexadecimal.sub(\"0\", s)\n    return s\n\n\n@pytest.fixture\ndef msg():\n    \"\"\"Sanitize messages and add custom failure explanation\"\"\"\n    return SanitizedString(_sanitize_message)\n\n\n# noinspection PyUnusedLocal\ndef pytest_assertrepr_compare(op, left, right):\n    \"\"\"Hook to insert custom failure explanation\"\"\"\n    if hasattr(left, \"explanation\"):\n        return left.explanation\n\n\n@contextlib.contextmanager\ndef suppress(exception):\n    \"\"\"Suppress the desired exception\"\"\"\n    try:\n        yield\n    except exception:\n        pass\n\n\ndef gc_collect():\n    \"\"\"Run the garbage collector twice (needed when running\n    reference counting tests with PyPy)\"\"\"\n    gc.collect()\n    gc.collect()\n\n\ndef pytest_configure():\n    pytest.suppress = suppress\n    pytest.gc_collect = gc_collect\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/constructor_stats.h",
    "content": "#pragma once\n/*\n    tests/constructor_stats.h -- framework for printing and tracking object\n    instance lifetimes in example/test code.\n\n    Copyright (c) 2016 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n\nThis header provides a few useful tools for writing examples or tests that want to check and/or\ndisplay object instance lifetimes.  It requires that you include this header and add the following\nfunction calls to constructors:\n\n    class MyClass {\n        MyClass() { ...; print_default_created(this); }\n        ~MyClass() { ...; print_destroyed(this); }\n        MyClass(const MyClass &c) { ...; print_copy_created(this); }\n        MyClass(MyClass &&c) { ...; print_move_created(this); }\n        MyClass(int a, int b) { ...; print_created(this, a, b); }\n        MyClass &operator=(const MyClass &c) { ...; print_copy_assigned(this); }\n        MyClass &operator=(MyClass &&c) { ...; print_move_assigned(this); }\n\n        ...\n    }\n\nYou can find various examples of these in several of the existing testing .cpp files.  (Of course\nyou don't need to add any of the above constructors/operators that you don't actually have, except\nfor the destructor).\n\nEach of these will print an appropriate message such as:\n\n    ### MyClass @ 0x2801910 created via default constructor\n    ### MyClass @ 0x27fa780 created 100 200\n    ### MyClass @ 0x2801910 destroyed\n    ### MyClass @ 0x27fa780 destroyed\n\nYou can also include extra arguments (such as the 100, 200 in the output above, coming from the\nvalue constructor) for all of the above methods which will be included in the output.\n\nFor testing, each of these also keeps track the created instances and allows you to check how many\nof the various constructors have been invoked from the Python side via code such as:\n\n    from pybind11_tests import ConstructorStats\n    cstats = ConstructorStats.get(MyClass)\n    print(cstats.alive())\n    print(cstats.default_constructions)\n\nNote that `.alive()` should usually be the first thing you call as it invokes Python's garbage\ncollector to actually destroy objects that aren't yet referenced.\n\nFor everything except copy and move constructors and destructors, any extra values given to the\nprint_...() function is stored in a class-specific values list which you can retrieve and inspect\nfrom the ConstructorStats instance `.values()` method.\n\nIn some cases, when you need to track instances of a C++ class not registered with pybind11, you\nneed to add a function returning the ConstructorStats for the C++ class; this can be done with:\n\n    m.def(\"get_special_cstats\", &ConstructorStats::get<SpecialClass>,\npy::return_value_policy::reference)\n\nFinally, you can suppress the output messages, but keep the constructor tracking (for\ninspection/testing in python) by using the functions with `print_` replaced with `track_` (e.g.\n`track_copy_created(this)`).\n\n*/\n\n#include \"pybind11_tests.h\"\n\n#include <list>\n#include <sstream>\n#include <typeindex>\n#include <unordered_map>\n\nclass ConstructorStats {\nprotected:\n    std::unordered_map<void *, int> _instances; // Need a map rather than set because members can\n                                                // shared address with parents\n    std::list<std::string> _values;             // Used to track values\n                                                // (e.g. of value constructors)\npublic:\n    int default_constructions = 0;\n    int copy_constructions = 0;\n    int move_constructions = 0;\n    int copy_assignments = 0;\n    int move_assignments = 0;\n\n    void copy_created(void *inst) {\n        created(inst);\n        copy_constructions++;\n    }\n\n    void move_created(void *inst) {\n        created(inst);\n        move_constructions++;\n    }\n\n    void default_created(void *inst) {\n        created(inst);\n        default_constructions++;\n    }\n\n    void created(void *inst) { ++_instances[inst]; }\n\n    void destroyed(void *inst) {\n        if (--_instances[inst] < 0) {\n            throw std::runtime_error(\"cstats.destroyed() called with unknown \"\n                                     \"instance; potential double-destruction \"\n                                     \"or a missing cstats.created()\");\n        }\n    }\n\n    static void gc() {\n        // Force garbage collection to ensure any pending destructors are invoked:\n#if defined(PYPY_VERSION)\n        PyObject *globals = PyEval_GetGlobals();\n        PyObject *result = PyRun_String(\"import gc\\n\"\n                                        \"for i in range(2):\"\n                                        \"    gc.collect()\\n\",\n                                        Py_file_input,\n                                        globals,\n                                        globals);\n        if (result == nullptr)\n            throw py::error_already_set();\n        Py_DECREF(result);\n#else\n        py::module_::import(\"gc\").attr(\"collect\")();\n#endif\n    }\n\n    int alive() {\n        gc();\n        int total = 0;\n        for (const auto &p : _instances) {\n            if (p.second > 0) {\n                total += p.second;\n            }\n        }\n        return total;\n    }\n\n    void value() {} // Recursion terminator\n    // Takes one or more values, converts them to strings, then stores them.\n    template <typename T, typename... Tmore>\n    void value(const T &v, Tmore &&...args) {\n        std::ostringstream oss;\n        oss << v;\n        _values.push_back(oss.str());\n        value(std::forward<Tmore>(args)...);\n    }\n\n    // Move out stored values\n    py::list values() {\n        py::list l;\n        for (const auto &v : _values) {\n            l.append(py::cast(v));\n        }\n        _values.clear();\n        return l;\n    }\n\n    // Gets constructor stats from a C++ type index\n    static ConstructorStats &get(std::type_index type) {\n        static std::unordered_map<std::type_index, ConstructorStats> all_cstats;\n        return all_cstats[type];\n    }\n\n    // Gets constructor stats from a C++ type\n    template <typename T>\n    static ConstructorStats &get() {\n#if defined(PYPY_VERSION)\n        gc();\n#endif\n        return get(typeid(T));\n    }\n\n    // Gets constructor stats from a Python class\n    static ConstructorStats &get(py::object class_) {\n        auto &internals = py::detail::get_internals();\n        const std::type_index *t1 = nullptr, *t2 = nullptr;\n        try {\n            auto *type_info\n                = internals.registered_types_py.at((PyTypeObject *) class_.ptr()).at(0);\n            for (auto &p : internals.registered_types_cpp) {\n                if (p.second == type_info) {\n                    if (t1) {\n                        t2 = &p.first;\n                        break;\n                    }\n                    t1 = &p.first;\n                }\n            }\n        } catch (const std::out_of_range &) {\n        }\n        if (!t1) {\n            throw std::runtime_error(\"Unknown class passed to ConstructorStats::get()\");\n        }\n        auto &cs1 = get(*t1);\n        // If we have both a t1 and t2 match, one is probably the trampoline class; return\n        // whichever has more constructions (typically one or the other will be 0)\n        if (t2) {\n            auto &cs2 = get(*t2);\n            int cs1_total = cs1.default_constructions + cs1.copy_constructions\n                            + cs1.move_constructions + (int) cs1._values.size();\n            int cs2_total = cs2.default_constructions + cs2.copy_constructions\n                            + cs2.move_constructions + (int) cs2._values.size();\n            if (cs2_total > cs1_total) {\n                return cs2;\n            }\n        }\n        return cs1;\n    }\n};\n\n// To track construction/destruction, you need to call these methods from the various\n// constructors/operators.  The ones that take extra values record the given values in the\n// constructor stats values for later inspection.\ntemplate <class T>\nvoid track_copy_created(T *inst) {\n    ConstructorStats::get<T>().copy_created(inst);\n}\ntemplate <class T>\nvoid track_move_created(T *inst) {\n    ConstructorStats::get<T>().move_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid track_copy_assigned(T *, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.copy_assignments++;\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_move_assigned(T *, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.move_assignments++;\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_default_created(T *inst, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.default_created(inst);\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_created(T *inst, Values &&...values) {\n    auto &cst = ConstructorStats::get<T>();\n    cst.created(inst);\n    cst.value(std::forward<Values>(values)...);\n}\ntemplate <class T, typename... Values>\nvoid track_destroyed(T *inst) {\n    ConstructorStats::get<T>().destroyed(inst);\n}\ntemplate <class T, typename... Values>\nvoid track_values(T *, Values &&...values) {\n    ConstructorStats::get<T>().value(std::forward<Values>(values)...);\n}\n\n/// Don't cast pointers to Python, print them as strings\ninline const char *format_ptrs(const char *p) { return p; }\ntemplate <typename T>\npy::str format_ptrs(T *p) {\n    return \"{:#x}\"_s.format(reinterpret_cast<std::uintptr_t>(p));\n}\ntemplate <typename T>\nauto format_ptrs(T &&x) -> decltype(std::forward<T>(x)) {\n    return std::forward<T>(x);\n}\n\ntemplate <class T, typename... Output>\nvoid print_constr_details(T *inst, const std::string &action, Output &&...output) {\n    py::print(\"###\",\n              py::type_id<T>(),\n              \"@\",\n              format_ptrs(inst),\n              action,\n              format_ptrs(std::forward<Output>(output))...);\n}\n\n// Verbose versions of the above:\ntemplate <class T, typename... Values>\nvoid print_copy_created(T *inst,\n                        Values &&...values) { // NB: this prints, but doesn't store, given values\n    print_constr_details(inst, \"created via copy constructor\", values...);\n    track_copy_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_move_created(T *inst,\n                        Values &&...values) { // NB: this prints, but doesn't store, given values\n    print_constr_details(inst, \"created via move constructor\", values...);\n    track_move_created(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_copy_assigned(T *inst, Values &&...values) {\n    print_constr_details(inst, \"assigned via copy assignment\", values...);\n    track_copy_assigned(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_move_assigned(T *inst, Values &&...values) {\n    print_constr_details(inst, \"assigned via move assignment\", values...);\n    track_move_assigned(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_default_created(T *inst, Values &&...values) {\n    print_constr_details(inst, \"created via default constructor\", values...);\n    track_default_created(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_created(T *inst, Values &&...values) {\n    print_constr_details(inst, \"created\", values...);\n    track_created(inst, values...);\n}\ntemplate <class T, typename... Values>\nvoid print_destroyed(T *inst, Values &&...values) { // Prints but doesn't store given values\n    print_constr_details(inst, \"destroyed\", values...);\n    track_destroyed(inst);\n}\ntemplate <class T, typename... Values>\nvoid print_values(T *inst, Values &&...values) {\n    print_constr_details(inst, \":\", values...);\n    track_values(inst, values...);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/cross_module_gil_utils.cpp",
    "content": "/*\n    tests/cross_module_gil_utils.cpp -- tools for acquiring GIL from a different module\n\n    Copyright (c) 2019 Google LLC\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n#include <pybind11/pybind11.h>\n\n#include <cstdint>\n\n// This file mimics a DSO that makes pybind11 calls but does not define a\n// PYBIND11_MODULE. The purpose is to test that such a DSO can create a\n// py::gil_scoped_acquire when the running thread is in a GIL-released state.\n//\n// Note that we define a Python module here for convenience, but in general\n// this need not be the case. The typical scenario would be a DSO that implements\n// shared logic used internally by multiple pybind11 modules.\n\nnamespace {\n\nnamespace py = pybind11;\nvoid gil_acquire() { py::gil_scoped_acquire gil; }\n\nconstexpr char kModuleName[] = \"cross_module_gil_utils\";\n\n#if PY_MAJOR_VERSION >= 3\nstruct PyModuleDef moduledef\n    = {PyModuleDef_HEAD_INIT, kModuleName, NULL, 0, NULL, NULL, NULL, NULL, NULL};\n#else\nPyMethodDef module_methods[] = {{NULL, NULL, 0, NULL}};\n#endif\n\n} // namespace\n\nextern \"C\" PYBIND11_EXPORT\n#if PY_MAJOR_VERSION >= 3\n    PyObject *\n    PyInit_cross_module_gil_utils()\n#else\n    void\n    initcross_module_gil_utils()\n#endif\n{\n\n    PyObject *m =\n#if PY_MAJOR_VERSION >= 3\n        PyModule_Create(&moduledef);\n#else\n        Py_InitModule(kModuleName, module_methods);\n#endif\n\n    if (m != NULL) {\n        static_assert(sizeof(&gil_acquire) == sizeof(void *),\n                      \"Function pointer must have the same size as void*\");\n        PyModule_AddObject(\n            m, \"gil_acquire_funcaddr\", PyLong_FromVoidPtr(reinterpret_cast<void *>(&gil_acquire)));\n    }\n\n#if PY_MAJOR_VERSION >= 3\n    return m;\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/env.py",
    "content": "# -*- coding: utf-8 -*-\nimport platform\nimport sys\n\nimport pytest\n\nLINUX = sys.platform.startswith(\"linux\")\nMACOS = sys.platform.startswith(\"darwin\")\nWIN = sys.platform.startswith(\"win32\") or sys.platform.startswith(\"cygwin\")\n\nCPYTHON = platform.python_implementation() == \"CPython\"\nPYPY = platform.python_implementation() == \"PyPy\"\n\nPY2 = sys.version_info.major == 2\n\nPY = sys.version_info\n\n\ndef deprecated_call():\n    \"\"\"\n    pytest.deprecated_call() seems broken in pytest<3.9.x; concretely, it\n    doesn't work on CPython 3.8.0 with pytest==3.3.2 on Ubuntu 18.04 (#2922).\n\n    This is a narrowed reimplementation of the following PR :(\n    https://github.com/pytest-dev/pytest/pull/4104\n    \"\"\"\n    # TODO: Remove this when testing requires pytest>=3.9.\n    pieces = pytest.__version__.split(\".\")\n    pytest_major_minor = (int(pieces[0]), int(pieces[1]))\n    if pytest_major_minor < (3, 9):\n        return pytest.warns((DeprecationWarning, PendingDeprecationWarning))\n    else:\n        return pytest.deprecated_call()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/extra_python_package/pytest.ini",
    "content": ""
  },
  {
    "path": "external/pybind11_2.9.2/tests/extra_python_package/test_files.py",
    "content": "# -*- coding: utf-8 -*-\nimport contextlib\nimport os\nimport string\nimport subprocess\nimport sys\nimport tarfile\nimport zipfile\n\n# These tests must be run explicitly\n# They require CMake 3.15+ (--install)\n\nDIR = os.path.abspath(os.path.dirname(__file__))\nMAIN_DIR = os.path.dirname(os.path.dirname(DIR))\n\n\nmain_headers = {\n    \"include/pybind11/attr.h\",\n    \"include/pybind11/buffer_info.h\",\n    \"include/pybind11/cast.h\",\n    \"include/pybind11/chrono.h\",\n    \"include/pybind11/common.h\",\n    \"include/pybind11/complex.h\",\n    \"include/pybind11/eigen.h\",\n    \"include/pybind11/embed.h\",\n    \"include/pybind11/eval.h\",\n    \"include/pybind11/functional.h\",\n    \"include/pybind11/gil.h\",\n    \"include/pybind11/iostream.h\",\n    \"include/pybind11/numpy.h\",\n    \"include/pybind11/operators.h\",\n    \"include/pybind11/options.h\",\n    \"include/pybind11/pybind11.h\",\n    \"include/pybind11/pytypes.h\",\n    \"include/pybind11/stl.h\",\n    \"include/pybind11/stl_bind.h\",\n}\n\ndetail_headers = {\n    \"include/pybind11/detail/class.h\",\n    \"include/pybind11/detail/common.h\",\n    \"include/pybind11/detail/descr.h\",\n    \"include/pybind11/detail/init.h\",\n    \"include/pybind11/detail/internals.h\",\n    \"include/pybind11/detail/type_caster_base.h\",\n    \"include/pybind11/detail/typeid.h\",\n}\n\nstl_headers = {\n    \"include/pybind11/stl/filesystem.h\",\n}\n\ncmake_files = {\n    \"share/cmake/pybind11/FindPythonLibsNew.cmake\",\n    \"share/cmake/pybind11/pybind11Common.cmake\",\n    \"share/cmake/pybind11/pybind11Config.cmake\",\n    \"share/cmake/pybind11/pybind11ConfigVersion.cmake\",\n    \"share/cmake/pybind11/pybind11NewTools.cmake\",\n    \"share/cmake/pybind11/pybind11Targets.cmake\",\n    \"share/cmake/pybind11/pybind11Tools.cmake\",\n}\n\npy_files = {\n    \"__init__.py\",\n    \"__main__.py\",\n    \"_version.py\",\n    \"_version.pyi\",\n    \"commands.py\",\n    \"py.typed\",\n    \"setup_helpers.py\",\n    \"setup_helpers.pyi\",\n}\n\nheaders = main_headers | detail_headers | stl_headers\nsrc_files = headers | cmake_files\nall_files = src_files | py_files\n\n\nsdist_files = {\n    \"pybind11\",\n    \"pybind11/include\",\n    \"pybind11/include/pybind11\",\n    \"pybind11/include/pybind11/detail\",\n    \"pybind11/include/pybind11/stl\",\n    \"pybind11/share\",\n    \"pybind11/share/cmake\",\n    \"pybind11/share/cmake/pybind11\",\n    \"pyproject.toml\",\n    \"setup.cfg\",\n    \"setup.py\",\n    \"LICENSE\",\n    \"MANIFEST.in\",\n    \"README.rst\",\n    \"PKG-INFO\",\n}\n\nlocal_sdist_files = {\n    \".egg-info\",\n    \".egg-info/PKG-INFO\",\n    \".egg-info/SOURCES.txt\",\n    \".egg-info/dependency_links.txt\",\n    \".egg-info/not-zip-safe\",\n    \".egg-info/top_level.txt\",\n}\n\n\ndef test_build_sdist(monkeypatch, tmpdir):\n\n    monkeypatch.chdir(MAIN_DIR)\n\n    out = subprocess.check_output(\n        [\n            sys.executable,\n            \"setup.py\",\n            \"sdist\",\n            \"--formats=tar\",\n            \"--dist-dir\",\n            str(tmpdir),\n        ]\n    )\n    if hasattr(out, \"decode\"):\n        out = out.decode()\n\n    (sdist,) = tmpdir.visit(\"*.tar\")\n\n    with tarfile.open(str(sdist)) as tar:\n        start = tar.getnames()[0] + \"/\"\n        version = start[9:-1]\n        simpler = {n.split(\"/\", 1)[-1] for n in tar.getnames()[1:]}\n\n        with contextlib.closing(\n            tar.extractfile(tar.getmember(start + \"setup.py\"))\n        ) as f:\n            setup_py = f.read()\n\n        with contextlib.closing(\n            tar.extractfile(tar.getmember(start + \"pyproject.toml\"))\n        ) as f:\n            pyproject_toml = f.read()\n\n        with contextlib.closing(\n            tar.extractfile(\n                tar.getmember(\n                    start + \"pybind11/share/cmake/pybind11/pybind11Config.cmake\"\n                )\n            )\n        ) as f:\n            contents = f.read().decode(\"utf8\")\n        assert 'set(pybind11_INCLUDE_DIR \"${PACKAGE_PREFIX_DIR}/include\")' in contents\n\n    files = {\"pybind11/{}\".format(n) for n in all_files}\n    files |= sdist_files\n    files |= {\"pybind11{}\".format(n) for n in local_sdist_files}\n    files.add(\"pybind11.egg-info/entry_points.txt\")\n    files.add(\"pybind11.egg-info/requires.txt\")\n    assert simpler == files\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"setup_main.py.in\"), \"rb\") as f:\n        contents = (\n            string.Template(f.read().decode())\n            .substitute(version=version, extra_cmd=\"\")\n            .encode()\n        )\n    assert setup_py == contents\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"pyproject.toml\"), \"rb\") as f:\n        contents = f.read()\n    assert pyproject_toml == contents\n\n\ndef test_build_global_dist(monkeypatch, tmpdir):\n\n    monkeypatch.chdir(MAIN_DIR)\n    monkeypatch.setenv(\"PYBIND11_GLOBAL_SDIST\", \"1\")\n\n    out = subprocess.check_output(\n        [\n            sys.executable,\n            \"setup.py\",\n            \"sdist\",\n            \"--formats=tar\",\n            \"--dist-dir\",\n            str(tmpdir),\n        ]\n    )\n    if hasattr(out, \"decode\"):\n        out = out.decode()\n\n    (sdist,) = tmpdir.visit(\"*.tar\")\n\n    with tarfile.open(str(sdist)) as tar:\n        start = tar.getnames()[0] + \"/\"\n        version = start[16:-1]\n        simpler = {n.split(\"/\", 1)[-1] for n in tar.getnames()[1:]}\n\n        with contextlib.closing(\n            tar.extractfile(tar.getmember(start + \"setup.py\"))\n        ) as f:\n            setup_py = f.read()\n\n        with contextlib.closing(\n            tar.extractfile(tar.getmember(start + \"pyproject.toml\"))\n        ) as f:\n            pyproject_toml = f.read()\n\n    files = {\"pybind11/{}\".format(n) for n in all_files}\n    files |= sdist_files\n    files |= {\"pybind11_global{}\".format(n) for n in local_sdist_files}\n    assert simpler == files\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"setup_global.py.in\"), \"rb\") as f:\n        contents = (\n            string.Template(f.read().decode())\n            .substitute(version=version, extra_cmd=\"\")\n            .encode()\n        )\n        assert setup_py == contents\n\n    with open(os.path.join(MAIN_DIR, \"tools\", \"pyproject.toml\"), \"rb\") as f:\n        contents = f.read()\n        assert pyproject_toml == contents\n\n\ndef tests_build_wheel(monkeypatch, tmpdir):\n    monkeypatch.chdir(MAIN_DIR)\n\n    subprocess.check_output(\n        [sys.executable, \"-m\", \"pip\", \"wheel\", \".\", \"-w\", str(tmpdir)]\n    )\n\n    (wheel,) = tmpdir.visit(\"*.whl\")\n\n    files = {\"pybind11/{}\".format(n) for n in all_files}\n    files |= {\n        \"dist-info/LICENSE\",\n        \"dist-info/METADATA\",\n        \"dist-info/RECORD\",\n        \"dist-info/WHEEL\",\n        \"dist-info/entry_points.txt\",\n        \"dist-info/top_level.txt\",\n    }\n\n    with zipfile.ZipFile(str(wheel)) as z:\n        names = z.namelist()\n\n    trimmed = {n for n in names if \"dist-info\" not in n}\n    trimmed |= {\n        \"dist-info/{}\".format(n.split(\"/\", 1)[-1]) for n in names if \"dist-info\" in n\n    }\n    assert files == trimmed\n\n\ndef tests_build_global_wheel(monkeypatch, tmpdir):\n    monkeypatch.chdir(MAIN_DIR)\n    monkeypatch.setenv(\"PYBIND11_GLOBAL_SDIST\", \"1\")\n\n    subprocess.check_output(\n        [sys.executable, \"-m\", \"pip\", \"wheel\", \".\", \"-w\", str(tmpdir)]\n    )\n\n    (wheel,) = tmpdir.visit(\"*.whl\")\n\n    files = {\"data/data/{}\".format(n) for n in src_files}\n    files |= {\"data/headers/{}\".format(n[8:]) for n in headers}\n    files |= {\n        \"dist-info/LICENSE\",\n        \"dist-info/METADATA\",\n        \"dist-info/WHEEL\",\n        \"dist-info/top_level.txt\",\n        \"dist-info/RECORD\",\n    }\n\n    with zipfile.ZipFile(str(wheel)) as z:\n        names = z.namelist()\n\n    beginning = names[0].split(\"/\", 1)[0].rsplit(\".\", 1)[0]\n    trimmed = {n[len(beginning) + 1 :] for n in names}\n\n    assert files == trimmed\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/extra_setuptools/pytest.ini",
    "content": ""
  },
  {
    "path": "external/pybind11_2.9.2/tests/extra_setuptools/test_setuphelper.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\nimport subprocess\nimport sys\nfrom textwrap import dedent\n\nimport pytest\n\nDIR = os.path.abspath(os.path.dirname(__file__))\nMAIN_DIR = os.path.dirname(os.path.dirname(DIR))\nWIN = sys.platform.startswith(\"win32\") or sys.platform.startswith(\"cygwin\")\n\n\n@pytest.mark.parametrize(\"parallel\", [False, True])\n@pytest.mark.parametrize(\"std\", [11, 0])\ndef test_simple_setup_py(monkeypatch, tmpdir, parallel, std):\n    monkeypatch.chdir(tmpdir)\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    (tmpdir / \"setup.py\").write_text(\n        dedent(\n            u\"\"\"\\\n            import sys\n            sys.path.append({MAIN_DIR!r})\n\n            from setuptools import setup, Extension\n            from pybind11.setup_helpers import build_ext, Pybind11Extension\n\n            std = {std}\n\n            ext_modules = [\n                Pybind11Extension(\n                    \"simple_setup\",\n                    sorted([\"main.cpp\"]),\n                    cxx_std=std,\n                ),\n            ]\n\n            cmdclass = dict()\n            if std == 0:\n                cmdclass[\"build_ext\"] = build_ext\n\n\n            parallel = {parallel}\n            if parallel:\n                from pybind11.setup_helpers import ParallelCompile\n                ParallelCompile().install()\n\n            setup(\n                name=\"simple_setup_package\",\n                cmdclass=cmdclass,\n                ext_modules=ext_modules,\n            )\n            \"\"\"\n        ).format(MAIN_DIR=MAIN_DIR, std=std, parallel=parallel),\n        encoding=\"ascii\",\n    )\n\n    (tmpdir / \"main.cpp\").write_text(\n        dedent(\n            u\"\"\"\\\n            #include <pybind11/pybind11.h>\n\n            int f(int x) {\n                return x * 3;\n            }\n            PYBIND11_MODULE(simple_setup, m) {\n                m.def(\"f\", &f);\n            }\n            \"\"\"\n        ),\n        encoding=\"ascii\",\n    )\n\n    out = subprocess.check_output(\n        [sys.executable, \"setup.py\", \"build_ext\", \"--inplace\"],\n    )\n    if not WIN:\n        assert b\"-g0\" in out\n    out = subprocess.check_output(\n        [sys.executable, \"setup.py\", \"build_ext\", \"--inplace\", \"--force\"],\n        env=dict(os.environ, CFLAGS=\"-g\"),\n    )\n    if not WIN:\n        assert b\"-g0\" not in out\n\n    # Debug helper printout, normally hidden\n    print(out)\n    for item in tmpdir.listdir():\n        print(item.basename)\n\n    assert (\n        len([f for f in tmpdir.listdir() if f.basename.startswith(\"simple_setup\")]) == 1\n    )\n    assert len(list(tmpdir.listdir())) == 4  # two files + output + build_dir\n\n    (tmpdir / \"test.py\").write_text(\n        dedent(\n            u\"\"\"\\\n            import simple_setup\n            assert simple_setup.f(3) == 9\n            \"\"\"\n        ),\n        encoding=\"ascii\",\n    )\n\n    subprocess.check_call(\n        [sys.executable, \"test.py\"], stdout=sys.stdout, stderr=sys.stderr\n    )\n\n\ndef test_intree_extensions(monkeypatch, tmpdir):\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    from pybind11.setup_helpers import intree_extensions\n\n    monkeypatch.chdir(tmpdir)\n    root = tmpdir\n    root.ensure_dir()\n    subdir = root / \"dir\"\n    subdir.ensure_dir()\n    src = subdir / \"ext.cpp\"\n    src.ensure()\n    (ext,) = intree_extensions([src.relto(tmpdir)])\n    assert ext.name == \"ext\"\n    subdir.ensure(\"__init__.py\")\n    (ext,) = intree_extensions([src.relto(tmpdir)])\n    assert ext.name == \"dir.ext\"\n\n\ndef test_intree_extensions_package_dir(monkeypatch, tmpdir):\n    monkeypatch.syspath_prepend(MAIN_DIR)\n\n    from pybind11.setup_helpers import intree_extensions\n\n    monkeypatch.chdir(tmpdir)\n    root = tmpdir / \"src\"\n    root.ensure_dir()\n    subdir = root / \"dir\"\n    subdir.ensure_dir()\n    src = subdir / \"ext.cpp\"\n    src.ensure()\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"\": \"src\"})\n    assert ext.name == \"dir.ext\"\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"foo\": \"src\"})\n    assert ext.name == \"foo.dir.ext\"\n    subdir.ensure(\"__init__.py\")\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"\": \"src\"})\n    assert ext.name == \"dir.ext\"\n    (ext,) = intree_extensions([src.relto(tmpdir)], package_dir={\"foo\": \"src\"})\n    assert ext.name == \"foo.dir.ext\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/local_bindings.h",
    "content": "#pragma once\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\n/// Simple class used to test py::local:\ntemplate <int>\nclass LocalBase {\npublic:\n    explicit LocalBase(int i) : i(i) {}\n    int i = -1;\n};\n\n/// Registered with py::module_local in both main and secondary modules:\nusing LocalType = LocalBase<0>;\n/// Registered without py::module_local in both modules:\nusing NonLocalType = LocalBase<1>;\n/// A second non-local type (for stl_bind tests):\nusing NonLocal2 = LocalBase<2>;\n/// Tests within-module, different-compilation-unit local definition conflict:\nusing LocalExternal = LocalBase<3>;\n/// Mixed: registered local first, then global\nusing MixedLocalGlobal = LocalBase<4>;\n/// Mixed: global first, then local\nusing MixedGlobalLocal = LocalBase<5>;\n\n/// Registered with py::module_local only in the secondary module:\nusing ExternalType1 = LocalBase<6>;\nusing ExternalType2 = LocalBase<7>;\n\nusing LocalVec = std::vector<LocalType>;\nusing LocalVec2 = std::vector<NonLocal2>;\nusing LocalMap = std::unordered_map<std::string, LocalType>;\nusing NonLocalVec = std::vector<NonLocalType>;\nusing NonLocalVec2 = std::vector<NonLocal2>;\nusing NonLocalMap = std::unordered_map<std::string, NonLocalType>;\nusing NonLocalMap2 = std::unordered_map<std::string, uint8_t>;\n\n// Exception that will be caught via the module local translator.\nclass LocalException : public std::exception {\npublic:\n    explicit LocalException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// Exception that will be registered with register_local_exception_translator\nclass LocalSimpleException : public std::exception {\npublic:\n    explicit LocalSimpleException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\nPYBIND11_MAKE_OPAQUE(LocalVec);\nPYBIND11_MAKE_OPAQUE(LocalVec2);\nPYBIND11_MAKE_OPAQUE(LocalMap);\nPYBIND11_MAKE_OPAQUE(NonLocalVec);\n// PYBIND11_MAKE_OPAQUE(NonLocalVec2); // same type as LocalVec2\nPYBIND11_MAKE_OPAQUE(NonLocalMap);\nPYBIND11_MAKE_OPAQUE(NonLocalMap2);\n\n// Simple bindings (used with the above):\ntemplate <typename T, int Adjust = 0, typename... Args>\npy::class_<T> bind_local(Args &&...args) {\n    return py::class_<T>(std::forward<Args>(args)...).def(py::init<int>()).def(\"get\", [](T &i) {\n        return i.i + Adjust;\n    });\n};\n\n// Simulate a foreign library base class (to match the example in the docs):\nnamespace pets {\nclass Pet {\npublic:\n    explicit Pet(std::string name) : name_(std::move(name)) {}\n    std::string name_;\n    const std::string &name() const { return name_; }\n};\n} // namespace pets\n\nstruct MixGL {\n    int i;\n    explicit MixGL(int i) : i{i} {}\n};\nstruct MixGL2 {\n    int i;\n    explicit MixGL2(int i) : i{i} {}\n};\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/object.h",
    "content": "#if !defined(__OBJECT_H)\n#    define __OBJECT_H\n\n#    include \"constructor_stats.h\"\n\n#    include <atomic>\n\n/// Reference counted object base class\nclass Object {\npublic:\n    /// Default constructor\n    Object() { print_default_created(this); }\n\n    /// Copy constructor\n    Object(const Object &) : m_refCount(0) { print_copy_created(this); }\n\n    /// Return the current reference count\n    int getRefCount() const { return m_refCount; };\n\n    /// Increase the object's reference count by one\n    void incRef() const { ++m_refCount; }\n\n    /** \\brief Decrease the reference count of\n     * the object and possibly deallocate it.\n     *\n     * The object will automatically be deallocated once\n     * the reference count reaches zero.\n     */\n    void decRef(bool dealloc = true) const {\n        --m_refCount;\n        if (m_refCount == 0 && dealloc) {\n            delete this;\n        } else if (m_refCount < 0) {\n            throw std::runtime_error(\"Internal error: reference count < 0!\");\n        }\n    }\n\n    virtual std::string toString() const = 0;\n\nprotected:\n    /** \\brief Virtual protected deconstructor.\n     * (Will only be called by \\ref ref)\n     */\n    virtual ~Object() { print_destroyed(this); }\n\nprivate:\n    mutable std::atomic<int> m_refCount{0};\n};\n\n// Tag class used to track constructions of ref objects.  When we track constructors, below, we\n// track and print out the actual class (e.g. ref<MyObject>), and *also* add a fake tracker for\n// ref_tag.  This lets us check that the total number of ref<Anything> constructors/destructors is\n// correct without having to check each individual ref<Whatever> type individually.\nclass ref_tag {};\n\n/**\n * \\brief Reference counting helper\n *\n * The \\a ref refeference template is a simple wrapper to store a\n * pointer to an object. It takes care of increasing and decreasing\n * the reference count of the object. When the last reference goes\n * out of scope, the associated object will be deallocated.\n *\n * \\ingroup libcore\n */\ntemplate <typename T>\nclass ref {\npublic:\n    /// Create a nullptr reference\n    ref() : m_ptr(nullptr) {\n        print_default_created(this);\n        track_default_created((ref_tag *) this);\n    }\n\n    /// Construct a reference from a pointer\n    explicit ref(T *ptr) : m_ptr(ptr) {\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n\n        print_created(this, \"from pointer\", m_ptr);\n        track_created((ref_tag *) this, \"from pointer\");\n    }\n\n    /// Copy constructor\n    ref(const ref &r) : m_ptr(r.m_ptr) {\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n\n        print_copy_created(this, \"with pointer\", m_ptr);\n        track_copy_created((ref_tag *) this);\n    }\n\n    /// Move constructor\n    ref(ref &&r) noexcept : m_ptr(r.m_ptr) {\n        r.m_ptr = nullptr;\n\n        print_move_created(this, \"with pointer\", m_ptr);\n        track_move_created((ref_tag *) this);\n    }\n\n    /// Destroy this reference\n    ~ref() {\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n\n        print_destroyed(this);\n        track_destroyed((ref_tag *) this);\n    }\n\n    /// Move another reference into the current one\n    ref &operator=(ref &&r) noexcept {\n        print_move_assigned(this, \"pointer\", r.m_ptr);\n        track_move_assigned((ref_tag *) this);\n\n        if (*this == r) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = r.m_ptr;\n        r.m_ptr = nullptr;\n        return *this;\n    }\n\n    /// Overwrite this reference with another reference\n    ref &operator=(const ref &r) {\n        if (this == &r) {\n            return *this;\n        }\n        print_copy_assigned(this, \"pointer\", r.m_ptr);\n        track_copy_assigned((ref_tag *) this);\n\n        if (m_ptr == r.m_ptr) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = r.m_ptr;\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n        return *this;\n    }\n\n    /// Overwrite this reference with a pointer to another object\n    ref &operator=(T *ptr) {\n        print_values(this, \"assigned pointer\");\n        track_values((ref_tag *) this, \"assigned pointer\");\n\n        if (m_ptr == ptr) {\n            return *this;\n        }\n        if (m_ptr) {\n            ((Object *) m_ptr)->decRef();\n        }\n        m_ptr = ptr;\n        if (m_ptr) {\n            ((Object *) m_ptr)->incRef();\n        }\n        return *this;\n    }\n\n    /// Compare this reference with another reference\n    bool operator==(const ref &r) const { return m_ptr == r.m_ptr; }\n\n    /// Compare this reference with another reference\n    bool operator!=(const ref &r) const { return m_ptr != r.m_ptr; }\n\n    /// Compare this reference with a pointer\n    bool operator==(const T *ptr) const { return m_ptr == ptr; }\n\n    /// Compare this reference with a pointer\n    bool operator!=(const T *ptr) const { return m_ptr != ptr; }\n\n    /// Access the object referenced by this reference\n    T *operator->() { return m_ptr; }\n\n    /// Access the object referenced by this reference\n    const T *operator->() const { return m_ptr; }\n\n    /// Return a C++ reference to the referenced object\n    T &operator*() { return *m_ptr; }\n\n    /// Return a const C++ reference to the referenced object\n    const T &operator*() const { return *m_ptr; }\n\n    /// Return a pointer to the referenced object\n    explicit operator T *() { return m_ptr; }\n\n    /// Return a const pointer to the referenced object\n    T *get_ptr() { return m_ptr; }\n\n    /// Return a pointer to the referenced object\n    const T *get_ptr() const { return m_ptr; }\n\nprivate:\n    T *m_ptr;\n};\n\n#endif /* __OBJECT_H */\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/pybind11_cross_module_tests.cpp",
    "content": "/*\n    tests/pybind11_cross_module_tests.cpp -- contains tests that require multiple modules\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl_bind.h>\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n#include \"test_exceptions.h\"\n\n#include <numeric>\n#include <utility>\n\nPYBIND11_MODULE(pybind11_cross_module_tests, m) {\n    m.doc() = \"pybind11 cross-module test module\";\n\n    // test_local_bindings.py tests:\n    //\n    // Definitions here are tested by importing both this module and the\n    // relevant pybind11_tests submodule from a test_whatever.py\n\n    // test_load_external\n    bind_local<ExternalType1>(m, \"ExternalType1\", py::module_local());\n    bind_local<ExternalType2>(m, \"ExternalType2\", py::module_local());\n\n    // test_exceptions.py\n    py::register_local_exception<LocalSimpleException>(m, \"LocalSimpleException\");\n    m.def(\"raise_runtime_error\", []() {\n        PyErr_SetString(PyExc_RuntimeError, \"My runtime error\");\n        throw py::error_already_set();\n    });\n    m.def(\"raise_value_error\", []() {\n        PyErr_SetString(PyExc_ValueError, \"My value error\");\n        throw py::error_already_set();\n    });\n    m.def(\"throw_pybind_value_error\", []() { throw py::value_error(\"pybind11 value error\"); });\n    m.def(\"throw_pybind_type_error\", []() { throw py::type_error(\"pybind11 type error\"); });\n    m.def(\"throw_stop_iteration\", []() { throw py::stop_iteration(); });\n    m.def(\"throw_local_error\", []() { throw LocalException(\"just local\"); });\n    m.def(\"throw_local_simple_error\", []() { throw LocalSimpleException(\"external mod\"); });\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const shared_exception &e) {\n            PyErr_SetString(PyExc_KeyError, e.what());\n        }\n    });\n\n    // translate the local exception into a key error but only in this module\n    py::register_local_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const LocalException &e) {\n            PyErr_SetString(PyExc_KeyError, e.what());\n        }\n    });\n\n    // test_local_bindings.py\n    // Local to both:\n    bind_local<LocalType, 1>(m, \"LocalType\", py::module_local()).def(\"get2\", [](LocalType &t) {\n        return t.i + 2;\n    });\n\n    // Can only be called with our python type:\n    m.def(\"local_value\", [](LocalType &l) { return l.i; });\n\n    // test_nonlocal_failure\n    // This registration will fail (global registration when LocalFail is already registered\n    // globally in the main test module):\n    m.def(\"register_nonlocal\", [m]() { bind_local<NonLocalType, 0>(m, \"NonLocalType\"); });\n\n    // test_stl_bind_local\n    // stl_bind.h binders defaults to py::module_local if the types are local or converting:\n    py::bind_vector<LocalVec>(m, \"LocalVec\");\n    py::bind_map<LocalMap>(m, \"LocalMap\");\n\n    // test_stl_bind_global\n    // and global if the type (or one of the types, for the map) is global (so these will fail,\n    // assuming pybind11_tests is already loaded):\n    m.def(\"register_nonlocal_vec\", [m]() { py::bind_vector<NonLocalVec>(m, \"NonLocalVec\"); });\n    m.def(\"register_nonlocal_map\", [m]() { py::bind_map<NonLocalMap>(m, \"NonLocalMap\"); });\n    // The default can, however, be overridden to global using `py::module_local()` or\n    // `py::module_local(false)`.\n    // Explicitly made local:\n    py::bind_vector<NonLocalVec2>(m, \"NonLocalVec2\", py::module_local());\n    // Explicitly made global (and so will fail to bind):\n    m.def(\"register_nonlocal_map2\",\n          [m]() { py::bind_map<NonLocalMap2>(m, \"NonLocalMap2\", py::module_local(false)); });\n\n    // test_mixed_local_global\n    // We try this both with the global type registered first and vice versa (the order shouldn't\n    // matter).\n    m.def(\"register_mixed_global_local\",\n          [m]() { bind_local<MixedGlobalLocal, 200>(m, \"MixedGlobalLocal\", py::module_local()); });\n    m.def(\"register_mixed_local_global\", [m]() {\n        bind_local<MixedLocalGlobal, 2000>(m, \"MixedLocalGlobal\", py::module_local(false));\n    });\n    m.def(\"get_mixed_gl\", [](int i) { return MixedGlobalLocal(i); });\n    m.def(\"get_mixed_lg\", [](int i) { return MixedLocalGlobal(i); });\n\n    // test_internal_locals_differ\n    m.def(\"local_cpp_types_addr\",\n          []() { return (uintptr_t) &py::detail::get_local_internals().registered_types_cpp; });\n\n    // test_stl_caster_vs_stl_bind\n    py::bind_vector<std::vector<int>>(m, \"VectorInt\");\n\n    m.def(\"load_vector_via_binding\",\n          [](std::vector<int> &v) { return std::accumulate(v.begin(), v.end(), 0); });\n\n    // test_cross_module_calls\n    m.def(\"return_self\", [](LocalVec *v) { return v; });\n    m.def(\"return_copy\", [](const LocalVec &v) { return LocalVec(v); });\n\n    class Dog : public pets::Pet {\n    public:\n        explicit Dog(std::string name) : Pet(std::move(name)) {}\n    };\n    py::class_<pets::Pet>(m, \"Pet\", py::module_local()).def(\"name\", &pets::Pet::name);\n    // Binding for local extending class:\n    py::class_<Dog, pets::Pet>(m, \"Dog\").def(py::init<std::string>());\n    m.def(\"pet_name\", [](pets::Pet &p) { return p.name(); });\n\n    py::class_<MixGL>(m, \"MixGL\", py::module_local()).def(py::init<int>());\n    m.def(\"get_gl_value\", [](MixGL &o) { return o.i + 100; });\n\n    py::class_<MixGL2>(m, \"MixGL2\", py::module_local()).def(py::init<int>());\n\n    // test_vector_bool\n    // We can't test both stl.h and stl_bind.h conversions of `std::vector<bool>` within\n    // the same module (it would be an ODR violation). Therefore `bind_vector` of `bool`\n    // is defined here and tested in `test_stl_binders.py`.\n    py::bind_vector<std::vector<bool>>(m, \"VectorBool\");\n\n    // test_missing_header_message\n    // The main module already includes stl.h, but we need to test the error message\n    // which appears when this header is missing.\n    m.def(\"missing_header_arg\", [](const std::vector<float> &) {});\n    m.def(\"missing_header_return\", []() { return std::vector<float>(); });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/pybind11_tests.cpp",
    "content": "/*\n    tests/pybind11_tests.cpp -- pybind example plugin\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n#include \"constructor_stats.h\"\n\n#include <functional>\n#include <list>\n\n/*\nFor testing purposes, we define a static global variable here in a function that each individual\ntest .cpp calls with its initialization lambda.  It's convenient here because we can just not\ncompile some test files to disable/ignore some of the test code.\n\nIt is NOT recommended as a way to use pybind11 in practice, however: the initialization order will\nbe essentially random, which is okay for our test scripts (there are no dependencies between the\nindividual pybind11 test .cpp files), but most likely not what you want when using pybind11\nproductively.\n\nInstead, see the \"How can I reduce the build time?\" question in the \"Frequently asked questions\"\nsection of the documentation for good practice on splitting binding code over multiple files.\n*/\nstd::list<std::function<void(py::module_ &)>> &initializers() {\n    static std::list<std::function<void(py::module_ &)>> inits;\n    return inits;\n}\n\ntest_initializer::test_initializer(Initializer init) { initializers().emplace_back(init); }\n\ntest_initializer::test_initializer(const char *submodule_name, Initializer init) {\n    initializers().emplace_back([=](py::module_ &parent) {\n        auto m = parent.def_submodule(submodule_name);\n        init(m);\n    });\n}\n\nvoid bind_ConstructorStats(py::module_ &m) {\n    py::class_<ConstructorStats>(m, \"ConstructorStats\")\n        .def(\"alive\", &ConstructorStats::alive)\n        .def(\"values\", &ConstructorStats::values)\n        .def_readwrite(\"default_constructions\", &ConstructorStats::default_constructions)\n        .def_readwrite(\"copy_assignments\", &ConstructorStats::copy_assignments)\n        .def_readwrite(\"move_assignments\", &ConstructorStats::move_assignments)\n        .def_readwrite(\"copy_constructions\", &ConstructorStats::copy_constructions)\n        .def_readwrite(\"move_constructions\", &ConstructorStats::move_constructions)\n        .def_static(\"get\",\n                    (ConstructorStats & (*) (py::object)) & ConstructorStats::get,\n                    py::return_value_policy::reference_internal)\n\n        // Not exactly ConstructorStats, but related: expose the internal pybind number of\n        // registered instances to allow instance cleanup checks (invokes a GC first)\n        .def_static(\"detail_reg_inst\", []() {\n            ConstructorStats::gc();\n            return py::detail::get_internals().registered_instances.size();\n        });\n}\n\nPYBIND11_MODULE(pybind11_tests, m) {\n    m.doc() = \"pybind11 test module\";\n\n    bind_ConstructorStats(m);\n\n#if !defined(NDEBUG)\n    m.attr(\"debug_enabled\") = true;\n#else\n    m.attr(\"debug_enabled\") = false;\n#endif\n\n    py::class_<UserType>(m, \"UserType\", \"A `py::class_` type for testing\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(\"get_value\", &UserType::value, \"Get value using a method\")\n        .def(\"set_value\", &UserType::set, \"Set value using a method\")\n        .def_property(\"value\", &UserType::value, &UserType::set, \"Get/set value using a property\")\n        .def(\"__repr__\", [](const UserType &u) { return \"UserType({})\"_s.format(u.value()); });\n\n    py::class_<IncType, UserType>(m, \"IncType\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(\"__repr__\", [](const IncType &u) { return \"IncType({})\"_s.format(u.value()); });\n\n    for (const auto &initializer : initializers()) {\n        initializer(m);\n    }\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/pybind11_tests.h",
    "content": "#pragma once\n\n#include <pybind11/eval.h>\n#include <pybind11/pybind11.h>\n\n#if defined(_MSC_VER) && _MSC_VER < 1910\n// We get some really long type names here which causes MSVC 2015 to emit warnings\n#    pragma warning(                                                                              \\\n        disable : 4503) // NOLINT: warning C4503: decorated name length exceeded, name was truncated\n#endif\n\nnamespace py = pybind11;\nusing namespace pybind11::literals;\n\nclass test_initializer {\n    using Initializer = void (*)(py::module_ &);\n\npublic:\n    explicit test_initializer(Initializer init);\n    test_initializer(const char *submodule_name, Initializer init);\n};\n\n#define TEST_SUBMODULE(name, variable)                                                            \\\n    void test_submodule_##name(py::module_ &);                                                    \\\n    test_initializer name(#name, test_submodule_##name);                                          \\\n    void test_submodule_##name(py::module_ &(variable))\n\n/// Dummy type which is not exported anywhere -- something to trigger a conversion error\nstruct UnregisteredType {};\n\n/// A user-defined type which is exported and can be used by any test\nclass UserType {\npublic:\n    UserType() = default;\n    explicit UserType(int i) : i(i) {}\n\n    int value() const { return i; }\n    void set(int set) { i = set; }\n\nprivate:\n    int i = -1;\n};\n\n/// Like UserType, but increments `value` on copy for quick reference vs. copy tests\nclass IncType : public UserType {\npublic:\n    using UserType::UserType;\n    IncType() = default;\n    IncType(const IncType &other) : IncType(other.value() + 1) {}\n    IncType(IncType &&) = delete;\n    IncType &operator=(const IncType &) = delete;\n    IncType &operator=(IncType &&) = delete;\n};\n\n/// A simple union for basic testing\nunion IntFloat {\n    int i;\n    float f;\n};\n\n/// Custom cast-only type that casts to a string \"rvalue\" or \"lvalue\" depending on the cast\n/// context. Used to test recursive casters (e.g. std::tuple, stl containers).\nstruct RValueCaster {};\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nclass type_caster<RValueCaster> {\npublic:\n    PYBIND11_TYPE_CASTER(RValueCaster, const_name(\"RValueCaster\"));\n    static handle cast(RValueCaster &&, return_value_policy, handle) {\n        return py::str(\"rvalue\").release();\n    }\n    static handle cast(const RValueCaster &, return_value_policy, handle) {\n        return py::str(\"lvalue\").release();\n    }\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\ntemplate <typename F>\nvoid ignoreOldStyleInitWarnings(F &&body) {\n    py::exec(R\"(\n    message = \"pybind11-bound class '.+' is using an old-style placement-new '(?:__init__|__setstate__)' which has been deprecated\"\n\n    import warnings\n    with warnings.catch_warnings():\n        warnings.filterwarnings(\"ignore\", message=message, category=FutureWarning)\n        body()\n    )\",\n             py::dict(py::arg(\"body\") = py::cpp_function(body)));\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/pytest.ini",
    "content": "[pytest]\nminversion = 3.1\nnorecursedirs = test_* extra_*\nxfail_strict = True\naddopts =\n    # show summary of skipped tests\n    -rs\n    # capture only Python print and C++ py::print, but not C output (low-level Python errors)\n    --capture=sys\nfilterwarnings =\n    # make warnings into errors but ignore certain third-party extension issues\n    error\n    # somehow, some DeprecationWarnings do not get turned into errors\n    always::DeprecationWarning\n    # importing scipy submodules on some version of Python\n    ignore::ImportWarning\n    # bogus numpy ABI warning (see numpy/#432)\n    ignore:.*numpy.dtype size changed.*:RuntimeWarning\n    ignore:.*numpy.ufunc size changed.*:RuntimeWarning\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/requirements.txt",
    "content": "numpy==1.16.6; python_version<\"3.6\" and sys_platform!=\"win32\" and platform_python_implementation!=\"PyPy\"\nnumpy==1.19.0; platform_python_implementation==\"PyPy\" and sys_platform==\"linux\" and python_version==\"3.6\"\nnumpy==1.20.0; platform_python_implementation==\"PyPy\" and sys_platform==\"linux\" and python_version==\"3.7\"\nnumpy==1.19.3; platform_python_implementation!=\"PyPy\" and python_version==\"3.6\"\nnumpy==1.21.3; platform_python_implementation!=\"PyPy\" and python_version>=\"3.7\" and python_version<\"3.11\"\npy @ git+https://github.com/pytest-dev/py; python_version>=\"3.11\"\npytest==4.6.9; python_version<\"3.5\"\npytest==6.1.2; python_version==\"3.5\"\npytest==6.2.4; python_version>=\"3.6\"\npytest-timeout\nscipy==1.2.3; platform_python_implementation!=\"PyPy\" and python_version<\"3.6\"\nscipy==1.5.4; platform_python_implementation!=\"PyPy\" and python_version>=\"3.6\" and python_version<\"3.10\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_async.cpp",
    "content": "/*\n    tests/test_async.cpp -- __await__ support\n\n    Copyright (c) 2019 Google Inc.\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(async_module, m) {\n    struct DoesNotSupportAsync {};\n    py::class_<DoesNotSupportAsync>(m, \"DoesNotSupportAsync\").def(py::init<>());\n    struct SupportsAsync {};\n    py::class_<SupportsAsync>(m, \"SupportsAsync\")\n        .def(py::init<>())\n        .def(\"__await__\", [](const SupportsAsync &self) -> py::object {\n            static_cast<void>(self);\n            py::object loop = py::module_::import(\"asyncio.events\").attr(\"get_event_loop\")();\n            py::object f = loop.attr(\"create_future\")();\n            f.attr(\"set_result\")(5);\n            return f.attr(\"__await__\")();\n        });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_async.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nasyncio = pytest.importorskip(\"asyncio\")\nm = pytest.importorskip(\"pybind11_tests.async_module\")\n\n\n@pytest.fixture\ndef event_loop():\n    loop = asyncio.new_event_loop()\n    yield loop\n    loop.close()\n\n\nasync def get_await_result(x):\n    return await x\n\n\ndef test_await(event_loop):\n    assert 5 == event_loop.run_until_complete(get_await_result(m.SupportsAsync()))\n\n\ndef test_await_missing(event_loop):\n    with pytest.raises(TypeError):\n        event_loop.run_until_complete(get_await_result(m.DoesNotSupportAsync()))\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_buffers.cpp",
    "content": "/*\n    tests/test_buffers.cpp -- supporting Pythons' buffer protocol\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(buffers, m) {\n    // test_from_python / test_to_python:\n    class Matrix {\n    public:\n        Matrix(py::ssize_t rows, py::ssize_t cols) : m_rows(rows), m_cols(cols) {\n            print_created(this, std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[(size_t) (rows * cols)];\n            memset(m_data, 0, sizeof(float) * (size_t) (rows * cols));\n        }\n\n        Matrix(const Matrix &s) : m_rows(s.m_rows), m_cols(s.m_cols) {\n            print_copy_created(this,\n                               std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[(size_t) (m_rows * m_cols)];\n            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));\n        }\n\n        Matrix(Matrix &&s) noexcept : m_rows(s.m_rows), m_cols(s.m_cols), m_data(s.m_data) {\n            print_move_created(this);\n            s.m_rows = 0;\n            s.m_cols = 0;\n            s.m_data = nullptr;\n        }\n\n        ~Matrix() {\n            print_destroyed(this,\n                            std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            delete[] m_data;\n        }\n\n        Matrix &operator=(const Matrix &s) {\n            if (this == &s) {\n                return *this;\n            }\n            print_copy_assigned(this,\n                                std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            delete[] m_data;\n            m_rows = s.m_rows;\n            m_cols = s.m_cols;\n            m_data = new float[(size_t) (m_rows * m_cols)];\n            memcpy(m_data, s.m_data, sizeof(float) * (size_t) (m_rows * m_cols));\n            return *this;\n        }\n\n        Matrix &operator=(Matrix &&s) noexcept {\n            print_move_assigned(this,\n                                std::to_string(m_rows) + \"x\" + std::to_string(m_cols) + \" matrix\");\n            if (&s != this) {\n                delete[] m_data;\n                m_rows = s.m_rows;\n                m_cols = s.m_cols;\n                m_data = s.m_data;\n                s.m_rows = 0;\n                s.m_cols = 0;\n                s.m_data = nullptr;\n            }\n            return *this;\n        }\n\n        float operator()(py::ssize_t i, py::ssize_t j) const {\n            return m_data[(size_t) (i * m_cols + j)];\n        }\n\n        float &operator()(py::ssize_t i, py::ssize_t j) {\n            return m_data[(size_t) (i * m_cols + j)];\n        }\n\n        float *data() { return m_data; }\n\n        py::ssize_t rows() const { return m_rows; }\n        py::ssize_t cols() const { return m_cols; }\n\n    private:\n        py::ssize_t m_rows;\n        py::ssize_t m_cols;\n        float *m_data;\n    };\n    py::class_<Matrix>(m, \"Matrix\", py::buffer_protocol())\n        .def(py::init<py::ssize_t, py::ssize_t>())\n        /// Construct from a buffer\n        .def(py::init([](const py::buffer &b) {\n            py::buffer_info info = b.request();\n            if (info.format != py::format_descriptor<float>::format() || info.ndim != 2) {\n                throw std::runtime_error(\"Incompatible buffer format!\");\n            }\n\n            auto *v = new Matrix(info.shape[0], info.shape[1]);\n            memcpy(v->data(), info.ptr, sizeof(float) * (size_t) (v->rows() * v->cols()));\n            return v;\n        }))\n\n        .def(\"rows\", &Matrix::rows)\n        .def(\"cols\", &Matrix::cols)\n\n        /// Bare bones interface\n        .def(\"__getitem__\",\n             [](const Matrix &m, std::pair<py::ssize_t, py::ssize_t> i) {\n                 if (i.first >= m.rows() || i.second >= m.cols()) {\n                     throw py::index_error();\n                 }\n                 return m(i.first, i.second);\n             })\n        .def(\"__setitem__\",\n             [](Matrix &m, std::pair<py::ssize_t, py::ssize_t> i, float v) {\n                 if (i.first >= m.rows() || i.second >= m.cols()) {\n                     throw py::index_error();\n                 }\n                 m(i.first, i.second) = v;\n             })\n        /// Provide buffer access\n        .def_buffer([](Matrix &m) -> py::buffer_info {\n            return py::buffer_info(\n                m.data(),                          /* Pointer to buffer */\n                {m.rows(), m.cols()},              /* Buffer dimensions */\n                {sizeof(float) * size_t(m.cols()), /* Strides (in bytes) for each index */\n                 sizeof(float)});\n        });\n\n    // test_inherited_protocol\n    class SquareMatrix : public Matrix {\n    public:\n        explicit SquareMatrix(py::ssize_t n) : Matrix(n, n) {}\n    };\n    // Derived classes inherit the buffer protocol and the buffer access function\n    py::class_<SquareMatrix, Matrix>(m, \"SquareMatrix\").def(py::init<py::ssize_t>());\n\n    // test_pointer_to_member_fn\n    // Tests that passing a pointer to member to the base class works in\n    // the derived class.\n    struct Buffer {\n        int32_t value = 0;\n\n        py::buffer_info get_buffer_info() {\n            return py::buffer_info(\n                &value, sizeof(value), py::format_descriptor<int32_t>::format(), 1);\n        }\n    };\n    py::class_<Buffer>(m, \"Buffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", &Buffer::value)\n        .def_buffer(&Buffer::get_buffer_info);\n\n    class ConstBuffer {\n        std::unique_ptr<int32_t> value;\n\n    public:\n        int32_t get_value() const { return *value; }\n        void set_value(int32_t v) { *value = v; }\n\n        py::buffer_info get_buffer_info() const {\n            return py::buffer_info(\n                value.get(), sizeof(*value), py::format_descriptor<int32_t>::format(), 1);\n        }\n\n        ConstBuffer() : value(new int32_t{0}) {}\n    };\n    py::class_<ConstBuffer>(m, \"ConstBuffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_property(\"value\", &ConstBuffer::get_value, &ConstBuffer::set_value)\n        .def_buffer(&ConstBuffer::get_buffer_info);\n\n    struct DerivedBuffer : public Buffer {};\n    py::class_<DerivedBuffer>(m, \"DerivedBuffer\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", (int32_t DerivedBuffer::*) &DerivedBuffer::value)\n        .def_buffer(&DerivedBuffer::get_buffer_info);\n\n    struct BufferReadOnly {\n        const uint8_t value = 0;\n        explicit BufferReadOnly(uint8_t value) : value(value) {}\n\n        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1); }\n    };\n    py::class_<BufferReadOnly>(m, \"BufferReadOnly\", py::buffer_protocol())\n        .def(py::init<uint8_t>())\n        .def_buffer(&BufferReadOnly::get_buffer_info);\n\n    struct BufferReadOnlySelect {\n        uint8_t value = 0;\n        bool readonly = false;\n\n        py::buffer_info get_buffer_info() { return py::buffer_info(&value, 1, readonly); }\n    };\n    py::class_<BufferReadOnlySelect>(m, \"BufferReadOnlySelect\", py::buffer_protocol())\n        .def(py::init<>())\n        .def_readwrite(\"value\", &BufferReadOnlySelect::value)\n        .def_readwrite(\"readonly\", &BufferReadOnlySelect::readonly)\n        .def_buffer(&BufferReadOnlySelect::get_buffer_info);\n\n    // Expose buffer_info for testing.\n    py::class_<py::buffer_info>(m, \"buffer_info\")\n        .def(py::init<>())\n        .def_readonly(\"itemsize\", &py::buffer_info::itemsize)\n        .def_readonly(\"size\", &py::buffer_info::size)\n        .def_readonly(\"format\", &py::buffer_info::format)\n        .def_readonly(\"ndim\", &py::buffer_info::ndim)\n        .def_readonly(\"shape\", &py::buffer_info::shape)\n        .def_readonly(\"strides\", &py::buffer_info::strides)\n        .def_readonly(\"readonly\", &py::buffer_info::readonly)\n        .def(\"__repr__\", [](py::handle self) {\n            return py::str(\"itemsize={0.itemsize!r}, size={0.size!r}, format={0.format!r}, \"\n                           \"ndim={0.ndim!r}, shape={0.shape!r}, strides={0.strides!r}, \"\n                           \"readonly={0.readonly!r}\")\n                .format(self);\n        });\n\n    m.def(\"get_buffer_info\", [](const py::buffer &buffer) { return buffer.request(); });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_buffers.py",
    "content": "# -*- coding: utf-8 -*-\nimport ctypes\nimport io\nimport struct\n\nimport pytest\n\nimport env\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import buffers as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_from_python():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.Matrix(np.array([1, 2, 3]))  # trying to assign a 1D array\n    assert str(excinfo.value) == \"Incompatible buffer format!\"\n\n    m3 = np.array([[1, 2, 3], [4, 5, 6]]).astype(np.float32)\n    m4 = m.Matrix(m3)\n\n    for i in range(m4.rows()):\n        for j in range(m4.cols()):\n            assert m3[i, j] == m4[i, j]\n\n    cstats = ConstructorStats.get(m.Matrix)\n    assert cstats.alive() == 1\n    del m3, m4\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"2x3 matrix\"]\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0  # Don't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2444\n# TODO: fix on recent PyPy\n@pytest.mark.xfail(\n    env.PYPY, reason=\"PyPy 7.3.7 doesn't clear this anymore\", strict=False\n)\ndef test_to_python():\n    mat = m.Matrix(5, 4)\n    assert memoryview(mat).shape == (5, 4)\n\n    assert mat[2, 3] == 0\n    mat[2, 3] = 4.0\n    mat[3, 2] = 7.0\n    assert mat[2, 3] == 4\n    assert mat[3, 2] == 7\n    assert struct.unpack_from(\"f\", mat, (3 * 4 + 2) * 4) == (7,)\n    assert struct.unpack_from(\"f\", mat, (2 * 4 + 3) * 4) == (4,)\n\n    mat2 = np.array(mat, copy=False)\n    assert mat2.shape == (5, 4)\n    assert abs(mat2).sum() == 11\n    assert mat2[2, 3] == 4 and mat2[3, 2] == 7\n    mat2[2, 3] = 5\n    assert mat2[2, 3] == 5\n\n    cstats = ConstructorStats.get(m.Matrix)\n    assert cstats.alive() == 1\n    del mat\n    pytest.gc_collect()\n    assert cstats.alive() == 1\n    del mat2  # holds a mat reference\n    pytest.gc_collect()\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"5x4 matrix\"]\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0  # Don't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_inherited_protocol():\n    \"\"\"SquareMatrix is derived from Matrix and inherits the buffer protocol\"\"\"\n\n    matrix = m.SquareMatrix(5)\n    assert memoryview(matrix).shape == (5, 5)\n    assert np.asarray(matrix).shape == (5, 5)\n\n\ndef test_pointer_to_member_fn():\n    for cls in [m.Buffer, m.ConstBuffer, m.DerivedBuffer]:\n        buf = cls()\n        buf.value = 0x12345678\n        value = struct.unpack(\"i\", bytearray(buf))[0]\n        assert value == 0x12345678\n\n\ndef test_readonly_buffer():\n    buf = m.BufferReadOnly(0x64)\n    view = memoryview(buf)\n    assert view[0] == b\"d\" if env.PY2 else 0x64\n    assert view.readonly\n    with pytest.raises(TypeError):\n        view[0] = b\"\\0\" if env.PY2 else 0\n\n\ndef test_selective_readonly_buffer():\n    buf = m.BufferReadOnlySelect()\n\n    memoryview(buf)[0] = b\"d\" if env.PY2 else 0x64\n    assert buf.value == 0x64\n\n    io.BytesIO(b\"A\").readinto(buf)\n    assert buf.value == ord(b\"A\")\n\n    buf.readonly = True\n    with pytest.raises(TypeError):\n        memoryview(buf)[0] = b\"\\0\" if env.PY2 else 0\n    with pytest.raises(TypeError):\n        io.BytesIO(b\"1\").readinto(buf)\n\n\ndef test_ctypes_array_1d():\n    char1d = (ctypes.c_char * 10)()\n    int1d = (ctypes.c_int * 15)()\n    long1d = (ctypes.c_long * 7)()\n\n    for carray in (char1d, int1d, long1d):\n        info = m.get_buffer_info(carray)\n        assert info.itemsize == ctypes.sizeof(carray._type_)\n        assert info.size == len(carray)\n        assert info.ndim == 1\n        assert info.shape == [info.size]\n        assert info.strides == [info.itemsize]\n        assert not info.readonly\n\n\ndef test_ctypes_array_2d():\n    char2d = ((ctypes.c_char * 10) * 4)()\n    int2d = ((ctypes.c_int * 15) * 3)()\n    long2d = ((ctypes.c_long * 7) * 2)()\n\n    for carray in (char2d, int2d, long2d):\n        info = m.get_buffer_info(carray)\n        assert info.itemsize == ctypes.sizeof(carray[0]._type_)\n        assert info.size == len(carray) * len(carray[0])\n        assert info.ndim == 2\n        assert info.shape == [len(carray), len(carray[0])]\n        assert info.strides == [info.itemsize * len(carray[0]), info.itemsize]\n        assert not info.readonly\n\n\n@pytest.mark.skipif(\n    \"env.PYPY and env.PY2\", reason=\"PyPy2 bytes buffer not reported as readonly\"\n)\ndef test_ctypes_from_buffer():\n    test_pystr = b\"0123456789\"\n    for pyarray in (test_pystr, bytearray(test_pystr)):\n        pyinfo = m.get_buffer_info(pyarray)\n\n        if pyinfo.readonly:\n            cbytes = (ctypes.c_char * len(pyarray)).from_buffer_copy(pyarray)\n            cinfo = m.get_buffer_info(cbytes)\n        else:\n            cbytes = (ctypes.c_char * len(pyarray)).from_buffer(pyarray)\n            cinfo = m.get_buffer_info(cbytes)\n\n        assert cinfo.size == pyinfo.size\n        assert cinfo.ndim == pyinfo.ndim\n        assert cinfo.shape == pyinfo.shape\n        assert cinfo.strides == pyinfo.strides\n        assert not cinfo.readonly\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_builtin_casters.cpp",
    "content": "/*\n    tests/test_builtin_casters.cpp -- Casters available without any additional headers\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/complex.h>\n\n#include \"pybind11_tests.h\"\n\nstruct ConstRefCasted {\n    int tag;\n};\n\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nclass type_caster<ConstRefCasted> {\npublic:\n    static constexpr auto name = const_name<ConstRefCasted>();\n\n    // Input is unimportant, a new value will always be constructed based on the\n    // cast operator.\n    bool load(handle, bool) { return true; }\n\n    explicit operator ConstRefCasted &&() {\n        value = {1};\n        // NOLINTNEXTLINE(performance-move-const-arg)\n        return std::move(value);\n    }\n    explicit operator ConstRefCasted &() {\n        value = {2};\n        return value;\n    }\n    explicit operator ConstRefCasted *() {\n        value = {3};\n        return &value;\n    }\n\n    explicit operator const ConstRefCasted &() {\n        value = {4};\n        return value;\n    }\n    explicit operator const ConstRefCasted *() {\n        value = {5};\n        return &value;\n    }\n\n    // custom cast_op to explicitly propagate types to the conversion operators.\n    template <typename T_>\n    using cast_op_type =\n        /// const\n        conditional_t<\n            std::is_same<remove_reference_t<T_>, const ConstRefCasted *>::value,\n            const ConstRefCasted *,\n            conditional_t<\n                std::is_same<T_, const ConstRefCasted &>::value,\n                const ConstRefCasted &,\n                /// non-const\n                conditional_t<std::is_same<remove_reference_t<T_>, ConstRefCasted *>::value,\n                              ConstRefCasted *,\n                              conditional_t<std::is_same<T_, ConstRefCasted &>::value,\n                                            ConstRefCasted &,\n                                            /* else */ ConstRefCasted &&>>>>;\n\nprivate:\n    ConstRefCasted value = {0};\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\nTEST_SUBMODULE(builtin_casters, m) {\n    // test_simple_string\n    m.def(\"string_roundtrip\", [](const char *s) { return s; });\n\n    // test_unicode_conversion\n    // Some test characters in utf16 and utf32 encodings.  The last one (the 𝐀) contains a null\n    // byte\n    char32_t a32 = 0x61 /*a*/, z32 = 0x7a /*z*/, ib32 = 0x203d /*‽*/, cake32 = 0x1f382 /*🎂*/,\n             mathbfA32 = 0x1d400 /*𝐀*/;\n    char16_t b16 = 0x62 /*b*/, z16 = 0x7a, ib16 = 0x203d, cake16_1 = 0xd83c, cake16_2 = 0xdf82,\n             mathbfA16_1 = 0xd835, mathbfA16_2 = 0xdc00;\n    std::wstring wstr;\n    wstr.push_back(0x61);   // a\n    wstr.push_back(0x2e18); // ⸘\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {\n        wstr.push_back(mathbfA16_1);\n        wstr.push_back(mathbfA16_2);\n    } // 𝐀, utf16\n    else {\n        wstr.push_back((wchar_t) mathbfA32);\n    }                     // 𝐀, utf32\n    wstr.push_back(0x7a); // z\n\n    m.def(\"good_utf8_string\", []() {\n        return std::string((const char *) u8\"Say utf8\\u203d \\U0001f382 \\U0001d400\");\n    }); // Say utf8‽ 🎂 𝐀\n    m.def(\"good_utf16_string\", [=]() {\n        return std::u16string({b16, ib16, cake16_1, cake16_2, mathbfA16_1, mathbfA16_2, z16});\n    }); // b‽🎂𝐀z\n    m.def(\"good_utf32_string\", [=]() {\n        return std::u32string({a32, mathbfA32, cake32, ib32, z32});\n    });                                                 // a𝐀🎂‽z\n    m.def(\"good_wchar_string\", [=]() { return wstr; }); // a‽𝐀z\n    m.def(\"bad_utf8_string\", []() {\n        return std::string(\"abc\\xd0\"\n                           \"def\");\n    });\n    m.def(\"bad_utf16_string\", [=]() { return std::u16string({b16, char16_t(0xd800), z16}); });\n#if PY_MAJOR_VERSION >= 3\n    // Under Python 2.7, invalid unicode UTF-32 characters don't appear to trigger\n    // UnicodeDecodeError\n    m.def(\"bad_utf32_string\", [=]() { return std::u32string({a32, char32_t(0xd800), z32}); });\n    if (PYBIND11_SILENCE_MSVC_C4127(sizeof(wchar_t) == 2)) {\n        m.def(\"bad_wchar_string\", [=]() {\n            return std::wstring({wchar_t(0x61), wchar_t(0xd800)});\n        });\n    }\n#endif\n    m.def(\"u8_Z\", []() -> char { return 'Z'; });\n    m.def(\"u8_eacute\", []() -> char { return '\\xe9'; });\n    m.def(\"u16_ibang\", [=]() -> char16_t { return ib16; });\n    m.def(\"u32_mathbfA\", [=]() -> char32_t { return mathbfA32; });\n    m.def(\"wchar_heart\", []() -> wchar_t { return 0x2665; });\n\n    // test_single_char_arguments\n    m.attr(\"wchar_size\") = py::cast(sizeof(wchar_t));\n    m.def(\"ord_char\", [](char c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char_lv\", [](char &c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char16\", [](char16_t c) -> uint16_t { return c; });\n    m.def(\"ord_char16_lv\", [](char16_t &c) -> uint16_t { return c; });\n    m.def(\"ord_char32\", [](char32_t c) -> uint32_t { return c; });\n    m.def(\"ord_wchar\", [](wchar_t c) -> int { return c; });\n\n    // test_bytes_to_string\n    m.def(\"strlen\", [](char *s) { return strlen(s); });\n    m.def(\"string_length\", [](const std::string &s) { return s.length(); });\n\n#ifdef PYBIND11_HAS_U8STRING\n    m.attr(\"has_u8string\") = true;\n    m.def(\"good_utf8_u8string\", []() {\n        return std::u8string(u8\"Say utf8\\u203d \\U0001f382 \\U0001d400\");\n    }); // Say utf8‽ 🎂 𝐀\n    m.def(\"bad_utf8_u8string\", []() {\n        return std::u8string((const char8_t *) \"abc\\xd0\"\n                                               \"def\");\n    });\n\n    m.def(\"u8_char8_Z\", []() -> char8_t { return u8'Z'; });\n\n    // test_single_char_arguments\n    m.def(\"ord_char8\", [](char8_t c) -> int { return static_cast<unsigned char>(c); });\n    m.def(\"ord_char8_lv\", [](char8_t &c) -> int { return static_cast<unsigned char>(c); });\n#endif\n\n    // test_string_view\n#ifdef PYBIND11_HAS_STRING_VIEW\n    m.attr(\"has_string_view\") = true;\n    m.def(\"string_view_print\", [](std::string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view16_print\", [](std::u16string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view32_print\", [](std::u32string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view_chars\", [](std::string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((std::uint8_t) c);\n        }\n        return l;\n    });\n    m.def(\"string_view16_chars\", [](std::u16string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((int) c);\n        }\n        return l;\n    });\n    m.def(\"string_view32_chars\", [](std::u32string_view s) {\n        py::list l;\n        for (auto c : s) {\n            l.append((int) c);\n        }\n        return l;\n    });\n    m.def(\"string_view_return\",\n          []() { return std::string_view((const char *) u8\"utf8 secret \\U0001f382\"); });\n    m.def(\"string_view16_return\",\n          []() { return std::u16string_view(u\"utf16 secret \\U0001f382\"); });\n    m.def(\"string_view32_return\",\n          []() { return std::u32string_view(U\"utf32 secret \\U0001f382\"); });\n\n    // The inner lambdas here are to also test implicit conversion\n    using namespace std::literals;\n    m.def(\"string_view_bytes\",\n          []() { return [](py::bytes b) { return b; }(\"abc \\x80\\x80 def\"sv); });\n    m.def(\"string_view_str\",\n          []() { return [](py::str s) { return s; }(\"abc \\342\\200\\275 def\"sv); });\n    m.def(\"string_view_from_bytes\",\n          [](const py::bytes &b) { return [](std::string_view s) { return s; }(b); });\n#    if PY_MAJOR_VERSION >= 3\n    m.def(\"string_view_memoryview\", []() {\n        static constexpr auto val = \"Have some \\360\\237\\216\\202\"sv;\n        return py::memoryview::from_memory(val);\n    });\n#    endif\n\n#    ifdef PYBIND11_HAS_U8STRING\n    m.def(\"string_view8_print\", [](std::u8string_view s) { py::print(s, s.size()); });\n    m.def(\"string_view8_chars\", [](std::u8string_view s) {\n        py::list l;\n        for (auto c : s)\n            l.append((std::uint8_t) c);\n        return l;\n    });\n    m.def(\"string_view8_return\", []() { return std::u8string_view(u8\"utf8 secret \\U0001f382\"); });\n    m.def(\"string_view8_str\", []() { return py::str{std::u8string_view{u8\"abc ‽ def\"}}; });\n#    endif\n\n    struct TypeWithBothOperatorStringAndStringView {\n        // NOLINTNEXTLINE(google-explicit-constructor)\n        operator std::string() const { return \"success\"; }\n        // NOLINTNEXTLINE(google-explicit-constructor)\n        operator std::string_view() const { return \"failure\"; }\n    };\n    m.def(\"bytes_from_type_with_both_operator_string_and_string_view\",\n          []() { return py::bytes(TypeWithBothOperatorStringAndStringView()); });\n    m.def(\"str_from_type_with_both_operator_string_and_string_view\",\n          []() { return py::str(TypeWithBothOperatorStringAndStringView()); });\n#endif\n\n    // test_integer_casting\n    m.def(\"i32_str\", [](std::int32_t v) { return std::to_string(v); });\n    m.def(\"u32_str\", [](std::uint32_t v) { return std::to_string(v); });\n    m.def(\"i64_str\", [](std::int64_t v) { return std::to_string(v); });\n    m.def(\"u64_str\", [](std::uint64_t v) { return std::to_string(v); });\n\n    // test_int_convert\n    m.def(\"int_passthrough\", [](int arg) { return arg; });\n    m.def(\n        \"int_passthrough_noconvert\", [](int arg) { return arg; }, py::arg{}.noconvert());\n\n    // test_tuple\n    m.def(\n        \"pair_passthrough\",\n        [](const std::pair<bool, std::string> &input) {\n            return std::make_pair(input.second, input.first);\n        },\n        \"Return a pair in reversed order\");\n    m.def(\n        \"tuple_passthrough\",\n        [](std::tuple<bool, std::string, int> input) {\n            return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input));\n        },\n        \"Return a triple in reversed order\");\n    m.def(\"empty_tuple\", []() { return std::tuple<>(); });\n    static std::pair<RValueCaster, RValueCaster> lvpair;\n    static std::tuple<RValueCaster, RValueCaster, RValueCaster> lvtuple;\n    static std::pair<RValueCaster, std::tuple<RValueCaster, std::pair<RValueCaster, RValueCaster>>>\n        lvnested;\n    m.def(\"rvalue_pair\", []() { return std::make_pair(RValueCaster{}, RValueCaster{}); });\n    m.def(\"lvalue_pair\", []() -> const decltype(lvpair) & { return lvpair; });\n    m.def(\"rvalue_tuple\",\n          []() { return std::make_tuple(RValueCaster{}, RValueCaster{}, RValueCaster{}); });\n    m.def(\"lvalue_tuple\", []() -> const decltype(lvtuple) & { return lvtuple; });\n    m.def(\"rvalue_nested\", []() {\n        return std::make_pair(\n            RValueCaster{},\n            std::make_tuple(RValueCaster{}, std::make_pair(RValueCaster{}, RValueCaster{})));\n    });\n    m.def(\"lvalue_nested\", []() -> const decltype(lvnested) & { return lvnested; });\n\n    static std::pair<int, std::string> int_string_pair{2, \"items\"};\n    m.def(\"int_string_pair\", []() { return &int_string_pair; });\n\n    // test_builtins_cast_return_none\n    m.def(\"return_none_string\", []() -> std::string * { return nullptr; });\n    m.def(\"return_none_char\", []() -> const char * { return nullptr; });\n    m.def(\"return_none_bool\", []() -> bool * { return nullptr; });\n    m.def(\"return_none_int\", []() -> int * { return nullptr; });\n    m.def(\"return_none_float\", []() -> float * { return nullptr; });\n    m.def(\"return_none_pair\", []() -> std::pair<int, int> * { return nullptr; });\n\n    // test_none_deferred\n    m.def(\"defer_none_cstring\", [](char *) { return false; });\n    m.def(\"defer_none_cstring\", [](const py::none &) { return true; });\n    m.def(\"defer_none_custom\", [](UserType *) { return false; });\n    m.def(\"defer_none_custom\", [](const py::none &) { return true; });\n    m.def(\"nodefer_none_void\", [](void *) { return true; });\n    m.def(\"nodefer_none_void\", [](const py::none &) { return false; });\n\n    // test_void_caster\n    m.def(\"load_nullptr_t\", [](std::nullptr_t) {}); // not useful, but it should still compile\n    m.def(\"cast_nullptr_t\", []() { return std::nullptr_t{}; });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_bool_caster\n    m.def(\"bool_passthrough\", [](bool arg) { return arg; });\n    m.def(\n        \"bool_passthrough_noconvert\", [](bool arg) { return arg; }, py::arg{}.noconvert());\n\n    // TODO: This should be disabled and fixed in future Intel compilers\n#if !defined(__INTEL_COMPILER)\n    // Test \"bool_passthrough_noconvert\" again, but using () instead of {} to construct py::arg\n    // When compiled with the Intel compiler, this results in segmentation faults when importing\n    // the module. Tested with icc (ICC) 2021.1 Beta 20200827, this should be tested again when\n    // a newer version of icc is available.\n    m.def(\n        \"bool_passthrough_noconvert2\", [](bool arg) { return arg; }, py::arg().noconvert());\n#endif\n\n    // test_reference_wrapper\n    m.def(\"refwrap_builtin\", [](std::reference_wrapper<int> p) { return 10 * p.get(); });\n    m.def(\"refwrap_usertype\", [](std::reference_wrapper<UserType> p) { return p.get().value(); });\n    m.def(\"refwrap_usertype_const\",\n          [](std::reference_wrapper<const UserType> p) { return p.get().value(); });\n\n    m.def(\"refwrap_lvalue\", []() -> std::reference_wrapper<UserType> {\n        static UserType x(1);\n        return std::ref(x);\n    });\n    m.def(\"refwrap_lvalue_const\", []() -> std::reference_wrapper<const UserType> {\n        static UserType x(1);\n        return std::cref(x);\n    });\n\n    // Not currently supported (std::pair caster has return-by-value cast operator);\n    // triggers static_assert failure.\n    // m.def(\"refwrap_pair\", [](std::reference_wrapper<std::pair<int, int>>) { });\n\n    m.def(\n        \"refwrap_list\",\n        [](bool copy) {\n            static IncType x1(1), x2(2);\n            py::list l;\n            for (const auto &f : {std::ref(x1), std::ref(x2)}) {\n                l.append(py::cast(\n                    f, copy ? py::return_value_policy::copy : py::return_value_policy::reference));\n            }\n            return l;\n        },\n        \"copy\"_a);\n\n    m.def(\"refwrap_iiw\", [](const IncType &w) { return w.value(); });\n    m.def(\"refwrap_call_iiw\", [](IncType &w, const py::function &f) {\n        py::list l;\n        l.append(f(std::ref(w)));\n        l.append(f(std::cref(w)));\n        IncType x(w.value());\n        l.append(f(std::ref(x)));\n        IncType y(w.value());\n        auto r3 = std::ref(y);\n        l.append(f(r3));\n        return l;\n    });\n\n    // test_complex\n    m.def(\"complex_cast\", [](float x) { return \"{}\"_s.format(x); });\n    m.def(\"complex_cast\",\n          [](std::complex<float> x) { return \"({}, {})\"_s.format(x.real(), x.imag()); });\n\n    // test int vs. long (Python 2)\n    m.def(\"int_cast\", []() { return (int) 42; });\n    m.def(\"long_cast\", []() { return (long) 42; });\n    m.def(\"longlong_cast\", []() { return ULLONG_MAX; });\n\n    /// test void* cast operator\n    m.def(\"test_void_caster\", []() -> bool {\n        void *v = (void *) 0xabcd;\n        py::object o = py::cast(v);\n        return py::cast<void *>(o) == v;\n    });\n\n    // Tests const/non-const propagation in cast_op.\n    m.def(\"takes\", [](ConstRefCasted x) { return x.tag; });\n    m.def(\"takes_move\", [](ConstRefCasted &&x) { return x.tag; });\n    m.def(\"takes_ptr\", [](ConstRefCasted *x) { return x->tag; });\n    m.def(\"takes_ref\", [](ConstRefCasted &x) { return x.tag; });\n    m.def(\"takes_ref_wrap\", [](std::reference_wrapper<ConstRefCasted> x) { return x.get().tag; });\n    m.def(\"takes_const_ptr\", [](const ConstRefCasted *x) { return x->tag; });\n    m.def(\"takes_const_ref\", [](const ConstRefCasted &x) { return x.tag; });\n    m.def(\"takes_const_ref_wrap\",\n          [](std::reference_wrapper<const ConstRefCasted> x) { return x.get().tag; });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_builtin_casters.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import IncType, UserType\nfrom pybind11_tests import builtin_casters as m\n\n\ndef test_simple_string():\n    assert m.string_roundtrip(\"const char *\") == \"const char *\"\n\n\ndef test_unicode_conversion():\n    \"\"\"Tests unicode conversion and error reporting.\"\"\"\n    assert m.good_utf8_string() == u\"Say utf8‽ 🎂 𝐀\"\n    assert m.good_utf16_string() == u\"b‽🎂𝐀z\"\n    assert m.good_utf32_string() == u\"a𝐀🎂‽z\"\n    assert m.good_wchar_string() == u\"a⸘𝐀z\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.good_utf8_u8string() == u\"Say utf8‽ 🎂 𝐀\"\n\n    with pytest.raises(UnicodeDecodeError):\n        m.bad_utf8_string()\n\n    with pytest.raises(UnicodeDecodeError):\n        m.bad_utf16_string()\n\n    # These are provided only if they actually fail (they don't when 32-bit and under Python 2.7)\n    if hasattr(m, \"bad_utf32_string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_utf32_string()\n    if hasattr(m, \"bad_wchar_string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_wchar_string()\n    if hasattr(m, \"has_u8string\"):\n        with pytest.raises(UnicodeDecodeError):\n            m.bad_utf8_u8string()\n\n    assert m.u8_Z() == \"Z\"\n    assert m.u8_eacute() == u\"é\"\n    assert m.u16_ibang() == u\"‽\"\n    assert m.u32_mathbfA() == u\"𝐀\"\n    assert m.wchar_heart() == u\"♥\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.u8_char8_Z() == \"Z\"\n\n\ndef test_single_char_arguments():\n    \"\"\"Tests failures for passing invalid inputs to char-accepting functions\"\"\"\n\n    def toobig_message(r):\n        return \"Character code point not in range({:#x})\".format(r)\n\n    toolong_message = \"Expected a character, but multi-character string found\"\n\n    assert m.ord_char(u\"a\") == 0x61  # simple ASCII\n    assert m.ord_char_lv(u\"b\") == 0x62\n    assert (\n        m.ord_char(u\"é\") == 0xE9\n    )  # requires 2 bytes in utf-8, but can be stuffed in a char\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char(u\"Ā\") == 0x100  # requires 2 bytes, doesn't fit in a char\n    assert str(excinfo.value) == toobig_message(0x100)\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char(u\"ab\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_char16(u\"a\") == 0x61\n    assert m.ord_char16(u\"é\") == 0xE9\n    assert m.ord_char16_lv(u\"ê\") == 0xEA\n    assert m.ord_char16(u\"Ā\") == 0x100\n    assert m.ord_char16(u\"‽\") == 0x203D\n    assert m.ord_char16(u\"♥\") == 0x2665\n    assert m.ord_char16_lv(u\"♡\") == 0x2661\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char16(u\"🎂\") == 0x1F382  # requires surrogate pair\n    assert str(excinfo.value) == toobig_message(0x10000)\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char16(u\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_char32(u\"a\") == 0x61\n    assert m.ord_char32(u\"é\") == 0xE9\n    assert m.ord_char32(u\"Ā\") == 0x100\n    assert m.ord_char32(u\"‽\") == 0x203D\n    assert m.ord_char32(u\"♥\") == 0x2665\n    assert m.ord_char32(u\"🎂\") == 0x1F382\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_char32(u\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    assert m.ord_wchar(u\"a\") == 0x61\n    assert m.ord_wchar(u\"é\") == 0xE9\n    assert m.ord_wchar(u\"Ā\") == 0x100\n    assert m.ord_wchar(u\"‽\") == 0x203D\n    assert m.ord_wchar(u\"♥\") == 0x2665\n    if m.wchar_size == 2:\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_wchar(u\"🎂\") == 0x1F382  # requires surrogate pair\n        assert str(excinfo.value) == toobig_message(0x10000)\n    else:\n        assert m.ord_wchar(u\"🎂\") == 0x1F382\n    with pytest.raises(ValueError) as excinfo:\n        assert m.ord_wchar(u\"aa\")\n    assert str(excinfo.value) == toolong_message\n\n    if hasattr(m, \"has_u8string\"):\n        assert m.ord_char8(u\"a\") == 0x61  # simple ASCII\n        assert m.ord_char8_lv(u\"b\") == 0x62\n        assert (\n            m.ord_char8(u\"é\") == 0xE9\n        )  # requires 2 bytes in utf-8, but can be stuffed in a char\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_char8(u\"Ā\") == 0x100  # requires 2 bytes, doesn't fit in a char\n        assert str(excinfo.value) == toobig_message(0x100)\n        with pytest.raises(ValueError) as excinfo:\n            assert m.ord_char8(u\"ab\")\n        assert str(excinfo.value) == toolong_message\n\n\ndef test_bytes_to_string():\n    \"\"\"Tests the ability to pass bytes to C++ string-accepting functions.  Note that this is\n    one-way: the only way to return bytes to Python is via the pybind11::bytes class.\"\"\"\n    # Issue #816\n\n    def to_bytes(s):\n        b = s if env.PY2 else s.encode(\"utf8\")\n        assert isinstance(b, bytes)\n        return b\n\n    assert m.strlen(to_bytes(\"hi\")) == 2\n    assert m.string_length(to_bytes(\"world\")) == 5\n    assert m.string_length(to_bytes(\"a\\x00b\")) == 3\n    assert m.strlen(to_bytes(\"a\\x00b\")) == 1  # C-string limitation\n\n    # passing in a utf8 encoded string should work\n    assert m.string_length(u\"💩\".encode(\"utf8\")) == 4\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_string_view\"), reason=\"no <string_view>\")\ndef test_string_view(capture):\n    \"\"\"Tests support for C++17 string_view arguments and return values\"\"\"\n    assert m.string_view_chars(\"Hi\") == [72, 105]\n    assert m.string_view_chars(\"Hi 🎂\") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]\n    assert m.string_view16_chars(u\"Hi 🎂\") == [72, 105, 32, 0xD83C, 0xDF82]\n    assert m.string_view32_chars(u\"Hi 🎂\") == [72, 105, 32, 127874]\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_chars(\"Hi\") == [72, 105]\n        assert m.string_view8_chars(u\"Hi 🎂\") == [72, 105, 32, 0xF0, 0x9F, 0x8E, 0x82]\n\n    assert m.string_view_return() == u\"utf8 secret 🎂\"\n    assert m.string_view16_return() == u\"utf16 secret 🎂\"\n    assert m.string_view32_return() == u\"utf32 secret 🎂\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_return() == u\"utf8 secret 🎂\"\n\n    with capture:\n        m.string_view_print(\"Hi\")\n        m.string_view_print(\"utf8 🎂\")\n        m.string_view16_print(u\"utf16 🎂\")\n        m.string_view32_print(u\"utf32 🎂\")\n    assert (\n        capture\n        == u\"\"\"\n        Hi 2\n        utf8 🎂 9\n        utf16 🎂 8\n        utf32 🎂 7\n    \"\"\"\n    )\n    if hasattr(m, \"has_u8string\"):\n        with capture:\n            m.string_view8_print(\"Hi\")\n            m.string_view8_print(u\"utf8 🎂\")\n        assert (\n            capture\n            == u\"\"\"\n            Hi 2\n            utf8 🎂 9\n        \"\"\"\n        )\n\n    with capture:\n        m.string_view_print(\"Hi, ascii\")\n        m.string_view_print(\"Hi, utf8 🎂\")\n        m.string_view16_print(u\"Hi, utf16 🎂\")\n        m.string_view32_print(u\"Hi, utf32 🎂\")\n    assert (\n        capture\n        == u\"\"\"\n        Hi, ascii 9\n        Hi, utf8 🎂 13\n        Hi, utf16 🎂 12\n        Hi, utf32 🎂 11\n    \"\"\"\n    )\n    if hasattr(m, \"has_u8string\"):\n        with capture:\n            m.string_view8_print(\"Hi, ascii\")\n            m.string_view8_print(u\"Hi, utf8 🎂\")\n        assert (\n            capture\n            == u\"\"\"\n            Hi, ascii 9\n            Hi, utf8 🎂 13\n        \"\"\"\n        )\n\n    assert m.string_view_bytes() == b\"abc \\x80\\x80 def\"\n    assert m.string_view_str() == u\"abc ‽ def\"\n    assert m.string_view_from_bytes(u\"abc ‽ def\".encode(\"utf-8\")) == u\"abc ‽ def\"\n    if hasattr(m, \"has_u8string\"):\n        assert m.string_view8_str() == u\"abc ‽ def\"\n    if not env.PY2:\n        assert m.string_view_memoryview() == \"Have some 🎂\".encode()\n\n    assert m.bytes_from_type_with_both_operator_string_and_string_view() == b\"success\"\n    assert m.str_from_type_with_both_operator_string_and_string_view() == \"success\"\n\n\ndef test_integer_casting():\n    \"\"\"Issue #929 - out-of-range integer values shouldn't be accepted\"\"\"\n    assert m.i32_str(-1) == \"-1\"\n    assert m.i64_str(-1) == \"-1\"\n    assert m.i32_str(2000000000) == \"2000000000\"\n    assert m.u32_str(2000000000) == \"2000000000\"\n    if env.PY2:\n        assert m.i32_str(long(-1)) == \"-1\"  # noqa: F821 undefined name 'long'\n        assert m.i64_str(long(-1)) == \"-1\"  # noqa: F821 undefined name 'long'\n        assert (\n            m.i64_str(long(-999999999999))  # noqa: F821 undefined name 'long'\n            == \"-999999999999\"\n        )\n        assert (\n            m.u64_str(long(999999999999))  # noqa: F821 undefined name 'long'\n            == \"999999999999\"\n        )\n    else:\n        assert m.i64_str(-999999999999) == \"-999999999999\"\n        assert m.u64_str(999999999999) == \"999999999999\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.u32_str(-1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.u64_str(-1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.i32_str(-3000000000)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.i32_str(3000000000)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    if env.PY2:\n        with pytest.raises(TypeError) as excinfo:\n            m.u32_str(long(-1))  # noqa: F821 undefined name 'long'\n        assert \"incompatible function arguments\" in str(excinfo.value)\n        with pytest.raises(TypeError) as excinfo:\n            m.u64_str(long(-1))  # noqa: F821 undefined name 'long'\n        assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_int_convert():\n    class Int(object):\n        def __int__(self):\n            return 42\n\n    class NotInt(object):\n        pass\n\n    class Float(object):\n        def __float__(self):\n            return 41.99999\n\n    class Index(object):\n        def __index__(self):\n            return 42\n\n    class IntAndIndex(object):\n        def __int__(self):\n            return 42\n\n        def __index__(self):\n            return 0\n\n    class RaisingTypeErrorOnIndex(object):\n        def __index__(self):\n            raise TypeError\n\n        def __int__(self):\n            return 42\n\n    class RaisingValueErrorOnIndex(object):\n        def __index__(self):\n            raise ValueError\n\n        def __int__(self):\n            return 42\n\n    convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert\n\n    def requires_conversion(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    assert convert(7) == 7\n    assert noconvert(7) == 7\n    cant_convert(3.14159)\n    # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)\n    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)\n    if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:\n        with env.deprecated_call():\n            assert convert(Int()) == 42\n    else:\n        assert convert(Int()) == 42\n    requires_conversion(Int())\n    cant_convert(NotInt())\n    cant_convert(Float())\n\n    # Before Python 3.8, `PyLong_AsLong` does not pick up on `obj.__index__`,\n    # but pybind11 \"backports\" this behavior.\n    assert convert(Index()) == 42\n    assert noconvert(Index()) == 42\n    assert convert(IntAndIndex()) == 0  # Fishy; `int(DoubleThought)` == 42\n    assert noconvert(IntAndIndex()) == 0\n    assert convert(RaisingTypeErrorOnIndex()) == 42\n    requires_conversion(RaisingTypeErrorOnIndex())\n    assert convert(RaisingValueErrorOnIndex()) == 42\n    requires_conversion(RaisingValueErrorOnIndex())\n\n\ndef test_numpy_int_convert():\n    np = pytest.importorskip(\"numpy\")\n\n    convert, noconvert = m.int_passthrough, m.int_passthrough_noconvert\n\n    def require_implicit(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    # `np.intc` is an alias that corresponds to a C++ `int`\n    assert convert(np.intc(42)) == 42\n    assert noconvert(np.intc(42)) == 42\n\n    # The implicit conversion from np.float32 is undesirable but currently accepted.\n    # TODO: Avoid DeprecationWarning in `PyLong_AsLong` (and similar)\n    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)\n    # https://github.com/pybind/pybind11/issues/3408\n    if (3, 8) <= env.PY < (3, 10) and env.CPYTHON:\n        with env.deprecated_call():\n            assert convert(np.float32(3.14159)) == 3\n    else:\n        assert convert(np.float32(3.14159)) == 3\n    require_implicit(np.float32(3.14159))\n\n\ndef test_tuple(doc):\n    \"\"\"std::pair <-> tuple & std::tuple <-> tuple\"\"\"\n    assert m.pair_passthrough((True, \"test\")) == (\"test\", True)\n    assert m.tuple_passthrough((True, \"test\", 5)) == (5, \"test\", True)\n    # Any sequence can be cast to a std::pair or std::tuple\n    assert m.pair_passthrough([True, \"test\"]) == (\"test\", True)\n    assert m.tuple_passthrough([True, \"test\", 5]) == (5, \"test\", True)\n    assert m.empty_tuple() == ()\n\n    assert (\n        doc(m.pair_passthrough)\n        == \"\"\"\n        pair_passthrough(arg0: Tuple[bool, str]) -> Tuple[str, bool]\n\n        Return a pair in reversed order\n    \"\"\"\n    )\n    assert (\n        doc(m.tuple_passthrough)\n        == \"\"\"\n        tuple_passthrough(arg0: Tuple[bool, str, int]) -> Tuple[int, str, bool]\n\n        Return a triple in reversed order\n    \"\"\"\n    )\n\n    assert m.rvalue_pair() == (\"rvalue\", \"rvalue\")\n    assert m.lvalue_pair() == (\"lvalue\", \"lvalue\")\n    assert m.rvalue_tuple() == (\"rvalue\", \"rvalue\", \"rvalue\")\n    assert m.lvalue_tuple() == (\"lvalue\", \"lvalue\", \"lvalue\")\n    assert m.rvalue_nested() == (\"rvalue\", (\"rvalue\", (\"rvalue\", \"rvalue\")))\n    assert m.lvalue_nested() == (\"lvalue\", (\"lvalue\", (\"lvalue\", \"lvalue\")))\n\n    assert m.int_string_pair() == (2, \"items\")\n\n\ndef test_builtins_cast_return_none():\n    \"\"\"Casters produced with PYBIND11_TYPE_CASTER() should convert nullptr to None\"\"\"\n    assert m.return_none_string() is None\n    assert m.return_none_char() is None\n    assert m.return_none_bool() is None\n    assert m.return_none_int() is None\n    assert m.return_none_float() is None\n    assert m.return_none_pair() is None\n\n\ndef test_none_deferred():\n    \"\"\"None passed as various argument types should defer to other overloads\"\"\"\n    assert not m.defer_none_cstring(\"abc\")\n    assert m.defer_none_cstring(None)\n    assert not m.defer_none_custom(UserType())\n    assert m.defer_none_custom(None)\n    assert m.nodefer_none_void(None)\n\n\ndef test_void_caster():\n    assert m.load_nullptr_t(None) is None\n    assert m.cast_nullptr_t() is None\n\n\ndef test_reference_wrapper():\n    \"\"\"std::reference_wrapper for builtin and user types\"\"\"\n    assert m.refwrap_builtin(42) == 420\n    assert m.refwrap_usertype(UserType(42)) == 42\n    assert m.refwrap_usertype_const(UserType(42)) == 42\n\n    with pytest.raises(TypeError) as excinfo:\n        m.refwrap_builtin(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.refwrap_usertype(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.refwrap_lvalue().value == 1\n    assert m.refwrap_lvalue_const().value == 1\n\n    a1 = m.refwrap_list(copy=True)\n    a2 = m.refwrap_list(copy=True)\n    assert [x.value for x in a1] == [2, 3]\n    assert [x.value for x in a2] == [2, 3]\n    assert not a1[0] is a2[0] and not a1[1] is a2[1]\n\n    b1 = m.refwrap_list(copy=False)\n    b2 = m.refwrap_list(copy=False)\n    assert [x.value for x in b1] == [1, 2]\n    assert [x.value for x in b2] == [1, 2]\n    assert b1[0] is b2[0] and b1[1] is b2[1]\n\n    assert m.refwrap_iiw(IncType(5)) == 5\n    assert m.refwrap_call_iiw(IncType(10), m.refwrap_iiw) == [10, 10, 10, 10]\n\n\ndef test_complex_cast():\n    \"\"\"std::complex casts\"\"\"\n    assert m.complex_cast(1) == \"1.0\"\n    assert m.complex_cast(2j) == \"(0.0, 2.0)\"\n\n\ndef test_bool_caster():\n    \"\"\"Test bool caster implicit conversions.\"\"\"\n    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert\n\n    def require_implicit(v):\n        pytest.raises(TypeError, noconvert, v)\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    # straight up bool\n    assert convert(True) is True\n    assert convert(False) is False\n    assert noconvert(True) is True\n    assert noconvert(False) is False\n\n    # None requires implicit conversion\n    require_implicit(None)\n    assert convert(None) is False\n\n    class A(object):\n        def __init__(self, x):\n            self.x = x\n\n        def __nonzero__(self):\n            return self.x\n\n        def __bool__(self):\n            return self.x\n\n    class B(object):\n        pass\n\n    # Arbitrary objects are not accepted\n    cant_convert(object())\n    cant_convert(B())\n\n    # Objects with __nonzero__ / __bool__ defined can be converted\n    require_implicit(A(True))\n    assert convert(A(True)) is True\n    assert convert(A(False)) is False\n\n\ndef test_numpy_bool():\n    np = pytest.importorskip(\"numpy\")\n\n    convert, noconvert = m.bool_passthrough, m.bool_passthrough_noconvert\n\n    def cant_convert(v):\n        pytest.raises(TypeError, convert, v)\n\n    # np.bool_ is not considered implicit\n    assert convert(np.bool_(True)) is True\n    assert convert(np.bool_(False)) is False\n    assert noconvert(np.bool_(True)) is True\n    assert noconvert(np.bool_(False)) is False\n    cant_convert(np.zeros(2, dtype=\"int\"))\n\n\ndef test_int_long():\n    \"\"\"In Python 2, a C++ int should return a Python int rather than long\n    if possible: longs are not always accepted where ints are used (such\n    as the argument to sys.exit()). A C++ long long is always a Python\n    long.\"\"\"\n\n    import sys\n\n    must_be_long = type(getattr(sys, \"maxint\", 1) + 1)\n    assert isinstance(m.int_cast(), int)\n    assert isinstance(m.long_cast(), int)\n    assert isinstance(m.longlong_cast(), must_be_long)\n\n\ndef test_void_caster_2():\n    assert m.test_void_caster()\n\n\ndef test_const_ref_caster():\n    \"\"\"Verifies that const-ref is propagated through type_caster cast_op.\n    The returned ConstRefCasted type is a minimal type that is constructed to\n    reference the casting mode used.\n    \"\"\"\n    x = False\n    assert m.takes(x) == 1\n    assert m.takes_move(x) == 1\n\n    assert m.takes_ptr(x) == 3\n    assert m.takes_ref(x) == 2\n    assert m.takes_ref_wrap(x) == 2\n\n    assert m.takes_const_ptr(x) == 5\n    assert m.takes_const_ref(x) == 4\n    assert m.takes_const_ref_wrap(x) == 4\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_call_policies.cpp",
    "content": "/*\n    tests/test_call_policies.cpp -- keep_alive and call_guard\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nstruct CustomGuard {\n    static bool enabled;\n\n    CustomGuard() { enabled = true; }\n    ~CustomGuard() { enabled = false; }\n\n    static const char *report_status() { return enabled ? \"guarded\" : \"unguarded\"; }\n};\nbool CustomGuard::enabled = false;\n\nstruct DependentGuard {\n    static bool enabled;\n\n    DependentGuard() { enabled = CustomGuard::enabled; }\n    ~DependentGuard() { enabled = false; }\n\n    static const char *report_status() { return enabled ? \"guarded\" : \"unguarded\"; }\n};\nbool DependentGuard::enabled = false;\n\nTEST_SUBMODULE(call_policies, m) {\n    // Parent/Child are used in:\n    // test_keep_alive_argument, test_keep_alive_return_value, test_alive_gc_derived,\n    // test_alive_gc_multi_derived, test_return_none, test_keep_alive_constructor\n    class Child {\n    public:\n        Child() { py::print(\"Allocating child.\"); }\n        Child(const Child &) = default;\n        Child(Child &&) = default;\n        ~Child() { py::print(\"Releasing child.\"); }\n    };\n    py::class_<Child>(m, \"Child\").def(py::init<>());\n\n    class Parent {\n    public:\n        Parent() { py::print(\"Allocating parent.\"); }\n        Parent(const Parent &parent) = default;\n        ~Parent() { py::print(\"Releasing parent.\"); }\n        void addChild(Child *) {}\n        Child *returnChild() { return new Child(); }\n        Child *returnNullChild() { return nullptr; }\n        static Child *staticFunction(Parent *) { return new Child(); }\n    };\n    py::class_<Parent>(m, \"Parent\")\n        .def(py::init<>())\n        .def(py::init([](Child *) { return new Parent(); }), py::keep_alive<1, 2>())\n        .def(\"addChild\", &Parent::addChild)\n        .def(\"addChildKeepAlive\", &Parent::addChild, py::keep_alive<1, 2>())\n        .def(\"returnChild\", &Parent::returnChild)\n        .def(\"returnChildKeepAlive\", &Parent::returnChild, py::keep_alive<1, 0>())\n        .def(\"returnNullChildKeepAliveChild\", &Parent::returnNullChild, py::keep_alive<1, 0>())\n        .def(\"returnNullChildKeepAliveParent\", &Parent::returnNullChild, py::keep_alive<0, 1>())\n        .def_static(\"staticFunction\", &Parent::staticFunction, py::keep_alive<1, 0>());\n\n    m.def(\n        \"free_function\", [](Parent *, Child *) {}, py::keep_alive<1, 2>());\n    m.def(\n        \"invalid_arg_index\", [] {}, py::keep_alive<0, 1>());\n\n#if !defined(PYPY_VERSION)\n    // test_alive_gc\n    class ParentGC : public Parent {\n    public:\n        using Parent::Parent;\n    };\n    py::class_<ParentGC, Parent>(m, \"ParentGC\", py::dynamic_attr()).def(py::init<>());\n#endif\n\n    // test_call_guard\n    m.def(\"unguarded_call\", &CustomGuard::report_status);\n    m.def(\"guarded_call\", &CustomGuard::report_status, py::call_guard<CustomGuard>());\n\n    m.def(\n        \"multiple_guards_correct_order\",\n        []() {\n            return CustomGuard::report_status() + std::string(\" & \")\n                   + DependentGuard::report_status();\n        },\n        py::call_guard<CustomGuard, DependentGuard>());\n\n    m.def(\n        \"multiple_guards_wrong_order\",\n        []() {\n            return DependentGuard::report_status() + std::string(\" & \")\n                   + CustomGuard::report_status();\n        },\n        py::call_guard<DependentGuard, CustomGuard>());\n\n#if defined(WITH_THREAD) && !defined(PYPY_VERSION)\n    // `py::call_guard<py::gil_scoped_release>()` should work in PyPy as well,\n    // but it's unclear how to test it without `PyGILState_GetThisThreadState`.\n    auto report_gil_status = []() {\n        auto is_gil_held = false;\n        if (auto *tstate = py::detail::get_thread_state_unchecked()) {\n            is_gil_held = (tstate == PyGILState_GetThisThreadState());\n        }\n\n        return is_gil_held ? \"GIL held\" : \"GIL released\";\n    };\n\n    m.def(\"with_gil\", report_gil_status);\n    m.def(\"without_gil\", report_gil_status, py::call_guard<py::gil_scoped_release>());\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_call_policies.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import call_policies as m\n\n\n@pytest.mark.xfail(\"env.PYPY\", reason=\"sometimes comes out 1 off on PyPy\", strict=False)\ndef test_keep_alive_argument(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.addChild(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Releasing child.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.addChildKeepAlive(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n    p = m.Parent()\n    c = m.Child()\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    m.free_function(p, c)\n    del c\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    del p\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.invalid_arg_index()\n    assert str(excinfo.value) == \"Could not activate keep_alive!\"\n\n\ndef test_keep_alive_return_value(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnChild()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Releasing child.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnChildKeepAlive()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n    p = m.Parent()\n    assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    with capture:\n        m.Parent.staticFunction(p)\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert capture == \"Allocating child.\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\", reason=\"_PyObject_GetDictPtr is unimplemented\")\ndef test_alive_gc(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = m.ParentGC()\n    p.addChildKeepAlive(m.Child())\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_alive_gc_derived(capture):\n    class Derived(m.Parent):\n        pass\n\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = Derived()\n    p.addChildKeepAlive(m.Child())\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_alive_gc_multi_derived(capture):\n    class Derived(m.Parent, m.Child):\n        def __init__(self):\n            m.Parent.__init__(self)\n            m.Child.__init__(self)\n\n    n_inst = ConstructorStats.detail_reg_inst()\n    p = Derived()\n    p.addChildKeepAlive(m.Child())\n    # +3 rather than +2 because Derived corresponds to two registered instances\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    lst = [p]\n    lst.append(lst)  # creates a circular reference\n    with capture:\n        del p, lst\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_return_none(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnNullChildKeepAliveChild()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert capture == \"\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n    with capture:\n        p = m.Parent()\n    assert capture == \"Allocating parent.\"\n    with capture:\n        p.returnNullChildKeepAliveParent()\n        assert ConstructorStats.detail_reg_inst() == n_inst + 1\n    assert capture == \"\"\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert capture == \"Releasing parent.\"\n\n\ndef test_keep_alive_constructor(capture):\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    with capture:\n        p = m.Parent(m.Child())\n        assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    assert (\n        capture\n        == \"\"\"\n        Allocating child.\n        Allocating parent.\n    \"\"\"\n    )\n    with capture:\n        del p\n        assert ConstructorStats.detail_reg_inst() == n_inst\n    assert (\n        capture\n        == \"\"\"\n        Releasing parent.\n        Releasing child.\n    \"\"\"\n    )\n\n\ndef test_call_guard():\n    assert m.unguarded_call() == \"unguarded\"\n    assert m.guarded_call() == \"guarded\"\n\n    assert m.multiple_guards_correct_order() == \"guarded & guarded\"\n    assert m.multiple_guards_wrong_order() == \"unguarded & guarded\"\n\n    if hasattr(m, \"with_gil\"):\n        assert m.with_gil() == \"GIL held\"\n        assert m.without_gil() == \"GIL released\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_callbacks.cpp",
    "content": "/*\n    tests/test_callbacks.cpp -- callbacks\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <thread>\n\nint dummy_function(int i) { return i + 1; }\n\nTEST_SUBMODULE(callbacks, m) {\n    // test_callbacks, test_function_signatures\n    m.def(\"test_callback1\", [](const py::object &func) { return func(); });\n    m.def(\"test_callback2\", [](const py::object &func) { return func(\"Hello\", 'x', true, 5); });\n    m.def(\"test_callback3\", [](const std::function<int(int)> &func) {\n        return \"func(43) = \" + std::to_string(func(43));\n    });\n    m.def(\"test_callback4\",\n          []() -> std::function<int(int)> { return [](int i) { return i + 1; }; });\n    m.def(\"test_callback5\",\n          []() { return py::cpp_function([](int i) { return i + 1; }, py::arg(\"number\")); });\n\n    // test_keyword_args_and_generalized_unpacking\n    m.def(\"test_tuple_unpacking\", [](const py::function &f) {\n        auto t1 = py::make_tuple(2, 3);\n        auto t2 = py::make_tuple(5, 6);\n        return f(\"positional\", 1, *t1, 4, *t2);\n    });\n\n    m.def(\"test_dict_unpacking\", [](const py::function &f) {\n        auto d1 = py::dict(\"key\"_a = \"value\", \"a\"_a = 1);\n        auto d2 = py::dict();\n        auto d3 = py::dict(\"b\"_a = 2);\n        return f(\"positional\", 1, **d1, **d2, **d3);\n    });\n\n    m.def(\"test_keyword_args\", [](const py::function &f) { return f(\"x\"_a = 10, \"y\"_a = 20); });\n\n    m.def(\"test_unpacking_and_keywords1\", [](const py::function &f) {\n        auto args = py::make_tuple(2);\n        auto kwargs = py::dict(\"d\"_a = 4);\n        return f(1, *args, \"c\"_a = 3, **kwargs);\n    });\n\n    m.def(\"test_unpacking_and_keywords2\", [](const py::function &f) {\n        auto kwargs1 = py::dict(\"a\"_a = 1);\n        auto kwargs2 = py::dict(\"c\"_a = 3, \"d\"_a = 4);\n        return f(\"positional\",\n                 *py::make_tuple(1),\n                 2,\n                 *py::make_tuple(3, 4),\n                 5,\n                 \"key\"_a = \"value\",\n                 **kwargs1,\n                 \"b\"_a = 2,\n                 **kwargs2,\n                 \"e\"_a = 5);\n    });\n\n    m.def(\"test_unpacking_error1\", [](const py::function &f) {\n        auto kwargs = py::dict(\"x\"_a = 3);\n        return f(\"x\"_a = 1, \"y\"_a = 2, **kwargs); // duplicate ** after keyword\n    });\n\n    m.def(\"test_unpacking_error2\", [](const py::function &f) {\n        auto kwargs = py::dict(\"x\"_a = 3);\n        return f(**kwargs, \"x\"_a = 1); // duplicate keyword after **\n    });\n\n    m.def(\"test_arg_conversion_error1\",\n          [](const py::function &f) { f(234, UnregisteredType(), \"kw\"_a = 567); });\n\n    m.def(\"test_arg_conversion_error2\", [](const py::function &f) {\n        f(234, \"expected_name\"_a = UnregisteredType(), \"kw\"_a = 567);\n    });\n\n    // test_lambda_closure_cleanup\n    struct Payload {\n        Payload() { print_default_created(this); }\n        ~Payload() { print_destroyed(this); }\n        Payload(const Payload &) { print_copy_created(this); }\n        Payload(Payload &&) noexcept { print_move_created(this); }\n    };\n    // Export the payload constructor statistics for testing purposes:\n    m.def(\"payload_cstats\", &ConstructorStats::get<Payload>);\n    m.def(\"test_lambda_closure_cleanup\", []() -> std::function<void()> {\n        Payload p;\n\n        // In this situation, `Func` in the implementation of\n        // `cpp_function::initialize` is NOT trivially destructible.\n        return [p]() {\n            /* p should be cleaned up when the returned function is garbage collected */\n            (void) p;\n        };\n    });\n\n    class CppCallable {\n    public:\n        CppCallable() { track_default_created(this); }\n        ~CppCallable() { track_destroyed(this); }\n        CppCallable(const CppCallable &) { track_copy_created(this); }\n        CppCallable(CppCallable &&) noexcept { track_move_created(this); }\n        void operator()() {}\n    };\n\n    m.def(\"test_cpp_callable_cleanup\", []() {\n        // Related issue: https://github.com/pybind/pybind11/issues/3228\n        // Related PR: https://github.com/pybind/pybind11/pull/3229\n        py::list alive_counts;\n        ConstructorStats &stat = ConstructorStats::get<CppCallable>();\n        alive_counts.append(stat.alive());\n        {\n            CppCallable cpp_callable;\n            alive_counts.append(stat.alive());\n            {\n                // In this situation, `Func` in the implementation of\n                // `cpp_function::initialize` IS trivially destructible,\n                // only `capture` is not.\n                py::cpp_function py_func(cpp_callable);\n                py::detail::silence_unused_warnings(py_func);\n                alive_counts.append(stat.alive());\n            }\n            alive_counts.append(stat.alive());\n            {\n                py::cpp_function py_func(std::move(cpp_callable));\n                py::detail::silence_unused_warnings(py_func);\n                alive_counts.append(stat.alive());\n            }\n            alive_counts.append(stat.alive());\n        }\n        alive_counts.append(stat.alive());\n        return alive_counts;\n    });\n\n    // test_cpp_function_roundtrip\n    /* Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer */\n    m.def(\"dummy_function\", &dummy_function);\n    m.def(\"dummy_function_overloaded\", [](int i, int j) { return i + j; });\n    m.def(\"dummy_function_overloaded\", &dummy_function);\n    m.def(\"dummy_function2\", [](int i, int j) { return i + j; });\n    m.def(\n        \"roundtrip\",\n        [](std::function<int(int)> f, bool expect_none = false) {\n            if (expect_none && f) {\n                throw std::runtime_error(\"Expected None to be converted to empty std::function\");\n            }\n            return f;\n        },\n        py::arg(\"f\"),\n        py::arg(\"expect_none\") = false);\n    m.def(\"test_dummy_function\", [](const std::function<int(int)> &f) -> std::string {\n        using fn_type = int (*)(int);\n        const auto *result = f.target<fn_type>();\n        if (!result) {\n            auto r = f(1);\n            return \"can't convert to function pointer: eval(1) = \" + std::to_string(r);\n        }\n        if (*result == dummy_function) {\n            auto r = (*result)(1);\n            return \"matches dummy_function: eval(1) = \" + std::to_string(r);\n        }\n        return \"argument does NOT match dummy_function. This should never happen!\";\n    });\n\n    class AbstractBase {\n    public:\n        // [workaround(intel)] = default does not work here\n        // Defaulting this destructor results in linking errors with the Intel compiler\n        // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)\n        virtual ~AbstractBase() {} // NOLINT(modernize-use-equals-default)\n        virtual unsigned int func() = 0;\n    };\n    m.def(\"func_accepting_func_accepting_base\",\n          [](const std::function<double(AbstractBase &)> &) {});\n\n    struct MovableObject {\n        bool valid = true;\n\n        MovableObject() = default;\n        MovableObject(const MovableObject &) = default;\n        MovableObject &operator=(const MovableObject &) = default;\n        MovableObject(MovableObject &&o) noexcept : valid(o.valid) { o.valid = false; }\n        MovableObject &operator=(MovableObject &&o) noexcept {\n            valid = o.valid;\n            o.valid = false;\n            return *this;\n        }\n    };\n    py::class_<MovableObject>(m, \"MovableObject\");\n\n    // test_movable_object\n    m.def(\"callback_with_movable\", [](const std::function<void(MovableObject &)> &f) {\n        auto x = MovableObject();\n        f(x);           // lvalue reference shouldn't move out object\n        return x.valid; // must still return `true`\n    });\n\n    // test_bound_method_callback\n    struct CppBoundMethodTest {};\n    py::class_<CppBoundMethodTest>(m, \"CppBoundMethodTest\")\n        .def(py::init<>())\n        .def(\"triple\", [](CppBoundMethodTest &, int val) { return 3 * val; });\n\n    // This checks that builtin functions can be passed as callbacks\n    // rather than throwing RuntimeError due to trying to extract as capsule\n    m.def(\"test_sum_builtin\",\n          [](const std::function<double(py::iterable)> &sum_builtin, const py::iterable &i) {\n              return sum_builtin(i);\n          });\n\n    // test async Python callbacks\n    using callback_f = std::function<void(int)>;\n    m.def(\"test_async_callback\", [](const callback_f &f, const py::list &work) {\n        // make detached thread that calls `f` with piece of work after a little delay\n        auto start_f = [f](int j) {\n            auto invoke_f = [f, j] {\n                std::this_thread::sleep_for(std::chrono::milliseconds(50));\n                f(j);\n            };\n            auto t = std::thread(std::move(invoke_f));\n            t.detach();\n        };\n\n        // spawn worker threads\n        for (auto i : work) {\n            start_f(py::cast<int>(i));\n        }\n    });\n\n    m.def(\"callback_num_times\", [](const py::function &f, std::size_t num) {\n        for (std::size_t i = 0; i < num; i++) {\n            f();\n        }\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_callbacks.py",
    "content": "# -*- coding: utf-8 -*-\nimport time\nfrom threading import Thread\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import callbacks as m\n\n\ndef test_callbacks():\n    from functools import partial\n\n    def func1():\n        return \"func1\"\n\n    def func2(a, b, c, d):\n        return \"func2\", a, b, c, d\n\n    def func3(a):\n        return \"func3({})\".format(a)\n\n    assert m.test_callback1(func1) == \"func1\"\n    assert m.test_callback2(func2) == (\"func2\", \"Hello\", \"x\", True, 5)\n    assert m.test_callback1(partial(func2, 1, 2, 3, 4)) == (\"func2\", 1, 2, 3, 4)\n    assert m.test_callback1(partial(func3, \"partial\")) == \"func3(partial)\"\n    assert m.test_callback3(lambda i: i + 1) == \"func(43) = 44\"\n\n    f = m.test_callback4()\n    assert f(43) == 44\n    f = m.test_callback5()\n    assert f(number=43) == 44\n\n\ndef test_bound_method_callback():\n    # Bound Python method:\n    class MyClass:\n        def double(self, val):\n            return 2 * val\n\n    z = MyClass()\n    assert m.test_callback3(z.double) == \"func(43) = 86\"\n\n    z = m.CppBoundMethodTest()\n    assert m.test_callback3(z.triple) == \"func(43) = 129\"\n\n\ndef test_keyword_args_and_generalized_unpacking():\n    def f(*args, **kwargs):\n        return args, kwargs\n\n    assert m.test_tuple_unpacking(f) == ((\"positional\", 1, 2, 3, 4, 5, 6), {})\n    assert m.test_dict_unpacking(f) == (\n        (\"positional\", 1),\n        {\"key\": \"value\", \"a\": 1, \"b\": 2},\n    )\n    assert m.test_keyword_args(f) == ((), {\"x\": 10, \"y\": 20})\n    assert m.test_unpacking_and_keywords1(f) == ((1, 2), {\"c\": 3, \"d\": 4})\n    assert m.test_unpacking_and_keywords2(f) == (\n        (\"positional\", 1, 2, 3, 4, 5),\n        {\"key\": \"value\", \"a\": 1, \"b\": 2, \"c\": 3, \"d\": 4, \"e\": 5},\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_unpacking_error1(f)\n    assert \"Got multiple values for keyword argument\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_unpacking_error2(f)\n    assert \"Got multiple values for keyword argument\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_arg_conversion_error1(f)\n    assert \"Unable to convert call argument\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.test_arg_conversion_error2(f)\n    assert \"Unable to convert call argument\" in str(excinfo.value)\n\n\ndef test_lambda_closure_cleanup():\n    m.test_lambda_closure_cleanup()\n    cstats = m.payload_cstats()\n    assert cstats.alive() == 0\n    assert cstats.copy_constructions == 1\n    assert cstats.move_constructions >= 1\n\n\ndef test_cpp_callable_cleanup():\n    alive_counts = m.test_cpp_callable_cleanup()\n    assert alive_counts == [0, 1, 2, 1, 2, 1, 0]\n\n\ndef test_cpp_function_roundtrip():\n    \"\"\"Test if passing a function pointer from C++ -> Python -> C++ yields the original pointer\"\"\"\n\n    assert (\n        m.test_dummy_function(m.dummy_function) == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert (\n        m.test_dummy_function(m.roundtrip(m.dummy_function))\n        == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert (\n        m.test_dummy_function(m.dummy_function_overloaded)\n        == \"matches dummy_function: eval(1) = 2\"\n    )\n    assert m.roundtrip(None, expect_none=True) is None\n    assert (\n        m.test_dummy_function(lambda x: x + 2)\n        == \"can't convert to function pointer: eval(1) = 3\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_dummy_function(m.dummy_function2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.test_dummy_function(lambda x, y: x + y)\n    assert any(\n        s in str(excinfo.value)\n        for s in (\"missing 1 required positional argument\", \"takes exactly 2 arguments\")\n    )\n\n\ndef test_function_signatures(doc):\n    assert doc(m.test_callback3) == \"test_callback3(arg0: Callable[[int], int]) -> str\"\n    assert doc(m.test_callback4) == \"test_callback4() -> Callable[[int], int]\"\n\n\ndef test_movable_object():\n    assert m.callback_with_movable(lambda _: None) is True\n\n\n@pytest.mark.skipif(\n    \"env.PYPY\",\n    reason=\"PyPy segfaults on here. See discussion on #1413.\",\n)\ndef test_python_builtins():\n    \"\"\"Test if python builtins like sum() can be used as callbacks\"\"\"\n    assert m.test_sum_builtin(sum, [1, 2, 3]) == 6\n    assert m.test_sum_builtin(sum, []) == 0\n\n\ndef test_async_callbacks():\n    # serves as state for async callback\n    class Item:\n        def __init__(self, value):\n            self.value = value\n\n    res = []\n\n    # generate stateful lambda that will store result in `res`\n    def gen_f():\n        s = Item(3)\n        return lambda j: res.append(s.value + j)\n\n    # do some work async\n    work = [1, 2, 3, 4]\n    m.test_async_callback(gen_f(), work)\n    # wait until work is done\n    from time import sleep\n\n    sleep(0.5)\n    assert sum(res) == sum(x + 3 for x in work)\n\n\ndef test_async_async_callbacks():\n    t = Thread(target=test_async_callbacks)\n    t.start()\n    t.join()\n\n\ndef test_callback_num_times():\n    # Super-simple micro-benchmarking related to PR #2919.\n    # Example runtimes (Intel Xeon 2.2GHz, fully optimized):\n    #   num_millions  1, repeats  2:  0.1 secs\n    #   num_millions 20, repeats 10: 11.5 secs\n    one_million = 1000000\n    num_millions = 1  # Try 20 for actual micro-benchmarking.\n    repeats = 2  # Try 10.\n    rates = []\n    for rep in range(repeats):\n        t0 = time.time()\n        m.callback_num_times(lambda: None, num_millions * one_million)\n        td = time.time() - t0\n        rate = num_millions / td if td else 0\n        rates.append(rate)\n        if not rep:\n            print()\n        print(\n            \"callback_num_times: {:d} million / {:.3f} seconds = {:.3f} million / second\".format(\n                num_millions, td, rate\n            )\n        )\n    if len(rates) > 1:\n        print(\"Min    Mean   Max\")\n        print(\n            \"{:6.3f} {:6.3f} {:6.3f}\".format(\n                min(rates), sum(rates) / len(rates), max(rates)\n            )\n        )\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_chrono.cpp",
    "content": "/*\n    tests/test_chrono.cpp -- test conversions to/from std::chrono types\n\n    Copyright (c) 2016 Trent Houliston <trent@houliston.me> and\n                       Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/chrono.h>\n\n#include \"pybind11_tests.h\"\n\n#include <chrono>\n\nstruct different_resolutions {\n    using time_point_h = std::chrono::time_point<std::chrono::system_clock, std::chrono::hours>;\n    using time_point_m = std::chrono::time_point<std::chrono::system_clock, std::chrono::minutes>;\n    using time_point_s = std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>;\n    using time_point_ms\n        = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>;\n    using time_point_us\n        = std::chrono::time_point<std::chrono::system_clock, std::chrono::microseconds>;\n    time_point_h timestamp_h;\n    time_point_m timestamp_m;\n    time_point_s timestamp_s;\n    time_point_ms timestamp_ms;\n    time_point_us timestamp_us;\n};\n\nTEST_SUBMODULE(chrono, m) {\n    using system_time = std::chrono::system_clock::time_point;\n    using steady_time = std::chrono::steady_clock::time_point;\n\n    using timespan = std::chrono::duration<int64_t, std::nano>;\n    using timestamp = std::chrono::time_point<std::chrono::system_clock, timespan>;\n\n    // test_chrono_system_clock\n    // Return the current time off the wall clock\n    m.def(\"test_chrono1\", []() { return std::chrono::system_clock::now(); });\n\n    // test_chrono_system_clock_roundtrip\n    // Round trip the passed in system clock time\n    m.def(\"test_chrono2\", [](system_time t) { return t; });\n\n    // test_chrono_duration_roundtrip\n    // Round trip the passed in duration\n    m.def(\"test_chrono3\", [](std::chrono::system_clock::duration d) { return d; });\n\n    // test_chrono_duration_subtraction_equivalence\n    // Difference between two passed in time_points\n    m.def(\"test_chrono4\", [](system_time a, system_time b) { return a - b; });\n\n    // test_chrono_steady_clock\n    // Return the current time off the steady_clock\n    m.def(\"test_chrono5\", []() { return std::chrono::steady_clock::now(); });\n\n    // test_chrono_steady_clock_roundtrip\n    // Round trip a steady clock timepoint\n    m.def(\"test_chrono6\", [](steady_time t) { return t; });\n\n    // test_floating_point_duration\n    // Roundtrip a duration in microseconds from a float argument\n    m.def(\"test_chrono7\", [](std::chrono::microseconds t) { return t; });\n    // Float durations (issue #719)\n    m.def(\"test_chrono_float_diff\",\n          [](std::chrono::duration<float> a, std::chrono::duration<float> b) { return a - b; });\n\n    m.def(\"test_nano_timepoint\",\n          [](timestamp start, timespan delta) -> timestamp { return start + delta; });\n\n    // Test different resolutions\n    py::class_<different_resolutions>(m, \"different_resolutions\")\n        .def(py::init<>())\n        .def_readwrite(\"timestamp_h\", &different_resolutions::timestamp_h)\n        .def_readwrite(\"timestamp_m\", &different_resolutions::timestamp_m)\n        .def_readwrite(\"timestamp_s\", &different_resolutions::timestamp_s)\n        .def_readwrite(\"timestamp_ms\", &different_resolutions::timestamp_ms)\n        .def_readwrite(\"timestamp_us\", &different_resolutions::timestamp_us);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_chrono.py",
    "content": "# -*- coding: utf-8 -*-\nimport datetime\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import chrono as m\n\n\ndef test_chrono_system_clock():\n\n    # Get the time from both c++ and datetime\n    date0 = datetime.datetime.today()\n    date1 = m.test_chrono1()\n    date2 = datetime.datetime.today()\n\n    # The returned value should be a datetime\n    assert isinstance(date1, datetime.datetime)\n\n    # The numbers should vary by a very small amount (time it took to execute)\n    diff_python = abs(date2 - date0)\n    diff = abs(date1 - date2)\n\n    # There should never be a days difference\n    assert diff.days == 0\n\n    # Since datetime.datetime.today() calls time.time(), and on some platforms\n    # that has 1 second accuracy, we compare this way\n    assert diff.seconds <= diff_python.seconds\n\n\ndef test_chrono_system_clock_roundtrip():\n    date1 = datetime.datetime.today()\n\n    # Roundtrip the time\n    date2 = m.test_chrono2(date1)\n\n    # The returned value should be a datetime\n    assert isinstance(date2, datetime.datetime)\n\n    # They should be identical (no information lost on roundtrip)\n    diff = abs(date1 - date2)\n    assert diff == datetime.timedelta(0)\n\n\ndef test_chrono_system_clock_roundtrip_date():\n    date1 = datetime.date.today()\n\n    # Roundtrip the time\n    datetime2 = m.test_chrono2(date1)\n    date2 = datetime2.date()\n    time2 = datetime2.time()\n\n    # The returned value should be a datetime\n    assert isinstance(datetime2, datetime.datetime)\n    assert isinstance(date2, datetime.date)\n    assert isinstance(time2, datetime.time)\n\n    # They should be identical (no information lost on roundtrip)\n    diff = abs(date1 - date2)\n    assert diff.days == 0\n    assert diff.seconds == 0\n    assert diff.microseconds == 0\n\n    # Year, Month & Day should be the same after the round trip\n    assert date1 == date2\n\n    # There should be no time information\n    assert time2.hour == 0\n    assert time2.minute == 0\n    assert time2.second == 0\n    assert time2.microsecond == 0\n\n\nSKIP_TZ_ENV_ON_WIN = pytest.mark.skipif(\n    \"env.WIN\", reason=\"TZ environment variable only supported on POSIX\"\n)\n\n\n@pytest.mark.parametrize(\n    \"time1\",\n    [\n        datetime.datetime.today().time(),\n        datetime.time(0, 0, 0),\n        datetime.time(0, 0, 0, 1),\n        datetime.time(0, 28, 45, 109827),\n        datetime.time(0, 59, 59, 999999),\n        datetime.time(1, 0, 0),\n        datetime.time(5, 59, 59, 0),\n        datetime.time(5, 59, 59, 1),\n    ],\n)\n@pytest.mark.parametrize(\n    \"tz\",\n    [\n        None,\n        pytest.param(\"Europe/Brussels\", marks=SKIP_TZ_ENV_ON_WIN),\n        pytest.param(\"Asia/Pyongyang\", marks=SKIP_TZ_ENV_ON_WIN),\n        pytest.param(\"America/New_York\", marks=SKIP_TZ_ENV_ON_WIN),\n    ],\n)\ndef test_chrono_system_clock_roundtrip_time(time1, tz, monkeypatch):\n    if tz is not None:\n        monkeypatch.setenv(\"TZ\", \"/usr/share/zoneinfo/{}\".format(tz))\n\n    # Roundtrip the time\n    datetime2 = m.test_chrono2(time1)\n    date2 = datetime2.date()\n    time2 = datetime2.time()\n\n    # The returned value should be a datetime\n    assert isinstance(datetime2, datetime.datetime)\n    assert isinstance(date2, datetime.date)\n    assert isinstance(time2, datetime.time)\n\n    # Hour, Minute, Second & Microsecond should be the same after the round trip\n    assert time1 == time2\n\n    # There should be no date information (i.e. date = python base date)\n    assert date2.year == 1970\n    assert date2.month == 1\n    assert date2.day == 1\n\n\ndef test_chrono_duration_roundtrip():\n\n    # Get the difference between two times (a timedelta)\n    date1 = datetime.datetime.today()\n    date2 = datetime.datetime.today()\n    diff = date2 - date1\n\n    # Make sure this is a timedelta\n    assert isinstance(diff, datetime.timedelta)\n\n    cpp_diff = m.test_chrono3(diff)\n\n    assert cpp_diff == diff\n\n    # Negative timedelta roundtrip\n    diff = datetime.timedelta(microseconds=-1)\n    cpp_diff = m.test_chrono3(diff)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_duration_subtraction_equivalence():\n\n    date1 = datetime.datetime.today()\n    date2 = datetime.datetime.today()\n\n    diff = date2 - date1\n    cpp_diff = m.test_chrono4(date2, date1)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_duration_subtraction_equivalence_date():\n\n    date1 = datetime.date.today()\n    date2 = datetime.date.today()\n\n    diff = date2 - date1\n    cpp_diff = m.test_chrono4(date2, date1)\n\n    assert cpp_diff == diff\n\n\ndef test_chrono_steady_clock():\n    time1 = m.test_chrono5()\n    assert isinstance(time1, datetime.timedelta)\n\n\ndef test_chrono_steady_clock_roundtrip():\n    time1 = datetime.timedelta(days=10, seconds=10, microseconds=100)\n    time2 = m.test_chrono6(time1)\n\n    assert isinstance(time2, datetime.timedelta)\n\n    # They should be identical (no information lost on roundtrip)\n    assert time1 == time2\n\n\ndef test_floating_point_duration():\n    # Test using a floating point number in seconds\n    time = m.test_chrono7(35.525123)\n\n    assert isinstance(time, datetime.timedelta)\n\n    assert time.seconds == 35\n    assert 525122 <= time.microseconds <= 525123\n\n    diff = m.test_chrono_float_diff(43.789012, 1.123456)\n    assert diff.seconds == 42\n    assert 665556 <= diff.microseconds <= 665557\n\n\ndef test_nano_timepoint():\n    time = datetime.datetime.now()\n    time1 = m.test_nano_timepoint(time, datetime.timedelta(seconds=60))\n    assert time1 == time + datetime.timedelta(seconds=60)\n\n\ndef test_chrono_different_resolutions():\n    resolutions = m.different_resolutions()\n    time = datetime.datetime.now()\n    resolutions.timestamp_h = time\n    resolutions.timestamp_m = time\n    resolutions.timestamp_s = time\n    resolutions.timestamp_ms = time\n    resolutions.timestamp_us = time\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_class.cpp",
    "content": "/*\n    tests/test_class.cpp -- test py::class_ definitions and basic functionality\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#if defined(__INTEL_COMPILER) && __cplusplus >= 201703L\n// Intel compiler requires a separate header file to support aligned new operators\n// and does not set the __cpp_aligned_new feature macro.\n// This header needs to be included before pybind11.\n#    include <aligned_new>\n#endif\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\n#if defined(_MSC_VER)\n#    pragma warning(disable : 4324)\n//     warning C4324: structure was padded due to alignment specifier\n#endif\n\n// test_brace_initialization\nstruct NoBraceInitialization {\n    explicit NoBraceInitialization(std::vector<int> v) : vec{std::move(v)} {}\n    template <typename T>\n    NoBraceInitialization(std::initializer_list<T> l) : vec(l) {}\n\n    std::vector<int> vec;\n};\n\nTEST_SUBMODULE(class_, m) {\n    // test_instance\n    struct NoConstructor {\n        NoConstructor() = default;\n        NoConstructor(const NoConstructor &) = default;\n        NoConstructor(NoConstructor &&) = default;\n        static NoConstructor *new_instance() {\n            auto *ptr = new NoConstructor();\n            print_created(ptr, \"via new_instance\");\n            return ptr;\n        }\n        ~NoConstructor() { print_destroyed(this); }\n    };\n    struct NoConstructorNew {\n        NoConstructorNew() = default;\n        NoConstructorNew(const NoConstructorNew &) = default;\n        NoConstructorNew(NoConstructorNew &&) = default;\n        static NoConstructorNew *new_instance() {\n            auto *ptr = new NoConstructorNew();\n            print_created(ptr, \"via new_instance\");\n            return ptr;\n        }\n        ~NoConstructorNew() { print_destroyed(this); }\n    };\n\n    py::class_<NoConstructor>(m, \"NoConstructor\")\n        .def_static(\"new_instance\", &NoConstructor::new_instance, \"Return an instance\");\n\n    py::class_<NoConstructorNew>(m, \"NoConstructorNew\")\n        .def(py::init([](const NoConstructorNew &self) { return self; })) // Need a NOOP __init__\n        .def_static(\"__new__\",\n                    [](const py::object &) { return NoConstructorNew::new_instance(); });\n\n    // test_inheritance\n    class Pet {\n    public:\n        Pet(const std::string &name, const std::string &species)\n            : m_name(name), m_species(species) {}\n        std::string name() const { return m_name; }\n        std::string species() const { return m_species; }\n\n    private:\n        std::string m_name;\n        std::string m_species;\n    };\n\n    class Dog : public Pet {\n    public:\n        explicit Dog(const std::string &name) : Pet(name, \"dog\") {}\n        std::string bark() const { return \"Woof!\"; }\n    };\n\n    class Rabbit : public Pet {\n    public:\n        explicit Rabbit(const std::string &name) : Pet(name, \"parrot\") {}\n    };\n\n    class Hamster : public Pet {\n    public:\n        explicit Hamster(const std::string &name) : Pet(name, \"rodent\") {}\n    };\n\n    class Chimera : public Pet {\n        Chimera() : Pet(\"Kimmy\", \"chimera\") {}\n    };\n\n    py::class_<Pet> pet_class(m, \"Pet\");\n    pet_class.def(py::init<std::string, std::string>())\n        .def(\"name\", &Pet::name)\n        .def(\"species\", &Pet::species);\n\n    /* One way of declaring a subclass relationship: reference parent's class_ object */\n    py::class_<Dog>(m, \"Dog\", pet_class).def(py::init<std::string>());\n\n    /* Another way of declaring a subclass relationship: reference parent's C++ type */\n    py::class_<Rabbit, Pet>(m, \"Rabbit\").def(py::init<std::string>());\n\n    /* And another: list parent in class template arguments */\n    py::class_<Hamster, Pet>(m, \"Hamster\").def(py::init<std::string>());\n\n    /* Constructors are not inherited by default */\n    py::class_<Chimera, Pet>(m, \"Chimera\");\n\n    m.def(\"pet_name_species\",\n          [](const Pet &pet) { return pet.name() + \" is a \" + pet.species(); });\n    m.def(\"dog_bark\", [](const Dog &dog) { return dog.bark(); });\n\n    // test_automatic_upcasting\n    struct BaseClass {\n        BaseClass() = default;\n        BaseClass(const BaseClass &) = default;\n        BaseClass(BaseClass &&) = default;\n        virtual ~BaseClass() = default;\n    };\n    struct DerivedClass1 : BaseClass {};\n    struct DerivedClass2 : BaseClass {};\n\n    py::class_<BaseClass>(m, \"BaseClass\").def(py::init<>());\n    py::class_<DerivedClass1>(m, \"DerivedClass1\").def(py::init<>());\n    py::class_<DerivedClass2>(m, \"DerivedClass2\").def(py::init<>());\n\n    m.def(\"return_class_1\", []() -> BaseClass * { return new DerivedClass1(); });\n    m.def(\"return_class_2\", []() -> BaseClass * { return new DerivedClass2(); });\n    m.def(\"return_class_n\", [](int n) -> BaseClass * {\n        if (n == 1) {\n            return new DerivedClass1();\n        }\n        if (n == 2) {\n            return new DerivedClass2();\n        }\n        return new BaseClass();\n    });\n    m.def(\"return_none\", []() -> BaseClass * { return nullptr; });\n\n    // test_isinstance\n    m.def(\"check_instances\", [](const py::list &l) {\n        return py::make_tuple(py::isinstance<py::tuple>(l[0]),\n                              py::isinstance<py::dict>(l[1]),\n                              py::isinstance<Pet>(l[2]),\n                              py::isinstance<Pet>(l[3]),\n                              py::isinstance<Dog>(l[4]),\n                              py::isinstance<Rabbit>(l[5]),\n                              py::isinstance<UnregisteredType>(l[6]));\n    });\n\n    struct Invalid {};\n\n    // test_type\n    m.def(\"check_type\", [](int category) {\n        // Currently not supported (via a fail at compile time)\n        // See https://github.com/pybind/pybind11/issues/2486\n        // if (category == 2)\n        //     return py::type::of<int>();\n        if (category == 1) {\n            return py::type::of<DerivedClass1>();\n        }\n        return py::type::of<Invalid>();\n    });\n\n    m.def(\"get_type_of\", [](py::object ob) { return py::type::of(std::move(ob)); });\n\n    m.def(\"get_type_classic\", [](py::handle h) { return h.get_type(); });\n\n    m.def(\"as_type\", [](const py::object &ob) { return py::type(ob); });\n\n    // test_mismatched_holder\n    struct MismatchBase1 {};\n    struct MismatchDerived1 : MismatchBase1 {};\n\n    struct MismatchBase2 {};\n    struct MismatchDerived2 : MismatchBase2 {};\n\n    m.def(\"mismatched_holder_1\", []() {\n        auto mod = py::module_::import(\"__main__\");\n        py::class_<MismatchBase1, std::shared_ptr<MismatchBase1>>(mod, \"MismatchBase1\");\n        py::class_<MismatchDerived1, MismatchBase1>(mod, \"MismatchDerived1\");\n    });\n    m.def(\"mismatched_holder_2\", []() {\n        auto mod = py::module_::import(\"__main__\");\n        py::class_<MismatchBase2>(mod, \"MismatchBase2\");\n        py::class_<MismatchDerived2, std::shared_ptr<MismatchDerived2>, MismatchBase2>(\n            mod, \"MismatchDerived2\");\n    });\n\n    // test_override_static\n    // #511: problem with inheritance + overwritten def_static\n    struct MyBase {\n        static std::unique_ptr<MyBase> make() { return std::unique_ptr<MyBase>(new MyBase()); }\n    };\n\n    struct MyDerived : MyBase {\n        static std::unique_ptr<MyDerived> make() {\n            return std::unique_ptr<MyDerived>(new MyDerived());\n        }\n    };\n\n    py::class_<MyBase>(m, \"MyBase\").def_static(\"make\", &MyBase::make);\n\n    py::class_<MyDerived, MyBase>(m, \"MyDerived\")\n        .def_static(\"make\", &MyDerived::make)\n        .def_static(\"make2\", &MyDerived::make);\n\n    // test_implicit_conversion_life_support\n    struct ConvertibleFromUserType {\n        int i;\n\n        explicit ConvertibleFromUserType(UserType u) : i(u.value()) {}\n    };\n\n    py::class_<ConvertibleFromUserType>(m, \"AcceptsUserType\").def(py::init<UserType>());\n    py::implicitly_convertible<UserType, ConvertibleFromUserType>();\n\n    m.def(\"implicitly_convert_argument\", [](const ConvertibleFromUserType &r) { return r.i; });\n    m.def(\"implicitly_convert_variable\", [](const py::object &o) {\n        // `o` is `UserType` and `r` is a reference to a temporary created by implicit\n        // conversion. This is valid when called inside a bound function because the temp\n        // object is attached to the same life support system as the arguments.\n        const auto &r = o.cast<const ConvertibleFromUserType &>();\n        return r.i;\n    });\n    m.add_object(\"implicitly_convert_variable_fail\", [&] {\n        auto f = [](PyObject *, PyObject *args) -> PyObject * {\n            auto o = py::reinterpret_borrow<py::tuple>(args)[0];\n            try { // It should fail here because there is no life support.\n                o.cast<const ConvertibleFromUserType &>();\n            } catch (const py::cast_error &e) {\n                return py::str(e.what()).release().ptr();\n            }\n            return py::str().release().ptr();\n        };\n\n        auto *def = new PyMethodDef{\"f\", f, METH_VARARGS, nullptr};\n        py::capsule def_capsule(def,\n                                [](void *ptr) { delete reinterpret_cast<PyMethodDef *>(ptr); });\n        return py::reinterpret_steal<py::object>(\n            PyCFunction_NewEx(def, def_capsule.ptr(), m.ptr()));\n    }());\n\n    // test_operator_new_delete\n    struct HasOpNewDel {\n        std::uint64_t i;\n        static void *operator new(size_t s) {\n            py::print(\"A new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"A placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p) {\n            py::print(\"A delete\");\n            return ::operator delete(p);\n        }\n    };\n    struct HasOpNewDelSize {\n        std::uint32_t i;\n        static void *operator new(size_t s) {\n            py::print(\"B new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"B placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"B delete\", s);\n            return ::operator delete(p);\n        }\n    };\n    struct AliasedHasOpNewDelSize {\n        std::uint64_t i;\n        static void *operator new(size_t s) {\n            py::print(\"C new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"C placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"C delete\", s);\n            return ::operator delete(p);\n        }\n        virtual ~AliasedHasOpNewDelSize() = default;\n        AliasedHasOpNewDelSize() = default;\n        AliasedHasOpNewDelSize(const AliasedHasOpNewDelSize &) = delete;\n    };\n    struct PyAliasedHasOpNewDelSize : AliasedHasOpNewDelSize {\n        PyAliasedHasOpNewDelSize() = default;\n        explicit PyAliasedHasOpNewDelSize(int) {}\n        std::uint64_t j;\n    };\n    struct HasOpNewDelBoth {\n        std::uint32_t i[8];\n        static void *operator new(size_t s) {\n            py::print(\"D new\", s);\n            return ::operator new(s);\n        }\n        static void *operator new(size_t s, void *ptr) {\n            py::print(\"D placement-new\", s);\n            return ptr;\n        }\n        static void operator delete(void *p) {\n            py::print(\"D delete\");\n            return ::operator delete(p);\n        }\n        static void operator delete(void *p, size_t s) {\n            py::print(\"D wrong delete\", s);\n            return ::operator delete(p);\n        }\n    };\n    py::class_<HasOpNewDel>(m, \"HasOpNewDel\").def(py::init<>());\n    py::class_<HasOpNewDelSize>(m, \"HasOpNewDelSize\").def(py::init<>());\n    py::class_<HasOpNewDelBoth>(m, \"HasOpNewDelBoth\").def(py::init<>());\n    py::class_<AliasedHasOpNewDelSize, PyAliasedHasOpNewDelSize> aliased(m,\n                                                                         \"AliasedHasOpNewDelSize\");\n    aliased.def(py::init<>());\n    aliased.attr(\"size_noalias\") = py::int_(sizeof(AliasedHasOpNewDelSize));\n    aliased.attr(\"size_alias\") = py::int_(sizeof(PyAliasedHasOpNewDelSize));\n\n    // This test is actually part of test_local_bindings (test_duplicate_local), but we need a\n    // definition in a different compilation unit within the same module:\n    bind_local<LocalExternal, 17>(m, \"LocalExternal\", py::module_local());\n\n    // test_bind_protected_functions\n    class ProtectedA {\n    protected:\n        int foo() const { return value; }\n\n    private:\n        int value = 42;\n    };\n\n    class PublicistA : public ProtectedA {\n    public:\n        using ProtectedA::foo;\n    };\n\n    py::class_<ProtectedA>(m, \"ProtectedA\")\n        .def(py::init<>())\n#if !defined(_MSC_VER) || _MSC_VER >= 1910\n        .def(\"foo\", &PublicistA::foo);\n#else\n        .def(\"foo\", static_cast<int (ProtectedA::*)() const>(&PublicistA::foo));\n#endif\n\n    class ProtectedB {\n    public:\n        virtual ~ProtectedB() = default;\n        ProtectedB() = default;\n        ProtectedB(const ProtectedB &) = delete;\n\n    protected:\n        virtual int foo() const { return value; }\n\n    private:\n        int value = 42;\n    };\n\n    class TrampolineB : public ProtectedB {\n    public:\n        int foo() const override { PYBIND11_OVERRIDE(int, ProtectedB, foo, ); }\n    };\n\n    class PublicistB : public ProtectedB {\n    public:\n        // [workaround(intel)] = default does not work here\n        // Removing or defaulting this destructor results in linking errors with the Intel compiler\n        // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827)\n        ~PublicistB() override{}; // NOLINT(modernize-use-equals-default)\n        using ProtectedB::foo;\n    };\n\n    py::class_<ProtectedB, TrampolineB>(m, \"ProtectedB\")\n        .def(py::init<>())\n#if !defined(_MSC_VER) || _MSC_VER >= 1910\n        .def(\"foo\", &PublicistB::foo);\n#else\n        .def(\"foo\", static_cast<int (ProtectedB::*)() const>(&PublicistB::foo));\n#endif\n\n    // test_brace_initialization\n    struct BraceInitialization {\n        int field1;\n        std::string field2;\n    };\n\n    py::class_<BraceInitialization>(m, \"BraceInitialization\")\n        .def(py::init<int, const std::string &>())\n        .def_readwrite(\"field1\", &BraceInitialization::field1)\n        .def_readwrite(\"field2\", &BraceInitialization::field2);\n    // We *don't* want to construct using braces when the given constructor argument maps to a\n    // constructor, because brace initialization could go to the wrong place (in particular when\n    // there is also an `initializer_list<T>`-accept constructor):\n    py::class_<NoBraceInitialization>(m, \"NoBraceInitialization\")\n        .def(py::init<std::vector<int>>())\n        .def_readonly(\"vec\", &NoBraceInitialization::vec);\n\n    // test_reentrant_implicit_conversion_failure\n    // #1035: issue with runaway reentrant implicit conversion\n    struct BogusImplicitConversion {\n        BogusImplicitConversion(const BogusImplicitConversion &) = default;\n    };\n\n    py::class_<BogusImplicitConversion>(m, \"BogusImplicitConversion\")\n        .def(py::init<const BogusImplicitConversion &>());\n\n    py::implicitly_convertible<int, BogusImplicitConversion>();\n\n    // test_qualname\n    // #1166: nested class docstring doesn't show nested name\n    // Also related: tests that __qualname__ is set properly\n    struct NestBase {};\n    struct Nested {};\n    py::class_<NestBase> base(m, \"NestBase\");\n    base.def(py::init<>());\n    py::class_<Nested>(base, \"Nested\")\n        .def(py::init<>())\n        .def(\"fn\", [](Nested &, int, NestBase &, Nested &) {})\n        .def(\n            \"fa\", [](Nested &, int, NestBase &, Nested &) {}, \"a\"_a, \"b\"_a, \"c\"_a);\n    base.def(\"g\", [](NestBase &, Nested &) {});\n    base.def(\"h\", []() { return NestBase(); });\n\n    // test_error_after_conversion\n    // The second-pass path through dispatcher() previously didn't\n    // remember which overload was used, and would crash trying to\n    // generate a useful error message\n\n    struct NotRegistered {};\n    struct StringWrapper {\n        std::string str;\n    };\n    m.def(\"test_error_after_conversions\", [](int) {});\n    m.def(\"test_error_after_conversions\",\n          [](const StringWrapper &) -> NotRegistered { return {}; });\n    py::class_<StringWrapper>(m, \"StringWrapper\").def(py::init<std::string>());\n    py::implicitly_convertible<std::string, StringWrapper>();\n\n#if defined(PYBIND11_CPP17)\n    struct alignas(1024) Aligned {\n        std::uintptr_t ptr() const { return (uintptr_t) this; }\n    };\n    py::class_<Aligned>(m, \"Aligned\").def(py::init<>()).def(\"ptr\", &Aligned::ptr);\n#endif\n\n    // test_final\n    struct IsFinal final {};\n    py::class_<IsFinal>(m, \"IsFinal\", py::is_final());\n\n    // test_non_final_final\n    struct IsNonFinalFinal {};\n    py::class_<IsNonFinalFinal>(m, \"IsNonFinalFinal\", py::is_final());\n\n    // test_exception_rvalue_abort\n    struct PyPrintDestructor {\n        PyPrintDestructor() = default;\n        ~PyPrintDestructor() { py::print(\"Print from destructor\"); }\n        void throw_something() { throw std::runtime_error(\"error\"); }\n    };\n    py::class_<PyPrintDestructor>(m, \"PyPrintDestructor\")\n        .def(py::init<>())\n        .def(\"throw_something\", &PyPrintDestructor::throw_something);\n\n    // test_multiple_instances_with_same_pointer\n    struct SamePointer {};\n    static SamePointer samePointer;\n    py::class_<SamePointer, std::unique_ptr<SamePointer, py::nodelete>>(m, \"SamePointer\")\n        .def(py::init([]() { return &samePointer; }));\n\n    struct Empty {};\n    py::class_<Empty>(m, \"Empty\").def(py::init<>());\n\n    // test_base_and_derived_nested_scope\n    struct BaseWithNested {\n        struct Nested {};\n    };\n\n    struct DerivedWithNested : BaseWithNested {\n        struct Nested {};\n    };\n\n    py::class_<BaseWithNested> baseWithNested_class(m, \"BaseWithNested\");\n    py::class_<DerivedWithNested, BaseWithNested> derivedWithNested_class(m, \"DerivedWithNested\");\n    py::class_<BaseWithNested::Nested>(baseWithNested_class, \"Nested\")\n        .def_static(\"get_name\", []() { return \"BaseWithNested::Nested\"; });\n    py::class_<DerivedWithNested::Nested>(derivedWithNested_class, \"Nested\")\n        .def_static(\"get_name\", []() { return \"DerivedWithNested::Nested\"; });\n\n    // test_register_duplicate_class\n    struct Duplicate {};\n    struct OtherDuplicate {};\n    struct DuplicateNested {};\n    struct OtherDuplicateNested {};\n\n    m.def(\"register_duplicate_class_name\", [](const py::module_ &m) {\n        py::class_<Duplicate>(m, \"Duplicate\");\n        py::class_<OtherDuplicate>(m, \"Duplicate\");\n    });\n    m.def(\"register_duplicate_class_type\", [](const py::module_ &m) {\n        py::class_<OtherDuplicate>(m, \"OtherDuplicate\");\n        py::class_<OtherDuplicate>(m, \"YetAnotherDuplicate\");\n    });\n    m.def(\"register_duplicate_nested_class_name\", [](const py::object &gt) {\n        py::class_<DuplicateNested>(gt, \"DuplicateNested\");\n        py::class_<OtherDuplicateNested>(gt, \"DuplicateNested\");\n    });\n    m.def(\"register_duplicate_nested_class_type\", [](const py::object &gt) {\n        py::class_<OtherDuplicateNested>(gt, \"OtherDuplicateNested\");\n        py::class_<OtherDuplicateNested>(gt, \"YetAnotherDuplicateNested\");\n    });\n}\n\ntemplate <int N>\nclass BreaksBase {\npublic:\n    virtual ~BreaksBase() = default;\n    BreaksBase() = default;\n    BreaksBase(const BreaksBase &) = delete;\n};\ntemplate <int N>\nclass BreaksTramp : public BreaksBase<N> {};\n// These should all compile just fine:\nusing DoesntBreak1 = py::class_<BreaksBase<1>, std::unique_ptr<BreaksBase<1>>, BreaksTramp<1>>;\nusing DoesntBreak2 = py::class_<BreaksBase<2>, BreaksTramp<2>, std::unique_ptr<BreaksBase<2>>>;\nusing DoesntBreak3 = py::class_<BreaksBase<3>, std::unique_ptr<BreaksBase<3>>>;\nusing DoesntBreak4 = py::class_<BreaksBase<4>, BreaksTramp<4>>;\nusing DoesntBreak5 = py::class_<BreaksBase<5>>;\nusing DoesntBreak6 = py::class_<BreaksBase<6>, std::shared_ptr<BreaksBase<6>>, BreaksTramp<6>>;\nusing DoesntBreak7 = py::class_<BreaksBase<7>, BreaksTramp<7>, std::shared_ptr<BreaksBase<7>>>;\nusing DoesntBreak8 = py::class_<BreaksBase<8>, std::shared_ptr<BreaksBase<8>>>;\n#define CHECK_BASE(N)                                                                             \\\n    static_assert(std::is_same<typename DoesntBreak##N::type, BreaksBase<(N)>>::value,            \\\n                  \"DoesntBreak\" #N \" has wrong type!\")\nCHECK_BASE(1);\nCHECK_BASE(2);\nCHECK_BASE(3);\nCHECK_BASE(4);\nCHECK_BASE(5);\nCHECK_BASE(6);\nCHECK_BASE(7);\nCHECK_BASE(8);\n#define CHECK_ALIAS(N)                                                                            \\\n    static_assert(                                                                                \\\n        DoesntBreak##N::has_alias                                                                 \\\n            && std::is_same<typename DoesntBreak##N::type_alias, BreaksTramp<(N)>>::value,        \\\n        \"DoesntBreak\" #N \" has wrong type_alias!\")\n#define CHECK_NOALIAS(N)                                                                          \\\n    static_assert(!DoesntBreak##N::has_alias                                                      \\\n                      && std::is_void<typename DoesntBreak##N::type_alias>::value,                \\\n                  \"DoesntBreak\" #N \" has type alias, but shouldn't!\")\nCHECK_ALIAS(1);\nCHECK_ALIAS(2);\nCHECK_NOALIAS(3);\nCHECK_ALIAS(4);\nCHECK_NOALIAS(5);\nCHECK_ALIAS(6);\nCHECK_ALIAS(7);\nCHECK_NOALIAS(8);\n#define CHECK_HOLDER(N, TYPE)                                                                     \\\n    static_assert(std::is_same<typename DoesntBreak##N::holder_type,                              \\\n                               std::TYPE##_ptr<BreaksBase<(N)>>>::value,                          \\\n                  \"DoesntBreak\" #N \" has wrong holder_type!\")\nCHECK_HOLDER(1, unique);\nCHECK_HOLDER(2, unique);\nCHECK_HOLDER(3, unique);\nCHECK_HOLDER(4, unique);\nCHECK_HOLDER(5, unique);\nCHECK_HOLDER(6, shared);\nCHECK_HOLDER(7, shared);\nCHECK_HOLDER(8, shared);\n\n// There's no nice way to test that these fail because they fail to compile; leave them here,\n// though, so that they can be manually tested by uncommenting them (and seeing that compilation\n// failures occurs).\n\n// We have to actually look into the type: the typedef alone isn't enough to instantiate the type:\n#define CHECK_BROKEN(N)                                                                           \\\n    static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value,                \\\n                  \"Breaks1 has wrong type!\");\n\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n// Two holder classes:\ntypedef py::\n    class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>>\n        Breaks1;\nCHECK_BROKEN(1);\n// Two aliases:\ntypedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;\nCHECK_BROKEN(2);\n// Holder + 2 aliases\ntypedef py::\n    class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>>\n        Breaks3;\nCHECK_BROKEN(3);\n// Alias + 2 holders\ntypedef py::class_<BreaksBase<-4>,\n                   std::unique_ptr<BreaksBase<-4>>,\n                   BreaksTramp<-4>,\n                   std::shared_ptr<BreaksBase<-4>>>\n    Breaks4;\nCHECK_BROKEN(4);\n// Invalid option (not a subclass or holder)\ntypedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;\nCHECK_BROKEN(5);\n// Invalid option: multiple inheritance not supported:\ntemplate <>\nstruct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};\ntypedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;\nCHECK_BROKEN(8);\n#endif\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_class.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import class_ as m\n\n\ndef test_repr():\n    # In Python 3.3+, repr() accesses __qualname__\n    assert \"pybind11_type\" in repr(type(UserType))\n    assert \"UserType\" in repr(UserType)\n\n\ndef test_instance(msg):\n    with pytest.raises(TypeError) as excinfo:\n        m.NoConstructor()\n    assert msg(excinfo.value) == \"m.class_.NoConstructor: No constructor defined!\"\n\n    instance = m.NoConstructor.new_instance()\n\n    cstats = ConstructorStats.get(m.NoConstructor)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n\ndef test_instance_new(msg):\n    instance = m.NoConstructorNew()  # .__new__(m.NoConstructor.__class__)\n    cstats = ConstructorStats.get(m.NoConstructorNew)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n\ndef test_type():\n    assert m.check_type(1) == m.DerivedClass1\n    with pytest.raises(RuntimeError) as execinfo:\n        m.check_type(0)\n\n    assert \"pybind11::detail::get_type_info: unable to find type info\" in str(\n        execinfo.value\n    )\n    assert \"Invalid\" in str(execinfo.value)\n\n    # Currently not supported\n    # See https://github.com/pybind/pybind11/issues/2486\n    # assert m.check_type(2) == int\n\n\ndef test_type_of_py():\n    assert m.get_type_of(1) == int\n    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1\n    assert m.get_type_of(int) == type\n\n\ndef test_type_of_classic():\n    assert m.get_type_classic(1) == int\n    assert m.get_type_classic(m.DerivedClass1()) == m.DerivedClass1\n    assert m.get_type_classic(int) == type\n\n\ndef test_type_of_py_nodelete():\n    # If the above test deleted the class, this will segfault\n    assert m.get_type_of(m.DerivedClass1()) == m.DerivedClass1\n\n\ndef test_as_type_py():\n    assert m.as_type(int) == int\n\n    with pytest.raises(TypeError):\n        assert m.as_type(1) == int\n\n    with pytest.raises(TypeError):\n        assert m.as_type(m.DerivedClass1()) == m.DerivedClass1\n\n\ndef test_docstrings(doc):\n    assert doc(UserType) == \"A `py::class_` type for testing\"\n    assert UserType.__name__ == \"UserType\"\n    assert UserType.__module__ == \"pybind11_tests\"\n    assert UserType.get_value.__name__ == \"get_value\"\n    assert UserType.get_value.__module__ == \"pybind11_tests\"\n\n    assert (\n        doc(UserType.get_value)\n        == \"\"\"\n        get_value(self: m.UserType) -> int\n\n        Get value using a method\n    \"\"\"\n    )\n    assert doc(UserType.value) == \"Get/set value using a property\"\n\n    assert (\n        doc(m.NoConstructor.new_instance)\n        == \"\"\"\n        new_instance() -> m.class_.NoConstructor\n\n        Return an instance\n    \"\"\"\n    )\n\n\ndef test_qualname(doc):\n    \"\"\"Tests that a properly qualified name is set in __qualname__ (even in pre-3.3, where we\n    backport the attribute) and that generated docstrings properly use it and the module name\"\"\"\n    assert m.NestBase.__qualname__ == \"NestBase\"\n    assert m.NestBase.Nested.__qualname__ == \"NestBase.Nested\"\n\n    assert (\n        doc(m.NestBase.__init__)\n        == \"\"\"\n        __init__(self: m.class_.NestBase) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.g)\n        == \"\"\"\n        g(self: m.class_.NestBase, arg0: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.Nested.__init__)\n        == \"\"\"\n        __init__(self: m.class_.NestBase.Nested) -> None\n    \"\"\"\n    )\n    assert (\n        doc(m.NestBase.Nested.fn)\n        == \"\"\"\n        fn(self: m.class_.NestBase.Nested, arg0: int, arg1: m.class_.NestBase, arg2: m.class_.NestBase.Nested) -> None\n    \"\"\"  # noqa: E501 line too long\n    )\n    assert (\n        doc(m.NestBase.Nested.fa)\n        == \"\"\"\n        fa(self: m.class_.NestBase.Nested, a: int, b: m.class_.NestBase, c: m.class_.NestBase.Nested) -> None\n    \"\"\"  # noqa: E501 line too long\n    )\n    assert m.NestBase.__module__ == \"pybind11_tests.class_\"\n    assert m.NestBase.Nested.__module__ == \"pybind11_tests.class_\"\n\n\ndef test_inheritance(msg):\n    roger = m.Rabbit(\"Rabbit\")\n    assert roger.name() + \" is a \" + roger.species() == \"Rabbit is a parrot\"\n    assert m.pet_name_species(roger) == \"Rabbit is a parrot\"\n\n    polly = m.Pet(\"Polly\", \"parrot\")\n    assert polly.name() + \" is a \" + polly.species() == \"Polly is a parrot\"\n    assert m.pet_name_species(polly) == \"Polly is a parrot\"\n\n    molly = m.Dog(\"Molly\")\n    assert molly.name() + \" is a \" + molly.species() == \"Molly is a dog\"\n    assert m.pet_name_species(molly) == \"Molly is a dog\"\n\n    fred = m.Hamster(\"Fred\")\n    assert fred.name() + \" is a \" + fred.species() == \"Fred is a rodent\"\n\n    assert m.dog_bark(molly) == \"Woof!\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.dog_bark(polly)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        dog_bark(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: m.class_.Dog) -> str\n\n        Invoked with: <m.class_.Pet object at 0>\n    \"\"\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.Chimera(\"lion\", \"goat\")\n    assert \"No constructor defined!\" in str(excinfo.value)\n\n\ndef test_inheritance_init(msg):\n\n    # Single base\n    class Python(m.Pet):\n        def __init__(self):\n            pass\n\n    with pytest.raises(TypeError) as exc_info:\n        Python()\n    expected = \"m.class_.Pet.__init__() must be called when overriding __init__\"\n    assert msg(exc_info.value) == expected\n\n    # Multiple bases\n    class RabbitHamster(m.Rabbit, m.Hamster):\n        def __init__(self):\n            m.Rabbit.__init__(self, \"RabbitHamster\")\n\n    with pytest.raises(TypeError) as exc_info:\n        RabbitHamster()\n    expected = \"m.class_.Hamster.__init__() must be called when overriding __init__\"\n    assert msg(exc_info.value) == expected\n\n\ndef test_automatic_upcasting():\n    assert type(m.return_class_1()).__name__ == \"DerivedClass1\"\n    assert type(m.return_class_2()).__name__ == \"DerivedClass2\"\n    assert type(m.return_none()).__name__ == \"NoneType\"\n    # Repeat these a few times in a random order to ensure no invalid caching is applied\n    assert type(m.return_class_n(1)).__name__ == \"DerivedClass1\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(0)).__name__ == \"BaseClass\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(2)).__name__ == \"DerivedClass2\"\n    assert type(m.return_class_n(0)).__name__ == \"BaseClass\"\n    assert type(m.return_class_n(1)).__name__ == \"DerivedClass1\"\n\n\ndef test_isinstance():\n    objects = [tuple(), dict(), m.Pet(\"Polly\", \"parrot\")] + [m.Dog(\"Molly\")] * 4\n    expected = (True, True, True, True, True, False, False)\n    assert m.check_instances(objects) == expected\n\n\ndef test_mismatched_holder():\n    import re\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.mismatched_holder_1()\n    assert re.match(\n        'generic_type: type \".*MismatchDerived1\" does not have a non-default '\n        'holder type while its base \".*MismatchBase1\" does',\n        str(excinfo.value),\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.mismatched_holder_2()\n    assert re.match(\n        'generic_type: type \".*MismatchDerived2\" has a non-default holder type '\n        'while its base \".*MismatchBase2\" does not',\n        str(excinfo.value),\n    )\n\n\ndef test_override_static():\n    \"\"\"#511: problem with inheritance + overwritten def_static\"\"\"\n    b = m.MyBase.make()\n    d1 = m.MyDerived.make2()\n    d2 = m.MyDerived.make()\n\n    assert isinstance(b, m.MyBase)\n    assert isinstance(d1, m.MyDerived)\n    assert isinstance(d2, m.MyDerived)\n\n\ndef test_implicit_conversion_life_support():\n    \"\"\"Ensure the lifetime of temporary objects created for implicit conversions\"\"\"\n    assert m.implicitly_convert_argument(UserType(5)) == 5\n    assert m.implicitly_convert_variable(UserType(5)) == 5\n\n    assert \"outside a bound function\" in m.implicitly_convert_variable_fail(UserType(5))\n\n\ndef test_operator_new_delete(capture):\n    \"\"\"Tests that class-specific operator new/delete functions are invoked\"\"\"\n\n    class SubAliased(m.AliasedHasOpNewDelSize):\n        pass\n\n    with capture:\n        a = m.HasOpNewDel()\n        b = m.HasOpNewDelSize()\n        d = m.HasOpNewDelBoth()\n    assert (\n        capture\n        == \"\"\"\n        A new 8\n        B new 4\n        D new 32\n    \"\"\"\n    )\n    sz_alias = str(m.AliasedHasOpNewDelSize.size_alias)\n    sz_noalias = str(m.AliasedHasOpNewDelSize.size_noalias)\n    with capture:\n        c = m.AliasedHasOpNewDelSize()\n        c2 = SubAliased()\n    assert capture == (\"C new \" + sz_noalias + \"\\n\" + \"C new \" + sz_alias + \"\\n\")\n\n    with capture:\n        del a\n        pytest.gc_collect()\n        del b\n        pytest.gc_collect()\n        del d\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        A delete\n        B delete 4\n        D delete\n    \"\"\"\n    )\n\n    with capture:\n        del c\n        pytest.gc_collect()\n        del c2\n        pytest.gc_collect()\n    assert capture == (\"C delete \" + sz_noalias + \"\\n\" + \"C delete \" + sz_alias + \"\\n\")\n\n\ndef test_bind_protected_functions():\n    \"\"\"Expose protected member functions to Python using a helper class\"\"\"\n    a = m.ProtectedA()\n    assert a.foo() == 42\n\n    b = m.ProtectedB()\n    assert b.foo() == 42\n\n    class C(m.ProtectedB):\n        def __init__(self):\n            m.ProtectedB.__init__(self)\n\n        def foo(self):\n            return 0\n\n    c = C()\n    assert c.foo() == 0\n\n\ndef test_brace_initialization():\n    \"\"\"Tests that simple POD classes can be constructed using C++11 brace initialization\"\"\"\n    a = m.BraceInitialization(123, \"test\")\n    assert a.field1 == 123\n    assert a.field2 == \"test\"\n\n    # Tests that a non-simple class doesn't get brace initialization (if the\n    # class defines an initializer_list constructor, in particular, it would\n    # win over the expected constructor).\n    b = m.NoBraceInitialization([123, 456])\n    assert b.vec == [123, 456]\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_class_refcount():\n    \"\"\"Instances must correctly increase/decrease the reference count of their types (#1029)\"\"\"\n    from sys import getrefcount\n\n    class PyDog(m.Dog):\n        pass\n\n    for cls in m.Dog, PyDog:\n        refcount_1 = getrefcount(cls)\n        molly = [cls(\"Molly\") for _ in range(10)]\n        refcount_2 = getrefcount(cls)\n\n        del molly\n        pytest.gc_collect()\n        refcount_3 = getrefcount(cls)\n\n        assert refcount_1 == refcount_3\n        assert refcount_2 > refcount_1\n\n\ndef test_reentrant_implicit_conversion_failure(msg):\n    # ensure that there is no runaway reentrant implicit conversion (#1035)\n    with pytest.raises(TypeError) as excinfo:\n        m.BogusImplicitConversion(0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.class_.BogusImplicitConversion(arg0: m.class_.BogusImplicitConversion)\n\n        Invoked with: 0\n    \"\"\"\n    )\n\n\ndef test_error_after_conversions():\n    with pytest.raises(TypeError) as exc_info:\n        m.test_error_after_conversions(\"hello\")\n    assert str(exc_info.value).startswith(\n        \"Unable to convert function return value to a Python type!\"\n    )\n\n\ndef test_aligned():\n    if hasattr(m, \"Aligned\"):\n        p = m.Aligned().ptr()\n        assert p % 1024 == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2742\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_final():\n    with pytest.raises(TypeError) as exc_info:\n\n        class PyFinalChild(m.IsFinal):\n            pass\n\n    assert str(exc_info.value).endswith(\"is not an acceptable base type\")\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2742\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_non_final_final():\n    with pytest.raises(TypeError) as exc_info:\n\n        class PyNonFinalFinalChild(m.IsNonFinalFinal):\n            pass\n\n    assert str(exc_info.value).endswith(\"is not an acceptable base type\")\n\n\n# https://github.com/pybind/pybind11/issues/1878\ndef test_exception_rvalue_abort():\n    with pytest.raises(RuntimeError):\n        m.PyPrintDestructor().throw_something()\n\n\n# https://github.com/pybind/pybind11/issues/1568\ndef test_multiple_instances_with_same_pointer(capture):\n    n = 100\n    instances = [m.SamePointer() for _ in range(n)]\n    for i in range(n):\n        # We need to reuse the same allocated memory for with a different type,\n        # to ensure the bug in `deregister_instance_impl` is detected. Otherwise\n        # `Py_TYPE(self) == Py_TYPE(it->second)` will still succeed, even though\n        # the `instance` is already deleted.\n        instances[i] = m.Empty()\n    # No assert: if this does not trigger the error\n    #   pybind11_fail(\"pybind11_object_dealloc(): Tried to deallocate unregistered instance!\");\n    # and just completes without crashing, we're good.\n\n\n# https://github.com/pybind/pybind11/issues/1624\ndef test_base_and_derived_nested_scope():\n    assert issubclass(m.DerivedWithNested, m.BaseWithNested)\n    assert m.BaseWithNested.Nested != m.DerivedWithNested.Nested\n    assert m.BaseWithNested.Nested.get_name() == \"BaseWithNested::Nested\"\n    assert m.DerivedWithNested.Nested.get_name() == \"DerivedWithNested::Nested\"\n\n\ndef test_register_duplicate_class():\n    import types\n\n    module_scope = types.ModuleType(\"module_scope\")\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_class_name(module_scope)\n    expected = (\n        'generic_type: cannot initialize type \"Duplicate\": '\n        \"an object with that name is already defined\"\n    )\n    assert str(exc_info.value) == expected\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_class_type(module_scope)\n    expected = 'generic_type: type \"YetAnotherDuplicate\" is already registered!'\n    assert str(exc_info.value) == expected\n\n    class ClassScope:\n        pass\n\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_nested_class_name(ClassScope)\n    expected = (\n        'generic_type: cannot initialize type \"DuplicateNested\": '\n        \"an object with that name is already defined\"\n    )\n    assert str(exc_info.value) == expected\n    with pytest.raises(RuntimeError) as exc_info:\n        m.register_duplicate_nested_class_type(ClassScope)\n    expected = 'generic_type: type \"YetAnotherDuplicateNested\" is already registered!'\n    assert str(exc_info.value) == expected\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/CMakeLists.txt",
    "content": "# Built-in in CMake 3.5+\ninclude(CMakeParseArguments)\n\nadd_custom_target(test_cmake_build)\n\nfunction(pybind11_add_build_test name)\n  cmake_parse_arguments(ARG \"INSTALL\" \"\" \"\" ${ARGN})\n\n  set(build_options \"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}\")\n\n  if(PYBIND11_FINDPYTHON)\n    list(APPEND build_options \"-DPYBIND11_FINDPYTHON=${PYBIND11_FINDPYTHON}\")\n\n    if(DEFINED Python_ROOT_DIR)\n      list(APPEND build_options \"-DPython_ROOT_DIR=${Python_ROOT_DIR}\")\n    endif()\n\n    list(APPEND build_options \"-DPython_EXECUTABLE=${Python_EXECUTABLE}\")\n  else()\n    list(APPEND build_options \"-DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}\")\n  endif()\n\n  if(DEFINED CMAKE_CXX_STANDARD)\n    list(APPEND build_options \"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}\")\n  endif()\n\n  if(NOT ARG_INSTALL)\n    list(APPEND build_options \"-Dpybind11_SOURCE_DIR=${pybind11_SOURCE_DIR}\")\n  else()\n    list(APPEND build_options \"-DCMAKE_PREFIX_PATH=${pybind11_BINARY_DIR}/mock_install\")\n  endif()\n\n  add_custom_target(\n    test_build_${name}\n    ${CMAKE_CTEST_COMMAND}\n    --build-and-test\n    \"${CMAKE_CURRENT_SOURCE_DIR}/${name}\"\n    \"${CMAKE_CURRENT_BINARY_DIR}/${name}\"\n    --build-config\n    Release\n    --build-noclean\n    --build-generator\n    ${CMAKE_GENERATOR}\n    $<$<BOOL:${CMAKE_GENERATOR_PLATFORM}>:--build-generator-platform>\n    ${CMAKE_GENERATOR_PLATFORM}\n    --build-makeprogram\n    ${CMAKE_MAKE_PROGRAM}\n    --build-target\n    check_${name}\n    --build-options\n    ${build_options})\n  if(ARG_INSTALL)\n    add_dependencies(test_build_${name} mock_install)\n  endif()\n  add_dependencies(test_cmake_build test_build_${name})\nendfunction()\n\npossibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)\n\npybind11_add_build_test(subdirectory_function)\npybind11_add_build_test(subdirectory_target)\nif(\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\")\n  message(STATUS \"Skipping embed test on PyPy\")\nelse()\n  pybind11_add_build_test(subdirectory_embed)\nendif()\n\nif(PYBIND11_INSTALL)\n  add_custom_target(\n    mock_install ${CMAKE_COMMAND} \"-DCMAKE_INSTALL_PREFIX=${pybind11_BINARY_DIR}/mock_install\" -P\n                 \"${pybind11_BINARY_DIR}/cmake_install.cmake\")\n\n  pybind11_add_build_test(installed_function INSTALL)\n  pybind11_add_build_test(installed_target INSTALL)\n  if(NOT (\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\"\n         ))\n    pybind11_add_build_test(installed_embed INSTALL)\n  endif()\nendif()\n\nadd_dependencies(check test_cmake_build)\n\nadd_subdirectory(subdirectory_target EXCLUDE_FROM_ALL)\nadd_subdirectory(subdirectory_embed EXCLUDE_FROM_ALL)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/embed.cpp",
    "content": "#include <pybind11/embed.h>\nnamespace py = pybind11;\n\nPYBIND11_EMBEDDED_MODULE(test_cmake_build, m) {\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n\nint main(int argc, char *argv[]) {\n    if (argc != 2) {\n        throw std::runtime_error(\"Expected test.py file as the first argument\");\n    }\n    auto *test_py_file = argv[1];\n\n    py::scoped_interpreter guard{};\n\n    auto m = py::module_::import(\"test_cmake_build\");\n    if (m.attr(\"add\")(1, 2).cast<int>() != 3) {\n        throw std::runtime_error(\"embed.cpp failed\");\n    }\n\n    py::module_::import(\"sys\").attr(\"argv\") = py::make_tuple(\"test.py\", \"embed.cpp\");\n    py::eval_file(test_py_file, py::globals());\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/installed_embed/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_embed CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(STATUS \"Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}\")\n\nadd_executable(test_installed_embed ../embed.cpp)\ntarget_link_libraries(test_installed_embed PRIVATE pybind11::embed)\nset_target_properties(test_installed_embed PROPERTIES OUTPUT_NAME test_cmake_build)\n\n# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::embed).\n# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.\nset_target_properties(test_installed_embed PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)\n\nadd_custom_target(\n  check_installed_embed\n  $<TARGET_FILE:test_installed_embed> ${PROJECT_SOURCE_DIR}/../test.py\n  DEPENDS test_installed_embed)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/installed_function/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\nproject(test_installed_module CXX)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_function CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(\n  STATUS \"Found pybind11 v${pybind11_VERSION} ${pybind11_VERSION_TYPE}: ${pybind11_INCLUDE_DIRS}\")\n\npybind11_add_module(test_installed_function SHARED NO_EXTRAS ../main.cpp)\nset_target_properties(test_installed_function PROPERTIES OUTPUT_NAME test_cmake_build)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_installed_function\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_installed_function>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_installed_function)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/installed_target/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_installed_target CXX)\n\nfind_package(pybind11 CONFIG REQUIRED)\nmessage(STATUS \"Found pybind11 v${pybind11_VERSION}: ${pybind11_INCLUDE_DIRS}\")\n\nadd_library(test_installed_target MODULE ../main.cpp)\n\ntarget_link_libraries(test_installed_target PRIVATE pybind11::module)\nset_target_properties(test_installed_target PROPERTIES OUTPUT_NAME test_cmake_build)\n\n# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib\npybind11_extension(test_installed_target)\n\n# Do not treat includes from IMPORTED target as SYSTEM (Python headers in pybind11::module).\n# This may be needed to resolve header conflicts, e.g. between Python release and debug headers.\nset_target_properties(test_installed_target PROPERTIES NO_SYSTEM_FROM_IMPORTED ON)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_installed_target\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_installed_target>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_installed_target)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/main.cpp",
    "content": "#include <pybind11/pybind11.h>\nnamespace py = pybind11;\n\nPYBIND11_MODULE(test_cmake_build, m) {\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/subdirectory_embed/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_embed CXX)\n\nset(PYBIND11_INSTALL\n    ON\n    CACHE BOOL \"\")\nset(PYBIND11_EXPORT_NAME test_export)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\n\n# Test basic target functionality\nadd_executable(test_subdirectory_embed ../embed.cpp)\ntarget_link_libraries(test_subdirectory_embed PRIVATE pybind11::embed)\nset_target_properties(test_subdirectory_embed PROPERTIES OUTPUT_NAME test_cmake_build)\n\nadd_custom_target(\n  check_subdirectory_embed\n  $<TARGET_FILE:test_subdirectory_embed> \"${PROJECT_SOURCE_DIR}/../test.py\"\n  DEPENDS test_subdirectory_embed)\n\n# Test custom export group -- PYBIND11_EXPORT_NAME\nadd_library(test_embed_lib ../embed.cpp)\ntarget_link_libraries(test_embed_lib PRIVATE pybind11::embed)\n\ninstall(\n  TARGETS test_embed_lib\n  EXPORT test_export\n  ARCHIVE DESTINATION bin\n  LIBRARY DESTINATION lib\n  RUNTIME DESTINATION lib)\ninstall(EXPORT test_export DESTINATION lib/cmake/test_export/test_export-Targets.cmake)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/subdirectory_function/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_function CXX)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\npybind11_add_module(test_subdirectory_function ../main.cpp)\nset_target_properties(test_subdirectory_function PROPERTIES OUTPUT_NAME test_cmake_build)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_subdirectory_function\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_function>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_subdirectory_function)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/subdirectory_target/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.4)\n\n# The `cmake_minimum_required(VERSION 3.4...3.18)` syntax does not work with\n# some versions of VS that have a patched CMake 3.11. This forces us to emulate\n# the behavior using the following workaround:\nif(${CMAKE_VERSION} VERSION_LESS 3.18)\n  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})\nelse()\n  cmake_policy(VERSION 3.18)\nendif()\n\nproject(test_subdirectory_target CXX)\n\nadd_subdirectory(\"${pybind11_SOURCE_DIR}\" pybind11)\n\nadd_library(test_subdirectory_target MODULE ../main.cpp)\nset_target_properties(test_subdirectory_target PROPERTIES OUTPUT_NAME test_cmake_build)\n\ntarget_link_libraries(test_subdirectory_target PRIVATE pybind11::module)\n\n# Make sure result is, for example, test_installed_target.so, not libtest_installed_target.dylib\npybind11_extension(test_subdirectory_target)\n\nif(DEFINED Python_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${Python_EXECUTABLE}\")\nelseif(DEFINED PYTHON_EXECUTABLE)\n  set(_Python_EXECUTABLE \"${PYTHON_EXECUTABLE}\")\nelse()\n  message(FATAL_ERROR \"No Python executable defined (should not be possible at this stage)\")\nendif()\n\nadd_custom_target(\n  check_subdirectory_target\n  ${CMAKE_COMMAND}\n  -E\n  env\n  PYTHONPATH=$<TARGET_FILE_DIR:test_subdirectory_target>\n  ${_Python_EXECUTABLE}\n  ${PROJECT_SOURCE_DIR}/../test.py\n  ${PROJECT_NAME}\n  DEPENDS test_subdirectory_target)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_cmake_build/test.py",
    "content": "# -*- coding: utf-8 -*-\nimport sys\n\nimport test_cmake_build\n\nif str is not bytes:  # If not Python2\n    assert isinstance(__file__, str)  # Test this is properly set\n\nassert test_cmake_build.add(1, 2) == 3\nprint(\"{} imports, runs, and adds: 1 + 2 = 3\".format(sys.argv[1]))\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_const_name.cpp",
    "content": "// Copyright (c) 2021 The Pybind Development Team.\n// All rights reserved. Use of this source code is governed by a\n// BSD-style license that can be found in the LICENSE file.\n\n#include \"pybind11_tests.h\"\n\n#if defined(_MSC_VER) && _MSC_VER < 1910\n\n// MSVC 2015 fails in bizarre ways.\n#    define PYBIND11_SKIP_TEST_CONST_NAME\n\n#else // Only test with MSVC 2017 or newer.\n\n// IUT = Implementation Under Test\n#    define CONST_NAME_TESTS(TEST_FUNC, IUT)                                                      \\\n        std::string TEST_FUNC(int selector) {                                                     \\\n            switch (selector) {                                                                   \\\n                case 0:                                                                           \\\n                    return IUT(\"\").text;                                                          \\\n                case 1:                                                                           \\\n                    return IUT(\"A\").text;                                                         \\\n                case 2:                                                                           \\\n                    return IUT(\"Bd\").text;                                                        \\\n                case 3:                                                                           \\\n                    return IUT(\"Cef\").text;                                                       \\\n                case 4:                                                                           \\\n                    return IUT<int>().text; /*NOLINT(bugprone-macro-parentheses)*/                \\\n                case 5:                                                                           \\\n                    return IUT<std::string>().text; /*NOLINT(bugprone-macro-parentheses)*/        \\\n                case 6:                                                                           \\\n                    return IUT<true>(\"T1\", \"T2\").text; /*NOLINT(bugprone-macro-parentheses)*/     \\\n                case 7:                                                                           \\\n                    return IUT<false>(\"U1\", \"U2\").text; /*NOLINT(bugprone-macro-parentheses)*/    \\\n                case 8:                                                                           \\\n                    /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/                                \\\n                    return IUT<true>(IUT(\"D1\"), IUT(\"D2\")).text;                                  \\\n                case 9:                                                                           \\\n                    /*NOLINTNEXTLINE(bugprone-macro-parentheses)*/                                \\\n                    return IUT<false>(IUT(\"E1\"), IUT(\"E2\")).text;                                 \\\n                case 10:                                                                          \\\n                    return IUT(\"KeepAtEnd\").text;                                                 \\\n                default:                                                                          \\\n                    break;                                                                        \\\n            }                                                                                     \\\n            throw std::runtime_error(\"Invalid selector value.\");                                  \\\n        }\n\nCONST_NAME_TESTS(const_name_tests, py::detail::const_name)\n\n#    ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\nCONST_NAME_TESTS(underscore_tests, py::detail::_)\n#    endif\n\n#endif // MSVC >= 2017\n\nTEST_SUBMODULE(const_name, m) {\n#ifdef PYBIND11_SKIP_TEST_CONST_NAME\n    m.attr(\"const_name_tests\") = \"PYBIND11_SKIP_TEST_CONST_NAME\";\n#else\n    m.def(\"const_name_tests\", const_name_tests);\n#endif\n\n#ifdef PYBIND11_SKIP_TEST_CONST_NAME\n    m.attr(\"underscore_tests\") = \"PYBIND11_SKIP_TEST_CONST_NAME\";\n#elif defined(PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY)\n    m.def(\"underscore_tests\", underscore_tests);\n#else\n    m.attr(\"underscore_tests\") = \"PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY not defined.\";\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_const_name.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import const_name as m\n\n\n@pytest.mark.parametrize(\"func\", (m.const_name_tests, m.underscore_tests))\n@pytest.mark.parametrize(\n    \"selector, expected\",\n    enumerate(\n        (\n            \"\",\n            \"A\",\n            \"Bd\",\n            \"Cef\",\n            \"%\",\n            \"%\",\n            \"T1\",\n            \"U2\",\n            \"D1\",\n            \"E2\",\n            \"KeepAtEnd\",\n        )\n    ),\n)\ndef test_const_name(func, selector, expected):\n    if isinstance(func, type(u\"\") if env.PY2 else str):\n        pytest.skip(func)\n    text = func(selector)\n    assert text == expected\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_constants_and_functions.cpp",
    "content": "/*\n    tests/test_constants_and_functions.cpp -- global constants and functions, enumerations, raw\n    byte strings\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nenum MyEnum { EFirstEntry = 1, ESecondEntry };\n\nstd::string test_function1() { return \"test_function()\"; }\n\nstd::string test_function2(MyEnum k) { return \"test_function(enum=\" + std::to_string(k) + \")\"; }\n\nstd::string test_function3(int i) { return \"test_function(\" + std::to_string(i) + \")\"; }\n\npy::str test_function4() { return \"test_function()\"; }\npy::str test_function4(char *) { return \"test_function(char *)\"; }\npy::str test_function4(int, float) { return \"test_function(int, float)\"; }\npy::str test_function4(float, int) { return \"test_function(float, int)\"; }\n\npy::bytes return_bytes() {\n    const char *data = \"\\x01\\x00\\x02\\x00\";\n    return std::string(data, 4);\n}\n\nstd::string print_bytes(const py::bytes &bytes) {\n    std::string ret = \"bytes[\";\n    const auto value = static_cast<std::string>(bytes);\n    for (size_t i = 0; i < value.length(); ++i) {\n        ret += std::to_string(static_cast<int>(value[i])) + \" \";\n    }\n    ret.back() = ']';\n    return ret;\n}\n\n// Test that we properly handle C++17 exception specifiers (which are part of the function\n// signature in C++17).  These should all still work before C++17, but don't affect the function\n// signature.\nnamespace test_exc_sp {\n// [workaround(intel)] Unable to use noexcept instead of noexcept(true)\n// Make the f1 test basically the same as the f2 test in C++17 mode for the Intel compiler as\n// it fails to compile with a plain noexcept (tested with icc (ICC) 2021.1 Beta 20200827).\n#if defined(__INTEL_COMPILER) && defined(PYBIND11_CPP17)\nint f1(int x) noexcept(true) { return x + 1; }\n#else\nint f1(int x) noexcept { return x + 1; }\n#endif\nint f2(int x) noexcept(true) { return x + 2; }\nint f3(int x) noexcept(false) { return x + 3; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wdeprecated\"\n#endif\n// NOLINTNEXTLINE(modernize-use-noexcept)\nint f4(int x) throw() { return x + 4; } // Deprecated equivalent to noexcept(true)\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\nstruct C {\n    int m1(int x) noexcept { return x - 1; }\n    int m2(int x) const noexcept { return x - 2; }\n    int m3(int x) noexcept(true) { return x - 3; }\n    int m4(int x) const noexcept(true) { return x - 4; }\n    int m5(int x) noexcept(false) { return x - 5; }\n    int m6(int x) const noexcept(false) { return x - 6; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n#    pragma GCC diagnostic ignored \"-Wdeprecated\"\n#endif\n    // NOLINTNEXTLINE(modernize-use-noexcept)\n    int m7(int x) throw() { return x - 7; }\n    // NOLINTNEXTLINE(modernize-use-noexcept)\n    int m8(int x) const throw() { return x - 8; }\n#if defined(__GNUG__) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n};\n} // namespace test_exc_sp\n\nTEST_SUBMODULE(constants_and_functions, m) {\n    // test_constants\n    m.attr(\"some_constant\") = py::int_(14);\n\n    // test_function_overloading\n    m.def(\"test_function\", &test_function1);\n    m.def(\"test_function\", &test_function2);\n    m.def(\"test_function\", &test_function3);\n\n#if defined(PYBIND11_OVERLOAD_CAST)\n    m.def(\"test_function\", py::overload_cast<>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<char *>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<int, float>(&test_function4));\n    m.def(\"test_function\", py::overload_cast<float, int>(&test_function4));\n#else\n    m.def(\"test_function\", static_cast<py::str (*)()>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(char *)>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(int, float)>(&test_function4));\n    m.def(\"test_function\", static_cast<py::str (*)(float, int)>(&test_function4));\n#endif\n\n    py::enum_<MyEnum>(m, \"MyEnum\")\n        .value(\"EFirstEntry\", EFirstEntry)\n        .value(\"ESecondEntry\", ESecondEntry)\n        .export_values();\n\n    // test_bytes\n    m.def(\"return_bytes\", &return_bytes);\n    m.def(\"print_bytes\", &print_bytes);\n\n    // test_exception_specifiers\n    using namespace test_exc_sp;\n    py::class_<C>(m, \"C\")\n        .def(py::init<>())\n        .def(\"m1\", &C::m1)\n        .def(\"m2\", &C::m2)\n        .def(\"m3\", &C::m3)\n        .def(\"m4\", &C::m4)\n        .def(\"m5\", &C::m5)\n        .def(\"m6\", &C::m6)\n        .def(\"m7\", &C::m7)\n        .def(\"m8\", &C::m8);\n    m.def(\"f1\", f1);\n    m.def(\"f2\", f2);\n#if defined(__INTEL_COMPILER)\n#    pragma warning push\n#    pragma warning disable 878 // incompatible exception specifications\n#endif\n    m.def(\"f3\", f3);\n#if defined(__INTEL_COMPILER)\n#    pragma warning pop\n#endif\n    m.def(\"f4\", f4);\n\n    // test_function_record_leaks\n    struct LargeCapture {\n        // This should always be enough to trigger the alternative branch\n        // where `sizeof(capture) > sizeof(rec->data)`\n        uint64_t zeros[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};\n    };\n    m.def(\"register_large_capture_with_invalid_arguments\", [](py::module_ m) {\n        LargeCapture capture; // VS 2015's MSVC is acting up if we create the array here\n        m.def(\n            \"should_raise\",\n            [capture](int) { return capture.zeros[9] + 33; },\n            py::kw_only(),\n            py::arg());\n    });\n    m.def(\"register_with_raising_repr\", [](py::module_ m, const py::object &default_value) {\n        m.def(\n            \"should_raise\",\n            [](int, int, const py::object &) { return 42; },\n            \"some docstring\",\n            py::arg_v(\"x\", 42),\n            py::arg_v(\"y\", 42, \"<the answer>\"),\n            py::arg_v(\"z\", default_value));\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_constants_and_functions.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nm = pytest.importorskip(\"pybind11_tests.constants_and_functions\")\n\n\ndef test_constants():\n    assert m.some_constant == 14\n\n\ndef test_function_overloading():\n    assert m.test_function() == \"test_function()\"\n    assert m.test_function(7) == \"test_function(7)\"\n    assert m.test_function(m.MyEnum.EFirstEntry) == \"test_function(enum=1)\"\n    assert m.test_function(m.MyEnum.ESecondEntry) == \"test_function(enum=2)\"\n\n    assert m.test_function() == \"test_function()\"\n    assert m.test_function(\"abcd\") == \"test_function(char *)\"\n    assert m.test_function(1, 1.0) == \"test_function(int, float)\"\n    assert m.test_function(1, 1.0) == \"test_function(int, float)\"\n    assert m.test_function(2.0, 2) == \"test_function(float, int)\"\n\n\ndef test_bytes():\n    assert m.print_bytes(m.return_bytes()) == \"bytes[1 0 2 0]\"\n\n\ndef test_exception_specifiers():\n    c = m.C()\n    assert c.m1(2) == 1\n    assert c.m2(3) == 1\n    assert c.m3(5) == 2\n    assert c.m4(7) == 3\n    assert c.m5(10) == 5\n    assert c.m6(14) == 8\n    assert c.m7(20) == 13\n    assert c.m8(29) == 21\n\n    assert m.f1(33) == 34\n    assert m.f2(53) == 55\n    assert m.f3(86) == 89\n    assert m.f4(140) == 144\n\n\ndef test_function_record_leaks():\n    class RaisingRepr:\n        def __repr__(self):\n            raise RuntimeError(\"Surprise!\")\n\n    with pytest.raises(RuntimeError):\n        m.register_large_capture_with_invalid_arguments(m)\n    with pytest.raises(RuntimeError):\n        m.register_with_raising_repr(m, RaisingRepr())\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_copy_move.cpp",
    "content": "/*\n    tests/test_copy_move_policies.cpp -- 'copy' and 'move' return value policies\n                                         and related tests\n\n    Copyright (c) 2016 Ben North <ben@redfrontdoor.org>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\ntemplate <typename derived>\nstruct empty {\n    static const derived &get_one() { return instance_; }\n    static derived instance_;\n};\n\nstruct lacking_copy_ctor : public empty<lacking_copy_ctor> {\n    lacking_copy_ctor() = default;\n    lacking_copy_ctor(const lacking_copy_ctor &other) = delete;\n};\n\ntemplate <>\nlacking_copy_ctor empty<lacking_copy_ctor>::instance_ = {};\n\nstruct lacking_move_ctor : public empty<lacking_move_ctor> {\n    lacking_move_ctor() = default;\n    lacking_move_ctor(const lacking_move_ctor &other) = delete;\n    lacking_move_ctor(lacking_move_ctor &&other) = delete;\n};\n\ntemplate <>\nlacking_move_ctor empty<lacking_move_ctor>::instance_ = {};\n\n/* Custom type caster move/copy test classes */\nclass MoveOnlyInt {\npublic:\n    MoveOnlyInt() { print_default_created(this); }\n    explicit MoveOnlyInt(int v) : value{v} { print_created(this, value); }\n    MoveOnlyInt(MoveOnlyInt &&m) noexcept {\n        print_move_created(this, m.value);\n        std::swap(value, m.value);\n    }\n    MoveOnlyInt &operator=(MoveOnlyInt &&m) noexcept {\n        print_move_assigned(this, m.value);\n        std::swap(value, m.value);\n        return *this;\n    }\n    MoveOnlyInt(const MoveOnlyInt &) = delete;\n    MoveOnlyInt &operator=(const MoveOnlyInt &) = delete;\n    ~MoveOnlyInt() { print_destroyed(this); }\n\n    int value;\n};\nclass MoveOrCopyInt {\npublic:\n    MoveOrCopyInt() { print_default_created(this); }\n    explicit MoveOrCopyInt(int v) : value{v} { print_created(this, value); }\n    MoveOrCopyInt(MoveOrCopyInt &&m) noexcept {\n        print_move_created(this, m.value);\n        std::swap(value, m.value);\n    }\n    MoveOrCopyInt &operator=(MoveOrCopyInt &&m) noexcept {\n        print_move_assigned(this, m.value);\n        std::swap(value, m.value);\n        return *this;\n    }\n    MoveOrCopyInt(const MoveOrCopyInt &c) {\n        print_copy_created(this, c.value);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = c.value;\n    }\n    MoveOrCopyInt &operator=(const MoveOrCopyInt &c) {\n        print_copy_assigned(this, c.value);\n        value = c.value;\n        return *this;\n    }\n    ~MoveOrCopyInt() { print_destroyed(this); }\n\n    int value;\n};\nclass CopyOnlyInt {\npublic:\n    CopyOnlyInt() { print_default_created(this); }\n    explicit CopyOnlyInt(int v) : value{v} { print_created(this, value); }\n    CopyOnlyInt(const CopyOnlyInt &c) {\n        print_copy_created(this, c.value);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = c.value;\n    }\n    CopyOnlyInt &operator=(const CopyOnlyInt &c) {\n        print_copy_assigned(this, c.value);\n        value = c.value;\n        return *this;\n    }\n    ~CopyOnlyInt() { print_destroyed(this); }\n\n    int value;\n};\nPYBIND11_NAMESPACE_BEGIN(pybind11)\nPYBIND11_NAMESPACE_BEGIN(detail)\ntemplate <>\nstruct type_caster<MoveOnlyInt> {\n    PYBIND11_TYPE_CASTER(MoveOnlyInt, const_name(\"MoveOnlyInt\"));\n    bool load(handle src, bool) {\n        value = MoveOnlyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const MoveOnlyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n};\n\ntemplate <>\nstruct type_caster<MoveOrCopyInt> {\n    PYBIND11_TYPE_CASTER(MoveOrCopyInt, const_name(\"MoveOrCopyInt\"));\n    bool load(handle src, bool) {\n        value = MoveOrCopyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const MoveOrCopyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n};\n\ntemplate <>\nstruct type_caster<CopyOnlyInt> {\nprotected:\n    CopyOnlyInt value;\n\npublic:\n    static constexpr auto name = const_name(\"CopyOnlyInt\");\n    bool load(handle src, bool) {\n        value = CopyOnlyInt(src.cast<int>());\n        return true;\n    }\n    static handle cast(const CopyOnlyInt &m, return_value_policy r, handle p) {\n        return pybind11::cast(m.value, r, p);\n    }\n    static handle cast(const CopyOnlyInt *src, return_value_policy policy, handle parent) {\n        if (!src) {\n            return none().release();\n        }\n        return cast(*src, policy, parent);\n    }\n    explicit operator CopyOnlyInt *() { return &value; }\n    explicit operator CopyOnlyInt &() { return value; }\n    template <typename T>\n    using cast_op_type = pybind11::detail::cast_op_type<T>;\n};\nPYBIND11_NAMESPACE_END(detail)\nPYBIND11_NAMESPACE_END(pybind11)\n\nTEST_SUBMODULE(copy_move_policies, m) {\n    // test_lacking_copy_ctor\n    py::class_<lacking_copy_ctor>(m, \"lacking_copy_ctor\")\n        .def_static(\"get_one\", &lacking_copy_ctor::get_one, py::return_value_policy::copy);\n    // test_lacking_move_ctor\n    py::class_<lacking_move_ctor>(m, \"lacking_move_ctor\")\n        .def_static(\"get_one\", &lacking_move_ctor::get_one, py::return_value_policy::move);\n\n    // test_move_and_copy_casts\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"move_and_copy_casts\", [](const py::object &o) {\n        int r = 0;\n        r += py::cast<MoveOrCopyInt>(o).value; /* moves */\n        r += py::cast<MoveOnlyInt>(o).value;   /* moves */\n        r += py::cast<CopyOnlyInt>(o).value;   /* copies */\n        auto m1(py::cast<MoveOrCopyInt>(o));   /* moves */\n        auto m2(py::cast<MoveOnlyInt>(o));     /* moves */\n        auto m3(py::cast<CopyOnlyInt>(o));     /* copies */\n        r += m1.value + m2.value + m3.value;\n\n        return r;\n    });\n\n    // test_move_and_copy_loads\n    m.def(\"move_only\", [](MoveOnlyInt m) { return m.value; });\n    // Changing this breaks the existing test: needs careful review.\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"move_or_copy\", [](MoveOrCopyInt m) { return m.value; });\n    // Changing this breaks the existing test: needs careful review.\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"copy_only\", [](CopyOnlyInt m) { return m.value; });\n    m.def(\"move_pair\",\n          [](std::pair<MoveOnlyInt, MoveOrCopyInt> p) { return p.first.value + p.second.value; });\n    m.def(\"move_tuple\", [](std::tuple<MoveOnlyInt, MoveOrCopyInt, MoveOnlyInt> t) {\n        return std::get<0>(t).value + std::get<1>(t).value + std::get<2>(t).value;\n    });\n    m.def(\"copy_tuple\", [](std::tuple<CopyOnlyInt, CopyOnlyInt> t) {\n        return std::get<0>(t).value + std::get<1>(t).value;\n    });\n    m.def(\"move_copy_nested\",\n          [](std::pair<MoveOnlyInt,\n                       std::pair<std::tuple<MoveOrCopyInt, CopyOnlyInt, std::tuple<MoveOnlyInt>>,\n                                 MoveOrCopyInt>> x) {\n              return x.first.value + std::get<0>(x.second.first).value\n                     + std::get<1>(x.second.first).value\n                     + std::get<0>(std::get<2>(x.second.first)).value + x.second.second.value;\n          });\n    m.def(\"move_and_copy_cstats\", []() {\n        ConstructorStats::gc();\n        // Reset counts to 0 so that previous tests don't affect later ones:\n        auto &mc = ConstructorStats::get<MoveOrCopyInt>();\n        mc.move_assignments = mc.move_constructions = mc.copy_assignments = mc.copy_constructions\n            = 0;\n        auto &mo = ConstructorStats::get<MoveOnlyInt>();\n        mo.move_assignments = mo.move_constructions = mo.copy_assignments = mo.copy_constructions\n            = 0;\n        auto &co = ConstructorStats::get<CopyOnlyInt>();\n        co.move_assignments = co.move_constructions = co.copy_assignments = co.copy_constructions\n            = 0;\n        py::dict d;\n        d[\"MoveOrCopyInt\"] = py::cast(mc, py::return_value_policy::reference);\n        d[\"MoveOnlyInt\"] = py::cast(mo, py::return_value_policy::reference);\n        d[\"CopyOnlyInt\"] = py::cast(co, py::return_value_policy::reference);\n        return d;\n    });\n#ifdef PYBIND11_HAS_OPTIONAL\n    // test_move_and_copy_load_optional\n    m.attr(\"has_optional\") = true;\n    m.def(\"move_optional\", [](std::optional<MoveOnlyInt> o) { return o->value; });\n    m.def(\"move_or_copy_optional\", [](std::optional<MoveOrCopyInt> o) { return o->value; });\n    m.def(\"copy_optional\", [](std::optional<CopyOnlyInt> o) { return o->value; });\n    m.def(\"move_optional_tuple\",\n          [](std::optional<std::tuple<MoveOrCopyInt, MoveOnlyInt, CopyOnlyInt>> x) {\n              return std::get<0>(*x).value + std::get<1>(*x).value + std::get<2>(*x).value;\n          });\n#else\n    m.attr(\"has_optional\") = false;\n#endif\n\n    // #70 compilation issue if operator new is not public - simple body added\n    // but not needed on most compilers; MSVC and nvcc don't like a local\n    // struct not having a method defined when declared, since it can not be\n    // added later.\n    struct PrivateOpNew {\n        int value = 1;\n\n    private:\n        void *operator new(size_t bytes) {\n            void *ptr = std::malloc(bytes);\n            if (ptr) {\n                return ptr;\n            }\n            throw std::bad_alloc{};\n        }\n    };\n    py::class_<PrivateOpNew>(m, \"PrivateOpNew\").def_readonly(\"value\", &PrivateOpNew::value);\n    m.def(\"private_op_new_value\", []() { return PrivateOpNew(); });\n    m.def(\n        \"private_op_new_reference\",\n        []() -> const PrivateOpNew & {\n            static PrivateOpNew x{};\n            return x;\n        },\n        py::return_value_policy::reference);\n\n    // test_move_fallback\n    // #389: rvp::move should fall-through to copy on non-movable objects\n    struct MoveIssue1 {\n        int v;\n        explicit MoveIssue1(int v) : v{v} {}\n        MoveIssue1(const MoveIssue1 &c) = default;\n        MoveIssue1(MoveIssue1 &&) = delete;\n    };\n    py::class_<MoveIssue1>(m, \"MoveIssue1\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MoveIssue1::v);\n\n    struct MoveIssue2 {\n        int v;\n        explicit MoveIssue2(int v) : v{v} {}\n        MoveIssue2(MoveIssue2 &&) = default;\n    };\n    py::class_<MoveIssue2>(m, \"MoveIssue2\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MoveIssue2::v);\n\n    // #2742: Don't expect ownership of raw pointer to `new`ed object to be transferred with\n    // `py::return_value_policy::move`\n    m.def(\n        \"get_moveissue1\",\n        [](int i) { return std::unique_ptr<MoveIssue1>(new MoveIssue1(i)); },\n        py::return_value_policy::move);\n    m.def(\n        \"get_moveissue2\", [](int i) { return MoveIssue2(i); }, py::return_value_policy::move);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_copy_move.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import copy_move_policies as m\n\n\ndef test_lacking_copy_ctor():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.lacking_copy_ctor.get_one()\n    assert \"is non-copyable!\" in str(excinfo.value)\n\n\ndef test_lacking_move_ctor():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.lacking_move_ctor.get_one()\n    assert \"is neither movable nor copyable!\" in str(excinfo.value)\n\n\ndef test_move_and_copy_casts():\n    \"\"\"Cast some values in C++ via custom type casters and count the number of moves/copies.\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    # The type move constructions/assignments below each get incremented: the move assignment comes\n    # from the type_caster load; the move construction happens when extracting that via a cast or\n    # loading into an argument.\n    assert m.move_and_copy_casts(3) == 18\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 2\n    assert c_m.move_constructions >= 2\n    assert c_mc.alive() == 0\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 2\n    assert c_mc.move_constructions >= 2\n    assert c_c.alive() == 0\n    assert c_c.copy_assignments == 2\n    assert c_c.copy_constructions >= 2\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\ndef test_move_and_copy_loads():\n    \"\"\"Call some functions that load arguments via custom type casters and count the number of\n    moves/copies.\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    assert m.move_only(10) == 10  # 1 move, c_m\n    assert m.move_or_copy(11) == 11  # 1 move, c_mc\n    assert m.copy_only(12) == 12  # 1 copy, c_c\n    assert m.move_pair((13, 14)) == 27  # 1 c_m move, 1 c_mc move\n    assert m.move_tuple((15, 16, 17)) == 48  # 2 c_m moves, 1 c_mc move\n    assert m.copy_tuple((18, 19)) == 37  # 2 c_c copies\n    # Direct constructions: 2 c_m moves, 2 c_mc moves, 1 c_c copy\n    # Extra moves/copies when moving pairs/tuples: 3 c_m, 3 c_mc, 2 c_c\n    assert m.move_copy_nested((1, ((2, 3, (4,)), 5))) == 15\n\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 6\n    assert c_m.move_constructions == 9\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 5\n    assert c_mc.move_constructions == 8\n    assert c_c.copy_assignments == 4\n    assert c_c.copy_constructions == 6\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\n@pytest.mark.skipif(not m.has_optional, reason=\"no <optional>\")\ndef test_move_and_copy_load_optional():\n    \"\"\"Tests move/copy loads of std::optional arguments\"\"\"\n\n    cstats = m.move_and_copy_cstats()\n    c_m, c_mc, c_c = (\n        cstats[\"MoveOnlyInt\"],\n        cstats[\"MoveOrCopyInt\"],\n        cstats[\"CopyOnlyInt\"],\n    )\n\n    # The extra move/copy constructions below come from the std::optional move (which has to move\n    # its arguments):\n    assert m.move_optional(10) == 10  # c_m: 1 move assign, 2 move construct\n    assert m.move_or_copy_optional(11) == 11  # c_mc: 1 move assign, 2 move construct\n    assert m.copy_optional(12) == 12  # c_c: 1 copy assign, 2 copy construct\n    # 1 move assign + move construct moves each of c_m, c_mc, 1 c_c copy\n    # +1 move/copy construct each from moving the tuple\n    # +1 move/copy construct each from moving the optional (which moves the tuple again)\n    assert m.move_optional_tuple((3, 4, 5)) == 12\n\n    assert c_m.copy_assignments + c_m.copy_constructions == 0\n    assert c_m.move_assignments == 2\n    assert c_m.move_constructions == 5\n    assert c_mc.copy_assignments + c_mc.copy_constructions == 0\n    assert c_mc.move_assignments == 2\n    assert c_mc.move_constructions == 5\n    assert c_c.copy_assignments == 2\n    assert c_c.copy_constructions == 5\n    assert c_m.alive() + c_mc.alive() + c_c.alive() == 0\n\n\ndef test_private_op_new():\n    \"\"\"An object with a private `operator new` cannot be returned by value\"\"\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.private_op_new_value()\n    assert \"is neither movable nor copyable\" in str(excinfo.value)\n\n    assert m.private_op_new_reference().value == 1\n\n\ndef test_move_fallback():\n    \"\"\"#389: rvp::move should fall-through to copy on non-movable objects\"\"\"\n\n    m1 = m.get_moveissue1(1)\n    assert m1.value == 1\n    m2 = m.get_moveissue2(2)\n    assert m2.value == 2\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_custom_type_casters.cpp",
    "content": "/*\n    tests/test_custom_type_casters.cpp -- tests type_caster<T>\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n// py::arg/py::arg_v testing: these arguments just record their argument when invoked\nclass ArgInspector1 {\npublic:\n    std::string arg = \"(default arg inspector 1)\";\n};\nclass ArgInspector2 {\npublic:\n    std::string arg = \"(default arg inspector 2)\";\n};\nclass ArgAlwaysConverts {};\n\nnamespace pybind11 {\nnamespace detail {\ntemplate <>\nstruct type_caster<ArgInspector1> {\npublic:\n    // Classic\n#ifdef PYBIND11_DETAIL_UNDERSCORE_BACKWARD_COMPATIBILITY\n    PYBIND11_TYPE_CASTER(ArgInspector1, _(\"ArgInspector1\"));\n#else\n    PYBIND11_TYPE_CASTER(ArgInspector1, const_name(\"ArgInspector1\"));\n#endif\n\n    bool load(handle src, bool convert) {\n        value.arg = \"loading ArgInspector1 argument \" + std::string(convert ? \"WITH\" : \"WITHOUT\")\n                    + \" conversion allowed.  \"\n                      \"Argument value = \"\n                    + (std::string) str(src);\n        return true;\n    }\n\n    static handle cast(const ArgInspector1 &src, return_value_policy, handle) {\n        return str(src.arg).release();\n    }\n};\ntemplate <>\nstruct type_caster<ArgInspector2> {\npublic:\n    PYBIND11_TYPE_CASTER(ArgInspector2, const_name(\"ArgInspector2\"));\n\n    bool load(handle src, bool convert) {\n        value.arg = \"loading ArgInspector2 argument \" + std::string(convert ? \"WITH\" : \"WITHOUT\")\n                    + \" conversion allowed.  \"\n                      \"Argument value = \"\n                    + (std::string) str(src);\n        return true;\n    }\n\n    static handle cast(const ArgInspector2 &src, return_value_policy, handle) {\n        return str(src.arg).release();\n    }\n};\ntemplate <>\nstruct type_caster<ArgAlwaysConverts> {\npublic:\n    PYBIND11_TYPE_CASTER(ArgAlwaysConverts, const_name(\"ArgAlwaysConverts\"));\n\n    bool load(handle, bool convert) { return convert; }\n\n    static handle cast(const ArgAlwaysConverts &, return_value_policy, handle) {\n        return py::none().release();\n    }\n};\n} // namespace detail\n} // namespace pybind11\n\n// test_custom_caster_destruction\nclass DestructionTester {\npublic:\n    DestructionTester() { print_default_created(this); }\n    ~DestructionTester() { print_destroyed(this); }\n    DestructionTester(const DestructionTester &) { print_copy_created(this); }\n    DestructionTester(DestructionTester &&) noexcept { print_move_created(this); }\n    DestructionTester &operator=(const DestructionTester &) {\n        print_copy_assigned(this);\n        return *this;\n    }\n    DestructionTester &operator=(DestructionTester &&) noexcept {\n        print_move_assigned(this);\n        return *this;\n    }\n};\nnamespace pybind11 {\nnamespace detail {\ntemplate <>\nstruct type_caster<DestructionTester> {\n    PYBIND11_TYPE_CASTER(DestructionTester, const_name(\"DestructionTester\"));\n    bool load(handle, bool) { return true; }\n\n    static handle cast(const DestructionTester &, return_value_policy, handle) {\n        return py::bool_(true).release();\n    }\n};\n} // namespace detail\n} // namespace pybind11\n\n// Define type caster outside of `pybind11::detail` and then alias it.\nnamespace other_lib {\nstruct MyType {};\n// Corrupt `py` shorthand alias for surrounding context.\nnamespace py {}\n// Corrupt unqualified relative `pybind11` namespace.\nnamespace pybind11 {}\n// Correct alias.\nnamespace py_ = ::pybind11;\n// Define caster. This is effectively no-op, we only ensure it compiles and we\n// don't have any symbol collision when using macro mixin.\nstruct my_caster {\n    PYBIND11_TYPE_CASTER(MyType, py_::detail::const_name(\"MyType\"));\n    bool load(py_::handle, bool) { return true; }\n\n    static py_::handle cast(const MyType &, py_::return_value_policy, py_::handle) {\n        return py_::bool_(true).release();\n    }\n};\n} // namespace other_lib\n// Effectively \"alias\" it into correct namespace (via inheritance).\nnamespace pybind11 {\nnamespace detail {\ntemplate <>\nstruct type_caster<other_lib::MyType> : public other_lib::my_caster {};\n} // namespace detail\n} // namespace pybind11\n\nTEST_SUBMODULE(custom_type_casters, m) {\n    // test_custom_type_casters\n\n    // test_noconvert_args\n    //\n    // Test converting.  The ArgAlwaysConverts is just there to make the first no-conversion pass\n    // fail so that our call always ends up happening via the second dispatch (the one that allows\n    // some conversion).\n    class ArgInspector {\n    public:\n        ArgInspector1 f(ArgInspector1 a, ArgAlwaysConverts) { return a; }\n        std::string g(const ArgInspector1 &a,\n                      const ArgInspector1 &b,\n                      int c,\n                      ArgInspector2 *d,\n                      ArgAlwaysConverts) {\n            return a.arg + \"\\n\" + b.arg + \"\\n\" + std::to_string(c) + \"\\n\" + d->arg;\n        }\n        static ArgInspector2 h(ArgInspector2 a, ArgAlwaysConverts) { return a; }\n    };\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n    py::class_<ArgInspector>(m, \"ArgInspector\")\n        .def(py::init<>())\n        .def(\"f\", &ArgInspector::f, py::arg(), py::arg() = ArgAlwaysConverts())\n        .def(\"g\",\n             &ArgInspector::g,\n             \"a\"_a.noconvert(),\n             \"b\"_a,\n             \"c\"_a.noconvert() = 13,\n             \"d\"_a = ArgInspector2(),\n             py::arg() = ArgAlwaysConverts())\n        .def_static(\"h\", &ArgInspector::h, py::arg{}.noconvert(), py::arg() = ArgAlwaysConverts());\n    m.def(\n        \"arg_inspect_func\",\n        [](const ArgInspector2 &a, const ArgInspector1 &b, ArgAlwaysConverts) {\n            return a.arg + \"\\n\" + b.arg;\n        },\n        py::arg{}.noconvert(false),\n        py::arg_v(nullptr, ArgInspector1()).noconvert(true),\n        py::arg() = ArgAlwaysConverts());\n\n    m.def(\n        \"floats_preferred\", [](double f) { return 0.5 * f; }, \"f\"_a);\n    m.def(\n        \"floats_only\", [](double f) { return 0.5 * f; }, \"f\"_a.noconvert());\n    m.def(\n        \"ints_preferred\", [](int i) { return i / 2; }, \"i\"_a);\n    m.def(\n        \"ints_only\", [](int i) { return i / 2; }, \"i\"_a.noconvert());\n\n    // test_custom_caster_destruction\n    // Test that `take_ownership` works on types with a custom type caster when given a pointer\n\n    // default policy: don't take ownership:\n    m.def(\"custom_caster_no_destroy\", []() {\n        static auto *dt = new DestructionTester();\n        return dt;\n    });\n\n    m.def(\n        \"custom_caster_destroy\",\n        []() { return new DestructionTester(); },\n        py::return_value_policy::take_ownership); // Takes ownership: destroy when finished\n    m.def(\n        \"custom_caster_destroy_const\",\n        []() -> const DestructionTester * { return new DestructionTester(); },\n        py::return_value_policy::take_ownership); // Likewise (const doesn't inhibit destruction)\n    m.def(\"destruction_tester_cstats\",\n          &ConstructorStats::get<DestructionTester>,\n          py::return_value_policy::reference);\n\n    m.def(\"other_lib_type\", [](other_lib::MyType x) { return x; });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_custom_type_casters.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import custom_type_casters as m\n\n\ndef test_noconvert_args(msg):\n    a = m.ArgInspector()\n    assert (\n        msg(a.f(\"hi\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = hi\n    \"\"\"\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        13\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = (default arg inspector 2)\n    \"\"\"  # noqa: E501 line too long\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\", 42))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        42\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = (default arg inspector 2)\n    \"\"\"  # noqa: E501 line too long\n    )\n    assert (\n        msg(a.g(\"this is a\", \"this is b\", 42, \"this is d\"))\n        == \"\"\"\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = this is a\n        loading ArgInspector1 argument WITH conversion allowed.  Argument value = this is b\n        42\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = this is d\n    \"\"\"\n    )\n    assert (\n        a.h(\"arg 1\")\n        == \"loading ArgInspector2 argument WITHOUT conversion allowed.  Argument value = arg 1\"\n    )\n    assert (\n        msg(m.arg_inspect_func(\"A1\", \"A2\"))\n        == \"\"\"\n        loading ArgInspector2 argument WITH conversion allowed.  Argument value = A1\n        loading ArgInspector1 argument WITHOUT conversion allowed.  Argument value = A2\n    \"\"\"\n    )\n\n    assert m.floats_preferred(4) == 2.0\n    assert m.floats_only(4.0) == 2.0\n    with pytest.raises(TypeError) as excinfo:\n        m.floats_only(4)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        floats_only(): incompatible function arguments. The following argument types are supported:\n            1. (f: float) -> float\n\n        Invoked with: 4\n    \"\"\"\n    )\n\n    assert m.ints_preferred(4) == 2\n    assert m.ints_preferred(True) == 0\n    with pytest.raises(TypeError) as excinfo:\n        m.ints_preferred(4.0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ints_preferred(): incompatible function arguments. The following argument types are supported:\n            1. (i: int) -> int\n\n        Invoked with: 4.0\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    assert m.ints_only(4) == 2\n    with pytest.raises(TypeError) as excinfo:\n        m.ints_only(4.0)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ints_only(): incompatible function arguments. The following argument types are supported:\n            1. (i: int) -> int\n\n        Invoked with: 4.0\n    \"\"\"\n    )\n\n\ndef test_custom_caster_destruction():\n    \"\"\"Tests that returning a pointer to a type that gets converted with a custom type caster gets\n    destroyed when the function has py::return_value_policy::take_ownership policy applied.\"\"\"\n\n    cstats = m.destruction_tester_cstats()\n    # This one *doesn't* have take_ownership: the pointer should be used but not destroyed:\n    z = m.custom_caster_no_destroy()\n    assert cstats.alive() == 1 and cstats.default_constructions == 1\n    assert z\n\n    # take_ownership applied: this constructs a new object, casts it, then destroys it:\n    z = m.custom_caster_destroy()\n    assert z\n    assert cstats.default_constructions == 2\n\n    # Same, but with a const pointer return (which should *not* inhibit destruction):\n    z = m.custom_caster_destroy_const()\n    assert z\n    assert cstats.default_constructions == 3\n\n    # Make sure we still only have the original object (from ..._no_destroy()) alive:\n    assert cstats.alive() == 1\n\n\ndef test_custom_caster_other_lib():\n    assert m.other_lib_type(True)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_custom_type_setup.cpp",
    "content": "/*\n    tests/test_custom_type_setup.cpp -- Tests `pybind11::custom_type_setup`\n\n    Copyright (c) Google LLC\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/pybind11.h>\n\n#include \"pybind11_tests.h\"\n\nnamespace py = pybind11;\n\nnamespace {\n\nstruct OwnsPythonObjects {\n    py::object value = py::none();\n};\n} // namespace\n\nTEST_SUBMODULE(custom_type_setup, m) {\n    py::class_<OwnsPythonObjects> cls(\n        m, \"OwnsPythonObjects\", py::custom_type_setup([](PyHeapTypeObject *heap_type) {\n            auto *type = &heap_type->ht_type;\n            type->tp_flags |= Py_TPFLAGS_HAVE_GC;\n            type->tp_traverse = [](PyObject *self_base, visitproc visit, void *arg) {\n                auto &self = py::cast<OwnsPythonObjects &>(py::handle(self_base));\n                Py_VISIT(self.value.ptr());\n                return 0;\n            };\n            type->tp_clear = [](PyObject *self_base) {\n                auto &self = py::cast<OwnsPythonObjects &>(py::handle(self_base));\n                self.value = py::none();\n                return 0;\n            };\n        }));\n    cls.def(py::init<>());\n    cls.def_readwrite(\"value\", &OwnsPythonObjects::value);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_custom_type_setup.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport gc\nimport weakref\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import custom_type_setup as m\n\n\n@pytest.fixture\ndef gc_tester():\n    \"\"\"Tests that an object is garbage collected.\n\n    Assumes that any unreferenced objects are fully collected after calling\n    `gc.collect()`.  That is true on CPython, but does not appear to reliably\n    hold on PyPy.\n    \"\"\"\n\n    weak_refs = []\n\n    def add_ref(obj):\n        # PyPy does not support `gc.is_tracked`.\n        if hasattr(gc, \"is_tracked\"):\n            assert gc.is_tracked(obj)\n        weak_refs.append(weakref.ref(obj))\n\n    yield add_ref\n\n    gc.collect()\n    for ref in weak_refs:\n        assert ref() is None\n\n\n# PyPy does not seem to reliably garbage collect.\n@pytest.mark.skipif(\"env.PYPY\")\ndef test_self_cycle(gc_tester):\n    obj = m.OwnsPythonObjects()\n    obj.value = obj\n    gc_tester(obj)\n\n\n# PyPy does not seem to reliably garbage collect.\n@pytest.mark.skipif(\"env.PYPY\")\ndef test_indirect_cycle(gc_tester):\n    obj = m.OwnsPythonObjects()\n    obj_list = [obj]\n    obj.value = obj_list\n    gc_tester(obj)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_docstring_options.cpp",
    "content": "/*\n    tests/test_docstring_options.cpp -- generation of docstrings and signatures\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(docstring_options, m) {\n    // test_docstring_options\n    {\n        py::options options;\n        options.disable_function_signatures();\n\n        m.def(\n            \"test_function1\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"));\n        m.def(\n            \"test_function2\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        m.def(\n            \"test_overloaded1\", [](int) {}, py::arg(\"i\"), \"Overload docstring\");\n        m.def(\n            \"test_overloaded1\", [](double) {}, py::arg(\"d\"));\n\n        m.def(\n            \"test_overloaded2\", [](int) {}, py::arg(\"i\"), \"overload docstring 1\");\n        m.def(\n            \"test_overloaded2\", [](double) {}, py::arg(\"d\"), \"overload docstring 2\");\n\n        m.def(\n            \"test_overloaded3\", [](int) {}, py::arg(\"i\"));\n        m.def(\n            \"test_overloaded3\", [](double) {}, py::arg(\"d\"), \"Overload docstr\");\n\n        options.enable_function_signatures();\n\n        m.def(\n            \"test_function3\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"));\n        m.def(\n            \"test_function4\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        options.disable_function_signatures().disable_user_defined_docstrings();\n\n        m.def(\n            \"test_function5\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n        {\n            py::options nested_options;\n            nested_options.enable_user_defined_docstrings();\n            m.def(\n                \"test_function6\",\n                [](int, int) {},\n                py::arg(\"a\"),\n                py::arg(\"b\"),\n                \"A custom docstring\");\n        }\n    }\n\n    m.def(\n        \"test_function7\", [](int, int) {}, py::arg(\"a\"), py::arg(\"b\"), \"A custom docstring\");\n\n    {\n        py::options options;\n        options.disable_user_defined_docstrings();\n        options.disable_function_signatures();\n\n        m.def(\"test_function8\", []() {});\n    }\n\n    {\n        py::options options;\n        options.disable_user_defined_docstrings();\n\n        struct DocstringTestFoo {\n            int value;\n            void setValue(int v) { value = v; }\n            int getValue() const { return value; }\n        };\n        py::class_<DocstringTestFoo>(m, \"DocstringTestFoo\", \"This is a class docstring\")\n            .def_property(\"value_prop\",\n                          &DocstringTestFoo::getValue,\n                          &DocstringTestFoo::setValue,\n                          \"This is a property docstring\");\n    }\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_docstring_options.py",
    "content": "# -*- coding: utf-8 -*-\nfrom pybind11_tests import docstring_options as m\n\n\ndef test_docstring_options():\n    # options.disable_function_signatures()\n    assert not m.test_function1.__doc__\n\n    assert m.test_function2.__doc__ == \"A custom docstring\"\n\n    # docstring specified on just the first overload definition:\n    assert m.test_overloaded1.__doc__ == \"Overload docstring\"\n\n    # docstring on both overloads:\n    assert m.test_overloaded2.__doc__ == \"overload docstring 1\\noverload docstring 2\"\n\n    # docstring on only second overload:\n    assert m.test_overloaded3.__doc__ == \"Overload docstr\"\n\n    # options.enable_function_signatures()\n    assert m.test_function3.__doc__.startswith(\"test_function3(a: int, b: int) -> None\")\n\n    assert m.test_function4.__doc__.startswith(\"test_function4(a: int, b: int) -> None\")\n    assert m.test_function4.__doc__.endswith(\"A custom docstring\\n\")\n\n    # options.disable_function_signatures()\n    # options.disable_user_defined_docstrings()\n    assert not m.test_function5.__doc__\n\n    # nested options.enable_user_defined_docstrings()\n    assert m.test_function6.__doc__ == \"A custom docstring\"\n\n    # RAII destructor\n    assert m.test_function7.__doc__.startswith(\"test_function7(a: int, b: int) -> None\")\n    assert m.test_function7.__doc__.endswith(\"A custom docstring\\n\")\n\n    # when all options are disabled, no docstring (instead of an empty one) should be generated\n    assert m.test_function8.__doc__ is None\n\n    # Suppression of user-defined docstrings for non-function objects\n    assert not m.DocstringTestFoo.__doc__\n    assert not m.DocstringTestFoo.value_prop.__doc__\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_eigen.cpp",
    "content": "/*\n    tests/eigen.cpp -- automatic conversion of Eigen types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/eigen.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#if defined(_MSC_VER)\n#    if _MSC_VER < 1910                 // VS 2015's MSVC\n#        pragma warning(disable : 4127) // C4127: conditional expression is constant\n#    endif\n#    pragma warning(disable : 4996) // C4996: std::unary_negation is deprecated\n#endif\n\n#include <Eigen/Cholesky>\n\nusing MatrixXdR = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;\n\n// Sets/resets a testing reference matrix to have values of 10*r + c, where r and c are the\n// (1-based) row/column number.\ntemplate <typename M>\nvoid reset_ref(M &x) {\n    for (int i = 0; i < x.rows(); i++) {\n        for (int j = 0; j < x.cols(); j++) {\n            x(i, j) = 11 + 10 * i + j;\n        }\n    }\n}\n\n// Returns a static, column-major matrix\nEigen::MatrixXd &get_cm() {\n    static Eigen::MatrixXd *x;\n    if (!x) {\n        x = new Eigen::MatrixXd(3, 3);\n        reset_ref(*x);\n    }\n    return *x;\n}\n// Likewise, but row-major\nMatrixXdR &get_rm() {\n    static MatrixXdR *x;\n    if (!x) {\n        x = new MatrixXdR(3, 3);\n        reset_ref(*x);\n    }\n    return *x;\n}\n// Resets the values of the static matrices returned by get_cm()/get_rm()\nvoid reset_refs() {\n    reset_ref(get_cm());\n    reset_ref(get_rm());\n}\n\n// Returns element 2,1 from a matrix (used to test copy/nocopy)\ndouble get_elem(const Eigen::Ref<const Eigen::MatrixXd> &m) { return m(2, 1); };\n\n// Returns a matrix with 10*r + 100*c added to each matrix element (to help test that the matrix\n// reference is referencing rows/columns correctly).\ntemplate <typename MatrixArgType>\nEigen::MatrixXd adjust_matrix(MatrixArgType m) {\n    Eigen::MatrixXd ret(m);\n    for (int c = 0; c < m.cols(); c++) {\n        for (int r = 0; r < m.rows(); r++) {\n            ret(r, c) += 10 * r + 100 * c; // NOLINT(clang-analyzer-core.uninitialized.Assign)\n        }\n    }\n    return ret;\n}\n\nstruct CustomOperatorNew {\n    CustomOperatorNew() = default;\n\n    Eigen::Matrix4d a = Eigen::Matrix4d::Zero();\n    Eigen::Matrix4d b = Eigen::Matrix4d::Identity();\n\n    EIGEN_MAKE_ALIGNED_OPERATOR_NEW;\n};\n\nTEST_SUBMODULE(eigen, m) {\n    using FixedMatrixR = Eigen::Matrix<float, 5, 6, Eigen::RowMajor>;\n    using FixedMatrixC = Eigen::Matrix<float, 5, 6>;\n    using DenseMatrixR = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;\n    using DenseMatrixC = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic>;\n    using FourRowMatrixC = Eigen::Matrix<float, 4, Eigen::Dynamic>;\n    using FourColMatrixC = Eigen::Matrix<float, Eigen::Dynamic, 4>;\n    using FourRowMatrixR = Eigen::Matrix<float, 4, Eigen::Dynamic>;\n    using FourColMatrixR = Eigen::Matrix<float, Eigen::Dynamic, 4>;\n    using SparseMatrixR = Eigen::SparseMatrix<float, Eigen::RowMajor>;\n    using SparseMatrixC = Eigen::SparseMatrix<float>;\n\n    // various tests\n    m.def(\"double_col\", [](const Eigen::VectorXf &x) -> Eigen::VectorXf { return 2.0f * x; });\n    m.def(\"double_row\",\n          [](const Eigen::RowVectorXf &x) -> Eigen::RowVectorXf { return 2.0f * x; });\n    m.def(\"double_complex\",\n          [](const Eigen::VectorXcf &x) -> Eigen::VectorXcf { return 2.0f * x; });\n    m.def(\"double_threec\", [](py::EigenDRef<Eigen::Vector3f> x) { x *= 2; });\n    m.def(\"double_threer\", [](py::EigenDRef<Eigen::RowVector3f> x) { x *= 2; });\n    m.def(\"double_mat_cm\", [](const Eigen::MatrixXf &x) -> Eigen::MatrixXf { return 2.0f * x; });\n    m.def(\"double_mat_rm\", [](const DenseMatrixR &x) -> DenseMatrixR { return 2.0f * x; });\n\n    // test_eigen_ref_to_python\n    // Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended\n    m.def(\"cholesky1\",\n          [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });\n    m.def(\"cholesky2\", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {\n        return x.llt().matrixL();\n    });\n    m.def(\"cholesky3\",\n          [](const Eigen::Ref<MatrixXdR> &x) -> Eigen::MatrixXd { return x.llt().matrixL(); });\n    m.def(\"cholesky4\", [](const Eigen::Ref<const MatrixXdR> &x) -> Eigen::MatrixXd {\n        return x.llt().matrixL();\n    });\n\n    // test_eigen_ref_mutators\n    // Mutators: these add some value to the given element using Eigen, but Eigen should be mapping\n    // into the numpy array data and so the result should show up there.  There are three versions:\n    // one that works on a contiguous-row matrix (numpy's default), one for a contiguous-column\n    // matrix, and one for any matrix.\n    auto add_rm = [](Eigen::Ref<MatrixXdR> x, int r, int c, double v) { x(r, c) += v; };\n    auto add_cm = [](Eigen::Ref<Eigen::MatrixXd> x, int r, int c, double v) { x(r, c) += v; };\n\n    // Mutators (Eigen maps into numpy variables):\n    m.def(\"add_rm\", add_rm); // Only takes row-contiguous\n    m.def(\"add_cm\", add_cm); // Only takes column-contiguous\n    // Overloaded versions that will accept either row or column contiguous:\n    m.def(\"add1\", add_rm);\n    m.def(\"add1\", add_cm);\n    m.def(\"add2\", add_cm);\n    m.def(\"add2\", add_rm);\n    // This one accepts a matrix of any stride:\n    m.def(\"add_any\",\n          [](py::EigenDRef<Eigen::MatrixXd> x, int r, int c, double v) { x(r, c) += v; });\n\n    // Return mutable references (numpy maps into eigen variables)\n    m.def(\"get_cm_ref\", []() { return Eigen::Ref<Eigen::MatrixXd>(get_cm()); });\n    m.def(\"get_rm_ref\", []() { return Eigen::Ref<MatrixXdR>(get_rm()); });\n    // The same references, but non-mutable (numpy maps into eigen variables, but is !writeable)\n    m.def(\"get_cm_const_ref\", []() { return Eigen::Ref<const Eigen::MatrixXd>(get_cm()); });\n    m.def(\"get_rm_const_ref\", []() { return Eigen::Ref<const MatrixXdR>(get_rm()); });\n\n    m.def(\"reset_refs\", reset_refs); // Restores get_{cm,rm}_ref to original values\n\n    // Increments and returns ref to (same) matrix\n    m.def(\n        \"incr_matrix\",\n        [](Eigen::Ref<Eigen::MatrixXd> m, double v) {\n            m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);\n            return m;\n        },\n        py::return_value_policy::reference);\n\n    // Same, but accepts a matrix of any strides\n    m.def(\n        \"incr_matrix_any\",\n        [](py::EigenDRef<Eigen::MatrixXd> m, double v) {\n            m += Eigen::MatrixXd::Constant(m.rows(), m.cols(), v);\n            return m;\n        },\n        py::return_value_policy::reference);\n\n    // Returns an eigen slice of even rows\n    m.def(\n        \"even_rows\",\n        [](py::EigenDRef<Eigen::MatrixXd> m) {\n            return py::EigenDMap<Eigen::MatrixXd>(\n                m.data(),\n                (m.rows() + 1) / 2,\n                m.cols(),\n                py::EigenDStride(m.outerStride(), 2 * m.innerStride()));\n        },\n        py::return_value_policy::reference);\n\n    // Returns an eigen slice of even columns\n    m.def(\n        \"even_cols\",\n        [](py::EigenDRef<Eigen::MatrixXd> m) {\n            return py::EigenDMap<Eigen::MatrixXd>(\n                m.data(),\n                m.rows(),\n                (m.cols() + 1) / 2,\n                py::EigenDStride(2 * m.outerStride(), m.innerStride()));\n        },\n        py::return_value_policy::reference);\n\n    // Returns diagonals: a vector-like object with an inner stride != 1\n    m.def(\"diagonal\", [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal(); });\n    m.def(\"diagonal_1\",\n          [](const Eigen::Ref<const Eigen::MatrixXd> &x) { return x.diagonal<1>(); });\n    m.def(\"diagonal_n\",\n          [](const Eigen::Ref<const Eigen::MatrixXd> &x, int index) { return x.diagonal(index); });\n\n    // Return a block of a matrix (gives non-standard strides)\n    m.def(\"block\",\n          [](const Eigen::Ref<const Eigen::MatrixXd> &x,\n             int start_row,\n             int start_col,\n             int block_rows,\n             int block_cols) { return x.block(start_row, start_col, block_rows, block_cols); });\n\n    // test_eigen_return_references, test_eigen_keepalive\n    // return value referencing/copying tests:\n    class ReturnTester {\n        Eigen::MatrixXd mat = create();\n\n    public:\n        ReturnTester() { print_created(this); }\n        ~ReturnTester() { print_destroyed(this); }\n        static Eigen::MatrixXd create() { return Eigen::MatrixXd::Ones(10, 10); }\n        // NOLINTNEXTLINE(readability-const-return-type)\n        static const Eigen::MatrixXd createConst() { return Eigen::MatrixXd::Ones(10, 10); }\n        Eigen::MatrixXd &get() { return mat; }\n        Eigen::MatrixXd *getPtr() { return &mat; }\n        const Eigen::MatrixXd &view() { return mat; }\n        const Eigen::MatrixXd *viewPtr() { return &mat; }\n        Eigen::Ref<Eigen::MatrixXd> ref() { return mat; }\n        Eigen::Ref<const Eigen::MatrixXd> refConst() { return mat; }\n        Eigen::Block<Eigen::MatrixXd> block(int r, int c, int nrow, int ncol) {\n            return mat.block(r, c, nrow, ncol);\n        }\n        Eigen::Block<const Eigen::MatrixXd> blockConst(int r, int c, int nrow, int ncol) const {\n            return mat.block(r, c, nrow, ncol);\n        }\n        py::EigenDMap<Eigen::Matrix2d> corners() {\n            return py::EigenDMap<Eigen::Matrix2d>(\n                mat.data(),\n                py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),\n                                 mat.innerStride() * (mat.innerSize() - 1)));\n        }\n        py::EigenDMap<const Eigen::Matrix2d> cornersConst() const {\n            return py::EigenDMap<const Eigen::Matrix2d>(\n                mat.data(),\n                py::EigenDStride(mat.outerStride() * (mat.outerSize() - 1),\n                                 mat.innerStride() * (mat.innerSize() - 1)));\n        }\n    };\n    using rvp = py::return_value_policy;\n    py::class_<ReturnTester>(m, \"ReturnTester\")\n        .def(py::init<>())\n        .def_static(\"create\", &ReturnTester::create)\n        .def_static(\"create_const\", &ReturnTester::createConst)\n        .def(\"get\", &ReturnTester::get, rvp::reference_internal)\n        .def(\"get_ptr\", &ReturnTester::getPtr, rvp::reference_internal)\n        .def(\"view\", &ReturnTester::view, rvp::reference_internal)\n        .def(\"view_ptr\", &ReturnTester::view, rvp::reference_internal)\n        .def(\"copy_get\", &ReturnTester::get)       // Default rvp: copy\n        .def(\"copy_view\", &ReturnTester::view)     //         \"\n        .def(\"ref\", &ReturnTester::ref)            // Default for Ref is to reference\n        .def(\"ref_const\", &ReturnTester::refConst) // Likewise, but const\n        .def(\"ref_safe\", &ReturnTester::ref, rvp::reference_internal)\n        .def(\"ref_const_safe\", &ReturnTester::refConst, rvp::reference_internal)\n        .def(\"copy_ref\", &ReturnTester::ref, rvp::copy)\n        .def(\"copy_ref_const\", &ReturnTester::refConst, rvp::copy)\n        .def(\"block\", &ReturnTester::block)\n        .def(\"block_safe\", &ReturnTester::block, rvp::reference_internal)\n        .def(\"block_const\", &ReturnTester::blockConst, rvp::reference_internal)\n        .def(\"copy_block\", &ReturnTester::block, rvp::copy)\n        .def(\"corners\", &ReturnTester::corners, rvp::reference_internal)\n        .def(\"corners_const\", &ReturnTester::cornersConst, rvp::reference_internal);\n\n    // test_special_matrix_objects\n    // Returns a DiagonalMatrix with diagonal (1,2,3,...)\n    m.def(\"incr_diag\", [](int k) {\n        Eigen::DiagonalMatrix<int, Eigen::Dynamic> m(k);\n        for (int i = 0; i < k; i++) {\n            m.diagonal()[i] = i + 1;\n        }\n        return m;\n    });\n\n    // Returns a SelfAdjointView referencing the lower triangle of m\n    m.def(\"symmetric_lower\",\n          [](const Eigen::MatrixXi &m) { return m.selfadjointView<Eigen::Lower>(); });\n    // Returns a SelfAdjointView referencing the lower triangle of m\n    m.def(\"symmetric_upper\",\n          [](const Eigen::MatrixXi &m) { return m.selfadjointView<Eigen::Upper>(); });\n\n    // Test matrix for various functions below.\n    Eigen::MatrixXf mat(5, 6);\n    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,\n        0, 8, 11;\n\n    // test_fixed, and various other tests\n    m.def(\"fixed_r\", [mat]() -> FixedMatrixR { return FixedMatrixR(mat); });\n    // Our Eigen does a hack which respects constness through the numpy writeable flag.\n    // Therefore, the const return actually affects this type despite being an rvalue.\n    // NOLINTNEXTLINE(readability-const-return-type)\n    m.def(\"fixed_r_const\", [mat]() -> const FixedMatrixR { return FixedMatrixR(mat); });\n    m.def(\"fixed_c\", [mat]() -> FixedMatrixC { return FixedMatrixC(mat); });\n    m.def(\"fixed_copy_r\", [](const FixedMatrixR &m) -> FixedMatrixR { return m; });\n    m.def(\"fixed_copy_c\", [](const FixedMatrixC &m) -> FixedMatrixC { return m; });\n    // test_mutator_descriptors\n    m.def(\"fixed_mutator_r\", [](const Eigen::Ref<FixedMatrixR> &) {});\n    m.def(\"fixed_mutator_c\", [](const Eigen::Ref<FixedMatrixC> &) {});\n    m.def(\"fixed_mutator_a\", [](const py::EigenDRef<FixedMatrixC> &) {});\n    // test_dense\n    m.def(\"dense_r\", [mat]() -> DenseMatrixR { return DenseMatrixR(mat); });\n    m.def(\"dense_c\", [mat]() -> DenseMatrixC { return DenseMatrixC(mat); });\n    m.def(\"dense_copy_r\", [](const DenseMatrixR &m) -> DenseMatrixR { return m; });\n    m.def(\"dense_copy_c\", [](const DenseMatrixC &m) -> DenseMatrixC { return m; });\n    // test_sparse, test_sparse_signature\n    m.def(\"sparse_r\", [mat]() -> SparseMatrixR {\n        // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)\n        return Eigen::SparseView<Eigen::MatrixXf>(mat);\n    });\n    m.def(\"sparse_c\",\n          [mat]() -> SparseMatrixC { return Eigen::SparseView<Eigen::MatrixXf>(mat); });\n    m.def(\"sparse_copy_r\", [](const SparseMatrixR &m) -> SparseMatrixR { return m; });\n    m.def(\"sparse_copy_c\", [](const SparseMatrixC &m) -> SparseMatrixC { return m; });\n    // test_partially_fixed\n    m.def(\"partial_copy_four_rm_r\", [](const FourRowMatrixR &m) -> FourRowMatrixR { return m; });\n    m.def(\"partial_copy_four_rm_c\", [](const FourColMatrixR &m) -> FourColMatrixR { return m; });\n    m.def(\"partial_copy_four_cm_r\", [](const FourRowMatrixC &m) -> FourRowMatrixC { return m; });\n    m.def(\"partial_copy_four_cm_c\", [](const FourColMatrixC &m) -> FourColMatrixC { return m; });\n\n    // test_cpp_casting\n    // Test that we can cast a numpy object to a Eigen::MatrixXd explicitly\n    m.def(\"cpp_copy\", [](py::handle m) { return m.cast<Eigen::MatrixXd>()(1, 0); });\n    m.def(\"cpp_ref_c\", [](py::handle m) { return m.cast<Eigen::Ref<Eigen::MatrixXd>>()(1, 0); });\n    m.def(\"cpp_ref_r\", [](py::handle m) { return m.cast<Eigen::Ref<MatrixXdR>>()(1, 0); });\n    m.def(\"cpp_ref_any\",\n          [](py::handle m) { return m.cast<py::EigenDRef<Eigen::MatrixXd>>()(1, 0); });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_nocopy_wrapper\n    // Test that we can prevent copying into an argument that would normally copy: First a version\n    // that would allow copying (if types or strides don't match) for comparison:\n    m.def(\"get_elem\", &get_elem);\n    // Now this alternative that calls the tells pybind to fail rather than copy:\n    m.def(\n        \"get_elem_nocopy\",\n        [](const Eigen::Ref<const Eigen::MatrixXd> &m) -> double { return get_elem(m); },\n        py::arg{}.noconvert());\n    // Also test a row-major-only no-copy const ref:\n    m.def(\n        \"get_elem_rm_nocopy\",\n        [](Eigen::Ref<const Eigen::Matrix<long, -1, -1, Eigen::RowMajor>> &m) -> long {\n            return m(2, 1);\n        },\n        py::arg{}.noconvert());\n\n    // test_issue738\n    // Issue #738: 1xN or Nx1 2D matrices were neither accepted nor properly copied with an\n    // incompatible stride value on the length-1 dimension--but that should be allowed (without\n    // requiring a copy!) because the stride value can be safely ignored on a size-1 dimension.\n    m.def(\"iss738_f1\",\n          &adjust_matrix<const Eigen::Ref<const Eigen::MatrixXd> &>,\n          py::arg{}.noconvert());\n    m.def(\"iss738_f2\",\n          &adjust_matrix<const Eigen::Ref<const Eigen::Matrix<double, -1, -1, Eigen::RowMajor>> &>,\n          py::arg{}.noconvert());\n\n    // test_issue1105\n    // Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense\n    // eigen Vector or RowVector, the argument would fail to load because the numpy copy would\n    // fail: numpy won't broadcast a Nx1 into a 1-dimensional vector.\n    m.def(\"iss1105_col\", [](const Eigen::VectorXd &) { return true; });\n    m.def(\"iss1105_row\", [](const Eigen::RowVectorXd &) { return true; });\n\n    // test_named_arguments\n    // Make sure named arguments are working properly:\n    m.def(\n        \"matrix_multiply\",\n        [](const py::EigenDRef<const Eigen::MatrixXd> &A,\n           const py::EigenDRef<const Eigen::MatrixXd> &B) -> Eigen::MatrixXd {\n            if (A.cols() != B.rows()) {\n                throw std::domain_error(\"Nonconformable matrices!\");\n            }\n            return A * B;\n        },\n        py::arg(\"A\"),\n        py::arg(\"B\"));\n\n    // test_custom_operator_new\n    py::class_<CustomOperatorNew>(m, \"CustomOperatorNew\")\n        .def(py::init<>())\n        .def_readonly(\"a\", &CustomOperatorNew::a)\n        .def_readonly(\"b\", &CustomOperatorNew::b);\n\n    // test_eigen_ref_life_support\n    // In case of a failure (the caster's temp array does not live long enough), creating\n    // a new array (np.ones(10)) increases the chances that the temp array will be garbage\n    // collected and/or that its memory will be overridden with different values.\n    m.def(\"get_elem_direct\", [](const Eigen::Ref<const Eigen::VectorXd> &v) {\n        py::module_::import(\"numpy\").attr(\"ones\")(10);\n        return v(5);\n    });\n    m.def(\"get_elem_indirect\", [](std::vector<Eigen::Ref<const Eigen::VectorXd>> v) {\n        py::module_::import(\"numpy\").attr(\"ones\")(10);\n        return v[0](5);\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_eigen.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import ConstructorStats\n\nnp = pytest.importorskip(\"numpy\")\nm = pytest.importorskip(\"pybind11_tests.eigen\")\n\n\nref = np.array(\n    [\n        [0.0, 3, 0, 0, 0, 11],\n        [22, 0, 0, 0, 17, 11],\n        [7, 5, 0, 1, 0, 11],\n        [0, 0, 0, 0, 0, 11],\n        [0, 0, 14, 0, 8, 11],\n    ]\n)\n\n\ndef assert_equal_ref(mat):\n    np.testing.assert_array_equal(mat, ref)\n\n\ndef assert_sparse_equal_ref(sparse_mat):\n    assert_equal_ref(sparse_mat.toarray())\n\n\ndef test_fixed():\n    assert_equal_ref(m.fixed_c())\n    assert_equal_ref(m.fixed_r())\n    assert_equal_ref(m.fixed_copy_r(m.fixed_r()))\n    assert_equal_ref(m.fixed_copy_c(m.fixed_c()))\n    assert_equal_ref(m.fixed_copy_r(m.fixed_c()))\n    assert_equal_ref(m.fixed_copy_c(m.fixed_r()))\n\n\ndef test_dense():\n    assert_equal_ref(m.dense_r())\n    assert_equal_ref(m.dense_c())\n    assert_equal_ref(m.dense_copy_r(m.dense_r()))\n    assert_equal_ref(m.dense_copy_c(m.dense_c()))\n    assert_equal_ref(m.dense_copy_r(m.dense_c()))\n    assert_equal_ref(m.dense_copy_c(m.dense_r()))\n\n\ndef test_partially_fixed():\n    ref2 = np.array([[0.0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]])\n    np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_rm_r(ref2[:, 1]), ref2[:, [1]])\n    np.testing.assert_array_equal(m.partial_copy_four_rm_c(ref2[0, :]), ref2[[0], :])\n    np.testing.assert_array_equal(\n        m.partial_copy_four_rm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]\n    )\n    np.testing.assert_array_equal(\n        m.partial_copy_four_rm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]\n    )\n\n    np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2), ref2)\n    np.testing.assert_array_equal(m.partial_copy_four_cm_r(ref2[:, 1]), ref2[:, [1]])\n    np.testing.assert_array_equal(m.partial_copy_four_cm_c(ref2[0, :]), ref2[[0], :])\n    np.testing.assert_array_equal(\n        m.partial_copy_four_cm_r(ref2[:, (0, 2)]), ref2[:, (0, 2)]\n    )\n    np.testing.assert_array_equal(\n        m.partial_copy_four_cm_c(ref2[(3, 1, 2), :]), ref2[(3, 1, 2), :]\n    )\n\n    # TypeError should be raise for a shape mismatch\n    functions = [\n        m.partial_copy_four_rm_r,\n        m.partial_copy_four_rm_c,\n        m.partial_copy_four_cm_r,\n        m.partial_copy_four_cm_c,\n    ]\n    matrix_with_wrong_shape = [[1, 2], [3, 4]]\n    for f in functions:\n        with pytest.raises(TypeError) as excinfo:\n            f(matrix_with_wrong_shape)\n        assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_mutator_descriptors():\n    zr = np.arange(30, dtype=\"float32\").reshape(5, 6)  # row-major\n    zc = zr.reshape(6, 5).transpose()  # column-major\n\n    m.fixed_mutator_r(zr)\n    m.fixed_mutator_c(zc)\n    m.fixed_mutator_a(zr)\n    m.fixed_mutator_a(zc)\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_r(zc)\n    assert (\n        \"(arg0: numpy.ndarray[numpy.float32[5, 6],\"\n        \" flags.writeable, flags.c_contiguous]) -> None\" in str(excinfo.value)\n    )\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_c(zr)\n    assert (\n        \"(arg0: numpy.ndarray[numpy.float32[5, 6],\"\n        \" flags.writeable, flags.f_contiguous]) -> None\" in str(excinfo.value)\n    )\n    with pytest.raises(TypeError) as excinfo:\n        m.fixed_mutator_a(np.array([[1, 2], [3, 4]], dtype=\"float32\"))\n    assert \"(arg0: numpy.ndarray[numpy.float32[5, 6], flags.writeable]) -> None\" in str(\n        excinfo.value\n    )\n    zr.flags.writeable = False\n    with pytest.raises(TypeError):\n        m.fixed_mutator_r(zr)\n    with pytest.raises(TypeError):\n        m.fixed_mutator_a(zr)\n\n\ndef test_cpp_casting():\n    assert m.cpp_copy(m.fixed_r()) == 22.0\n    assert m.cpp_copy(m.fixed_c()) == 22.0\n    z = np.array([[5.0, 6], [7, 8]])\n    assert m.cpp_copy(z) == 7.0\n    assert m.cpp_copy(m.get_cm_ref()) == 21.0\n    assert m.cpp_copy(m.get_rm_ref()) == 21.0\n    assert m.cpp_ref_c(m.get_cm_ref()) == 21.0\n    assert m.cpp_ref_r(m.get_rm_ref()) == 21.0\n    with pytest.raises(RuntimeError) as excinfo:\n        # Can't reference m.fixed_c: it contains floats, m.cpp_ref_any wants doubles\n        m.cpp_ref_any(m.fixed_c())\n    assert \"Unable to cast Python instance\" in str(excinfo.value)\n    with pytest.raises(RuntimeError) as excinfo:\n        # Can't reference m.fixed_r: it contains floats, m.cpp_ref_any wants doubles\n        m.cpp_ref_any(m.fixed_r())\n    assert \"Unable to cast Python instance\" in str(excinfo.value)\n    assert m.cpp_ref_any(m.ReturnTester.create()) == 1.0\n\n    assert m.cpp_ref_any(m.get_cm_ref()) == 21.0\n    assert m.cpp_ref_any(m.get_cm_ref()) == 21.0\n\n\ndef test_pass_readonly_array():\n    z = np.full((5, 6), 42.0)\n    z.flags.writeable = False\n    np.testing.assert_array_equal(z, m.fixed_copy_r(z))\n    np.testing.assert_array_equal(m.fixed_r_const(), m.fixed_r())\n    assert not m.fixed_r_const().flags.writeable\n    np.testing.assert_array_equal(m.fixed_copy_r(m.fixed_r_const()), m.fixed_r_const())\n\n\ndef test_nonunit_stride_from_python():\n    counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))\n    second_row = counting_mat[1, :]\n    second_col = counting_mat[:, 1]\n    np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)\n\n    counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))\n    slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]\n    for ref_mat in slices:\n        np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)\n        np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)\n\n    # Mutator:\n    m.double_threer(second_row)\n    m.double_threec(second_col)\n    np.testing.assert_array_equal(counting_mat, [[0.0, 2, 2], [6, 16, 10], [6, 14, 8]])\n\n\ndef test_negative_stride_from_python(msg):\n    \"\"\"Eigen doesn't support (as of yet) negative strides. When a function takes an Eigen matrix by\n    copy or const reference, we can pass a numpy array that has negative strides.  Otherwise, an\n    exception will be thrown as Eigen will not be able to map the numpy array.\"\"\"\n\n    counting_mat = np.arange(9.0, dtype=np.float32).reshape((3, 3))\n    counting_mat = counting_mat[::-1, ::-1]\n    second_row = counting_mat[1, :]\n    second_col = counting_mat[:, 1]\n    np.testing.assert_array_equal(m.double_row(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_col(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_complex(second_row), 2.0 * second_row)\n    np.testing.assert_array_equal(m.double_row(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_col(second_col), 2.0 * second_col)\n    np.testing.assert_array_equal(m.double_complex(second_col), 2.0 * second_col)\n\n    counting_3d = np.arange(27.0, dtype=np.float32).reshape((3, 3, 3))\n    counting_3d = counting_3d[::-1, ::-1, ::-1]\n    slices = [counting_3d[0, :, :], counting_3d[:, 0, :], counting_3d[:, :, 0]]\n    for ref_mat in slices:\n        np.testing.assert_array_equal(m.double_mat_cm(ref_mat), 2.0 * ref_mat)\n        np.testing.assert_array_equal(m.double_mat_rm(ref_mat), 2.0 * ref_mat)\n\n    # Mutator:\n    with pytest.raises(TypeError) as excinfo:\n        m.double_threer(second_row)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        double_threer(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float32[1, 3], flags.writeable]) -> None\n\n        Invoked with: \"\"\"  # noqa: E501 line too long\n        + repr(np.array([5.0, 4.0, 3.0], dtype=\"float32\"))\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.double_threec(second_col)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        double_threec(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float32[3, 1], flags.writeable]) -> None\n\n        Invoked with: \"\"\"  # noqa: E501 line too long\n        + repr(np.array([7.0, 4.0, 1.0], dtype=\"float32\"))\n    )\n\n\ndef test_nonunit_stride_to_python():\n    assert np.all(m.diagonal(ref) == ref.diagonal())\n    assert np.all(m.diagonal_1(ref) == ref.diagonal(1))\n    for i in range(-5, 7):\n        assert np.all(\n            m.diagonal_n(ref, i) == ref.diagonal(i)\n        ), \"m.diagonal_n({})\".format(i)\n\n    assert np.all(m.block(ref, 2, 1, 3, 3) == ref[2:5, 1:4])\n    assert np.all(m.block(ref, 1, 4, 4, 2) == ref[1:, 4:])\n    assert np.all(m.block(ref, 1, 4, 3, 2) == ref[1:4, 4:])\n\n\ndef test_eigen_ref_to_python():\n    chols = [m.cholesky1, m.cholesky2, m.cholesky3, m.cholesky4]\n    for i, chol in enumerate(chols, start=1):\n        mymat = chol(np.array([[1.0, 2, 4], [2, 13, 23], [4, 23, 77]]))\n        assert np.all(\n            mymat == np.array([[1, 0, 0], [2, 3, 0], [4, 5, 6]])\n        ), \"cholesky{}\".format(i)\n\n\ndef assign_both(a1, a2, r, c, v):\n    a1[r, c] = v\n    a2[r, c] = v\n\n\ndef array_copy_but_one(a, r, c, v):\n    z = np.array(a, copy=True)\n    z[r, c] = v\n    return z\n\n\ndef test_eigen_return_references():\n    \"\"\"Tests various ways of returning references and non-referencing copies\"\"\"\n\n    master = np.ones((10, 10))\n    a = m.ReturnTester()\n    a_get1 = a.get()\n    assert not a_get1.flags.owndata and a_get1.flags.writeable\n    assign_both(a_get1, master, 3, 3, 5)\n    a_get2 = a.get_ptr()\n    assert not a_get2.flags.owndata and a_get2.flags.writeable\n    assign_both(a_get1, master, 2, 3, 6)\n\n    a_view1 = a.view()\n    assert not a_view1.flags.owndata and not a_view1.flags.writeable\n    with pytest.raises(ValueError):\n        a_view1[2, 3] = 4\n    a_view2 = a.view_ptr()\n    assert not a_view2.flags.owndata and not a_view2.flags.writeable\n    with pytest.raises(ValueError):\n        a_view2[2, 3] = 4\n\n    a_copy1 = a.copy_get()\n    assert a_copy1.flags.owndata and a_copy1.flags.writeable\n    np.testing.assert_array_equal(a_copy1, master)\n    a_copy1[7, 7] = -44  # Shouldn't affect anything else\n    c1want = array_copy_but_one(master, 7, 7, -44)\n    a_copy2 = a.copy_view()\n    assert a_copy2.flags.owndata and a_copy2.flags.writeable\n    np.testing.assert_array_equal(a_copy2, master)\n    a_copy2[4, 4] = -22  # Shouldn't affect anything else\n    c2want = array_copy_but_one(master, 4, 4, -22)\n\n    a_ref1 = a.ref()\n    assert not a_ref1.flags.owndata and a_ref1.flags.writeable\n    assign_both(a_ref1, master, 1, 1, 15)\n    a_ref2 = a.ref_const()\n    assert not a_ref2.flags.owndata and not a_ref2.flags.writeable\n    with pytest.raises(ValueError):\n        a_ref2[5, 5] = 33\n    a_ref3 = a.ref_safe()\n    assert not a_ref3.flags.owndata and a_ref3.flags.writeable\n    assign_both(a_ref3, master, 0, 7, 99)\n    a_ref4 = a.ref_const_safe()\n    assert not a_ref4.flags.owndata and not a_ref4.flags.writeable\n    with pytest.raises(ValueError):\n        a_ref4[7, 0] = 987654321\n\n    a_copy3 = a.copy_ref()\n    assert a_copy3.flags.owndata and a_copy3.flags.writeable\n    np.testing.assert_array_equal(a_copy3, master)\n    a_copy3[8, 1] = 11\n    c3want = array_copy_but_one(master, 8, 1, 11)\n    a_copy4 = a.copy_ref_const()\n    assert a_copy4.flags.owndata and a_copy4.flags.writeable\n    np.testing.assert_array_equal(a_copy4, master)\n    a_copy4[8, 4] = 88\n    c4want = array_copy_but_one(master, 8, 4, 88)\n\n    a_block1 = a.block(3, 3, 2, 2)\n    assert not a_block1.flags.owndata and a_block1.flags.writeable\n    a_block1[0, 0] = 55\n    master[3, 3] = 55\n    a_block2 = a.block_safe(2, 2, 3, 2)\n    assert not a_block2.flags.owndata and a_block2.flags.writeable\n    a_block2[2, 1] = -123\n    master[4, 3] = -123\n    a_block3 = a.block_const(6, 7, 4, 3)\n    assert not a_block3.flags.owndata and not a_block3.flags.writeable\n    with pytest.raises(ValueError):\n        a_block3[2, 2] = -44444\n\n    a_copy5 = a.copy_block(2, 2, 2, 3)\n    assert a_copy5.flags.owndata and a_copy5.flags.writeable\n    np.testing.assert_array_equal(a_copy5, master[2:4, 2:5])\n    a_copy5[1, 1] = 777\n    c5want = array_copy_but_one(master[2:4, 2:5], 1, 1, 777)\n\n    a_corn1 = a.corners()\n    assert not a_corn1.flags.owndata and a_corn1.flags.writeable\n    a_corn1 *= 50\n    a_corn1[1, 1] = 999\n    master[0, 0] = 50\n    master[0, 9] = 50\n    master[9, 0] = 50\n    master[9, 9] = 999\n    a_corn2 = a.corners_const()\n    assert not a_corn2.flags.owndata and not a_corn2.flags.writeable\n    with pytest.raises(ValueError):\n        a_corn2[1, 0] = 51\n\n    # All of the changes made all the way along should be visible everywhere\n    # now (except for the copies, of course)\n    np.testing.assert_array_equal(a_get1, master)\n    np.testing.assert_array_equal(a_get2, master)\n    np.testing.assert_array_equal(a_view1, master)\n    np.testing.assert_array_equal(a_view2, master)\n    np.testing.assert_array_equal(a_ref1, master)\n    np.testing.assert_array_equal(a_ref2, master)\n    np.testing.assert_array_equal(a_ref3, master)\n    np.testing.assert_array_equal(a_ref4, master)\n    np.testing.assert_array_equal(a_block1, master[3:5, 3:5])\n    np.testing.assert_array_equal(a_block2, master[2:5, 2:4])\n    np.testing.assert_array_equal(a_block3, master[6:10, 7:10])\n    np.testing.assert_array_equal(\n        a_corn1, master[0 :: master.shape[0] - 1, 0 :: master.shape[1] - 1]\n    )\n    np.testing.assert_array_equal(\n        a_corn2, master[0 :: master.shape[0] - 1, 0 :: master.shape[1] - 1]\n    )\n\n    np.testing.assert_array_equal(a_copy1, c1want)\n    np.testing.assert_array_equal(a_copy2, c2want)\n    np.testing.assert_array_equal(a_copy3, c3want)\n    np.testing.assert_array_equal(a_copy4, c4want)\n    np.testing.assert_array_equal(a_copy5, c5want)\n\n\ndef assert_keeps_alive(cl, method, *args):\n    cstats = ConstructorStats.get(cl)\n    start_with = cstats.alive()\n    a = cl()\n    assert cstats.alive() == start_with + 1\n    z = method(a, *args)\n    assert cstats.alive() == start_with + 1\n    del a\n    # Here's the keep alive in action:\n    assert cstats.alive() == start_with + 1\n    del z\n    # Keep alive should have expired:\n    assert cstats.alive() == start_with\n\n\ndef test_eigen_keepalive():\n    a = m.ReturnTester()\n    cstats = ConstructorStats.get(m.ReturnTester)\n    assert cstats.alive() == 1\n    unsafe = [a.ref(), a.ref_const(), a.block(1, 2, 3, 4)]\n    copies = [\n        a.copy_get(),\n        a.copy_view(),\n        a.copy_ref(),\n        a.copy_ref_const(),\n        a.copy_block(4, 3, 2, 1),\n    ]\n    del a\n    assert cstats.alive() == 0\n    del unsafe\n    del copies\n\n    for meth in [\n        m.ReturnTester.get,\n        m.ReturnTester.get_ptr,\n        m.ReturnTester.view,\n        m.ReturnTester.view_ptr,\n        m.ReturnTester.ref_safe,\n        m.ReturnTester.ref_const_safe,\n        m.ReturnTester.corners,\n        m.ReturnTester.corners_const,\n    ]:\n        assert_keeps_alive(m.ReturnTester, meth)\n\n    for meth in [m.ReturnTester.block_safe, m.ReturnTester.block_const]:\n        assert_keeps_alive(m.ReturnTester, meth, 4, 3, 2, 1)\n\n\ndef test_eigen_ref_mutators():\n    \"\"\"Tests Eigen's ability to mutate numpy values\"\"\"\n\n    orig = np.array([[1.0, 2, 3], [4, 5, 6], [7, 8, 9]])\n    zr = np.array(orig)\n    zc = np.array(orig, order=\"F\")\n    m.add_rm(zr, 1, 0, 100)\n    assert np.all(zr == np.array([[1.0, 2, 3], [104, 5, 6], [7, 8, 9]]))\n    m.add_cm(zc, 1, 0, 200)\n    assert np.all(zc == np.array([[1.0, 2, 3], [204, 5, 6], [7, 8, 9]]))\n\n    m.add_any(zr, 1, 0, 20)\n    assert np.all(zr == np.array([[1.0, 2, 3], [124, 5, 6], [7, 8, 9]]))\n    m.add_any(zc, 1, 0, 10)\n    assert np.all(zc == np.array([[1.0, 2, 3], [214, 5, 6], [7, 8, 9]]))\n\n    # Can't reference a col-major array with a row-major Ref, and vice versa:\n    with pytest.raises(TypeError):\n        m.add_rm(zc, 1, 0, 1)\n    with pytest.raises(TypeError):\n        m.add_cm(zr, 1, 0, 1)\n\n    # Overloads:\n    m.add1(zr, 1, 0, -100)\n    m.add2(zr, 1, 0, -20)\n    assert np.all(zr == orig)\n    m.add1(zc, 1, 0, -200)\n    m.add2(zc, 1, 0, -10)\n    assert np.all(zc == orig)\n\n    # a non-contiguous slice (this won't work on either the row- or\n    # column-contiguous refs, but should work for the any)\n    cornersr = zr[0::2, 0::2]\n    cornersc = zc[0::2, 0::2]\n\n    assert np.all(cornersr == np.array([[1.0, 3], [7, 9]]))\n    assert np.all(cornersc == np.array([[1.0, 3], [7, 9]]))\n\n    with pytest.raises(TypeError):\n        m.add_rm(cornersr, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_cm(cornersr, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_rm(cornersc, 0, 1, 25)\n    with pytest.raises(TypeError):\n        m.add_cm(cornersc, 0, 1, 25)\n    m.add_any(cornersr, 0, 1, 25)\n    m.add_any(cornersc, 0, 1, 44)\n    assert np.all(zr == np.array([[1.0, 2, 28], [4, 5, 6], [7, 8, 9]]))\n    assert np.all(zc == np.array([[1.0, 2, 47], [4, 5, 6], [7, 8, 9]]))\n\n    # You shouldn't be allowed to pass a non-writeable array to a mutating Eigen method:\n    zro = zr[0:4, 0:4]\n    zro.flags.writeable = False\n    with pytest.raises(TypeError):\n        m.add_rm(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add_any(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add1(zro, 0, 0, 0)\n    with pytest.raises(TypeError):\n        m.add2(zro, 0, 0, 0)\n\n    # integer array shouldn't be passable to a double-matrix-accepting mutating func:\n    zi = np.array([[1, 2], [3, 4]])\n    with pytest.raises(TypeError):\n        m.add_rm(zi)\n\n\ndef test_numpy_ref_mutators():\n    \"\"\"Tests numpy mutating Eigen matrices (for returned Eigen::Ref<...>s)\"\"\"\n\n    m.reset_refs()  # In case another test already changed it\n\n    zc = m.get_cm_ref()\n    zcro = m.get_cm_const_ref()\n    zr = m.get_rm_ref()\n    zrro = m.get_rm_const_ref()\n\n    assert [zc[1, 2], zcro[1, 2], zr[1, 2], zrro[1, 2]] == [23] * 4\n\n    assert not zc.flags.owndata and zc.flags.writeable\n    assert not zr.flags.owndata and zr.flags.writeable\n    assert not zcro.flags.owndata and not zcro.flags.writeable\n    assert not zrro.flags.owndata and not zrro.flags.writeable\n\n    zc[1, 2] = 99\n    expect = np.array([[11.0, 12, 13], [21, 22, 99], [31, 32, 33]])\n    # We should have just changed zc, of course, but also zcro and the original eigen matrix\n    assert np.all(zc == expect)\n    assert np.all(zcro == expect)\n    assert np.all(m.get_cm_ref() == expect)\n\n    zr[1, 2] = 99\n    assert np.all(zr == expect)\n    assert np.all(zrro == expect)\n    assert np.all(m.get_rm_ref() == expect)\n\n    # Make sure the readonly ones are numpy-readonly:\n    with pytest.raises(ValueError):\n        zcro[1, 2] = 6\n    with pytest.raises(ValueError):\n        zrro[1, 2] = 6\n\n    # We should be able to explicitly copy like this (and since we're copying,\n    # the const should drop away)\n    y1 = np.array(m.get_cm_const_ref())\n\n    assert y1.flags.owndata and y1.flags.writeable\n    # We should get copies of the eigen data, which was modified above:\n    assert y1[1, 2] == 99\n    y1[1, 2] += 12\n    assert y1[1, 2] == 111\n    assert zc[1, 2] == 99  # Make sure we aren't referencing the original\n\n\ndef test_both_ref_mutators():\n    \"\"\"Tests a complex chain of nested eigen/numpy references\"\"\"\n\n    m.reset_refs()  # In case another test already changed it\n\n    z = m.get_cm_ref()  # numpy -> eigen\n    z[0, 2] -= 3\n    z2 = m.incr_matrix(z, 1)  # numpy -> eigen -> numpy -> eigen\n    z2[1, 1] += 6\n    z3 = m.incr_matrix(z, 2)  # (numpy -> eigen)^3\n    z3[2, 2] += -5\n    z4 = m.incr_matrix(z, 3)  # (numpy -> eigen)^4\n    z4[1, 1] -= 1\n    z5 = m.incr_matrix(z, 4)  # (numpy -> eigen)^5\n    z5[0, 0] = 0\n    assert np.all(z == z2)\n    assert np.all(z == z3)\n    assert np.all(z == z4)\n    assert np.all(z == z5)\n    expect = np.array([[0.0, 22, 20], [31, 37, 33], [41, 42, 38]])\n    assert np.all(z == expect)\n\n    y = np.array(range(100), dtype=\"float64\").reshape(10, 10)\n    y2 = m.incr_matrix_any(y, 10)  # np -> eigen -> np\n    y3 = m.incr_matrix_any(\n        y2[0::2, 0::2], -33\n    )  # np -> eigen -> np slice -> np -> eigen -> np\n    y4 = m.even_rows(y3)  # numpy -> eigen slice -> (... y3)\n    y5 = m.even_cols(y4)  # numpy -> eigen slice -> (... y4)\n    y6 = m.incr_matrix_any(y5, 1000)  # numpy -> eigen -> (... y5)\n\n    # Apply same mutations using just numpy:\n    yexpect = np.array(range(100), dtype=\"float64\").reshape(10, 10)\n    yexpect += 10\n    yexpect[0::2, 0::2] -= 33\n    yexpect[0::4, 0::4] += 1000\n    assert np.all(y6 == yexpect[0::4, 0::4])\n    assert np.all(y5 == yexpect[0::4, 0::4])\n    assert np.all(y4 == yexpect[0::4, 0::2])\n    assert np.all(y3 == yexpect[0::2, 0::2])\n    assert np.all(y2 == yexpect)\n    assert np.all(y == yexpect)\n\n\ndef test_nocopy_wrapper():\n    # get_elem requires a column-contiguous matrix reference, but should be\n    # callable with other types of matrix (via copying):\n    int_matrix_colmajor = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], order=\"F\")\n    dbl_matrix_colmajor = np.array(\n        int_matrix_colmajor, dtype=\"double\", order=\"F\", copy=True\n    )\n    int_matrix_rowmajor = np.array(int_matrix_colmajor, order=\"C\", copy=True)\n    dbl_matrix_rowmajor = np.array(\n        int_matrix_rowmajor, dtype=\"double\", order=\"C\", copy=True\n    )\n\n    # All should be callable via get_elem:\n    assert m.get_elem(int_matrix_colmajor) == 8\n    assert m.get_elem(dbl_matrix_colmajor) == 8\n    assert m.get_elem(int_matrix_rowmajor) == 8\n    assert m.get_elem(dbl_matrix_rowmajor) == 8\n\n    # All but the second should fail with m.get_elem_nocopy:\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(int_matrix_colmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n    assert m.get_elem_nocopy(dbl_matrix_colmajor) == 8\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(int_matrix_rowmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_nocopy(dbl_matrix_rowmajor)\n    assert \"get_elem_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.f_contiguous\" in str(excinfo.value)\n\n    # For the row-major test, we take a long matrix in row-major, so only the third is allowed:\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(int_matrix_colmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(dbl_matrix_colmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n    assert m.get_elem_rm_nocopy(int_matrix_rowmajor) == 8\n    with pytest.raises(TypeError) as excinfo:\n        m.get_elem_rm_nocopy(dbl_matrix_rowmajor)\n    assert \"get_elem_rm_nocopy(): incompatible function arguments.\" in str(\n        excinfo.value\n    ) and \", flags.c_contiguous\" in str(excinfo.value)\n\n\ndef test_eigen_ref_life_support():\n    \"\"\"Ensure the lifetime of temporary arrays created by the `Ref` caster\n\n    The `Ref` caster sometimes creates a copy which needs to stay alive. This needs to\n    happen both for directs casts (just the array) or indirectly (e.g. list of arrays).\n    \"\"\"\n\n    a = np.full(shape=10, fill_value=8, dtype=np.int8)\n    assert m.get_elem_direct(a) == 8\n\n    list_of_a = [a]\n    assert m.get_elem_indirect(list_of_a) == 8\n\n\ndef test_special_matrix_objects():\n    assert np.all(m.incr_diag(7) == np.diag([1.0, 2, 3, 4, 5, 6, 7]))\n\n    asymm = np.array([[1.0, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]])\n    symm_lower = np.array(asymm)\n    symm_upper = np.array(asymm)\n    for i in range(4):\n        for j in range(i + 1, 4):\n            symm_lower[i, j] = symm_lower[j, i]\n            symm_upper[j, i] = symm_upper[i, j]\n\n    assert np.all(m.symmetric_lower(asymm) == symm_lower)\n    assert np.all(m.symmetric_upper(asymm) == symm_upper)\n\n\ndef test_dense_signature(doc):\n    assert (\n        doc(m.double_col)\n        == \"\"\"\n        double_col(arg0: numpy.ndarray[numpy.float32[m, 1]]) -> numpy.ndarray[numpy.float32[m, 1]]\n    \"\"\"\n    )\n    assert (\n        doc(m.double_row)\n        == \"\"\"\n        double_row(arg0: numpy.ndarray[numpy.float32[1, n]]) -> numpy.ndarray[numpy.float32[1, n]]\n    \"\"\"\n    )\n    assert doc(m.double_complex) == (\n        \"\"\"\n        double_complex(arg0: numpy.ndarray[numpy.complex64[m, 1]])\"\"\"\n        \"\"\" -> numpy.ndarray[numpy.complex64[m, 1]]\n    \"\"\"\n    )\n    assert doc(m.double_mat_rm) == (\n        \"\"\"\n        double_mat_rm(arg0: numpy.ndarray[numpy.float32[m, n]])\"\"\"\n        \"\"\" -> numpy.ndarray[numpy.float32[m, n]]\n    \"\"\"\n    )\n\n\ndef test_named_arguments():\n    a = np.array([[1.0, 2], [3, 4], [5, 6]])\n    b = np.ones((2, 1))\n\n    assert np.all(m.matrix_multiply(a, b) == np.array([[3.0], [7], [11]]))\n    assert np.all(m.matrix_multiply(A=a, B=b) == np.array([[3.0], [7], [11]]))\n    assert np.all(m.matrix_multiply(B=b, A=a) == np.array([[3.0], [7], [11]]))\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(b, a)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(A=b, B=a)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.matrix_multiply(B=a, A=b)\n    assert str(excinfo.value) == \"Nonconformable matrices!\"\n\n\ndef test_sparse():\n    pytest.importorskip(\"scipy\")\n    assert_sparse_equal_ref(m.sparse_r())\n    assert_sparse_equal_ref(m.sparse_c())\n    assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_r()))\n    assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_c()))\n    assert_sparse_equal_ref(m.sparse_copy_r(m.sparse_c()))\n    assert_sparse_equal_ref(m.sparse_copy_c(m.sparse_r()))\n\n\ndef test_sparse_signature(doc):\n    pytest.importorskip(\"scipy\")\n    assert (\n        doc(m.sparse_copy_r)\n        == \"\"\"\n        sparse_copy_r(arg0: scipy.sparse.csr_matrix[numpy.float32]) -> scipy.sparse.csr_matrix[numpy.float32]\n    \"\"\"  # noqa: E501 line too long\n    )\n    assert (\n        doc(m.sparse_copy_c)\n        == \"\"\"\n        sparse_copy_c(arg0: scipy.sparse.csc_matrix[numpy.float32]) -> scipy.sparse.csc_matrix[numpy.float32]\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_issue738():\n    \"\"\"Ignore strides on a length-1 dimension (even if they would be incompatible length > 1)\"\"\"\n    assert np.all(m.iss738_f1(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))\n    assert np.all(\n        m.iss738_f1(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])\n    )\n\n    assert np.all(m.iss738_f2(np.array([[1.0, 2, 3]])) == np.array([[1.0, 102, 203]]))\n    assert np.all(\n        m.iss738_f2(np.array([[1.0], [2], [3]])) == np.array([[1.0], [12], [23]])\n    )\n\n\ndef test_issue1105():\n    \"\"\"Issue 1105: 1xN or Nx1 input arrays weren't accepted for eigen\n    compile-time row vectors or column vector\"\"\"\n    assert m.iss1105_row(np.ones((1, 7)))\n    assert m.iss1105_col(np.ones((7, 1)))\n\n    # These should still fail (incompatible dimensions):\n    with pytest.raises(TypeError) as excinfo:\n        m.iss1105_row(np.ones((7, 1)))\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.iss1105_col(np.ones((1, 7)))\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_custom_operator_new():\n    \"\"\"Using Eigen types as member variables requires a class-specific\n    operator new with proper alignment\"\"\"\n\n    o = m.CustomOperatorNew()\n    np.testing.assert_allclose(o.a, 0.0)\n    np.testing.assert_allclose(o.b.diagonal(), 1.0)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/CMakeLists.txt",
    "content": "possibly_uninitialized(PYTHON_MODULE_EXTENSION Python_INTERPRETER_ID)\n\nif(\"${PYTHON_MODULE_EXTENSION}\" MATCHES \"pypy\" OR \"${Python_INTERPRETER_ID}\" STREQUAL \"PyPy\")\n  message(STATUS \"Skipping embed test on PyPy\")\n  add_custom_target(cpptest) # Dummy target on PyPy. Embedding is not supported.\n  set(_suppress_unused_variable_warning \"${DOWNLOAD_CATCH}\")\n  return()\nendif()\n\nfind_package(Catch 2.13.5)\n\nif(CATCH_FOUND)\n  message(STATUS \"Building interpreter tests using Catch v${CATCH_VERSION}\")\nelse()\n  message(STATUS \"Catch not detected. Interpreter tests will be skipped. Install Catch headers\"\n                 \" manually or use `cmake -DDOWNLOAD_CATCH=ON` to fetch them automatically.\")\n  return()\nendif()\n\nfind_package(Threads REQUIRED)\n\nadd_executable(test_embed catch.cpp test_interpreter.cpp)\npybind11_enable_warnings(test_embed)\n\ntarget_link_libraries(test_embed PRIVATE pybind11::embed Catch2::Catch2 Threads::Threads)\n\nif(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)\n  file(COPY test_interpreter.py test_trampoline.py DESTINATION \"${CMAKE_CURRENT_BINARY_DIR}\")\nendif()\n\nadd_custom_target(\n  cpptest\n  COMMAND \"$<TARGET_FILE:test_embed>\"\n  DEPENDS test_embed\n  WORKING_DIRECTORY \"${CMAKE_CURRENT_BINARY_DIR}\")\n\npybind11_add_module(external_module THIN_LTO external_module.cpp)\nset_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY\n                                                 \"${CMAKE_CURRENT_BINARY_DIR}\")\nforeach(config ${CMAKE_CONFIGURATION_TYPES})\n  string(TOUPPER ${config} config)\n  set_target_properties(external_module PROPERTIES LIBRARY_OUTPUT_DIRECTORY_${config}\n                                                   \"${CMAKE_CURRENT_BINARY_DIR}\")\nendforeach()\nadd_dependencies(cpptest external_module)\n\nadd_dependencies(check cpptest)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/catch.cpp",
    "content": "// The Catch implementation is compiled here. This is a standalone\n// translation unit to avoid recompiling it for every test change.\n\n#include <pybind11/embed.h>\n\n#ifdef _MSC_VER\n// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to\n// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).\n#    pragma warning(disable : 4996)\n#endif\n\n// Catch uses _ internally, which breaks gettext style defines\n#ifdef _\n#    undef _\n#endif\n\n#define CATCH_CONFIG_RUNNER\n#include <catch.hpp>\n\nnamespace py = pybind11;\n\nint main(int argc, char *argv[]) {\n    py::scoped_interpreter guard{};\n    auto result = Catch::Session().run(argc, argv);\n\n    return result < 0xff ? result : 0xff;\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/external_module.cpp",
    "content": "#include <pybind11/pybind11.h>\n\nnamespace py = pybind11;\n\n/* Simple test module/test class to check that the referenced internals data of external pybind11\n * modules aren't preserved over a finalize/initialize.\n */\n\nPYBIND11_MODULE(external_module, m) {\n    class A {\n    public:\n        explicit A(int value) : v{value} {};\n        int v;\n    };\n\n    py::class_<A>(m, \"A\").def(py::init<int>()).def_readwrite(\"value\", &A::v);\n\n    m.def(\"internals_at\",\n          []() { return reinterpret_cast<uintptr_t>(&py::detail::get_internals()); });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/test_interpreter.cpp",
    "content": "#include <pybind11/embed.h>\n\n#ifdef _MSC_VER\n// Silence MSVC C++17 deprecation warning from Catch regarding std::uncaught_exceptions (up to\n// catch 2.0.1; this should be fixed in the next catch release after 2.0.1).\n#    pragma warning(disable : 4996)\n#endif\n\n#include <catch.hpp>\n#include <cstdlib>\n#include <fstream>\n#include <functional>\n#include <thread>\n#include <utility>\n\nnamespace py = pybind11;\nusing namespace py::literals;\n\nclass Widget {\npublic:\n    explicit Widget(std::string message) : message(std::move(message)) {}\n    virtual ~Widget() = default;\n\n    std::string the_message() const { return message; }\n    virtual int the_answer() const = 0;\n    virtual std::string argv0() const = 0;\n\nprivate:\n    std::string message;\n};\n\nclass PyWidget final : public Widget {\n    using Widget::Widget;\n\n    int the_answer() const override { PYBIND11_OVERRIDE_PURE(int, Widget, the_answer); }\n    std::string argv0() const override { PYBIND11_OVERRIDE_PURE(std::string, Widget, argv0); }\n};\n\nclass test_override_cache_helper {\n\npublic:\n    virtual int func() { return 0; }\n\n    test_override_cache_helper() = default;\n    virtual ~test_override_cache_helper() = default;\n    // Non-copyable\n    test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;\n    test_override_cache_helper(test_override_cache_helper const &Copy) = delete;\n};\n\nclass test_override_cache_helper_trampoline : public test_override_cache_helper {\n    int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }\n};\n\nPYBIND11_EMBEDDED_MODULE(widget_module, m) {\n    py::class_<Widget, PyWidget>(m, \"Widget\")\n        .def(py::init<std::string>())\n        .def_property_readonly(\"the_message\", &Widget::the_message);\n\n    m.def(\"add\", [](int i, int j) { return i + j; });\n}\n\nPYBIND11_EMBEDDED_MODULE(trampoline_module, m) {\n    py::class_<test_override_cache_helper,\n               test_override_cache_helper_trampoline,\n               std::shared_ptr<test_override_cache_helper>>(m, \"test_override_cache_helper\")\n        .def(py::init_alias<>())\n        .def(\"func\", &test_override_cache_helper::func);\n}\n\nPYBIND11_EMBEDDED_MODULE(throw_exception, ) { throw std::runtime_error(\"C++ Error\"); }\n\nPYBIND11_EMBEDDED_MODULE(throw_error_already_set, ) {\n    auto d = py::dict();\n    d[\"missing\"].cast<py::object>();\n}\n\nTEST_CASE(\"Pass classes and data between modules defined in C++ and Python\") {\n    auto module_ = py::module_::import(\"test_interpreter\");\n    REQUIRE(py::hasattr(module_, \"DerivedWidget\"));\n\n    auto locals = py::dict(\"hello\"_a = \"Hello, World!\", \"x\"_a = 5, **module_.attr(\"__dict__\"));\n    py::exec(R\"(\n        widget = DerivedWidget(\"{} - {}\".format(hello, x))\n        message = widget.the_message\n    )\",\n             py::globals(),\n             locals);\n    REQUIRE(locals[\"message\"].cast<std::string>() == \"Hello, World! - 5\");\n\n    auto py_widget = module_.attr(\"DerivedWidget\")(\"The question\");\n    auto message = py_widget.attr(\"the_message\");\n    REQUIRE(message.cast<std::string>() == \"The question\");\n\n    const auto &cpp_widget = py_widget.cast<const Widget &>();\n    REQUIRE(cpp_widget.the_answer() == 42);\n}\n\nTEST_CASE(\"Override cache\") {\n    auto module_ = py::module_::import(\"test_trampoline\");\n    REQUIRE(py::hasattr(module_, \"func\"));\n    REQUIRE(py::hasattr(module_, \"func2\"));\n\n    auto locals = py::dict(**module_.attr(\"__dict__\"));\n\n    int i = 0;\n    for (; i < 1500; ++i) {\n        std::shared_ptr<test_override_cache_helper> p_obj;\n        std::shared_ptr<test_override_cache_helper> p_obj2;\n\n        py::object loc_inst = locals[\"func\"]();\n        p_obj = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);\n\n        int ret = p_obj->func();\n\n        REQUIRE(ret == 42);\n\n        loc_inst = locals[\"func2\"]();\n\n        p_obj2 = py::cast<std::shared_ptr<test_override_cache_helper>>(loc_inst);\n\n        p_obj2->func();\n    }\n}\n\nTEST_CASE(\"Import error handling\") {\n    REQUIRE_NOTHROW(py::module_::import(\"widget_module\"));\n    REQUIRE_THROWS_WITH(py::module_::import(\"throw_exception\"), \"ImportError: C++ Error\");\n#if PY_VERSION_HEX >= 0x03030000\n    REQUIRE_THROWS_WITH(py::module_::import(\"throw_error_already_set\"),\n                        Catch::Contains(\"ImportError: initialization failed\"));\n\n    auto locals = py::dict(\"is_keyerror\"_a = false, \"message\"_a = \"not set\");\n    py::exec(R\"(\n        try:\n            import throw_error_already_set\n        except ImportError as e:\n            is_keyerror = type(e.__cause__) == KeyError\n            message = str(e.__cause__)\n    )\",\n             py::globals(),\n             locals);\n    REQUIRE(locals[\"is_keyerror\"].cast<bool>() == true);\n    REQUIRE(locals[\"message\"].cast<std::string>() == \"'missing'\");\n#else\n    REQUIRE_THROWS_WITH(py::module_::import(\"throw_error_already_set\"),\n                        Catch::Contains(\"ImportError: KeyError\"));\n#endif\n}\n\nTEST_CASE(\"There can be only one interpreter\") {\n    static_assert(std::is_move_constructible<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_move_assignable<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_copy_constructible<py::scoped_interpreter>::value, \"\");\n    static_assert(!std::is_copy_assignable<py::scoped_interpreter>::value, \"\");\n\n    REQUIRE_THROWS_WITH(py::initialize_interpreter(), \"The interpreter is already running\");\n    REQUIRE_THROWS_WITH(py::scoped_interpreter(), \"The interpreter is already running\");\n\n    py::finalize_interpreter();\n    REQUIRE_NOTHROW(py::scoped_interpreter());\n    {\n        auto pyi1 = py::scoped_interpreter();\n        auto pyi2 = std::move(pyi1);\n    }\n    py::initialize_interpreter();\n}\n\nbool has_pybind11_internals_builtin() {\n    auto builtins = py::handle(PyEval_GetBuiltins());\n    return builtins.contains(PYBIND11_INTERNALS_ID);\n};\n\nbool has_pybind11_internals_static() {\n    auto **&ipp = py::detail::get_internals_pp();\n    return (ipp != nullptr) && (*ipp != nullptr);\n}\n\nTEST_CASE(\"Restart the interpreter\") {\n    // Verify pre-restart state.\n    REQUIRE(py::module_::import(\"widget_module\").attr(\"add\")(1, 2).cast<int>() == 3);\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n    REQUIRE(py::module_::import(\"external_module\").attr(\"A\")(123).attr(\"value\").cast<int>()\n            == 123);\n\n    // local and foreign module internals should point to the same internals:\n    REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())\n            == py::module_::import(\"external_module\").attr(\"internals_at\")().cast<uintptr_t>());\n\n    // Restart the interpreter.\n    py::finalize_interpreter();\n    REQUIRE(Py_IsInitialized() == 0);\n\n    py::initialize_interpreter();\n    REQUIRE(Py_IsInitialized() == 1);\n\n    // Internals are deleted after a restart.\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n    pybind11::detail::get_internals();\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n    REQUIRE(reinterpret_cast<uintptr_t>(*py::detail::get_internals_pp())\n            == py::module_::import(\"external_module\").attr(\"internals_at\")().cast<uintptr_t>());\n\n    // Make sure that an interpreter with no get_internals() created until finalize still gets the\n    // internals destroyed\n    py::finalize_interpreter();\n    py::initialize_interpreter();\n    bool ran = false;\n    py::module_::import(\"__main__\").attr(\"internals_destroy_test\")\n        = py::capsule(&ran, [](void *ran) {\n              py::detail::get_internals();\n              *static_cast<bool *>(ran) = true;\n          });\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n    REQUIRE_FALSE(ran);\n    py::finalize_interpreter();\n    REQUIRE(ran);\n    py::initialize_interpreter();\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE_FALSE(has_pybind11_internals_static());\n\n    // C++ modules can be reloaded.\n    auto cpp_module = py::module_::import(\"widget_module\");\n    REQUIRE(cpp_module.attr(\"add\")(1, 2).cast<int>() == 3);\n\n    // C++ type information is reloaded and can be used in python modules.\n    auto py_module = py::module_::import(\"test_interpreter\");\n    auto py_widget = py_module.attr(\"DerivedWidget\")(\"Hello after restart\");\n    REQUIRE(py_widget.attr(\"the_message\").cast<std::string>() == \"Hello after restart\");\n}\n\nTEST_CASE(\"Subinterpreter\") {\n    // Add tags to the modules in the main interpreter and test the basics.\n    py::module_::import(\"__main__\").attr(\"main_tag\") = \"main interpreter\";\n    {\n        auto m = py::module_::import(\"widget_module\");\n        m.attr(\"extension_module_tag\") = \"added to module in main interpreter\";\n\n        REQUIRE(m.attr(\"add\")(1, 2).cast<int>() == 3);\n    }\n    REQUIRE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n\n    /// Create and switch to a subinterpreter.\n    auto *main_tstate = PyThreadState_Get();\n    auto *sub_tstate = Py_NewInterpreter();\n\n    // Subinterpreters get their own copy of builtins. detail::get_internals() still\n    // works by returning from the static variable, i.e. all interpreters share a single\n    // global pybind11::internals;\n    REQUIRE_FALSE(has_pybind11_internals_builtin());\n    REQUIRE(has_pybind11_internals_static());\n\n    // Modules tags should be gone.\n    REQUIRE_FALSE(py::hasattr(py::module_::import(\"__main__\"), \"tag\"));\n    {\n        auto m = py::module_::import(\"widget_module\");\n        REQUIRE_FALSE(py::hasattr(m, \"extension_module_tag\"));\n\n        // Function bindings should still work.\n        REQUIRE(m.attr(\"add\")(1, 2).cast<int>() == 3);\n    }\n\n    // Restore main interpreter.\n    Py_EndInterpreter(sub_tstate);\n    PyThreadState_Swap(main_tstate);\n\n    REQUIRE(py::hasattr(py::module_::import(\"__main__\"), \"main_tag\"));\n    REQUIRE(py::hasattr(py::module_::import(\"widget_module\"), \"extension_module_tag\"));\n}\n\nTEST_CASE(\"Execution frame\") {\n    // When the interpreter is embedded, there is no execution frame, but `py::exec`\n    // should still function by using reasonable globals: `__main__.__dict__`.\n    py::exec(\"var = dict(number=42)\");\n    REQUIRE(py::globals()[\"var\"][\"number\"].cast<int>() == 42);\n}\n\nTEST_CASE(\"Threads\") {\n    // Restart interpreter to ensure threads are not initialized\n    py::finalize_interpreter();\n    py::initialize_interpreter();\n    REQUIRE_FALSE(has_pybind11_internals_static());\n\n    constexpr auto num_threads = 10;\n    auto locals = py::dict(\"count\"_a = 0);\n\n    {\n        py::gil_scoped_release gil_release{};\n        REQUIRE(has_pybind11_internals_static());\n\n        auto threads = std::vector<std::thread>();\n        for (auto i = 0; i < num_threads; ++i) {\n            threads.emplace_back([&]() {\n                py::gil_scoped_acquire gil{};\n                locals[\"count\"] = locals[\"count\"].cast<int>() + 1;\n            });\n        }\n\n        for (auto &thread : threads) {\n            thread.join();\n        }\n    }\n\n    REQUIRE(locals[\"count\"].cast<int>() == num_threads);\n}\n\n// Scope exit utility https://stackoverflow.com/a/36644501/7255855\nstruct scope_exit {\n    std::function<void()> f_;\n    explicit scope_exit(std::function<void()> f) noexcept : f_(std::move(f)) {}\n    ~scope_exit() {\n        if (f_) {\n            f_();\n        }\n    }\n};\n\nTEST_CASE(\"Reload module from file\") {\n    // Disable generation of cached bytecode (.pyc files) for this test, otherwise\n    // Python might pick up an old version from the cache instead of the new versions\n    // of the .py files generated below\n    auto sys = py::module_::import(\"sys\");\n    bool dont_write_bytecode = sys.attr(\"dont_write_bytecode\").cast<bool>();\n    sys.attr(\"dont_write_bytecode\") = true;\n    // Reset the value at scope exit\n    scope_exit reset_dont_write_bytecode(\n        [&]() { sys.attr(\"dont_write_bytecode\") = dont_write_bytecode; });\n\n    std::string module_name = \"test_module_reload\";\n    std::string module_file = module_name + \".py\";\n\n    // Create the module .py file\n    std::ofstream test_module(module_file);\n    test_module << \"def test():\\n\";\n    test_module << \"    return 1\\n\";\n    test_module.close();\n    // Delete the file at scope exit\n    scope_exit delete_module_file([&]() { std::remove(module_file.c_str()); });\n\n    // Import the module from file\n    auto module_ = py::module_::import(module_name.c_str());\n    int result = module_.attr(\"test\")().cast<int>();\n    REQUIRE(result == 1);\n\n    // Update the module .py file with a small change\n    test_module.open(module_file);\n    test_module << \"def test():\\n\";\n    test_module << \"    return 2\\n\";\n    test_module.close();\n\n    // Reload the module\n    module_.reload();\n    result = module_.attr(\"test\")().cast<int>();\n    REQUIRE(result == 2);\n}\n\nTEST_CASE(\"sys.argv gets initialized properly\") {\n    py::finalize_interpreter();\n    {\n        py::scoped_interpreter default_scope;\n        auto module = py::module::import(\"test_interpreter\");\n        auto py_widget = module.attr(\"DerivedWidget\")(\"The question\");\n        const auto &cpp_widget = py_widget.cast<const Widget &>();\n        REQUIRE(cpp_widget.argv0().empty());\n    }\n\n    {\n        char *argv[] = {strdup(\"a.out\")};\n        py::scoped_interpreter argv_scope(true, 1, argv);\n        std::free(argv[0]);\n        auto module = py::module::import(\"test_interpreter\");\n        auto py_widget = module.attr(\"DerivedWidget\")(\"The question\");\n        const auto &cpp_widget = py_widget.cast<const Widget &>();\n        REQUIRE(cpp_widget.argv0() == \"a.out\");\n    }\n    py::initialize_interpreter();\n}\n\nTEST_CASE(\"make_iterator can be called before then after finalizing an interpreter\") {\n    // Reproduction of issue #2101 (https://github.com/pybind/pybind11/issues/2101)\n    py::finalize_interpreter();\n\n    std::vector<int> container;\n    {\n        pybind11::scoped_interpreter g;\n        auto iter = pybind11::make_iterator(container.begin(), container.end());\n    }\n\n    REQUIRE_NOTHROW([&]() {\n        pybind11::scoped_interpreter g;\n        auto iter = pybind11::make_iterator(container.begin(), container.end());\n    }());\n\n    py::initialize_interpreter();\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/test_interpreter.py",
    "content": "# -*- coding: utf-8 -*-\nimport sys\n\nfrom widget_module import Widget\n\n\nclass DerivedWidget(Widget):\n    def __init__(self, message):\n        super(DerivedWidget, self).__init__(message)\n\n    def the_answer(self):\n        return 42\n\n    def argv0(self):\n        return sys.argv[0]\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_embed/test_trampoline.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport trampoline_module\n\n\ndef func():\n    class Test(trampoline_module.test_override_cache_helper):\n        def func(self):\n            return 42\n\n    return Test()\n\n\ndef func2():\n    class Test(trampoline_module.test_override_cache_helper):\n        pass\n\n    return Test()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_enum.cpp",
    "content": "/*\n    tests/test_enums.cpp -- enumerations\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(enums, m) {\n    // test_unscoped_enum\n    enum UnscopedEnum { EOne = 1, ETwo, EThree };\n    py::enum_<UnscopedEnum>(m, \"UnscopedEnum\", py::arithmetic(), \"An unscoped enumeration\")\n        .value(\"EOne\", EOne, \"Docstring for EOne\")\n        .value(\"ETwo\", ETwo, \"Docstring for ETwo\")\n        .value(\"EThree\", EThree, \"Docstring for EThree\")\n        .export_values();\n\n    // test_scoped_enum\n    enum class ScopedEnum { Two = 2, Three };\n    py::enum_<ScopedEnum>(m, \"ScopedEnum\", py::arithmetic())\n        .value(\"Two\", ScopedEnum::Two)\n        .value(\"Three\", ScopedEnum::Three);\n\n    m.def(\"test_scoped_enum\", [](ScopedEnum z) {\n        return \"ScopedEnum::\" + std::string(z == ScopedEnum::Two ? \"Two\" : \"Three\");\n    });\n\n    // test_binary_operators\n    enum Flags { Read = 4, Write = 2, Execute = 1 };\n    py::enum_<Flags>(m, \"Flags\", py::arithmetic())\n        .value(\"Read\", Flags::Read)\n        .value(\"Write\", Flags::Write)\n        .value(\"Execute\", Flags::Execute)\n        .export_values();\n\n    // test_implicit_conversion\n    class ClassWithUnscopedEnum {\n    public:\n        enum EMode { EFirstMode = 1, ESecondMode };\n\n        static EMode test_function(EMode mode) { return mode; }\n    };\n    py::class_<ClassWithUnscopedEnum> exenum_class(m, \"ClassWithUnscopedEnum\");\n    exenum_class.def_static(\"test_function\", &ClassWithUnscopedEnum::test_function);\n    py::enum_<ClassWithUnscopedEnum::EMode>(exenum_class, \"EMode\")\n        .value(\"EFirstMode\", ClassWithUnscopedEnum::EFirstMode)\n        .value(\"ESecondMode\", ClassWithUnscopedEnum::ESecondMode)\n        .export_values();\n\n    // test_enum_to_int\n    m.def(\"test_enum_to_int\", [](int) {});\n    m.def(\"test_enum_to_uint\", [](uint32_t) {});\n    m.def(\"test_enum_to_long_long\", [](long long) {});\n\n    // test_duplicate_enum_name\n    enum SimpleEnum { ONE, TWO, THREE };\n\n    m.def(\"register_bad_enum\", [m]() {\n        py::enum_<SimpleEnum>(m, \"SimpleEnum\")\n            .value(\"ONE\", SimpleEnum::ONE) // NOTE: all value function calls are called with the\n                                           // same first parameter value\n            .value(\"ONE\", SimpleEnum::TWO)\n            .value(\"ONE\", SimpleEnum::THREE)\n            .export_values();\n    });\n\n    // test_enum_scalar\n    enum UnscopedUCharEnum : unsigned char {};\n    enum class ScopedShortEnum : short {};\n    enum class ScopedLongEnum : long {};\n    enum UnscopedUInt64Enum : std::uint64_t {};\n    static_assert(\n        py::detail::all_of<\n            std::is_same<py::enum_<UnscopedUCharEnum>::Scalar, unsigned char>,\n            std::is_same<py::enum_<ScopedShortEnum>::Scalar, short>,\n            std::is_same<py::enum_<ScopedLongEnum>::Scalar, long>,\n            std::is_same<py::enum_<UnscopedUInt64Enum>::Scalar, std::uint64_t>>::value,\n        \"Error during the deduction of enum's scalar type with normal integer underlying\");\n\n    // test_enum_scalar_with_char_underlying\n    enum class ScopedCharEnum : char { Zero, Positive };\n    enum class ScopedWCharEnum : wchar_t { Zero, Positive };\n    enum class ScopedChar32Enum : char32_t { Zero, Positive };\n    enum class ScopedChar16Enum : char16_t { Zero, Positive };\n\n    // test the scalar of char type enums according to chapter 'Character types'\n    // from https://en.cppreference.com/w/cpp/language/types\n    static_assert(\n        py::detail::any_of<\n            std::is_same<py::enum_<ScopedCharEnum>::Scalar, signed char>,  // e.g. gcc on x86\n            std::is_same<py::enum_<ScopedCharEnum>::Scalar, unsigned char> // e.g. arm linux\n            >::value,\n        \"char should be cast to either signed char or unsigned char\");\n    static_assert(sizeof(py::enum_<ScopedWCharEnum>::Scalar) == 2\n                      || sizeof(py::enum_<ScopedWCharEnum>::Scalar) == 4,\n                  \"wchar_t should be either 16 bits (Windows) or 32 (everywhere else)\");\n    static_assert(\n        py::detail::all_of<\n            std::is_same<py::enum_<ScopedChar32Enum>::Scalar, std::uint_least32_t>,\n            std::is_same<py::enum_<ScopedChar16Enum>::Scalar, std::uint_least16_t>>::value,\n        \"char32_t, char16_t (and char8_t)'s size, signedness, and alignment is determined\");\n#if defined(PYBIND11_HAS_U8STRING)\n    enum class ScopedChar8Enum : char8_t { Zero, Positive };\n    static_assert(std::is_same<py::enum_<ScopedChar8Enum>::Scalar, unsigned char>::value);\n#endif\n\n    // test_char_underlying_enum\n    py::enum_<ScopedCharEnum>(m, \"ScopedCharEnum\")\n        .value(\"Zero\", ScopedCharEnum::Zero)\n        .value(\"Positive\", ScopedCharEnum::Positive);\n    py::enum_<ScopedWCharEnum>(m, \"ScopedWCharEnum\")\n        .value(\"Zero\", ScopedWCharEnum::Zero)\n        .value(\"Positive\", ScopedWCharEnum::Positive);\n    py::enum_<ScopedChar32Enum>(m, \"ScopedChar32Enum\")\n        .value(\"Zero\", ScopedChar32Enum::Zero)\n        .value(\"Positive\", ScopedChar32Enum::Positive);\n    py::enum_<ScopedChar16Enum>(m, \"ScopedChar16Enum\")\n        .value(\"Zero\", ScopedChar16Enum::Zero)\n        .value(\"Positive\", ScopedChar16Enum::Positive);\n\n    // test_bool_underlying_enum\n    enum class ScopedBoolEnum : bool { FALSE, TRUE };\n\n    // bool is unsigned (std::is_signed returns false) and 1-byte long, so represented with u8\n    static_assert(std::is_same<py::enum_<ScopedBoolEnum>::Scalar, std::uint8_t>::value, \"\");\n\n    py::enum_<ScopedBoolEnum>(m, \"ScopedBoolEnum\")\n        .value(\"FALSE\", ScopedBoolEnum::FALSE)\n        .value(\"TRUE\", ScopedBoolEnum::TRUE);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_enum.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import enums as m\n\n\ndef test_unscoped_enum():\n    assert str(m.UnscopedEnum.EOne) == \"UnscopedEnum.EOne\"\n    assert str(m.UnscopedEnum.ETwo) == \"UnscopedEnum.ETwo\"\n    assert str(m.EOne) == \"UnscopedEnum.EOne\"\n    assert repr(m.UnscopedEnum.EOne) == \"<UnscopedEnum.EOne: 1>\"\n    assert repr(m.UnscopedEnum.ETwo) == \"<UnscopedEnum.ETwo: 2>\"\n    assert repr(m.EOne) == \"<UnscopedEnum.EOne: 1>\"\n\n    # name property\n    assert m.UnscopedEnum.EOne.name == \"EOne\"\n    assert m.UnscopedEnum.EOne.value == 1\n    assert m.UnscopedEnum.ETwo.name == \"ETwo\"\n    assert m.UnscopedEnum.ETwo.value == 2\n    assert m.EOne is m.UnscopedEnum.EOne\n    # name, value readonly\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.EOne.name = \"\"\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.EOne.value = 10\n    # name, value returns a copy\n    # TODO: Neither the name nor value tests actually check against aliasing.\n    # Use a mutable type that has reference semantics.\n    nonaliased_name = m.UnscopedEnum.EOne.name\n    nonaliased_name = \"bar\"  # noqa: F841\n    assert m.UnscopedEnum.EOne.name == \"EOne\"\n    nonaliased_value = m.UnscopedEnum.EOne.value\n    nonaliased_value = 10  # noqa: F841\n    assert m.UnscopedEnum.EOne.value == 1\n\n    # __members__ property\n    assert m.UnscopedEnum.__members__ == {\n        \"EOne\": m.UnscopedEnum.EOne,\n        \"ETwo\": m.UnscopedEnum.ETwo,\n        \"EThree\": m.UnscopedEnum.EThree,\n    }\n    # __members__ readonly\n    with pytest.raises(AttributeError):\n        m.UnscopedEnum.__members__ = {}\n    # __members__ returns a copy\n    nonaliased_members = m.UnscopedEnum.__members__\n    nonaliased_members[\"bar\"] = \"baz\"\n    assert m.UnscopedEnum.__members__ == {\n        \"EOne\": m.UnscopedEnum.EOne,\n        \"ETwo\": m.UnscopedEnum.ETwo,\n        \"EThree\": m.UnscopedEnum.EThree,\n    }\n\n    for docstring_line in \"\"\"An unscoped enumeration\n\nMembers:\n\n  EOne : Docstring for EOne\n\n  ETwo : Docstring for ETwo\n\n  EThree : Docstring for EThree\"\"\".split(\n        \"\\n\"\n    ):\n        assert docstring_line in m.UnscopedEnum.__doc__\n\n    # Unscoped enums will accept ==/!= int comparisons\n    y = m.UnscopedEnum.ETwo\n    assert y == 2\n    assert 2 == y\n    assert y != 3\n    assert 3 != y\n    # Compare with None\n    assert y != None  # noqa: E711\n    assert not (y == None)  # noqa: E711\n    # Compare with an object\n    assert y != object()\n    assert not (y == object())\n    # Compare with string\n    assert y != \"2\"\n    assert \"2\" != y\n    assert not (\"2\" == y)\n    assert not (y == \"2\")\n\n    with pytest.raises(TypeError):\n        y < object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y <= object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y > object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y >= object()  # noqa: B015\n\n    with pytest.raises(TypeError):\n        y | object()\n\n    with pytest.raises(TypeError):\n        y & object()\n\n    with pytest.raises(TypeError):\n        y ^ object()\n\n    assert int(m.UnscopedEnum.ETwo) == 2\n    assert str(m.UnscopedEnum(2)) == \"UnscopedEnum.ETwo\"\n\n    # order\n    assert m.UnscopedEnum.EOne < m.UnscopedEnum.ETwo\n    assert m.UnscopedEnum.EOne < 2\n    assert m.UnscopedEnum.ETwo > m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.ETwo > 1\n    assert m.UnscopedEnum.ETwo <= 2\n    assert m.UnscopedEnum.ETwo >= 2\n    assert m.UnscopedEnum.EOne <= m.UnscopedEnum.ETwo\n    assert m.UnscopedEnum.EOne <= 2\n    assert m.UnscopedEnum.ETwo >= m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.ETwo >= 1\n    assert not (m.UnscopedEnum.ETwo < m.UnscopedEnum.EOne)\n    assert not (2 < m.UnscopedEnum.EOne)\n\n    # arithmetic\n    assert m.UnscopedEnum.EOne & m.UnscopedEnum.EThree == m.UnscopedEnum.EOne\n    assert m.UnscopedEnum.EOne | m.UnscopedEnum.ETwo == m.UnscopedEnum.EThree\n    assert m.UnscopedEnum.EOne ^ m.UnscopedEnum.EThree == m.UnscopedEnum.ETwo\n\n\ndef test_scoped_enum():\n    assert m.test_scoped_enum(m.ScopedEnum.Three) == \"ScopedEnum::Three\"\n    z = m.ScopedEnum.Two\n    assert m.test_scoped_enum(z) == \"ScopedEnum::Two\"\n\n    # Scoped enums will *NOT* accept ==/!= int comparisons (Will always return False)\n    assert not z == 3\n    assert not 3 == z\n    assert z != 3\n    assert 3 != z\n    # Compare with None\n    assert z != None  # noqa: E711\n    assert not (z == None)  # noqa: E711\n    # Compare with an object\n    assert z != object()\n    assert not (z == object())\n    # Scoped enums will *NOT* accept >, <, >= and <= int comparisons (Will throw exceptions)\n    with pytest.raises(TypeError):\n        z > 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z < 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z >= 3  # noqa: B015\n    with pytest.raises(TypeError):\n        z <= 3  # noqa: B015\n\n    # order\n    assert m.ScopedEnum.Two < m.ScopedEnum.Three\n    assert m.ScopedEnum.Three > m.ScopedEnum.Two\n    assert m.ScopedEnum.Two <= m.ScopedEnum.Three\n    assert m.ScopedEnum.Two <= m.ScopedEnum.Two\n    assert m.ScopedEnum.Two >= m.ScopedEnum.Two\n    assert m.ScopedEnum.Three >= m.ScopedEnum.Two\n\n\ndef test_implicit_conversion():\n    assert str(m.ClassWithUnscopedEnum.EMode.EFirstMode) == \"EMode.EFirstMode\"\n    assert str(m.ClassWithUnscopedEnum.EFirstMode) == \"EMode.EFirstMode\"\n    assert repr(m.ClassWithUnscopedEnum.EMode.EFirstMode) == \"<EMode.EFirstMode: 1>\"\n    assert repr(m.ClassWithUnscopedEnum.EFirstMode) == \"<EMode.EFirstMode: 1>\"\n\n    f = m.ClassWithUnscopedEnum.test_function\n    first = m.ClassWithUnscopedEnum.EFirstMode\n    second = m.ClassWithUnscopedEnum.ESecondMode\n\n    assert f(first) == 1\n\n    assert f(first) == f(first)\n    assert not f(first) != f(first)\n\n    assert f(first) != f(second)\n    assert not f(first) == f(second)\n\n    assert f(first) == int(f(first))\n    assert not f(first) != int(f(first))\n\n    assert f(first) != int(f(second))\n    assert not f(first) == int(f(second))\n\n    # noinspection PyDictCreation\n    x = {f(first): 1, f(second): 2}\n    x[f(first)] = 3\n    x[f(second)] = 4\n    # Hashing test\n    assert repr(x) == \"{<EMode.EFirstMode: 1>: 3, <EMode.ESecondMode: 2>: 4}\"\n\n\ndef test_binary_operators():\n    assert int(m.Flags.Read) == 4\n    assert int(m.Flags.Write) == 2\n    assert int(m.Flags.Execute) == 1\n    assert int(m.Flags.Read | m.Flags.Write | m.Flags.Execute) == 7\n    assert int(m.Flags.Read | m.Flags.Write) == 6\n    assert int(m.Flags.Read | m.Flags.Execute) == 5\n    assert int(m.Flags.Write | m.Flags.Execute) == 3\n    assert int(m.Flags.Write | 1) == 3\n    assert ~m.Flags.Write == -3\n\n    state = m.Flags.Read | m.Flags.Write\n    assert (state & m.Flags.Read) != 0\n    assert (state & m.Flags.Write) != 0\n    assert (state & m.Flags.Execute) == 0\n    assert (state & 1) == 0\n\n    state2 = ~state\n    assert state2 == -7\n    assert int(state ^ state2) == -1\n\n\ndef test_enum_to_int():\n    m.test_enum_to_int(m.Flags.Read)\n    m.test_enum_to_int(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_int(m.ScopedCharEnum.Positive)\n    m.test_enum_to_int(m.ScopedBoolEnum.TRUE)\n    m.test_enum_to_uint(m.Flags.Read)\n    m.test_enum_to_uint(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_uint(m.ScopedCharEnum.Positive)\n    m.test_enum_to_uint(m.ScopedBoolEnum.TRUE)\n    m.test_enum_to_long_long(m.Flags.Read)\n    m.test_enum_to_long_long(m.ClassWithUnscopedEnum.EMode.EFirstMode)\n    m.test_enum_to_long_long(m.ScopedCharEnum.Positive)\n    m.test_enum_to_long_long(m.ScopedBoolEnum.TRUE)\n\n\ndef test_duplicate_enum_name():\n    with pytest.raises(ValueError) as excinfo:\n        m.register_bad_enum()\n    assert str(excinfo.value) == 'SimpleEnum: element \"ONE\" already exists!'\n\n\ndef test_char_underlying_enum():  # Issue #1331/PR #1334:\n    assert type(m.ScopedCharEnum.Positive.__int__()) is int\n    assert int(m.ScopedChar16Enum.Zero) == 0\n    assert hash(m.ScopedChar32Enum.Positive) == 1\n    if env.PY2:\n        assert m.ScopedCharEnum.Positive.__getstate__() == 1  # long\n    else:\n        assert type(m.ScopedCharEnum.Positive.__getstate__()) is int\n    assert m.ScopedWCharEnum(1) == m.ScopedWCharEnum.Positive\n    with pytest.raises(TypeError):\n        # Even if the underlying type is char, only an int can be used to construct the enum:\n        m.ScopedCharEnum(\"0\")\n\n\ndef test_bool_underlying_enum():\n    assert type(m.ScopedBoolEnum.TRUE.__int__()) is int\n    assert int(m.ScopedBoolEnum.FALSE) == 0\n    assert hash(m.ScopedBoolEnum.TRUE) == 1\n    if env.PY2:\n        assert m.ScopedBoolEnum.TRUE.__getstate__() == 1  # long\n    else:\n        assert type(m.ScopedBoolEnum.TRUE.__getstate__()) is int\n    assert m.ScopedBoolEnum(1) == m.ScopedBoolEnum.TRUE\n    # Enum could construct with a bool\n    # (bool is a strict subclass of int, and False will be converted to 0)\n    assert m.ScopedBoolEnum(False) == m.ScopedBoolEnum.FALSE\n\n\ndef test_docstring_signatures():\n    for enum_type in [m.ScopedEnum, m.UnscopedEnum]:\n        for attr in enum_type.__dict__.values():\n            # Issue #2623/PR #2637: Add argument names to enum_ methods\n            assert \"arg0\" not in (attr.__doc__ or \"\")\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_eval.cpp",
    "content": "/*\n    tests/test_eval.cpp -- Usage of eval() and eval_file()\n\n    Copyright (c) 2016 Klemens D. Morgenstern\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/eval.h>\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nTEST_SUBMODULE(eval_, m) {\n    // test_evals\n\n    auto global = py::dict(py::module_::import(\"__main__\").attr(\"__dict__\"));\n\n    m.def(\"test_eval_statements\", [global]() {\n        auto local = py::dict();\n        local[\"call_test\"] = py::cpp_function([&]() -> int { return 42; });\n\n        // Regular string literal\n        py::exec(\"message = 'Hello World!'\\n\"\n                 \"x = call_test()\",\n                 global,\n                 local);\n\n        // Multi-line raw string literal\n        py::exec(R\"(\n            if x == 42:\n                print(message)\n            else:\n                raise RuntimeError\n            )\",\n                 global,\n                 local);\n        auto x = local[\"x\"].cast<int>();\n\n        return x == 42;\n    });\n\n    m.def(\"test_eval\", [global]() {\n        auto local = py::dict();\n        local[\"x\"] = py::int_(42);\n        auto x = py::eval(\"x\", global, local);\n        return x.cast<int>() == 42;\n    });\n\n    m.def(\"test_eval_single_statement\", []() {\n        auto local = py::dict();\n        local[\"call_test\"] = py::cpp_function([&]() -> int { return 42; });\n\n        auto result = py::eval<py::eval_single_statement>(\"x = call_test()\", py::dict(), local);\n        auto x = local[\"x\"].cast<int>();\n        return result.is_none() && x == 42;\n    });\n\n    m.def(\"test_eval_file\", [global](py::str filename) {\n        auto local = py::dict();\n        local[\"y\"] = py::int_(43);\n\n        int val_out = 0;\n        local[\"call_test2\"] = py::cpp_function([&](int value) { val_out = value; });\n\n        auto result = py::eval_file(std::move(filename), global, local);\n        return val_out == 43 && result.is_none();\n    });\n\n    m.def(\"test_eval_failure\", []() {\n        try {\n            py::eval(\"nonsense code ...\");\n        } catch (py::error_already_set &) {\n            return true;\n        }\n        return false;\n    });\n\n    m.def(\"test_eval_file_failure\", []() {\n        try {\n            py::eval_file(\"non-existing file\");\n        } catch (std::exception &) {\n            return true;\n        }\n        return false;\n    });\n\n    // test_eval_empty_globals\n    m.def(\"eval_empty_globals\", [](py::object global) {\n        if (global.is_none()) {\n            global = py::dict();\n        }\n        auto int_class = py::eval(\"isinstance(42, int)\", global);\n        return global;\n    });\n\n    // test_eval_closure\n    m.def(\"test_eval_closure\", []() {\n        py::dict global;\n        global[\"closure_value\"] = 42;\n        py::dict local;\n        local[\"closure_value\"] = 0;\n        py::exec(R\"(\n            local_value = closure_value\n\n            def func_global():\n                return closure_value\n\n            def func_local():\n                return local_value\n            )\",\n                 global,\n                 local);\n        return std::make_pair(global, local);\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_eval.py",
    "content": "# -*- coding: utf-8 -*-\nimport os\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import eval_ as m\n\n\ndef test_evals(capture):\n    with capture:\n        assert m.test_eval_statements()\n    assert capture == \"Hello World!\"\n\n    assert m.test_eval()\n    assert m.test_eval_single_statement()\n\n    assert m.test_eval_failure()\n\n\n@pytest.mark.xfail(\"env.PYPY and not env.PY2\", raises=RuntimeError)\ndef test_eval_file():\n    filename = os.path.join(os.path.dirname(__file__), \"test_eval_call.py\")\n    assert m.test_eval_file(filename)\n\n    assert m.test_eval_file_failure()\n\n\ndef test_eval_empty_globals():\n    assert \"__builtins__\" in m.eval_empty_globals(None)\n\n    g = {}\n    assert \"__builtins__\" in m.eval_empty_globals(g)\n    assert \"__builtins__\" in g\n\n\ndef test_eval_closure():\n    global_, local = m.test_eval_closure()\n\n    assert global_[\"closure_value\"] == 42\n    assert local[\"closure_value\"] == 0\n\n    assert \"local_value\" not in global_\n    assert local[\"local_value\"] == 0\n\n    assert \"func_global\" not in global_\n    assert local[\"func_global\"]() == 42\n\n    assert \"func_local\" not in global_\n    with pytest.raises(NameError):\n        local[\"func_local\"]()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_eval_call.py",
    "content": "# -*- coding: utf-8 -*-\n# This file is called from 'test_eval.py'\n\nif \"call_test2\" in locals():\n    call_test2(y)  # noqa: F821 undefined name\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_exceptions.cpp",
    "content": "/*\n    tests/test_custom-exceptions.cpp -- exception translation\n\n    Copyright (c) 2016 Pim Schellart <P.Schellart@princeton.edu>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n#include \"test_exceptions.h\"\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <exception>\n#include <stdexcept>\n#include <utility>\n\n// A type that should be raised as an exception in Python\nclass MyException : public std::exception {\npublic:\n    explicit MyException(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// A type that should be translated to a standard Python exception\nclass MyException2 : public std::exception {\npublic:\n    explicit MyException2(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// A type that is not derived from std::exception (and is thus unknown)\nclass MyException3 {\npublic:\n    explicit MyException3(const char *m) : message{m} {}\n    virtual const char *what() const noexcept { return message.c_str(); }\n    // Rule of 5 BEGIN: to preempt compiler warnings.\n    MyException3(const MyException3 &) = default;\n    MyException3(MyException3 &&) = default;\n    MyException3 &operator=(const MyException3 &) = default;\n    MyException3 &operator=(MyException3 &&) = default;\n    virtual ~MyException3() = default;\n    // Rule of 5 END.\nprivate:\n    std::string message = \"\";\n};\n\n// A type that should be translated to MyException\n// and delegated to its exception translator\nclass MyException4 : public std::exception {\npublic:\n    explicit MyException4(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\n// Like the above, but declared via the helper function\nclass MyException5 : public std::logic_error {\npublic:\n    explicit MyException5(const std::string &what) : std::logic_error(what) {}\n};\n\n// Inherits from MyException5\nclass MyException5_1 : public MyException5 {\n    using MyException5::MyException5;\n};\n\n// Exception that will be caught via the module local translator.\nclass MyException6 : public std::exception {\npublic:\n    explicit MyException6(const char *m) : message{m} {}\n    const char *what() const noexcept override { return message.c_str(); }\n\nprivate:\n    std::string message = \"\";\n};\n\nstruct PythonCallInDestructor {\n    explicit PythonCallInDestructor(const py::dict &d) : d(d) {}\n    ~PythonCallInDestructor() { d[\"good\"] = true; }\n\n    py::dict d;\n};\n\nstruct PythonAlreadySetInDestructor {\n    explicit PythonAlreadySetInDestructor(const py::str &s) : s(s) {}\n    ~PythonAlreadySetInDestructor() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            ex.discard_as_unraisable(s);\n        }\n    }\n\n    py::str s;\n};\n\nTEST_SUBMODULE(exceptions, m) {\n    m.def(\"throw_std_exception\",\n          []() { throw std::runtime_error(\"This exception was intentionally thrown.\"); });\n\n    // make a new custom exception and use it as a translation target\n    static py::exception<MyException> ex(m, \"MyException\");\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException &e) {\n            // Set MyException as the active python error\n            ex(e.what());\n        }\n    });\n\n    // register new translator for MyException2\n    // no need to store anything here because this type will\n    // never by visible from Python\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException2 &e) {\n            // Translate this exception to a standard RuntimeError\n            PyErr_SetString(PyExc_RuntimeError, e.what());\n        }\n    });\n\n    // register new translator for MyException4\n    // which will catch it and delegate to the previously registered\n    // translator for MyException by throwing a new exception\n    py::register_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException4 &e) {\n            throw MyException(e.what());\n        }\n    });\n\n    // A simple exception translation:\n    auto ex5 = py::register_exception<MyException5>(m, \"MyException5\");\n    // A slightly more complicated one that declares MyException5_1 as a subclass of MyException5\n    py::register_exception<MyException5_1>(m, \"MyException5_1\", ex5.ptr());\n\n    // py::register_local_exception<LocalSimpleException>(m, \"LocalSimpleException\")\n\n    py::register_local_exception_translator([](std::exception_ptr p) {\n        try {\n            if (p) {\n                std::rethrow_exception(p);\n            }\n        } catch (const MyException6 &e) {\n            PyErr_SetString(PyExc_RuntimeError, e.what());\n        }\n    });\n\n    m.def(\"throws1\", []() { throw MyException(\"this error should go to a custom type\"); });\n    m.def(\"throws2\",\n          []() { throw MyException2(\"this error should go to a standard Python exception\"); });\n    m.def(\"throws3\", []() { throw MyException3(\"this error cannot be translated\"); });\n    m.def(\"throws4\", []() { throw MyException4(\"this error is rethrown\"); });\n    m.def(\"throws5\",\n          []() { throw MyException5(\"this is a helper-defined translated exception\"); });\n    m.def(\"throws5_1\", []() { throw MyException5_1(\"MyException5 subclass\"); });\n    m.def(\"throws6\", []() { throw MyException6(\"MyException6 only handled in this module\"); });\n    m.def(\"throws_logic_error\", []() {\n        throw std::logic_error(\"this error should fall through to the standard handler\");\n    });\n    m.def(\"throws_overflow_error\", []() { throw std::overflow_error(\"\"); });\n    m.def(\"throws_local_error\", []() { throw LocalException(\"never caught\"); });\n    m.def(\"throws_local_simple_error\", []() { throw LocalSimpleException(\"this mod\"); });\n    m.def(\"exception_matches\", []() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_KeyError)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n    m.def(\"exception_matches_base\", []() {\n        py::dict foo;\n        try {\n            // Assign to a py::object to force read access of nonexistent dict entry\n            py::object o = foo[\"bar\"];\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_Exception)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n    m.def(\"modulenotfound_exception_matches_base\", []() {\n        try {\n            // On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError\n            py::module_::import(\"nonexistent\");\n        } catch (py::error_already_set &ex) {\n            if (!ex.matches(PyExc_ImportError)) {\n                throw;\n            }\n            return true;\n        }\n        return false;\n    });\n\n    m.def(\"throw_already_set\", [](bool err) {\n        if (err) {\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n        }\n        try {\n            throw py::error_already_set();\n        } catch (const std::runtime_error &e) {\n            if ((err && e.what() != std::string(\"ValueError: foo\"))\n                || (!err && e.what() != std::string(\"Unknown internal error occurred\"))) {\n                PyErr_Clear();\n                throw std::runtime_error(\"error message mismatch\");\n            }\n        }\n        PyErr_Clear();\n        if (err) {\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n        }\n        throw py::error_already_set();\n    });\n\n    m.def(\"python_call_in_destructor\", [](const py::dict &d) {\n        bool retval = false;\n        try {\n            PythonCallInDestructor set_dict_in_destructor(d);\n            PyErr_SetString(PyExc_ValueError, \"foo\");\n            throw py::error_already_set();\n        } catch (const py::error_already_set &) {\n            retval = true;\n        }\n        return retval;\n    });\n\n    m.def(\"python_alreadyset_in_destructor\", [](const py::str &s) {\n        PythonAlreadySetInDestructor alreadyset_in_destructor(s);\n        return true;\n    });\n\n    // test_nested_throws\n    m.def(\"try_catch\",\n          [m](const py::object &exc_type, const py::function &f, const py::args &args) {\n              try {\n                  f(*args);\n              } catch (py::error_already_set &ex) {\n                  if (ex.matches(exc_type)) {\n                      py::print(ex.what());\n                  } else {\n                      throw;\n                  }\n              }\n          });\n\n    // Test repr that cannot be displayed\n    m.def(\"simple_bool_passthrough\", [](bool x) { return x; });\n\n    m.def(\"throw_should_be_translated_to_key_error\", []() { throw shared_exception(); });\n\n#if PY_VERSION_HEX >= 0x03030000\n\n    m.def(\"raise_from\", []() {\n        PyErr_SetString(PyExc_ValueError, \"inner\");\n        py::raise_from(PyExc_ValueError, \"outer\");\n        throw py::error_already_set();\n    });\n\n    m.def(\"raise_from_already_set\", []() {\n        try {\n            PyErr_SetString(PyExc_ValueError, \"inner\");\n            throw py::error_already_set();\n        } catch (py::error_already_set &e) {\n            py::raise_from(e, PyExc_ValueError, \"outer\");\n            throw py::error_already_set();\n        }\n    });\n\n    m.def(\"throw_nested_exception\", []() {\n        try {\n            throw std::runtime_error(\"Inner Exception\");\n        } catch (const std::runtime_error &) {\n            std::throw_with_nested(std::runtime_error(\"Outer Exception\"));\n        }\n    });\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_exceptions.h",
    "content": "#pragma once\n#include \"pybind11_tests.h\"\n\n#include <stdexcept>\n\n// shared exceptions for cross_module_tests\n\nclass PYBIND11_EXPORT_EXCEPTION shared_exception : public pybind11::builtin_exception {\npublic:\n    using builtin_exception::builtin_exception;\n    explicit shared_exception() : shared_exception(\"\") {}\n    void set_error() const override { PyErr_SetString(PyExc_RuntimeError, what()); }\n};\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_exceptions.py",
    "content": "# -*- coding: utf-8 -*-\nimport sys\n\nimport pytest\n\nimport env\nimport pybind11_cross_module_tests as cm\nfrom pybind11_tests import exceptions as m\n\n\ndef test_std_exception(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_std_exception()\n    assert msg(excinfo.value) == \"This exception was intentionally thrown.\"\n\n\ndef test_error_already_set(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_already_set(False)\n    assert msg(excinfo.value) == \"Unknown internal error occurred\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.throw_already_set(True)\n    assert msg(excinfo.value) == \"foo\"\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_raise_from(msg):\n    with pytest.raises(ValueError) as excinfo:\n        m.raise_from()\n    assert msg(excinfo.value) == \"outer\"\n    assert msg(excinfo.value.__cause__) == \"inner\"\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_raise_from_already_set(msg):\n    with pytest.raises(ValueError) as excinfo:\n        m.raise_from_already_set()\n    assert msg(excinfo.value) == \"outer\"\n    assert msg(excinfo.value.__cause__) == \"inner\"\n\n\ndef test_cross_module_exceptions(msg):\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.raise_runtime_error()\n    assert str(excinfo.value) == \"My runtime error\"\n\n    with pytest.raises(ValueError) as excinfo:\n        cm.raise_value_error()\n    assert str(excinfo.value) == \"My value error\"\n\n    with pytest.raises(ValueError) as excinfo:\n        cm.throw_pybind_value_error()\n    assert str(excinfo.value) == \"pybind11 value error\"\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.throw_pybind_type_error()\n    assert str(excinfo.value) == \"pybind11 type error\"\n\n    with pytest.raises(StopIteration) as excinfo:\n        cm.throw_stop_iteration()\n\n    with pytest.raises(cm.LocalSimpleException) as excinfo:\n        cm.throw_local_simple_error()\n    assert msg(excinfo.value) == \"external mod\"\n\n    with pytest.raises(KeyError) as excinfo:\n        cm.throw_local_error()\n    # KeyError is a repr of the key, so it has an extra set of quotes\n    assert str(excinfo.value) == \"'just local'\"\n\n\n# TODO: FIXME\n@pytest.mark.xfail(\n    \"env.PYPY and env.MACOS\",\n    raises=RuntimeError,\n    reason=\"Expected failure with PyPy and libc++ (Issue #2847 & PR #2999)\",\n)\ndef test_cross_module_exception_translator():\n    with pytest.raises(KeyError):\n        # translator registered in cross_module_tests\n        m.throw_should_be_translated_to_key_error()\n\n\ndef test_python_call_in_catch():\n    d = {}\n    assert m.python_call_in_destructor(d) is True\n    assert d[\"good\"] is True\n\n\ndef ignore_pytest_unraisable_warning(f):\n    unraisable = \"PytestUnraisableExceptionWarning\"\n    if hasattr(pytest, unraisable):  # Python >= 3.8 and pytest >= 6\n        dec = pytest.mark.filterwarnings(\"ignore::pytest.{}\".format(unraisable))\n        return dec(f)\n    else:\n        return f\n\n\n# TODO: find out why this fails on PyPy, https://foss.heptapod.net/pypy/pypy/-/issues/3583\n@pytest.mark.xfail(env.PYPY, reason=\"Failure on PyPy 3.8 (7.3.7)\", strict=False)\n@ignore_pytest_unraisable_warning\ndef test_python_alreadyset_in_destructor(monkeypatch, capsys):\n    hooked = False\n    triggered = [False]  # mutable, so Python 2.7 closure can modify it\n\n    if hasattr(sys, \"unraisablehook\"):  # Python 3.8+\n        hooked = True\n        # Don't take `sys.unraisablehook`, as that's overwritten by pytest\n        default_hook = sys.__unraisablehook__\n\n        def hook(unraisable_hook_args):\n            exc_type, exc_value, exc_tb, err_msg, obj = unraisable_hook_args\n            if obj == \"already_set demo\":\n                triggered[0] = True\n            default_hook(unraisable_hook_args)\n            return\n\n        # Use monkeypatch so pytest can apply and remove the patch as appropriate\n        monkeypatch.setattr(sys, \"unraisablehook\", hook)\n\n    assert m.python_alreadyset_in_destructor(\"already_set demo\") is True\n    if hooked:\n        assert triggered[0] is True\n\n    _, captured_stderr = capsys.readouterr()\n    # Error message is different in Python 2 and 3, check for words that appear in both\n    assert \"ignored\" in captured_stderr and \"already_set demo\" in captured_stderr\n\n\ndef test_exception_matches():\n    assert m.exception_matches()\n    assert m.exception_matches_base()\n    assert m.modulenotfound_exception_matches_base()\n\n\ndef test_custom(msg):\n    # Can we catch a MyException?\n    with pytest.raises(m.MyException) as excinfo:\n        m.throws1()\n    assert msg(excinfo.value) == \"this error should go to a custom type\"\n\n    # Can we translate to standard Python exceptions?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws2()\n    assert msg(excinfo.value) == \"this error should go to a standard Python exception\"\n\n    # Can we handle unknown exceptions?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws3()\n    assert msg(excinfo.value) == \"Caught an unknown exception!\"\n\n    # Can we delegate to another handler by rethrowing?\n    with pytest.raises(m.MyException) as excinfo:\n        m.throws4()\n    assert msg(excinfo.value) == \"this error is rethrown\"\n\n    # Can we fall-through to the default handler?\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws_logic_error()\n    assert (\n        msg(excinfo.value) == \"this error should fall through to the standard handler\"\n    )\n\n    # OverFlow error translation.\n    with pytest.raises(OverflowError) as excinfo:\n        m.throws_overflow_error()\n\n    # Can we handle a helper-declared exception?\n    with pytest.raises(m.MyException5) as excinfo:\n        m.throws5()\n    assert msg(excinfo.value) == \"this is a helper-defined translated exception\"\n\n    # Exception subclassing:\n    with pytest.raises(m.MyException5) as excinfo:\n        m.throws5_1()\n    assert msg(excinfo.value) == \"MyException5 subclass\"\n    assert isinstance(excinfo.value, m.MyException5_1)\n\n    with pytest.raises(m.MyException5_1) as excinfo:\n        m.throws5_1()\n    assert msg(excinfo.value) == \"MyException5 subclass\"\n\n    with pytest.raises(m.MyException5) as excinfo:\n        try:\n            m.throws5()\n        except m.MyException5_1:\n            raise RuntimeError(\"Exception error: caught child from parent\")\n    assert msg(excinfo.value) == \"this is a helper-defined translated exception\"\n\n\ndef test_nested_throws(capture):\n    \"\"\"Tests nested (e.g. C++ -> Python -> C++) exception handling\"\"\"\n\n    def throw_myex():\n        raise m.MyException(\"nested error\")\n\n    def throw_myex5():\n        raise m.MyException5(\"nested error 5\")\n\n    # In the comments below, the exception is caught in the first step, thrown in the last step\n\n    # C++ -> Python\n    with capture:\n        m.try_catch(m.MyException5, throw_myex5)\n    assert str(capture).startswith(\"MyException5: nested error 5\")\n\n    # Python -> C++ -> Python\n    with pytest.raises(m.MyException) as excinfo:\n        m.try_catch(m.MyException5, throw_myex)\n    assert str(excinfo.value) == \"nested error\"\n\n    def pycatch(exctype, f, *args):\n        try:\n            f(*args)\n        except m.MyException as e:\n            print(e)\n\n    # C++ -> Python -> C++ -> Python\n    with capture:\n        m.try_catch(\n            m.MyException5,\n            pycatch,\n            m.MyException,\n            m.try_catch,\n            m.MyException,\n            throw_myex5,\n        )\n    assert str(capture).startswith(\"MyException5: nested error 5\")\n\n    # C++ -> Python -> C++\n    with capture:\n        m.try_catch(m.MyException, pycatch, m.MyException5, m.throws4)\n    assert capture == \"this error is rethrown\"\n\n    # Python -> C++ -> Python -> C++\n    with pytest.raises(m.MyException5) as excinfo:\n        m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)\n    assert str(excinfo.value) == \"this is a helper-defined translated exception\"\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_throw_nested_exception():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throw_nested_exception()\n    assert str(excinfo.value) == \"Outer Exception\"\n    assert str(excinfo.value.__cause__) == \"Inner Exception\"\n\n\n# This can often happen if you wrap a pybind11 class in a Python wrapper\ndef test_invalid_repr():\n    class MyRepr(object):\n        def __repr__(self):\n            raise AttributeError(\"Example error\")\n\n    with pytest.raises(TypeError):\n        m.simple_bool_passthrough(MyRepr())\n\n\ndef test_local_translator(msg):\n    \"\"\"Tests that a local translator works and that the local translator from\n    the cross module is not applied\"\"\"\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws6()\n    assert msg(excinfo.value) == \"MyException6 only handled in this module\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.throws_local_error()\n    assert not isinstance(excinfo.value, KeyError)\n    assert msg(excinfo.value) == \"never caught\"\n\n    with pytest.raises(Exception) as excinfo:\n        m.throws_local_simple_error()\n    assert not isinstance(excinfo.value, cm.LocalSimpleException)\n    assert msg(excinfo.value) == \"this mod\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_factory_constructors.cpp",
    "content": "/*\n    tests/test_factory_constructors.cpp -- tests construction from a factory function\n                                           via py::init_factory()\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <cmath>\n#include <new>\n#include <utility>\n\n// Classes for testing python construction via C++ factory function:\n// Not publicly constructible, copyable, or movable:\nclass TestFactory1 {\n    friend class TestFactoryHelper;\n    TestFactory1() : value(\"(empty)\") { print_default_created(this); }\n    explicit TestFactory1(int v) : value(std::to_string(v)) { print_created(this, value); }\n    explicit TestFactory1(std::string v) : value(std::move(v)) { print_created(this, value); }\n\npublic:\n    std::string value;\n    TestFactory1(TestFactory1 &&) = delete;\n    TestFactory1(const TestFactory1 &) = delete;\n    TestFactory1 &operator=(TestFactory1 &&) = delete;\n    TestFactory1 &operator=(const TestFactory1 &) = delete;\n    ~TestFactory1() { print_destroyed(this); }\n};\n// Non-public construction, but moveable:\nclass TestFactory2 {\n    friend class TestFactoryHelper;\n    TestFactory2() : value(\"(empty2)\") { print_default_created(this); }\n    explicit TestFactory2(int v) : value(std::to_string(v)) { print_created(this, value); }\n    explicit TestFactory2(std::string v) : value(std::move(v)) { print_created(this, value); }\n\npublic:\n    TestFactory2(TestFactory2 &&m) noexcept : value{std::move(m.value)} {\n        print_move_created(this);\n    }\n    TestFactory2 &operator=(TestFactory2 &&m) noexcept {\n        value = std::move(m.value);\n        print_move_assigned(this);\n        return *this;\n    }\n    std::string value;\n    ~TestFactory2() { print_destroyed(this); }\n};\n// Mixed direct/factory construction:\nclass TestFactory3 {\nprotected:\n    friend class TestFactoryHelper;\n    TestFactory3() : value(\"(empty3)\") { print_default_created(this); }\n    explicit TestFactory3(int v) : value(std::to_string(v)) { print_created(this, value); }\n\npublic:\n    explicit TestFactory3(std::string v) : value(std::move(v)) { print_created(this, value); }\n    TestFactory3(TestFactory3 &&m) noexcept : value{std::move(m.value)} {\n        print_move_created(this);\n    }\n    TestFactory3 &operator=(TestFactory3 &&m) noexcept {\n        value = std::move(m.value);\n        print_move_assigned(this);\n        return *this;\n    }\n    std::string value;\n    virtual ~TestFactory3() { print_destroyed(this); }\n};\n// Inheritance test\nclass TestFactory4 : public TestFactory3 {\npublic:\n    TestFactory4() : TestFactory3() { print_default_created(this); }\n    explicit TestFactory4(int v) : TestFactory3(v) { print_created(this, v); }\n    ~TestFactory4() override { print_destroyed(this); }\n};\n// Another class for an invalid downcast test\nclass TestFactory5 : public TestFactory3 {\npublic:\n    explicit TestFactory5(int i) : TestFactory3(i) { print_created(this, i); }\n    ~TestFactory5() override { print_destroyed(this); }\n};\n\nclass TestFactory6 {\nprotected:\n    int value;\n    bool alias = false;\n\npublic:\n    explicit TestFactory6(int i) : value{i} { print_created(this, i); }\n    TestFactory6(TestFactory6 &&f) noexcept {\n        print_move_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    TestFactory6(const TestFactory6 &f) {\n        print_copy_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    virtual ~TestFactory6() { print_destroyed(this); }\n    virtual int get() { return value; }\n    bool has_alias() const { return alias; }\n};\nclass PyTF6 : public TestFactory6 {\npublic:\n    // Special constructor that allows the factory to construct a PyTF6 from a TestFactory6 only\n    // when an alias is needed:\n    explicit PyTF6(TestFactory6 &&base) : TestFactory6(std::move(base)) {\n        alias = true;\n        print_created(this, \"move\", value);\n    }\n    explicit PyTF6(int i) : TestFactory6(i) {\n        alias = true;\n        print_created(this, i);\n    }\n    PyTF6(PyTF6 &&f) noexcept : TestFactory6(std::move(f)) { print_move_created(this); }\n    PyTF6(const PyTF6 &f) : TestFactory6(f) { print_copy_created(this); }\n    explicit PyTF6(std::string s) : TestFactory6((int) s.size()) {\n        alias = true;\n        print_created(this, s);\n    }\n    ~PyTF6() override { print_destroyed(this); }\n    int get() override { PYBIND11_OVERRIDE(int, TestFactory6, get, /*no args*/); }\n};\n\nclass TestFactory7 {\nprotected:\n    int value;\n    bool alias = false;\n\npublic:\n    explicit TestFactory7(int i) : value{i} { print_created(this, i); }\n    TestFactory7(TestFactory7 &&f) noexcept {\n        print_move_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    TestFactory7(const TestFactory7 &f) {\n        print_copy_created(this);\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        value = f.value;\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = f.alias;\n    }\n    virtual ~TestFactory7() { print_destroyed(this); }\n    virtual int get() { return value; }\n    bool has_alias() const { return alias; }\n};\nclass PyTF7 : public TestFactory7 {\npublic:\n    explicit PyTF7(int i) : TestFactory7(i) {\n        // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n        alias = true;\n        print_created(this, i);\n    }\n    PyTF7(PyTF7 &&f) noexcept : TestFactory7(std::move(f)) { print_move_created(this); }\n    PyTF7(const PyTF7 &f) : TestFactory7(f) { print_copy_created(this); }\n    ~PyTF7() override { print_destroyed(this); }\n    int get() override { PYBIND11_OVERRIDE(int, TestFactory7, get, /*no args*/); }\n};\n\nclass TestFactoryHelper {\npublic:\n    // Non-movable, non-copyable type:\n    // Return via pointer:\n    static TestFactory1 *construct1() { return new TestFactory1(); }\n    // Holder:\n    static std::unique_ptr<TestFactory1> construct1(int a) {\n        return std::unique_ptr<TestFactory1>(new TestFactory1(a));\n    }\n    // pointer again\n    static TestFactory1 *construct1_string(std::string a) {\n        return new TestFactory1(std::move(a));\n    }\n\n    // Moveable type:\n    // pointer:\n    static TestFactory2 *construct2() { return new TestFactory2(); }\n    // holder:\n    static std::unique_ptr<TestFactory2> construct2(int a) {\n        return std::unique_ptr<TestFactory2>(new TestFactory2(a));\n    }\n    // by value moving:\n    static TestFactory2 construct2(std::string a) { return TestFactory2(std::move(a)); }\n\n    // shared_ptr holder type:\n    // pointer:\n    static TestFactory3 *construct3() { return new TestFactory3(); }\n    // holder:\n    static std::shared_ptr<TestFactory3> construct3(int a) {\n        return std::shared_ptr<TestFactory3>(new TestFactory3(a));\n    }\n};\n\nTEST_SUBMODULE(factory_constructors, m) {\n\n    // Define various trivial types to allow simpler overload resolution:\n    py::module_ m_tag = m.def_submodule(\"tag\");\n#define MAKE_TAG_TYPE(Name)                                                                       \\\n    struct Name##_tag {};                                                                         \\\n    py::class_<Name##_tag>(m_tag, #Name \"_tag\").def(py::init<>());                                \\\n    m_tag.attr(#Name) = py::cast(Name##_tag{})\n    MAKE_TAG_TYPE(pointer);\n    MAKE_TAG_TYPE(unique_ptr);\n    MAKE_TAG_TYPE(move);\n    MAKE_TAG_TYPE(shared_ptr);\n    MAKE_TAG_TYPE(derived);\n    MAKE_TAG_TYPE(TF4);\n    MAKE_TAG_TYPE(TF5);\n    MAKE_TAG_TYPE(null_ptr);\n    MAKE_TAG_TYPE(null_unique_ptr);\n    MAKE_TAG_TYPE(null_shared_ptr);\n    MAKE_TAG_TYPE(base);\n    MAKE_TAG_TYPE(invalid_base);\n    MAKE_TAG_TYPE(alias);\n    MAKE_TAG_TYPE(unaliasable);\n    MAKE_TAG_TYPE(mixed);\n\n    // test_init_factory_basic, test_bad_type\n    py::class_<TestFactory1>(m, \"TestFactory1\")\n        .def(py::init([](unique_ptr_tag, int v) { return TestFactoryHelper::construct1(v); }))\n        .def(py::init(&TestFactoryHelper::construct1_string)) // raw function pointer\n        .def(py::init([](pointer_tag) { return TestFactoryHelper::construct1(); }))\n        .def(py::init(\n            [](py::handle, int v, py::handle) { return TestFactoryHelper::construct1(v); }))\n        .def_readwrite(\"value\", &TestFactory1::value);\n    py::class_<TestFactory2>(m, \"TestFactory2\")\n        .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct2(v); }))\n        .def(py::init([](unique_ptr_tag, std::string v) {\n            return TestFactoryHelper::construct2(std::move(v));\n        }))\n        .def(py::init([](move_tag) { return TestFactoryHelper::construct2(); }))\n        .def_readwrite(\"value\", &TestFactory2::value);\n\n    // Stateful & reused:\n    int c = 1;\n    auto c4a = [c](pointer_tag, TF4_tag, int a) {\n        (void) c;\n        return new TestFactory4(a);\n    };\n\n    // test_init_factory_basic, test_init_factory_casting\n    py::class_<TestFactory3, std::shared_ptr<TestFactory3>> pyTestFactory3(m, \"TestFactory3\");\n    pyTestFactory3\n        .def(py::init([](pointer_tag, int v) { return TestFactoryHelper::construct3(v); }))\n        .def(py::init([](shared_ptr_tag) { return TestFactoryHelper::construct3(); }));\n    ignoreOldStyleInitWarnings([&pyTestFactory3]() {\n        pyTestFactory3.def(\"__init__\", [](TestFactory3 &self, std::string v) {\n            new (&self) TestFactory3(std::move(v));\n        }); // placement-new ctor\n    });\n    pyTestFactory3\n        // factories returning a derived type:\n        .def(py::init(c4a)) // derived ptr\n        .def(py::init([](pointer_tag, TF5_tag, int a) { return new TestFactory5(a); }))\n        // derived shared ptr:\n        .def(py::init(\n            [](shared_ptr_tag, TF4_tag, int a) { return std::make_shared<TestFactory4>(a); }))\n        .def(py::init(\n            [](shared_ptr_tag, TF5_tag, int a) { return std::make_shared<TestFactory5>(a); }))\n\n        // Returns nullptr:\n        .def(py::init([](null_ptr_tag) { return (TestFactory3 *) nullptr; }))\n        .def(py::init([](null_unique_ptr_tag) { return std::unique_ptr<TestFactory3>(); }))\n        .def(py::init([](null_shared_ptr_tag) { return std::shared_ptr<TestFactory3>(); }))\n\n        .def_readwrite(\"value\", &TestFactory3::value);\n\n    // test_init_factory_casting\n    py::class_<TestFactory4, TestFactory3, std::shared_ptr<TestFactory4>>(m, \"TestFactory4\")\n        .def(py::init(c4a)) // pointer\n        ;\n\n    // Doesn't need to be registered, but registering makes getting ConstructorStats easier:\n    py::class_<TestFactory5, TestFactory3, std::shared_ptr<TestFactory5>>(m, \"TestFactory5\");\n\n    // test_init_factory_alias\n    // Alias testing\n    py::class_<TestFactory6, PyTF6>(m, \"TestFactory6\")\n        .def(py::init([](base_tag, int i) { return TestFactory6(i); }))\n        .def(py::init([](alias_tag, int i) { return PyTF6(i); }))\n        .def(py::init([](alias_tag, std::string s) { return PyTF6(std::move(s)); }))\n        .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF6(i); }))\n        .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory6(i); }))\n        .def(py::init(\n            [](base_tag, alias_tag, pointer_tag, int i) { return (TestFactory6 *) new PyTF6(i); }))\n\n        .def(\"get\", &TestFactory6::get)\n        .def(\"has_alias\", &TestFactory6::has_alias)\n\n        .def_static(\n            \"get_cstats\", &ConstructorStats::get<TestFactory6>, py::return_value_policy::reference)\n        .def_static(\n            \"get_alias_cstats\", &ConstructorStats::get<PyTF6>, py::return_value_policy::reference);\n\n    // test_init_factory_dual\n    // Separate alias constructor testing\n    py::class_<TestFactory7, PyTF7, std::shared_ptr<TestFactory7>>(m, \"TestFactory7\")\n        .def(py::init([](int i) { return TestFactory7(i); }, [](int i) { return PyTF7(i); }))\n        .def(py::init([](pointer_tag, int i) { return new TestFactory7(i); },\n                      [](pointer_tag, int i) { return new PyTF7(i); }))\n        .def(py::init([](mixed_tag, int i) { return new TestFactory7(i); },\n                      [](mixed_tag, int i) { return PyTF7(i); }))\n        .def(py::init([](mixed_tag, const std::string &s) { return TestFactory7((int) s.size()); },\n                      [](mixed_tag, const std::string &s) { return new PyTF7((int) s.size()); }))\n        .def(py::init([](base_tag, pointer_tag, int i) { return new TestFactory7(i); },\n                      [](base_tag, pointer_tag, int i) { return (TestFactory7 *) new PyTF7(i); }))\n        .def(py::init([](alias_tag, pointer_tag, int i) { return new PyTF7(i); },\n                      [](alias_tag, pointer_tag, int i) { return new PyTF7(10 * i); }))\n        .def(py::init(\n            [](shared_ptr_tag, base_tag, int i) { return std::make_shared<TestFactory7>(i); },\n            [](shared_ptr_tag, base_tag, int i) {\n                auto *p = new PyTF7(i);\n                return std::shared_ptr<TestFactory7>(p);\n            }))\n        .def(py::init([](shared_ptr_tag,\n                         invalid_base_tag,\n                         int i) { return std::make_shared<TestFactory7>(i); },\n                      [](shared_ptr_tag, invalid_base_tag, int i) {\n                          return std::make_shared<TestFactory7>(i);\n                      })) // <-- invalid alias factory\n\n        .def(\"get\", &TestFactory7::get)\n        .def(\"has_alias\", &TestFactory7::has_alias)\n\n        .def_static(\n            \"get_cstats\", &ConstructorStats::get<TestFactory7>, py::return_value_policy::reference)\n        .def_static(\n            \"get_alias_cstats\", &ConstructorStats::get<PyTF7>, py::return_value_policy::reference);\n\n    // test_placement_new_alternative\n    // Class with a custom new operator but *without* a placement new operator (issue #948)\n    class NoPlacementNew {\n    public:\n        explicit NoPlacementNew(int i) : i(i) {}\n        static void *operator new(std::size_t s) {\n            auto *p = ::operator new(s);\n            py::print(\"operator new called, returning\", reinterpret_cast<uintptr_t>(p));\n            return p;\n        }\n        static void operator delete(void *p) {\n            py::print(\"operator delete called on\", reinterpret_cast<uintptr_t>(p));\n            ::operator delete(p);\n        }\n        int i;\n    };\n    // As of 2.2, `py::init<args>` no longer requires placement new\n    py::class_<NoPlacementNew>(m, \"NoPlacementNew\")\n        .def(py::init<int>())\n        .def(py::init([]() { return new NoPlacementNew(100); }))\n        .def_readwrite(\"i\", &NoPlacementNew::i);\n\n    // test_reallocations\n    // Class that has verbose operator_new/operator_delete calls\n    struct NoisyAlloc {\n        NoisyAlloc(const NoisyAlloc &) = default;\n        explicit NoisyAlloc(int i) { py::print(py::str(\"NoisyAlloc(int {})\").format(i)); }\n        explicit NoisyAlloc(double d) { py::print(py::str(\"NoisyAlloc(double {})\").format(d)); }\n        ~NoisyAlloc() { py::print(\"~NoisyAlloc()\"); }\n\n        static void *operator new(size_t s) {\n            py::print(\"noisy new\");\n            return ::operator new(s);\n        }\n        static void *operator new(size_t, void *p) {\n            py::print(\"noisy placement new\");\n            return p;\n        }\n        static void operator delete(void *p, size_t) {\n            py::print(\"noisy delete\");\n            ::operator delete(p);\n        }\n        static void operator delete(void *, void *) { py::print(\"noisy placement delete\"); }\n#if defined(_MSC_VER) && _MSC_VER < 1910\n        // MSVC 2015 bug: the above \"noisy delete\" isn't invoked (fixed in MSVC 2017)\n        static void operator delete(void *p) {\n            py::print(\"noisy delete\");\n            ::operator delete(p);\n        }\n#endif\n    };\n\n    py::class_<NoisyAlloc> pyNoisyAlloc(m, \"NoisyAlloc\");\n    // Since these overloads have the same number of arguments, the dispatcher will try each of\n    // them until the arguments convert.  Thus we can get a pre-allocation here when passing a\n    // single non-integer:\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\"__init__\", [](NoisyAlloc *a, int i) {\n            new (a) NoisyAlloc(i);\n        }); // Regular constructor, runs first, requires preallocation\n    });\n\n    pyNoisyAlloc.def(py::init([](double d) { return new NoisyAlloc(d); }));\n\n    // The two-argument version: first the factory pointer overload.\n    pyNoisyAlloc.def(py::init([](int i, int) { return new NoisyAlloc(i); }));\n    // Return-by-value:\n    pyNoisyAlloc.def(py::init([](double d, int) { return NoisyAlloc(d); }));\n    // Old-style placement new init; requires preallocation\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\"__init__\",\n                         [](NoisyAlloc &a, double d, double) { new (&a) NoisyAlloc(d); });\n    });\n    // Requires deallocation of previous overload preallocated value:\n    pyNoisyAlloc.def(py::init([](int i, double) { return new NoisyAlloc(i); }));\n    // Regular again: requires yet another preallocation\n    ignoreOldStyleInitWarnings([&pyNoisyAlloc]() {\n        pyNoisyAlloc.def(\n            \"__init__\", [](NoisyAlloc &a, int i, const std::string &) { new (&a) NoisyAlloc(i); });\n    });\n\n    // static_assert testing (the following def's should all fail with appropriate compilation\n    // errors):\n#if 0\n    struct BadF1Base {};\n    struct BadF1 : BadF1Base {};\n    struct PyBadF1 : BadF1 {};\n    py::class_<BadF1, PyBadF1, std::shared_ptr<BadF1>> bf1(m, \"BadF1\");\n    // wrapped factory function must return a compatible pointer, holder, or value\n    bf1.def(py::init([]() { return 3; }));\n    // incompatible factory function pointer return type\n    bf1.def(py::init([]() { static int three = 3; return &three; }));\n    // incompatible factory function std::shared_ptr<T> return type: cannot convert shared_ptr<T> to holder\n    // (non-polymorphic base)\n    bf1.def(py::init([]() { return std::shared_ptr<BadF1Base>(new BadF1()); }));\n#endif\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_factory_constructors.py",
    "content": "# -*- coding: utf-8 -*-\nimport re\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import factory_constructors as m\nfrom pybind11_tests.factory_constructors import tag\n\n\ndef test_init_factory_basic():\n    \"\"\"Tests py::init_factory() wrapper around various ways of returning the object\"\"\"\n\n    cstats = [\n        ConstructorStats.get(c)\n        for c in [m.TestFactory1, m.TestFactory2, m.TestFactory3]\n    ]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    x1 = m.TestFactory1(tag.unique_ptr, 3)\n    assert x1.value == \"3\"\n    y1 = m.TestFactory1(tag.pointer)\n    assert y1.value == \"(empty)\"\n    z1 = m.TestFactory1(\"hi!\")\n    assert z1.value == \"hi!\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n\n    x2 = m.TestFactory2(tag.move)\n    assert x2.value == \"(empty2)\"\n    y2 = m.TestFactory2(tag.pointer, 7)\n    assert y2.value == \"7\"\n    z2 = m.TestFactory2(tag.unique_ptr, \"hi again\")\n    assert z2.value == \"hi again\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n\n    x3 = m.TestFactory3(tag.shared_ptr)\n    assert x3.value == \"(empty3)\"\n    y3 = m.TestFactory3(tag.pointer, 42)\n    assert y3.value == \"42\"\n    z3 = m.TestFactory3(\"bye\")\n    assert z3.value == \"bye\"\n\n    for null_ptr_kind in [tag.null_ptr, tag.null_unique_ptr, tag.null_shared_ptr]:\n        with pytest.raises(TypeError) as excinfo:\n            m.TestFactory3(null_ptr_kind)\n        assert (\n            str(excinfo.value) == \"pybind11::init(): factory function returned nullptr\"\n        )\n\n    assert [i.alive() for i in cstats] == [3, 3, 3]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 9\n\n    del x1, y2, y3, z3\n    assert [i.alive() for i in cstats] == [2, 2, 1]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 5\n    del x2, x3, y1, z1, z2\n    assert [i.alive() for i in cstats] == [0, 0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"3\", \"hi!\"],\n        [\"7\", \"hi again\"],\n        [\"42\", \"bye\"],\n    ]\n    assert [i.default_constructions for i in cstats] == [1, 1, 1]\n\n\ndef test_init_factory_signature(msg):\n    with pytest.raises(TypeError) as excinfo:\n        m.TestFactory1(\"invalid\", \"constructor\", \"arguments\")\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int)\n            2. m.factory_constructors.TestFactory1(arg0: str)\n            3. m.factory_constructors.TestFactory1(arg0: m.factory_constructors.tag.pointer_tag)\n            4. m.factory_constructors.TestFactory1(arg0: handle, arg1: int, arg2: handle)\n\n        Invoked with: 'invalid', 'constructor', 'arguments'\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    assert (\n        msg(m.TestFactory1.__init__.__doc__)\n        == \"\"\"\n        __init__(*args, **kwargs)\n        Overloaded function.\n\n        1. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.unique_ptr_tag, arg1: int) -> None\n\n        2. __init__(self: m.factory_constructors.TestFactory1, arg0: str) -> None\n\n        3. __init__(self: m.factory_constructors.TestFactory1, arg0: m.factory_constructors.tag.pointer_tag) -> None\n\n        4. __init__(self: m.factory_constructors.TestFactory1, arg0: handle, arg1: int, arg2: handle) -> None\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_init_factory_casting():\n    \"\"\"Tests py::init_factory() wrapper with various upcasting and downcasting returns\"\"\"\n\n    cstats = [\n        ConstructorStats.get(c)\n        for c in [m.TestFactory3, m.TestFactory4, m.TestFactory5]\n    ]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    # Construction from derived references:\n    a = m.TestFactory3(tag.pointer, tag.TF4, 4)\n    assert a.value == \"4\"\n    b = m.TestFactory3(tag.shared_ptr, tag.TF4, 5)\n    assert b.value == \"5\"\n    c = m.TestFactory3(tag.pointer, tag.TF5, 6)\n    assert c.value == \"6\"\n    d = m.TestFactory3(tag.shared_ptr, tag.TF5, 7)\n    assert d.value == \"7\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    # Shared a lambda with TF3:\n    e = m.TestFactory4(tag.pointer, tag.TF4, 8)\n    assert e.value == \"8\"\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 5\n    assert [i.alive() for i in cstats] == [5, 3, 2]\n\n    del a\n    assert [i.alive() for i in cstats] == [4, 2, 2]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    del b, c, e\n    assert [i.alive() for i in cstats] == [1, 0, 1]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 1\n\n    del d\n    assert [i.alive() for i in cstats] == [0, 0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"4\", \"5\", \"6\", \"7\", \"8\"],\n        [\"4\", \"5\", \"8\"],\n        [\"6\", \"7\"],\n    ]\n\n\ndef test_init_factory_alias():\n    \"\"\"Tests py::init_factory() wrapper with value conversions and alias types\"\"\"\n\n    cstats = [m.TestFactory6.get_cstats(), m.TestFactory6.get_alias_cstats()]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    a = m.TestFactory6(tag.base, 1)\n    assert a.get() == 1\n    assert not a.has_alias()\n    b = m.TestFactory6(tag.alias, \"hi there\")\n    assert b.get() == 8\n    assert b.has_alias()\n    c = m.TestFactory6(tag.alias, 3)\n    assert c.get() == 3\n    assert c.has_alias()\n    d = m.TestFactory6(tag.alias, tag.pointer, 4)\n    assert d.get() == 4\n    assert d.has_alias()\n    e = m.TestFactory6(tag.base, tag.pointer, 5)\n    assert e.get() == 5\n    assert not e.has_alias()\n    f = m.TestFactory6(tag.base, tag.alias, tag.pointer, 6)\n    assert f.get() == 6\n    assert f.has_alias()\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n    assert [i.alive() for i in cstats] == [6, 4]\n\n    del a, b, e\n    assert [i.alive() for i in cstats] == [3, 3]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    del f, c, d\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    class MyTest(m.TestFactory6):\n        def __init__(self, *args):\n            m.TestFactory6.__init__(self, *args)\n\n        def get(self):\n            return -5 + m.TestFactory6.get(self)\n\n    # Return Class by value, moved into new alias:\n    z = MyTest(tag.base, 123)\n    assert z.get() == 118\n    assert z.has_alias()\n\n    # Return alias by value, moved into new alias:\n    y = MyTest(tag.alias, \"why hello!\")\n    assert y.get() == 5\n    assert y.has_alias()\n\n    # Return Class by pointer, moved into new alias then original destroyed:\n    x = MyTest(tag.base, tag.pointer, 47)\n    assert x.get() == 42\n    assert x.has_alias()\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 3\n    assert [i.alive() for i in cstats] == [3, 3]\n    del x, y, z\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"1\", \"8\", \"3\", \"4\", \"5\", \"6\", \"123\", \"10\", \"47\"],\n        [\"hi there\", \"3\", \"4\", \"6\", \"move\", \"123\", \"why hello!\", \"move\", \"47\"],\n    ]\n\n\ndef test_init_factory_dual():\n    \"\"\"Tests init factory functions with dual main/alias factory functions\"\"\"\n    from pybind11_tests.factory_constructors import TestFactory7\n\n    cstats = [TestFactory7.get_cstats(), TestFactory7.get_alias_cstats()]\n    cstats[0].alive()  # force gc\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    class PythFactory7(TestFactory7):\n        def get(self):\n            return 100 + TestFactory7.get(self)\n\n    a1 = TestFactory7(1)\n    a2 = PythFactory7(2)\n    assert a1.get() == 1\n    assert a2.get() == 102\n    assert not a1.has_alias()\n    assert a2.has_alias()\n\n    b1 = TestFactory7(tag.pointer, 3)\n    b2 = PythFactory7(tag.pointer, 4)\n    assert b1.get() == 3\n    assert b2.get() == 104\n    assert not b1.has_alias()\n    assert b2.has_alias()\n\n    c1 = TestFactory7(tag.mixed, 5)\n    c2 = PythFactory7(tag.mixed, 6)\n    assert c1.get() == 5\n    assert c2.get() == 106\n    assert not c1.has_alias()\n    assert c2.has_alias()\n\n    d1 = TestFactory7(tag.base, tag.pointer, 7)\n    d2 = PythFactory7(tag.base, tag.pointer, 8)\n    assert d1.get() == 7\n    assert d2.get() == 108\n    assert not d1.has_alias()\n    assert d2.has_alias()\n\n    # Both return an alias; the second multiplies the value by 10:\n    e1 = TestFactory7(tag.alias, tag.pointer, 9)\n    e2 = PythFactory7(tag.alias, tag.pointer, 10)\n    assert e1.get() == 9\n    assert e2.get() == 200\n    assert e1.has_alias()\n    assert e2.has_alias()\n\n    f1 = TestFactory7(tag.shared_ptr, tag.base, 11)\n    f2 = PythFactory7(tag.shared_ptr, tag.base, 12)\n    assert f1.get() == 11\n    assert f2.get() == 112\n    assert not f1.has_alias()\n    assert f2.has_alias()\n\n    g1 = TestFactory7(tag.shared_ptr, tag.invalid_base, 13)\n    assert g1.get() == 13\n    assert not g1.has_alias()\n    with pytest.raises(TypeError) as excinfo:\n        PythFactory7(tag.shared_ptr, tag.invalid_base, 14)\n    assert (\n        str(excinfo.value)\n        == \"pybind11::init(): construction failed: returned holder-wrapped instance is not an \"\n        \"alias instance\"\n    )\n\n    assert [i.alive() for i in cstats] == [13, 7]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 13\n\n    del a1, a2, b1, d1, e1, e2\n    assert [i.alive() for i in cstats] == [7, 4]\n    assert ConstructorStats.detail_reg_inst() == n_inst + 7\n    del b2, c1, c2, d2, f1, f2, g1\n    assert [i.alive() for i in cstats] == [0, 0]\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    assert [i.values() for i in cstats] == [\n        [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"100\", \"11\", \"12\", \"13\", \"14\"],\n        [\"2\", \"4\", \"6\", \"8\", \"9\", \"100\", \"12\"],\n    ]\n\n\ndef test_no_placement_new(capture):\n    \"\"\"Prior to 2.2, `py::init<...>` relied on the type supporting placement\n    new; this tests a class without placement new support.\"\"\"\n    with capture:\n        a = m.NoPlacementNew(123)\n\n    found = re.search(r\"^operator new called, returning (\\d+)\\n$\", str(capture))\n    assert found\n    assert a.i == 123\n    with capture:\n        del a\n        pytest.gc_collect()\n    assert capture == \"operator delete called on \" + found.group(1)\n\n    with capture:\n        b = m.NoPlacementNew()\n\n    found = re.search(r\"^operator new called, returning (\\d+)\\n$\", str(capture))\n    assert found\n    assert b.i == 100\n    with capture:\n        del b\n        pytest.gc_collect()\n    assert capture == \"operator delete called on \" + found.group(1)\n\n\ndef test_multiple_inheritance():\n    class MITest(m.TestFactory1, m.TestFactory2):\n        def __init__(self):\n            m.TestFactory1.__init__(self, tag.unique_ptr, 33)\n            m.TestFactory2.__init__(self, tag.move)\n\n    a = MITest()\n    assert m.TestFactory1.value.fget(a) == \"33\"\n    assert m.TestFactory2.value.fget(a) == \"(empty2)\"\n\n\ndef create_and_destroy(*args):\n    a = m.NoisyAlloc(*args)\n    print(\"---\")\n    del a\n    pytest.gc_collect()\n\n\ndef strip_comments(s):\n    return re.sub(r\"\\s+#.*\", \"\", s)\n\n\ndef test_reallocation_a(capture, msg):\n    \"\"\"When the constructor is overloaded, previous overloads can require a preallocated value.\n    This test makes sure that such preallocated values only happen when they might be necessary,\n    and that they are deallocated properly.\"\"\"\n\n    pytest.gc_collect()\n\n    with capture:\n        create_and_destroy(1)\n    assert (\n        msg(capture)\n        == \"\"\"\n        noisy new\n        noisy placement new\n        NoisyAlloc(int 1)\n        ---\n        ~NoisyAlloc()\n        noisy delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_b(capture, msg):\n    with capture:\n        create_and_destroy(1.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new               # allocation required to attempt first overload\n        noisy delete            # have to dealloc before considering factory init overload\n        noisy new               # pointer factory calling \"new\", part 1: allocation\n        NoisyAlloc(double 1.5)  # ... part two, invoking constructor\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_c(capture, msg):\n    with capture:\n        create_and_destroy(2, 3)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new          # pointer factory calling \"new\", allocation\n        NoisyAlloc(int 2)  # constructor\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_d(capture, msg):\n    with capture:\n        create_and_destroy(2.5, 3)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        NoisyAlloc(double 2.5)  # construction (local func variable: operator_new not called)\n        noisy new               # return-by-value \"new\" part 1: allocation\n        ~NoisyAlloc()           # moved-away local func variable destruction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_e(capture, msg):\n    with capture:\n        create_and_destroy(3.5, 4.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new               # preallocation needed before invoking placement-new overload\n        noisy placement new     # Placement new\n        NoisyAlloc(double 3.5)  # construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_f(capture, msg):\n    with capture:\n        create_and_destroy(4, 0.5)\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new          # preallocation needed before invoking placement-new overload\n        noisy delete       # deallocation of preallocated storage\n        noisy new          # Factory pointer allocation\n        NoisyAlloc(int 4)  # factory pointer construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\ndef test_reallocation_g(capture, msg):\n    with capture:\n        create_and_destroy(5, \"hi\")\n    assert msg(capture) == strip_comments(\n        \"\"\"\n        noisy new            # preallocation needed before invoking first placement new\n        noisy delete         # delete before considering new-style constructor\n        noisy new            # preallocation for second placement new\n        noisy placement new  # Placement new in the second placement new overload\n        NoisyAlloc(int 5)    # construction\n        ---\n        ~NoisyAlloc()  # Destructor\n        noisy delete   # operator delete\n    \"\"\"\n    )\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_invalid_self():\n    \"\"\"Tests invocation of the pybind-registered base class with an invalid `self` argument.  You\n    can only actually do this on Python 3: Python 2 raises an exception itself if you try.\"\"\"\n\n    class NotPybindDerived(object):\n        pass\n\n    # Attempts to initialize with an invalid type passed as `self`:\n    class BrokenTF1(m.TestFactory1):\n        def __init__(self, bad):\n            if bad == 1:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory1.__init__(a, tag.pointer)\n            elif bad == 2:\n                a = NotPybindDerived()\n                m.TestFactory1.__init__(a, tag.pointer)\n\n    # Same as above, but for a class with an alias:\n    class BrokenTF6(m.TestFactory6):\n        def __init__(self, bad):\n            if bad == 0:\n                m.TestFactory6.__init__()\n            elif bad == 1:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory6.__init__(a, tag.base, 1)\n            elif bad == 2:\n                a = m.TestFactory2(tag.pointer, 1)\n                m.TestFactory6.__init__(a, tag.alias, 1)\n            elif bad == 3:\n                m.TestFactory6.__init__(\n                    NotPybindDerived.__new__(NotPybindDerived), tag.base, 1\n                )\n            elif bad == 4:\n                m.TestFactory6.__init__(\n                    NotPybindDerived.__new__(NotPybindDerived), tag.alias, 1\n                )\n\n    for arg in (1, 2):\n        with pytest.raises(TypeError) as excinfo:\n            BrokenTF1(arg)\n        assert (\n            str(excinfo.value)\n            == \"__init__(self, ...) called with invalid or missing `self` argument\"\n        )\n\n    for arg in (0, 1, 2, 3, 4):\n        with pytest.raises(TypeError) as excinfo:\n            BrokenTF6(arg)\n        assert (\n            str(excinfo.value)\n            == \"__init__(self, ...) called with invalid or missing `self` argument\"\n        )\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_gil_scoped.cpp",
    "content": "/*\n    tests/test_gil_scoped.cpp -- acquire and release gil\n\n    Copyright (c) 2017 Borja Zarco (Google LLC) <bzarco@google.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"pybind11_tests.h\"\n\nclass VirtClass {\npublic:\n    virtual ~VirtClass() = default;\n    VirtClass() = default;\n    VirtClass(const VirtClass &) = delete;\n    virtual void virtual_func() {}\n    virtual void pure_virtual_func() = 0;\n};\n\nclass PyVirtClass : public VirtClass {\n    void virtual_func() override { PYBIND11_OVERRIDE(void, VirtClass, virtual_func, ); }\n    void pure_virtual_func() override {\n        PYBIND11_OVERRIDE_PURE(void, VirtClass, pure_virtual_func, );\n    }\n};\n\nTEST_SUBMODULE(gil_scoped, m) {\n    py::class_<VirtClass, PyVirtClass>(m, \"VirtClass\")\n        .def(py::init<>())\n        .def(\"virtual_func\", &VirtClass::virtual_func)\n        .def(\"pure_virtual_func\", &VirtClass::pure_virtual_func);\n\n    m.def(\"test_callback_py_obj\", [](py::object &func) { func(); });\n    m.def(\"test_callback_std_func\", [](const std::function<void()> &func) { func(); });\n    m.def(\"test_callback_virtual_func\", [](VirtClass &virt) { virt.virtual_func(); });\n    m.def(\"test_callback_pure_virtual_func\", [](VirtClass &virt) { virt.pure_virtual_func(); });\n    m.def(\"test_cross_module_gil\", []() {\n        auto cm = py::module_::import(\"cross_module_gil_utils\");\n        auto gil_acquire = reinterpret_cast<void (*)()>(\n            PyLong_AsVoidPtr(cm.attr(\"gil_acquire_funcaddr\").ptr()));\n        py::gil_scoped_release gil_release;\n        gil_acquire();\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_gil_scoped.py",
    "content": "# -*- coding: utf-8 -*-\nimport multiprocessing\nimport threading\n\nfrom pybind11_tests import gil_scoped as m\n\n\ndef _run_in_process(target, *args, **kwargs):\n    \"\"\"Runs target in process and returns its exitcode after 10s (None if still alive).\"\"\"\n    process = multiprocessing.Process(target=target, args=args, kwargs=kwargs)\n    process.daemon = True\n    try:\n        process.start()\n        # Do not need to wait much, 10s should be more than enough.\n        process.join(timeout=10)\n        return process.exitcode\n    finally:\n        if process.is_alive():\n            process.terminate()\n\n\ndef _python_to_cpp_to_python():\n    \"\"\"Calls different C++ functions that come back to Python.\"\"\"\n\n    class ExtendedVirtClass(m.VirtClass):\n        def virtual_func(self):\n            pass\n\n        def pure_virtual_func(self):\n            pass\n\n    extended = ExtendedVirtClass()\n    m.test_callback_py_obj(lambda: None)\n    m.test_callback_std_func(lambda: None)\n    m.test_callback_virtual_func(extended)\n    m.test_callback_pure_virtual_func(extended)\n\n\ndef _python_to_cpp_to_python_from_threads(num_threads, parallel=False):\n    \"\"\"Calls different C++ functions that come back to Python, from Python threads.\"\"\"\n    threads = []\n    for _ in range(num_threads):\n        thread = threading.Thread(target=_python_to_cpp_to_python)\n        thread.daemon = True\n        thread.start()\n        if parallel:\n            threads.append(thread)\n        else:\n            thread.join()\n    for thread in threads:\n        thread.join()\n\n\n# TODO: FIXME, sometimes returns -11 (segfault) instead of 0 on macOS Python 3.9\ndef test_python_to_cpp_to_python_from_thread():\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert _run_in_process(_python_to_cpp_to_python_from_threads, 1) == 0\n\n\n# TODO: FIXME on macOS Python 3.9\ndef test_python_to_cpp_to_python_from_thread_multiple_parallel():\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread multiple times in parallel.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=True) == 0\n\n\n# TODO: FIXME on macOS Python 3.9\ndef test_python_to_cpp_to_python_from_thread_multiple_sequential():\n    \"\"\"Makes sure there is no GIL deadlock when running in a thread multiple times sequentially.\n\n    It runs in a separate process to be able to stop and assert if it deadlocks.\n    \"\"\"\n    assert (\n        _run_in_process(_python_to_cpp_to_python_from_threads, 8, parallel=False) == 0\n    )\n\n\n# TODO: FIXME on macOS Python 3.9\ndef test_python_to_cpp_to_python_from_process():\n    \"\"\"Makes sure there is no GIL deadlock when using processes.\n\n    This test is for completion, but it was never an issue.\n    \"\"\"\n    assert _run_in_process(_python_to_cpp_to_python) == 0\n\n\ndef test_cross_module_gil():\n    \"\"\"Makes sure that the GIL can be acquired by another module from a GIL-released state.\"\"\"\n    m.test_cross_module_gil()  # Should not raise a SIGSEGV\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_iostream.cpp",
    "content": "/*\n    tests/test_iostream.cpp -- Usage of scoped_output_redirect\n\n    Copyright (c) 2017 Henry F. Schreiner\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1910 // VS 2015's MSVC\n#    pragma warning(disable : 4702)      // unreachable code in system header (xatomic.h(382))\n#endif\n\n#include <pybind11/iostream.h>\n\n#include \"pybind11_tests.h\"\n\n#include <atomic>\n#include <iostream>\n#include <mutex>\n#include <string>\n#include <thread>\n\nvoid noisy_function(const std::string &msg, bool flush) {\n\n    std::cout << msg;\n    if (flush) {\n        std::cout << std::flush;\n    }\n}\n\nvoid noisy_funct_dual(const std::string &msg, const std::string &emsg) {\n    std::cout << msg;\n    std::cerr << emsg;\n}\n\n// object to manage C++ thread\n// simply repeatedly write to std::cerr until stopped\n// redirect is called at some point to test the safety of scoped_estream_redirect\nstruct TestThread {\n    TestThread() : stop_{false} {\n        auto thread_f = [this] {\n            static std::mutex cout_mutex;\n            while (!stop_) {\n                {\n                    // #HelpAppreciated: Work on iostream.h thread safety.\n                    // Without this lock, the clang ThreadSanitizer (tsan) reliably reports a\n                    // data race, and this test is predictably flakey on Windows.\n                    // For more background see the discussion under\n                    // https://github.com/pybind/pybind11/pull/2982 and\n                    // https://github.com/pybind/pybind11/pull/2995.\n                    const std::lock_guard<std::mutex> lock(cout_mutex);\n                    std::cout << \"x\" << std::flush;\n                }\n                std::this_thread::sleep_for(std::chrono::microseconds(50));\n            }\n        };\n        t_ = new std::thread(std::move(thread_f));\n    }\n\n    ~TestThread() { delete t_; }\n\n    void stop() { stop_ = true; }\n\n    void join() const {\n        py::gil_scoped_release gil_lock;\n        t_->join();\n    }\n\n    void sleep() {\n        py::gil_scoped_release gil_lock;\n        std::this_thread::sleep_for(std::chrono::milliseconds(50));\n    }\n\n    std::thread *t_{nullptr};\n    std::atomic<bool> stop_;\n};\n\nTEST_SUBMODULE(iostream, m) {\n\n    add_ostream_redirect(m);\n\n    // test_evals\n\n    m.def(\"captured_output_default\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir;\n        std::cout << msg << std::flush;\n    });\n\n    m.def(\"captured_output\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir(std::cout, py::module_::import(\"sys\").attr(\"stdout\"));\n        std::cout << msg << std::flush;\n    });\n\n    m.def(\"guard_output\",\n          &noisy_function,\n          py::call_guard<py::scoped_ostream_redirect>(),\n          py::arg(\"msg\"),\n          py::arg(\"flush\") = true);\n\n    m.def(\"captured_err\", [](const std::string &msg) {\n        py::scoped_ostream_redirect redir(std::cerr, py::module_::import(\"sys\").attr(\"stderr\"));\n        std::cerr << msg << std::flush;\n    });\n\n    m.def(\"noisy_function\", &noisy_function, py::arg(\"msg\"), py::arg(\"flush\") = true);\n\n    m.def(\"dual_guard\",\n          &noisy_funct_dual,\n          py::call_guard<py::scoped_ostream_redirect, py::scoped_estream_redirect>(),\n          py::arg(\"msg\"),\n          py::arg(\"emsg\"));\n\n    m.def(\"raw_output\", [](const std::string &msg) { std::cout << msg << std::flush; });\n\n    m.def(\"raw_err\", [](const std::string &msg) { std::cerr << msg << std::flush; });\n\n    m.def(\"captured_dual\", [](const std::string &msg, const std::string &emsg) {\n        py::scoped_ostream_redirect redirout(std::cout, py::module_::import(\"sys\").attr(\"stdout\"));\n        py::scoped_ostream_redirect redirerr(std::cerr, py::module_::import(\"sys\").attr(\"stderr\"));\n        std::cout << msg << std::flush;\n        std::cerr << emsg << std::flush;\n    });\n\n    py::class_<TestThread>(m, \"TestThread\")\n        .def(py::init<>())\n        .def(\"stop\", &TestThread::stop)\n        .def(\"join\", &TestThread::join)\n        .def(\"sleep\", &TestThread::sleep);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_iostream.py",
    "content": "# -*- coding: utf-8 -*-\nimport sys\nfrom contextlib import contextmanager\n\nfrom pybind11_tests import iostream as m\n\ntry:\n    # Python 3\n    from io import StringIO\nexcept ImportError:\n    # Python 2\n    try:\n        from cStringIO import StringIO\n    except ImportError:\n        from StringIO import StringIO\n\ntry:\n    # Python 3.4\n    from contextlib import redirect_stdout\nexcept ImportError:\n\n    @contextmanager\n    def redirect_stdout(target):\n        original = sys.stdout\n        sys.stdout = target\n        yield\n        sys.stdout = original\n\n\ntry:\n    # Python 3.5\n    from contextlib import redirect_stderr\nexcept ImportError:\n\n    @contextmanager\n    def redirect_stderr(target):\n        original = sys.stderr\n        sys.stderr = target\n        yield\n        sys.stderr = original\n\n\ndef test_captured(capsys):\n    msg = \"I've been redirected to Python, I hope!\"\n    m.captured_output(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n    m.captured_err(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == \"\"\n    assert stderr == msg\n\n\ndef test_captured_large_string(capsys):\n    # Make this bigger than the buffer used on the C++ side: 1024 chars\n    msg = \"I've been redirected to Python, I hope!\"\n    msg = msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_2byte_offset0(capsys):\n    msg = \"\\u07FF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_2byte_offset1(capsys):\n    msg = \"\\u07FF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset0(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset1(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_3byte_offset2(capsys):\n    msg = \"\\uFFFF\"\n    msg = \"12\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset0(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset1(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"1\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset2(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"12\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_captured_utf8_4byte_offset3(capsys):\n    msg = \"\\U0010FFFF\"\n    msg = \"123\" + msg * (1024 // len(msg) + 1)\n\n    m.captured_output_default(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_guard_capture(capsys):\n    msg = \"I've been redirected to Python, I hope!\"\n    m.guard_output(msg)\n    stdout, stderr = capsys.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n\n\ndef test_series_captured(capture):\n    with capture:\n        m.captured_output(\"a\")\n        m.captured_output(\"b\")\n    assert capture == \"ab\"\n\n\ndef test_flush(capfd):\n    msg = \"(not flushed)\"\n    msg2 = \"(flushed)\"\n\n    with m.ostream_redirect():\n        m.noisy_function(msg, flush=False)\n        stdout, stderr = capfd.readouterr()\n        assert stdout == \"\"\n\n        m.noisy_function(msg2, flush=True)\n        stdout, stderr = capfd.readouterr()\n        assert stdout == msg + msg2\n\n        m.noisy_function(msg, flush=False)\n\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n\n\ndef test_not_captured(capfd):\n    msg = \"Something that should not show up in log\"\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.captured_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n\n\ndef test_err(capfd):\n    msg = \"Something that should not show up in log\"\n    stream = StringIO()\n    with redirect_stderr(stream):\n        m.raw_err(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == msg\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stderr(stream):\n        m.captured_err(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n\n\ndef test_multi_captured(capfd):\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.captured_output(\"a\")\n        m.raw_output(\"b\")\n        m.captured_output(\"c\")\n        m.raw_output(\"d\")\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"bd\"\n    assert stream.getvalue() == \"ac\"\n\n\ndef test_dual(capsys):\n    m.captured_dual(\"a\", \"b\")\n    stdout, stderr = capsys.readouterr()\n    assert stdout == \"a\"\n    assert stderr == \"b\"\n\n\ndef test_redirect(capfd):\n    msg = \"Should not be in log!\"\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stream.getvalue() == \"\"\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        with m.ostream_redirect():\n            m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stream.getvalue() == msg\n\n    stream = StringIO()\n    with redirect_stdout(stream):\n        m.raw_output(msg)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stream.getvalue() == \"\"\n\n\ndef test_redirect_err(capfd):\n    msg = \"StdOut\"\n    msg2 = \"StdErr\"\n\n    stream = StringIO()\n    with redirect_stderr(stream):\n        with m.ostream_redirect(stdout=False):\n            m.raw_output(msg)\n            m.raw_err(msg2)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == msg\n    assert stderr == \"\"\n    assert stream.getvalue() == msg2\n\n\ndef test_redirect_both(capfd):\n    msg = \"StdOut\"\n    msg2 = \"StdErr\"\n\n    stream = StringIO()\n    stream2 = StringIO()\n    with redirect_stdout(stream):\n        with redirect_stderr(stream2):\n            with m.ostream_redirect():\n                m.raw_output(msg)\n                m.raw_err(msg2)\n    stdout, stderr = capfd.readouterr()\n    assert stdout == \"\"\n    assert stderr == \"\"\n    assert stream.getvalue() == msg\n    assert stream2.getvalue() == msg2\n\n\ndef test_threading():\n    with m.ostream_redirect(stdout=True, stderr=False):\n        # start some threads\n        threads = []\n\n        # start some threads\n        for _j in range(20):\n            threads.append(m.TestThread())\n\n        # give the threads some time to fail\n        threads[0].sleep()\n\n        # stop all the threads\n        for t in threads:\n            t.stop()\n\n        for t in threads:\n            t.join()\n\n        # if a thread segfaults, we don't get here\n        assert True\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_kwargs_and_defaults.cpp",
    "content": "/*\n    tests/test_kwargs_and_defaults.cpp -- keyword arguments and default values\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nTEST_SUBMODULE(kwargs_and_defaults, m) {\n    auto kw_func\n        = [](int x, int y) { return \"x=\" + std::to_string(x) + \", y=\" + std::to_string(y); };\n\n    // test_named_arguments\n    m.def(\"kw_func0\", kw_func);\n    m.def(\"kw_func1\", kw_func, py::arg(\"x\"), py::arg(\"y\"));\n    m.def(\"kw_func2\", kw_func, py::arg(\"x\") = 100, py::arg(\"y\") = 200);\n    m.def(\n        \"kw_func3\", [](const char *) {}, py::arg(\"data\") = std::string(\"Hello world!\"));\n\n    /* A fancier default argument */\n    std::vector<int> list{{13, 17}};\n    m.def(\n        \"kw_func4\",\n        [](const std::vector<int> &entries) {\n            std::string ret = \"{\";\n            for (int i : entries) {\n                ret += std::to_string(i) + \" \";\n            }\n            ret.back() = '}';\n            return ret;\n        },\n        py::arg(\"myList\") = list);\n\n    m.def(\"kw_func_udl\", kw_func, \"x\"_a, \"y\"_a = 300);\n    m.def(\"kw_func_udl_z\", kw_func, \"x\"_a, \"y\"_a = 0);\n\n    // test_args_and_kwargs\n    m.def(\"args_function\", [](py::args args) -> py::tuple { return std::move(args); });\n    m.def(\"args_kwargs_function\", [](const py::args &args, const py::kwargs &kwargs) {\n        return py::make_tuple(args, kwargs);\n    });\n\n    // test_mixed_args_and_kwargs\n    m.def(\"mixed_plus_args\",\n          [](int i, double j, const py::args &args) { return py::make_tuple(i, j, args); });\n    m.def(\"mixed_plus_kwargs\",\n          [](int i, double j, const py::kwargs &kwargs) { return py::make_tuple(i, j, kwargs); });\n    auto mixed_plus_both = [](int i, double j, const py::args &args, const py::kwargs &kwargs) {\n        return py::make_tuple(i, j, args, kwargs);\n    };\n    m.def(\"mixed_plus_args_kwargs\", mixed_plus_both);\n\n    m.def(\"mixed_plus_args_kwargs_defaults\",\n          mixed_plus_both,\n          py::arg(\"i\") = 1,\n          py::arg(\"j\") = 3.14159);\n\n    m.def(\n        \"args_kwonly\",\n        [](int i, double j, const py::args &args, int z) { return py::make_tuple(i, j, args, z); },\n        \"i\"_a,\n        \"j\"_a,\n        \"z\"_a);\n    m.def(\n        \"args_kwonly_kwargs\",\n        [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, args, z, kwargs);\n        },\n        \"i\"_a,\n        \"j\"_a,\n        py::kw_only{},\n        \"z\"_a);\n    m.def(\n        \"args_kwonly_kwargs_defaults\",\n        [](int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, args, z, kwargs);\n        },\n        \"i\"_a = 1,\n        \"j\"_a = 3.14159,\n        \"z\"_a = 42);\n    m.def(\n        \"args_kwonly_full_monty\",\n        [](int h, int i, double j, const py::args &args, int z, const py::kwargs &kwargs) {\n            return py::make_tuple(h, i, j, args, z, kwargs);\n        },\n        py::arg() = 1,\n        py::arg() = 2,\n        py::pos_only{},\n        \"j\"_a = 3.14159,\n        \"z\"_a = 42);\n\n// test_args_refcount\n// PyPy needs a garbage collection to get the reference count values to match CPython's behaviour\n#ifdef PYPY_VERSION\n#    define GC_IF_NEEDED ConstructorStats::gc()\n#else\n#    define GC_IF_NEEDED\n#endif\n    m.def(\"arg_refcount_h\", [](py::handle h) {\n        GC_IF_NEEDED;\n        return h.ref_count();\n    });\n    m.def(\"arg_refcount_h\", [](py::handle h, py::handle, py::handle) {\n        GC_IF_NEEDED;\n        return h.ref_count();\n    });\n    m.def(\"arg_refcount_o\", [](const py::object &o) {\n        GC_IF_NEEDED;\n        return o.ref_count();\n    });\n    m.def(\"args_refcount\", [](py::args a) {\n        GC_IF_NEEDED;\n        py::tuple t(a.size());\n        for (size_t i = 0; i < a.size(); i++) {\n            // Use raw Python API here to avoid an extra, intermediate incref on the tuple item:\n            t[i] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i)));\n        }\n        return t;\n    });\n    m.def(\"mixed_args_refcount\", [](const py::object &o, py::args a) {\n        GC_IF_NEEDED;\n        py::tuple t(a.size() + 1);\n        t[0] = o.ref_count();\n        for (size_t i = 0; i < a.size(); i++) {\n            // Use raw Python API here to avoid an extra, intermediate incref on the tuple item:\n            t[i + 1] = (int) Py_REFCNT(PyTuple_GET_ITEM(a.ptr(), static_cast<py::ssize_t>(i)));\n        }\n        return t;\n    });\n\n    // pybind11 won't allow these to be bound: args and kwargs, if present, must be at the end.\n    // Uncomment these to test that the static_assert is indeed working:\n    //    m.def(\"bad_args1\", [](py::args, int) {});\n    //    m.def(\"bad_args2\", [](py::kwargs, int) {});\n    //    m.def(\"bad_args3\", [](py::kwargs, py::args) {});\n    //    m.def(\"bad_args4\", [](py::args, int, py::kwargs) {});\n    //    m.def(\"bad_args5\", [](py::args, py::kwargs, int) {});\n    //    m.def(\"bad_args6\", [](py::args, py::args) {});\n    //    m.def(\"bad_args7\", [](py::kwargs, py::kwargs) {});\n\n    // test_keyword_only_args\n    m.def(\n        \"kw_only_all\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::kw_only(),\n        py::arg(\"i\"),\n        py::arg(\"j\"));\n    m.def(\n        \"kw_only_some\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(),\n        py::kw_only(),\n        py::arg(\"j\"),\n        py::arg(\"k\"));\n    m.def(\n        \"kw_only_with_defaults\",\n        [](int i, int j, int k, int z) { return py::make_tuple(i, j, k, z); },\n        py::arg() = 3,\n        \"j\"_a = 4,\n        py::kw_only(),\n        \"k\"_a = 5,\n        \"z\"_a);\n    m.def(\n        \"kw_only_mixed\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        \"i\"_a,\n        py::kw_only(),\n        \"j\"_a);\n    m.def(\n        \"kw_only_plus_more\",\n        [](int i, int j, int k, const py::kwargs &kwargs) {\n            return py::make_tuple(i, j, k, kwargs);\n        },\n        py::arg() /* positional */,\n        py::arg(\"j\") = -1 /* both */,\n        py::kw_only(),\n        py::arg(\"k\") /* kw-only */);\n\n    m.def(\"register_invalid_kw_only\", [](py::module_ m) {\n        m.def(\n            \"bad_kw_only\",\n            [](int i, int j) { return py::make_tuple(i, j); },\n            py::kw_only(),\n            py::arg() /* invalid unnamed argument */,\n            \"j\"_a);\n    });\n\n    // test_positional_only_args\n    m.def(\n        \"pos_only_all\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::arg(\"i\"),\n        py::arg(\"j\"),\n        py::pos_only());\n    m.def(\n        \"pos_only_mix\",\n        [](int i, int j) { return py::make_tuple(i, j); },\n        py::arg(\"i\"),\n        py::pos_only(),\n        py::arg(\"j\"));\n    m.def(\n        \"pos_kw_only_mix\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(\"i\"),\n        py::pos_only(),\n        py::arg(\"j\"),\n        py::kw_only(),\n        py::arg(\"k\"));\n    m.def(\n        \"pos_only_def_mix\",\n        [](int i, int j, int k) { return py::make_tuple(i, j, k); },\n        py::arg(\"i\"),\n        py::arg(\"j\") = 2,\n        py::pos_only(),\n        py::arg(\"k\") = 3);\n\n    // These should fail to compile:\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n    // argument annotations are required when using kw_only\n    m.def(\n        \"bad_kw_only1\", [](int) {}, py::kw_only());\n    // can't specify both `py::kw_only` and a `py::args` argument\n    m.def(\n        \"bad_kw_only2\", [](int i, py::args) {}, py::kw_only(), \"i\"_a);\n#endif\n\n    // test_function_signatures (along with most of the above)\n    struct KWClass {\n        void foo(int, float) {}\n    };\n    py::class_<KWClass>(m, \"KWClass\")\n        .def(\"foo0\", &KWClass::foo)\n        .def(\"foo1\", &KWClass::foo, \"x\"_a, \"y\"_a);\n\n    // Make sure a class (not an instance) can be used as a default argument.\n    // The return value doesn't matter, only that the module is importable.\n    m.def(\n        \"class_default_argument\",\n        [](py::object a) { return py::repr(std::move(a)); },\n        \"a\"_a = py::module_::import(\"decimal\").attr(\"Decimal\"));\n\n    // Initial implementation of kw_only was broken when used on a method/constructor before any\n    // other arguments\n    // https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n\n    struct first_arg_kw_only {};\n    py::class_<first_arg_kw_only>(m, \"first_arg_kw_only\")\n        .def(py::init([](int) { return first_arg_kw_only(); }),\n             py::kw_only(), // This being before any args was broken\n             py::arg(\"i\") = 0)\n        .def(\n            \"method\",\n            [](first_arg_kw_only &, int, int) {},\n            py::kw_only(), // and likewise here\n            py::arg(\"i\") = 1,\n            py::arg(\"j\") = 2)\n        // Closely related: pos_only marker didn't show up properly when it was before any other\n        // arguments (although that is fairly useless in practice).\n        .def(\n            \"pos_only\",\n            [](first_arg_kw_only &, int, int) {},\n            py::pos_only{},\n            py::arg(\"i\"),\n            py::arg(\"j\"));\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_kwargs_and_defaults.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import kwargs_and_defaults as m\n\n\ndef test_function_signatures(doc):\n    assert doc(m.kw_func0) == \"kw_func0(arg0: int, arg1: int) -> str\"\n    assert doc(m.kw_func1) == \"kw_func1(x: int, y: int) -> str\"\n    assert doc(m.kw_func2) == \"kw_func2(x: int = 100, y: int = 200) -> str\"\n    assert doc(m.kw_func3) == \"kw_func3(data: str = 'Hello world!') -> None\"\n    assert doc(m.kw_func4) == \"kw_func4(myList: List[int] = [13, 17]) -> str\"\n    assert doc(m.kw_func_udl) == \"kw_func_udl(x: int, y: int = 300) -> str\"\n    assert doc(m.kw_func_udl_z) == \"kw_func_udl_z(x: int, y: int = 0) -> str\"\n    assert doc(m.args_function) == \"args_function(*args) -> tuple\"\n    assert (\n        doc(m.args_kwargs_function) == \"args_kwargs_function(*args, **kwargs) -> tuple\"\n    )\n    assert (\n        doc(m.KWClass.foo0)\n        == \"foo0(self: m.kwargs_and_defaults.KWClass, arg0: int, arg1: float) -> None\"\n    )\n    assert (\n        doc(m.KWClass.foo1)\n        == \"foo1(self: m.kwargs_and_defaults.KWClass, x: int, y: float) -> None\"\n    )\n\n\ndef test_named_arguments(msg):\n    assert m.kw_func0(5, 10) == \"x=5, y=10\"\n\n    assert m.kw_func1(5, 10) == \"x=5, y=10\"\n    assert m.kw_func1(5, y=10) == \"x=5, y=10\"\n    assert m.kw_func1(y=10, x=5) == \"x=5, y=10\"\n\n    assert m.kw_func2() == \"x=100, y=200\"\n    assert m.kw_func2(5) == \"x=5, y=200\"\n    assert m.kw_func2(x=5) == \"x=5, y=200\"\n    assert m.kw_func2(y=10) == \"x=100, y=10\"\n    assert m.kw_func2(5, 10) == \"x=5, y=10\"\n    assert m.kw_func2(x=5, y=10) == \"x=5, y=10\"\n\n    with pytest.raises(TypeError) as excinfo:\n        # noinspection PyArgumentList\n        m.kw_func2(x=5, y=10, z=12)\n    assert excinfo.match(\n        r\"(?s)^kw_func2\\(\\): incompatible.*Invoked with: kwargs: ((x=5|y=10|z=12)(, |$))\"\n        + \"{3}$\"\n    )\n\n    assert m.kw_func4() == \"{13 17}\"\n    assert m.kw_func4(myList=[1, 2, 3]) == \"{1 2 3}\"\n\n    assert m.kw_func_udl(x=5, y=10) == \"x=5, y=10\"\n    assert m.kw_func_udl_z(x=5) == \"x=5, y=0\"\n\n\ndef test_arg_and_kwargs():\n    args = \"arg1_value\", \"arg2_value\", 3\n    assert m.args_function(*args) == args\n\n    args = \"a1\", \"a2\"\n    kwargs = dict(arg3=\"a3\", arg4=4)\n    assert m.args_kwargs_function(*args, **kwargs) == (args, kwargs)\n\n\ndef test_mixed_args_and_kwargs(msg):\n    mpa = m.mixed_plus_args\n    mpk = m.mixed_plus_kwargs\n    mpak = m.mixed_plus_args_kwargs\n    mpakd = m.mixed_plus_args_kwargs_defaults\n\n    assert mpa(1, 2.5, 4, 99.5, None) == (1, 2.5, (4, 99.5, None))\n    assert mpa(1, 2.5) == (1, 2.5, ())\n    with pytest.raises(TypeError) as excinfo:\n        assert mpa(1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: int, arg1: float, *args) -> tuple\n\n        Invoked with: 1\n    \"\"\"  # noqa: E501 line too long\n    )\n    with pytest.raises(TypeError) as excinfo:\n        assert mpa()\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: int, arg1: float, *args) -> tuple\n\n        Invoked with:\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    assert mpk(-2, 3.5, pi=3.14159, e=2.71828) == (\n        -2,\n        3.5,\n        {\"e\": 2.71828, \"pi\": 3.14159},\n    )\n    assert mpak(7, 7.7, 7.77, 7.777, 7.7777, minusseven=-7) == (\n        7,\n        7.7,\n        (7.77, 7.777, 7.7777),\n        {\"minusseven\": -7},\n    )\n    assert mpakd() == (1, 3.14159, (), {})\n    assert mpakd(3) == (3, 3.14159, (), {})\n    assert mpakd(j=2.71828) == (1, 2.71828, (), {})\n    assert mpakd(k=42) == (1, 3.14159, (), {\"k\": 42})\n    assert mpakd(1, 1, 2, 3, 5, 8, then=13, followedby=21) == (\n        1,\n        1,\n        (2, 3, 5, 8),\n        {\"then\": 13, \"followedby\": 21},\n    )\n    # Arguments specified both positionally and via kwargs should fail:\n    with pytest.raises(TypeError) as excinfo:\n        assert mpakd(1, i=1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:\n            1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple\n\n        Invoked with: 1; kwargs: i=1\n    \"\"\"  # noqa: E501 line too long\n    )\n    with pytest.raises(TypeError) as excinfo:\n        assert mpakd(1, 2, j=1)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        mixed_plus_args_kwargs_defaults(): incompatible function arguments. The following argument types are supported:\n            1. (i: int = 1, j: float = 3.14159, *args, **kwargs) -> tuple\n\n        Invoked with: 1, 2; kwargs: j=1\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    # Arguments after a py::args are automatically keyword-only (pybind 2.9+)\n    assert m.args_kwonly(2, 2.5, z=22) == (2, 2.5, (), 22)\n    assert m.args_kwonly(2, 2.5, \"a\", \"b\", \"c\", z=22) == (2, 2.5, (\"a\", \"b\", \"c\"), 22)\n    assert m.args_kwonly(z=22, i=4, j=16) == (4, 16, (), 22)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.args_kwonly(2, 2.5, 22)  # missing z= keyword\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        args_kwonly(): incompatible function arguments. The following argument types are supported:\n            1. (i: int, j: float, *args, z: int) -> tuple\n\n        Invoked with: 2, 2.5, 22\n    \"\"\"\n    )\n\n    assert m.args_kwonly_kwargs(i=1, k=4, j=10, z=-1, y=9) == (\n        1,\n        10,\n        (),\n        -1,\n        {\"k\": 4, \"y\": 9},\n    )\n    assert m.args_kwonly_kwargs(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, z=11, y=12) == (\n        1,\n        2,\n        (3, 4, 5, 6, 7, 8, 9, 10),\n        11,\n        {\"y\": 12},\n    )\n    assert (\n        m.args_kwonly_kwargs.__doc__\n        == \"args_kwonly_kwargs(i: int, j: float, *args, z: int, **kwargs) -> tuple\\n\"\n    )\n\n    assert (\n        m.args_kwonly_kwargs_defaults.__doc__\n        == \"args_kwonly_kwargs_defaults(i: int = 1, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\\n\"  # noqa: E501 line too long\n    )\n    assert m.args_kwonly_kwargs_defaults() == (1, 3.14159, (), 42, {})\n    assert m.args_kwonly_kwargs_defaults(2) == (2, 3.14159, (), 42, {})\n    assert m.args_kwonly_kwargs_defaults(z=-99) == (1, 3.14159, (), -99, {})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, 8) == (5, 6, (7, 8), 42, {})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8) == (5, 6, (7,), 42, {\"m\": 8})\n    assert m.args_kwonly_kwargs_defaults(5, 6, 7, m=8, z=9) == (5, 6, (7,), 9, {\"m\": 8})\n\n\ndef test_keyword_only_args(msg):\n    assert m.kw_only_all(i=1, j=2) == (1, 2)\n    assert m.kw_only_all(j=1, i=2) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_all(i=1) == (1,)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_all(1, 2) == (1, 2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.kw_only_some(1, k=3, j=2) == (1, 2, 3)\n\n    assert m.kw_only_with_defaults(z=8) == (3, 4, 5, 8)\n    assert m.kw_only_with_defaults(2, z=8) == (2, 4, 5, 8)\n    assert m.kw_only_with_defaults(2, j=7, k=8, z=9) == (2, 7, 8, 9)\n    assert m.kw_only_with_defaults(2, 7, z=9, k=8) == (2, 7, 8, 9)\n\n    assert m.kw_only_mixed(1, j=2) == (1, 2)\n    assert m.kw_only_mixed(j=2, i=3) == (3, 2)\n    assert m.kw_only_mixed(i=2, j=3) == (2, 3)\n\n    assert m.kw_only_plus_more(4, 5, k=6, extra=7) == (4, 5, 6, {\"extra\": 7})\n    assert m.kw_only_plus_more(3, k=5, j=4, extra=6) == (3, 4, 5, {\"extra\": 6})\n    assert m.kw_only_plus_more(2, k=3, extra=4) == (2, -1, 3, {\"extra\": 4})\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.kw_only_mixed(i=1) == (1,)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_invalid_kw_only(m)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        arg(): cannot specify an unnamed argument after a kw_only() annotation or args() argument\n    \"\"\"\n    )\n\n    # https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n    x = m.first_arg_kw_only(i=1)\n    x.method()\n    x.method(i=1, j=2)\n    assert (\n        m.first_arg_kw_only.__init__.__doc__\n        == \"__init__(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 0) -> None\\n\"  # noqa: E501 line too long\n    )\n    assert (\n        m.first_arg_kw_only.method.__doc__\n        == \"method(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, *, i: int = 1, j: int = 2) -> None\\n\"  # noqa: E501 line too long\n    )\n\n\ndef test_positional_only_args(msg):\n    assert m.pos_only_all(1, 2) == (1, 2)\n    assert m.pos_only_all(2, 1) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_all(i=1, j=2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_only_mix(1, 2) == (1, 2)\n    assert m.pos_only_mix(2, j=1) == (2, 1)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_mix(i=1, j=2)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_kw_only_mix(1, 2, k=3) == (1, 2, 3)\n    assert m.pos_kw_only_mix(1, j=2, k=3) == (1, 2, 3)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_kw_only_mix(i=1, j=2, k=3)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_kw_only_mix(1, 2, 3)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_def_mix()\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    assert m.pos_only_def_mix(1) == (1, 2, 3)\n    assert m.pos_only_def_mix(1, 4) == (1, 4, 3)\n    assert m.pos_only_def_mix(1, 4, 7) == (1, 4, 7)\n    assert m.pos_only_def_mix(1, 4, k=7) == (1, 4, 7)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.pos_only_def_mix(1, j=4)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    # Mix it with args and kwargs:\n    assert (\n        m.args_kwonly_full_monty.__doc__\n        == \"args_kwonly_full_monty(arg0: int = 1, arg1: int = 2, /, j: float = 3.14159, *args, z: int = 42, **kwargs) -> tuple\\n\"  # noqa: E501 line too long\n    )\n    assert m.args_kwonly_full_monty() == (1, 2, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8) == (8, 2, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8, 9) == (8, 9, 3.14159, (), 42, {})\n    assert m.args_kwonly_full_monty(8, 9, 10) == (8, 9, 10.0, (), 42, {})\n    assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (\n        3,\n        4,\n        5.0,\n        (\n            6,\n            7,\n        ),\n        9,\n        {\"m\": 8},\n    )\n    assert m.args_kwonly_full_monty(3, 4, 5, 6, 7, m=8, z=9) == (\n        3,\n        4,\n        5.0,\n        (\n            6,\n            7,\n        ),\n        9,\n        {\"m\": 8},\n    )\n    assert m.args_kwonly_full_monty(5, j=7, m=8, z=9) == (5, 2, 7.0, (), 9, {\"m\": 8})\n    assert m.args_kwonly_full_monty(i=5, j=7, m=8, z=9) == (\n        1,\n        2,\n        7.0,\n        (),\n        9,\n        {\"i\": 5, \"m\": 8},\n    )\n\n    # pos_only at the beginning of the argument list was \"broken\" in how it was displayed (though\n    # this is fairly useless in practice).  Related to:\n    # https://github.com/pybind/pybind11/pull/3402#issuecomment-963341987\n    assert (\n        m.first_arg_kw_only.pos_only.__doc__\n        == \"pos_only(self: pybind11_tests.kwargs_and_defaults.first_arg_kw_only, /, i: int, j: int) -> None\\n\"  # noqa: E501 line too long\n    )\n\n\ndef test_signatures():\n    assert \"kw_only_all(*, i: int, j: int) -> tuple\\n\" == m.kw_only_all.__doc__\n    assert \"kw_only_mixed(i: int, *, j: int) -> tuple\\n\" == m.kw_only_mixed.__doc__\n    assert \"pos_only_all(i: int, j: int, /) -> tuple\\n\" == m.pos_only_all.__doc__\n    assert \"pos_only_mix(i: int, /, j: int) -> tuple\\n\" == m.pos_only_mix.__doc__\n    assert (\n        \"pos_kw_only_mix(i: int, /, j: int, *, k: int) -> tuple\\n\"\n        == m.pos_kw_only_mix.__doc__\n    )\n\n\n@pytest.mark.xfail(\"env.PYPY and env.PY2\", reason=\"PyPy2 doesn't double count\")\ndef test_args_refcount():\n    \"\"\"Issue/PR #1216 - py::args elements get double-inc_ref()ed when combined with regular\n    arguments\"\"\"\n    refcount = m.arg_refcount_h\n\n    myval = 54321\n    expected = refcount(myval)\n    assert m.arg_refcount_h(myval) == expected\n    assert m.arg_refcount_o(myval) == expected + 1\n    assert m.arg_refcount_h(myval) == expected\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_args(1, 2.0, \"a\", myval) == (1, 2.0, (\"a\", myval))\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_kwargs(3, 4.0, a=1, b=myval) == (3, 4.0, {\"a\": 1, \"b\": myval})\n    assert refcount(myval) == expected\n\n    assert m.args_function(-1, myval) == (-1, myval)\n    assert refcount(myval) == expected\n\n    assert m.mixed_plus_args_kwargs(5, 6.0, myval, a=myval) == (\n        5,\n        6.0,\n        (myval,),\n        {\"a\": myval},\n    )\n    assert refcount(myval) == expected\n\n    assert m.args_kwargs_function(7, 8, myval, a=1, b=myval) == (\n        (7, 8, myval),\n        {\"a\": 1, \"b\": myval},\n    )\n    assert refcount(myval) == expected\n\n    exp3 = refcount(myval, myval, myval)\n    assert m.args_refcount(myval, myval, myval) == (exp3, exp3, exp3)\n    assert refcount(myval) == expected\n\n    # This function takes the first arg as a `py::object` and the rest as a `py::args`.  Unlike the\n    # previous case, when we have both positional and `py::args` we need to construct a new tuple\n    # for the `py::args`; in the previous case, we could simply inc_ref and pass on Python's input\n    # tuple without having to inc_ref the individual elements, but here we can't, hence the extra\n    # refs.\n    assert m.mixed_args_refcount(myval, myval, myval) == (exp3 + 3, exp3 + 3, exp3 + 3)\n\n    assert m.class_default_argument() == \"<class 'decimal.Decimal'>\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_local_bindings.cpp",
    "content": "/*\n    tests/test_local_bindings.cpp -- tests the py::module_local class feature which makes a class\n                                     binding local to the module in which it is defined.\n\n    Copyright (c) 2017 Jason Rhinelander <jason@imaginary.ca>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n#include <pybind11/stl_bind.h>\n\n#include \"local_bindings.h\"\n#include \"pybind11_tests.h\"\n\n#include <numeric>\n#include <utility>\n\nTEST_SUBMODULE(local_bindings, m) {\n    // test_load_external\n    m.def(\"load_external1\", [](ExternalType1 &e) { return e.i; });\n    m.def(\"load_external2\", [](ExternalType2 &e) { return e.i; });\n\n    // test_local_bindings\n    // Register a class with py::module_local:\n    bind_local<LocalType, -1>(m, \"LocalType\", py::module_local()).def(\"get3\", [](LocalType &t) {\n        return t.i + 3;\n    });\n\n    m.def(\"local_value\", [](LocalType &l) { return l.i; });\n\n    // test_nonlocal_failure\n    // The main pybind11 test module is loaded first, so this registration will succeed (the second\n    // one, in pybind11_cross_module_tests.cpp, is designed to fail):\n    bind_local<NonLocalType, 0>(m, \"NonLocalType\")\n        .def(py::init<int>())\n        .def(\"get\", [](LocalType &i) { return i.i; });\n\n    // test_duplicate_local\n    // py::module_local declarations should be visible across compilation units that get linked\n    // together; this tries to register a duplicate local.  It depends on a definition in\n    // test_class.cpp and should raise a runtime error from the duplicate definition attempt.  If\n    // test_class isn't available it *also* throws a runtime error (with \"test_class not enabled\"\n    // as value).\n    m.def(\"register_local_external\", [m]() {\n        auto main = py::module_::import(\"pybind11_tests\");\n        if (py::hasattr(main, \"class_\")) {\n            bind_local<LocalExternal, 7>(m, \"LocalExternal\", py::module_local());\n        } else {\n            throw std::runtime_error(\"test_class not enabled\");\n        }\n    });\n\n    // test_stl_bind_local\n    // stl_bind.h binders defaults to py::module_local if the types are local or converting:\n    py::bind_vector<LocalVec>(m, \"LocalVec\");\n    py::bind_map<LocalMap>(m, \"LocalMap\");\n    // and global if the type (or one of the types, for the map) is global:\n    py::bind_vector<NonLocalVec>(m, \"NonLocalVec\");\n    py::bind_map<NonLocalMap>(m, \"NonLocalMap\");\n\n    // test_stl_bind_global\n    // They can, however, be overridden to global using `py::module_local(false)`:\n    bind_local<NonLocal2, 10>(m, \"NonLocal2\");\n    py::bind_vector<LocalVec2>(m, \"LocalVec2\", py::module_local());\n    py::bind_map<NonLocalMap2>(m, \"NonLocalMap2\", py::module_local(false));\n\n    // test_mixed_local_global\n    // We try this both with the global type registered first and vice versa (the order shouldn't\n    // matter).\n    m.def(\"register_mixed_global\", [m]() {\n        bind_local<MixedGlobalLocal, 100>(m, \"MixedGlobalLocal\", py::module_local(false));\n    });\n    m.def(\"register_mixed_local\", [m]() {\n        bind_local<MixedLocalGlobal, 1000>(m, \"MixedLocalGlobal\", py::module_local());\n    });\n    m.def(\"get_mixed_gl\", [](int i) { return MixedGlobalLocal(i); });\n    m.def(\"get_mixed_lg\", [](int i) { return MixedLocalGlobal(i); });\n\n    // test_internal_locals_differ\n    m.def(\"local_cpp_types_addr\",\n          []() { return (uintptr_t) &py::detail::get_local_internals().registered_types_cpp; });\n\n    // test_stl_caster_vs_stl_bind\n    m.def(\"load_vector_via_caster\",\n          [](std::vector<int> v) { return std::accumulate(v.begin(), v.end(), 0); });\n\n    // test_cross_module_calls\n    m.def(\"return_self\", [](LocalVec *v) { return v; });\n    m.def(\"return_copy\", [](const LocalVec &v) { return LocalVec(v); });\n\n    class Cat : public pets::Pet {\n    public:\n        explicit Cat(std::string name) : Pet(std::move(name)) {}\n    };\n    py::class_<pets::Pet>(m, \"Pet\", py::module_local()).def(\"get_name\", &pets::Pet::name);\n    // Binding for local extending class:\n    py::class_<Cat, pets::Pet>(m, \"Cat\").def(py::init<std::string>());\n    m.def(\"pet_name\", [](pets::Pet &p) { return p.name(); });\n\n    py::class_<MixGL>(m, \"MixGL\").def(py::init<int>());\n    m.def(\"get_gl_value\", [](MixGL &o) { return o.i + 10; });\n\n    py::class_<MixGL2>(m, \"MixGL2\").def(py::init<int>());\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_local_bindings.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import local_bindings as m\n\n\ndef test_load_external():\n    \"\"\"Load a `py::module_local` type that's only registered in an external module\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    assert m.load_external1(cm.ExternalType1(11)) == 11\n    assert m.load_external2(cm.ExternalType2(22)) == 22\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.load_external2(cm.ExternalType1(21)) == 21\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        assert m.load_external1(cm.ExternalType2(12)) == 12\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_local_bindings():\n    \"\"\"Tests that duplicate `py::module_local` class bindings work across modules\"\"\"\n\n    # Make sure we can load the second module with the conflicting (but local) definition:\n    import pybind11_cross_module_tests as cm\n\n    i1 = m.LocalType(5)\n    assert i1.get() == 4\n    assert i1.get3() == 8\n\n    i2 = cm.LocalType(10)\n    assert i2.get() == 11\n    assert i2.get2() == 12\n\n    assert not hasattr(i1, \"get2\")\n    assert not hasattr(i2, \"get3\")\n\n    # Loading within the local module\n    assert m.local_value(i1) == 5\n    assert cm.local_value(i2) == 10\n\n    # Cross-module loading works as well (on failure, the type loader looks for\n    # external module-local converters):\n    assert m.local_value(i2) == 10\n    assert cm.local_value(i1) == 5\n\n\ndef test_nonlocal_failure():\n    \"\"\"Tests that attempting to register a non-local type in multiple modules fails\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalType\" is already registered!'\n    )\n\n\ndef test_duplicate_local():\n    \"\"\"Tests expected failure when registering a class twice with py::local in the same module\"\"\"\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_local_external()\n    import pybind11_tests\n\n    assert str(excinfo.value) == (\n        'generic_type: type \"LocalExternal\" is already registered!'\n        if hasattr(pybind11_tests, \"class_\")\n        else \"test_class not enabled\"\n    )\n\n\ndef test_stl_bind_local():\n    import pybind11_cross_module_tests as cm\n\n    v1, v2 = m.LocalVec(), cm.LocalVec()\n    v1.append(m.LocalType(1))\n    v1.append(m.LocalType(2))\n    v2.append(cm.LocalType(1))\n    v2.append(cm.LocalType(2))\n\n    # Cross module value loading:\n    v1.append(cm.LocalType(3))\n    v2.append(m.LocalType(3))\n\n    assert [i.get() for i in v1] == [0, 1, 2]\n    assert [i.get() for i in v2] == [2, 3, 4]\n\n    v3, v4 = m.NonLocalVec(), cm.NonLocalVec2()\n    v3.append(m.NonLocalType(1))\n    v3.append(m.NonLocalType(2))\n    v4.append(m.NonLocal2(3))\n    v4.append(m.NonLocal2(4))\n\n    assert [i.get() for i in v3] == [1, 2]\n    assert [i.get() for i in v4] == [13, 14]\n\n    d1, d2 = m.LocalMap(), cm.LocalMap()\n    d1[\"a\"] = v1[0]\n    d1[\"b\"] = v1[1]\n    d2[\"c\"] = v2[0]\n    d2[\"d\"] = v2[1]\n    assert {i: d1[i].get() for i in d1} == {\"a\": 0, \"b\": 1}\n    assert {i: d2[i].get() for i in d2} == {\"c\": 2, \"d\": 3}\n\n\ndef test_stl_bind_global():\n    import pybind11_cross_module_tests as cm\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_map()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalMap\" is already registered!'\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_vec()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalVec\" is already registered!'\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        cm.register_nonlocal_map2()\n    assert (\n        str(excinfo.value) == 'generic_type: type \"NonLocalMap2\" is already registered!'\n    )\n\n\ndef test_mixed_local_global():\n    \"\"\"Local types take precedence over globally registered types: a module with a `module_local`\n    type can be registered even if the type is already registered globally.  With the module,\n    casting will go to the local type; outside the module casting goes to the global type.\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    m.register_mixed_global()\n    m.register_mixed_local()\n\n    a = []\n    a.append(m.MixedGlobalLocal(1))\n    a.append(m.MixedLocalGlobal(2))\n    a.append(m.get_mixed_gl(3))\n    a.append(m.get_mixed_lg(4))\n\n    assert [x.get() for x in a] == [101, 1002, 103, 1004]\n\n    cm.register_mixed_global_local()\n    cm.register_mixed_local_global()\n    a.append(m.MixedGlobalLocal(5))\n    a.append(m.MixedLocalGlobal(6))\n    a.append(cm.MixedGlobalLocal(7))\n    a.append(cm.MixedLocalGlobal(8))\n    a.append(m.get_mixed_gl(9))\n    a.append(m.get_mixed_lg(10))\n    a.append(cm.get_mixed_gl(11))\n    a.append(cm.get_mixed_lg(12))\n\n    assert [x.get() for x in a] == [\n        101,\n        1002,\n        103,\n        1004,\n        105,\n        1006,\n        207,\n        2008,\n        109,\n        1010,\n        211,\n        2012,\n    ]\n\n\ndef test_internal_locals_differ():\n    \"\"\"Makes sure the internal local type map differs across the two modules\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    assert m.local_cpp_types_addr() != cm.local_cpp_types_addr()\n\n\n@pytest.mark.xfail(\"env.PYPY and sys.pypy_version_info < (7, 3, 2)\")\ndef test_stl_caster_vs_stl_bind(msg):\n    \"\"\"One module uses a generic vector caster from `<pybind11/stl.h>` while the other\n    exports `std::vector<int>` via `py:bind_vector` and `py::module_local`\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    v1 = cm.VectorInt([1, 2, 3])\n    assert m.load_vector_via_caster(v1) == 6\n    assert cm.load_vector_via_binding(v1) == 6\n\n    v2 = [1, 2, 3]\n    assert m.load_vector_via_caster(v2) == 6\n    with pytest.raises(TypeError) as excinfo:\n        cm.load_vector_via_binding(v2)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n    load_vector_via_binding(): incompatible function arguments. The following argument types are supported:\n        1. (arg0: pybind11_cross_module_tests.VectorInt) -> int\n\n    Invoked with: [1, 2, 3]\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_cross_module_calls():\n    import pybind11_cross_module_tests as cm\n\n    v1 = m.LocalVec()\n    v1.append(m.LocalType(1))\n    v2 = cm.LocalVec()\n    v2.append(cm.LocalType(2))\n\n    # Returning the self pointer should get picked up as returning an existing\n    # instance (even when that instance is of a foreign, non-local type).\n    assert m.return_self(v1) is v1\n    assert cm.return_self(v2) is v2\n    assert m.return_self(v2) is v2\n    assert cm.return_self(v1) is v1\n\n    assert m.LocalVec is not cm.LocalVec\n    # Returning a copy, on the other hand, always goes to the local type,\n    # regardless of where the source type came from.\n    assert type(m.return_copy(v1)) is m.LocalVec\n    assert type(m.return_copy(v2)) is m.LocalVec\n    assert type(cm.return_copy(v1)) is cm.LocalVec\n    assert type(cm.return_copy(v2)) is cm.LocalVec\n\n    # Test the example given in the documentation (which also tests inheritance casting):\n    mycat = m.Cat(\"Fluffy\")\n    mydog = cm.Dog(\"Rover\")\n    assert mycat.get_name() == \"Fluffy\"\n    assert mydog.name() == \"Rover\"\n    assert m.Cat.__base__.__name__ == \"Pet\"\n    assert cm.Dog.__base__.__name__ == \"Pet\"\n    assert m.Cat.__base__ is not cm.Dog.__base__\n    assert m.pet_name(mycat) == \"Fluffy\"\n    assert m.pet_name(mydog) == \"Rover\"\n    assert cm.pet_name(mycat) == \"Fluffy\"\n    assert cm.pet_name(mydog) == \"Rover\"\n\n    assert m.MixGL is not cm.MixGL\n    a = m.MixGL(1)\n    b = cm.MixGL(2)\n    assert m.get_gl_value(a) == 11\n    assert m.get_gl_value(b) == 12\n    assert cm.get_gl_value(a) == 101\n    assert cm.get_gl_value(b) == 102\n\n    c, d = m.MixGL2(3), cm.MixGL2(4)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_gl_value(c)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.get_gl_value(d)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_methods_and_attributes.cpp",
    "content": "/*\n    tests/test_methods_and_attributes.cpp -- constructors, deconstructors, attribute access,\n    __str__, argument and return value conventions\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#if !defined(PYBIND11_OVERLOAD_CAST)\ntemplate <typename... Args>\nusing overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;\n#endif\n\nclass ExampleMandA {\npublic:\n    ExampleMandA() { print_default_created(this); }\n    explicit ExampleMandA(int value) : value(value) { print_created(this, value); }\n    ExampleMandA(const ExampleMandA &e) : value(e.value) { print_copy_created(this); }\n    explicit ExampleMandA(std::string &&) {}\n    ExampleMandA(ExampleMandA &&e) noexcept : value(e.value) { print_move_created(this); }\n    ~ExampleMandA() { print_destroyed(this); }\n\n    std::string toString() const { return \"ExampleMandA[value=\" + std::to_string(value) + \"]\"; }\n\n    void operator=(const ExampleMandA &e) {\n        print_copy_assigned(this);\n        value = e.value;\n    }\n    void operator=(ExampleMandA &&e) noexcept {\n        print_move_assigned(this);\n        value = e.value;\n    }\n\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    void add1(ExampleMandA other) { value += other.value; }         // passing by value\n    void add2(ExampleMandA &other) { value += other.value; }        // passing by reference\n    void add3(const ExampleMandA &other) { value += other.value; }  // passing by const reference\n    void add4(ExampleMandA *other) { value += other->value; }       // passing by pointer\n    void add5(const ExampleMandA *other) { value += other->value; } // passing by const pointer\n\n    void add6(int other) { value += other; }        // passing by value\n    void add7(int &other) { value += other; }       // passing by reference\n    void add8(const int &other) { value += other; } // passing by const reference\n    // NOLINTNEXTLINE(readability-non-const-parameter) Deliberately non-const for testing\n    void add9(int *other) { value += *other; }        // passing by pointer\n    void add10(const int *other) { value += *other; } // passing by const pointer\n\n    void consume_str(std::string &&) {}\n\n    ExampleMandA self1() { return *this; }              // return by value\n    ExampleMandA &self2() { return *this; }             // return by reference\n    const ExampleMandA &self3() const { return *this; } // return by const reference\n    ExampleMandA *self4() { return this; }              // return by pointer\n    const ExampleMandA *self5() const { return this; }  // return by const pointer\n\n    int internal1() const { return value; }        // return by value\n    int &internal2() { return value; }             // return by reference\n    const int &internal3() const { return value; } // return by const reference\n    int *internal4() { return &value; }            // return by pointer\n    const int *internal5() { return &value; }      // return by const pointer\n\n    py::str overloaded() { return \"()\"; }\n    py::str overloaded(int) { return \"(int)\"; }\n    py::str overloaded(int, float) { return \"(int, float)\"; }\n    py::str overloaded(float, int) { return \"(float, int)\"; }\n    py::str overloaded(int, int) { return \"(int, int)\"; }\n    py::str overloaded(float, float) { return \"(float, float)\"; }\n    py::str overloaded(int) const { return \"(int) const\"; }\n    py::str overloaded(int, float) const { return \"(int, float) const\"; }\n    py::str overloaded(float, int) const { return \"(float, int) const\"; }\n    py::str overloaded(int, int) const { return \"(int, int) const\"; }\n    py::str overloaded(float, float) const { return \"(float, float) const\"; }\n\n    static py::str overloaded(float) { return \"static float\"; }\n\n    int value = 0;\n};\n\nstruct TestProperties {\n    int value = 1;\n    static int static_value;\n\n    int get() const { return value; }\n    void set(int v) { value = v; }\n\n    static int static_get() { return static_value; }\n    static void static_set(int v) { static_value = v; }\n};\nint TestProperties::static_value = 1;\n\nstruct TestPropertiesOverride : TestProperties {\n    int value = 99;\n    static int static_value;\n};\nint TestPropertiesOverride::static_value = 99;\n\nstruct TestPropRVP {\n    UserType v1{1};\n    UserType v2{1};\n    static UserType sv1;\n    static UserType sv2;\n\n    const UserType &get1() const { return v1; }\n    const UserType &get2() const { return v2; }\n    UserType get_rvalue() const { return v2; }\n    void set1(int v) { v1.set(v); }\n    void set2(int v) { v2.set(v); }\n};\nUserType TestPropRVP::sv1(1);\nUserType TestPropRVP::sv2(1);\n\n// Test None-allowed py::arg argument policy\nclass NoneTester {\npublic:\n    int answer = 42;\n};\nint none1(const NoneTester &obj) { return obj.answer; }\nint none2(NoneTester *obj) { return obj ? obj->answer : -1; }\nint none3(std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }\nint none4(std::shared_ptr<NoneTester> *obj) { return obj && *obj ? (*obj)->answer : -1; }\nint none5(const std::shared_ptr<NoneTester> &obj) { return obj ? obj->answer : -1; }\n\n// Issue #2778: implicit casting from None to object (not pointer)\nclass NoneCastTester {\npublic:\n    int answer = -1;\n    NoneCastTester() = default;\n    explicit NoneCastTester(int v) : answer(v) {}\n};\n\nstruct StrIssue {\n    int val = -1;\n\n    StrIssue() = default;\n    explicit StrIssue(int i) : val{i} {}\n};\n\n// Issues #854, #910: incompatible function args when member function/pointer is in unregistered\n// base class\nclass UnregisteredBase {\npublic:\n    void do_nothing() const {}\n    void increase_value() {\n        rw_value++;\n        ro_value += 0.25;\n    }\n    void set_int(int v) { rw_value = v; }\n    int get_int() const { return rw_value; }\n    double get_double() const { return ro_value; }\n    int rw_value = 42;\n    double ro_value = 1.25;\n};\nclass RegisteredDerived : public UnregisteredBase {\npublic:\n    using UnregisteredBase::UnregisteredBase;\n    double sum() const { return rw_value + ro_value; }\n};\n\n// Test explicit lvalue ref-qualification\nstruct RefQualified {\n    int value = 0;\n\n    void refQualified(int other) & { value += other; }\n    int constRefQualified(int other) const & { return value + other; }\n};\n\n// Test rvalue ref param\nstruct RValueRefParam {\n    std::size_t func1(std::string &&s) { return s.size(); }\n    std::size_t func2(std::string &&s) const { return s.size(); }\n    std::size_t func3(std::string &&s) & { return s.size(); }\n    std::size_t func4(std::string &&s) const & { return s.size(); }\n};\n\nTEST_SUBMODULE(methods_and_attributes, m) {\n    // test_methods_and_attributes\n    py::class_<ExampleMandA> emna(m, \"ExampleMandA\");\n    emna.def(py::init<>())\n        .def(py::init<int>())\n        .def(py::init<std::string &&>())\n        .def(py::init<const ExampleMandA &>())\n        .def(\"add1\", &ExampleMandA::add1)\n        .def(\"add2\", &ExampleMandA::add2)\n        .def(\"add3\", &ExampleMandA::add3)\n        .def(\"add4\", &ExampleMandA::add4)\n        .def(\"add5\", &ExampleMandA::add5)\n        .def(\"add6\", &ExampleMandA::add6)\n        .def(\"add7\", &ExampleMandA::add7)\n        .def(\"add8\", &ExampleMandA::add8)\n        .def(\"add9\", &ExampleMandA::add9)\n        .def(\"add10\", &ExampleMandA::add10)\n        .def(\"consume_str\", &ExampleMandA::consume_str)\n        .def(\"self1\", &ExampleMandA::self1)\n        .def(\"self2\", &ExampleMandA::self2)\n        .def(\"self3\", &ExampleMandA::self3)\n        .def(\"self4\", &ExampleMandA::self4)\n        .def(\"self5\", &ExampleMandA::self5)\n        .def(\"internal1\", &ExampleMandA::internal1)\n        .def(\"internal2\", &ExampleMandA::internal2)\n        .def(\"internal3\", &ExampleMandA::internal3)\n        .def(\"internal4\", &ExampleMandA::internal4)\n        .def(\"internal5\", &ExampleMandA::internal5)\n#if defined(PYBIND11_OVERLOAD_CAST)\n        .def(\"overloaded\", py::overload_cast<>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<float, int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<int, int>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", py::overload_cast<float, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded_float\", py::overload_cast<float, float>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", py::overload_cast<int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<int, float>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<float, int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<int, int>(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\",\n             py::overload_cast<float, float>(&ExampleMandA::overloaded, py::const_))\n#else\n        // Use both the traditional static_cast method and the C++11 compatible overload_cast_\n        .def(\"overloaded\", overload_cast_<>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", overload_cast_<int>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", overload_cast_<int,   float>()(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(float,   int)>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(int,     int)>(&ExampleMandA::overloaded))\n        .def(\"overloaded\", static_cast<py::str (ExampleMandA::*)(float, float)>(&ExampleMandA::overloaded))\n        .def(\"overloaded_float\", overload_cast_<float, float>()(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", overload_cast_<int         >()(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\", overload_cast_<int,   float>()(&ExampleMandA::overloaded, py::const_))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(float,   int) const>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(int,     int) const>(&ExampleMandA::overloaded))\n        .def(\"overloaded_const\", static_cast<py::str (ExampleMandA::*)(float, float) const>(&ExampleMandA::overloaded))\n#endif\n        // test_no_mixed_overloads\n        // Raise error if trying to mix static/non-static overloads on the same name:\n        .def_static(\"add_mixed_overloads1\",\n                    []() {\n                        auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(\n                            py::module_::import(\"pybind11_tests.methods_and_attributes\")\n                                .attr(\"ExampleMandA\"));\n                        emna.def(\"overload_mixed1\",\n                                 static_cast<py::str (ExampleMandA::*)(int, int)>(\n                                     &ExampleMandA::overloaded))\n                            .def_static(\n                                \"overload_mixed1\",\n                                static_cast<py::str (*)(float)>(&ExampleMandA::overloaded));\n                    })\n        .def_static(\"add_mixed_overloads2\",\n                    []() {\n                        auto emna = py::reinterpret_borrow<py::class_<ExampleMandA>>(\n                            py::module_::import(\"pybind11_tests.methods_and_attributes\")\n                                .attr(\"ExampleMandA\"));\n                        emna.def_static(\"overload_mixed2\",\n                                        static_cast<py::str (*)(float)>(&ExampleMandA::overloaded))\n                            .def(\"overload_mixed2\",\n                                 static_cast<py::str (ExampleMandA::*)(int, int)>(\n                                     &ExampleMandA::overloaded));\n                    })\n        .def(\"__str__\", &ExampleMandA::toString)\n        .def_readwrite(\"value\", &ExampleMandA::value);\n\n    // test_copy_method\n    // Issue #443: can't call copied methods in Python 3\n    emna.attr(\"add2b\") = emna.attr(\"add2\");\n\n    // test_properties, test_static_properties, test_static_cls\n    py::class_<TestProperties>(m, \"TestProperties\")\n        .def(py::init<>())\n        .def_readonly(\"def_readonly\", &TestProperties::value)\n        .def_readwrite(\"def_readwrite\", &TestProperties::value)\n        .def_property(\"def_writeonly\", nullptr, [](TestProperties &s, int v) { s.value = v; })\n        .def_property(\"def_property_writeonly\", nullptr, &TestProperties::set)\n        .def_property_readonly(\"def_property_readonly\", &TestProperties::get)\n        .def_property(\"def_property\", &TestProperties::get, &TestProperties::set)\n        .def_property(\"def_property_impossible\", nullptr, nullptr)\n        .def_readonly_static(\"def_readonly_static\", &TestProperties::static_value)\n        .def_readwrite_static(\"def_readwrite_static\", &TestProperties::static_value)\n        .def_property_static(\"def_writeonly_static\",\n                             nullptr,\n                             [](const py::object &, int v) { TestProperties::static_value = v; })\n        .def_property_readonly_static(\n            \"def_property_readonly_static\",\n            [](const py::object &) { return TestProperties::static_get(); })\n        .def_property_static(\n            \"def_property_writeonly_static\",\n            nullptr,\n            [](const py::object &, int v) { return TestProperties::static_set(v); })\n        .def_property_static(\n            \"def_property_static\",\n            [](const py::object &) { return TestProperties::static_get(); },\n            [](const py::object &, int v) { TestProperties::static_set(v); })\n        .def_property_static(\n            \"static_cls\",\n            [](py::object cls) { return cls; },\n            [](const py::object &cls, const py::function &f) { f(cls); });\n\n    py::class_<TestPropertiesOverride, TestProperties>(m, \"TestPropertiesOverride\")\n        .def(py::init<>())\n        .def_readonly(\"def_readonly\", &TestPropertiesOverride::value)\n        .def_readonly_static(\"def_readonly_static\", &TestPropertiesOverride::static_value);\n\n    auto static_get1 = [](const py::object &) -> const UserType & { return TestPropRVP::sv1; };\n    auto static_get2 = [](const py::object &) -> const UserType & { return TestPropRVP::sv2; };\n    auto static_set1 = [](const py::object &, int v) { TestPropRVP::sv1.set(v); };\n    auto static_set2 = [](const py::object &, int v) { TestPropRVP::sv2.set(v); };\n    auto rvp_copy = py::return_value_policy::copy;\n\n    // test_property_return_value_policies\n    py::class_<TestPropRVP>(m, \"TestPropRVP\")\n        .def(py::init<>())\n        .def_property_readonly(\"ro_ref\", &TestPropRVP::get1)\n        .def_property_readonly(\"ro_copy\", &TestPropRVP::get2, rvp_copy)\n        .def_property_readonly(\"ro_func\", py::cpp_function(&TestPropRVP::get2, rvp_copy))\n        .def_property(\"rw_ref\", &TestPropRVP::get1, &TestPropRVP::set1)\n        .def_property(\"rw_copy\", &TestPropRVP::get2, &TestPropRVP::set2, rvp_copy)\n        .def_property(\n            \"rw_func\", py::cpp_function(&TestPropRVP::get2, rvp_copy), &TestPropRVP::set2)\n        .def_property_readonly_static(\"static_ro_ref\", static_get1)\n        .def_property_readonly_static(\"static_ro_copy\", static_get2, rvp_copy)\n        .def_property_readonly_static(\"static_ro_func\", py::cpp_function(static_get2, rvp_copy))\n        .def_property_static(\"static_rw_ref\", static_get1, static_set1)\n        .def_property_static(\"static_rw_copy\", static_get2, static_set2, rvp_copy)\n        .def_property_static(\n            \"static_rw_func\", py::cpp_function(static_get2, rvp_copy), static_set2)\n        // test_property_rvalue_policy\n        .def_property_readonly(\"rvalue\", &TestPropRVP::get_rvalue)\n        .def_property_readonly_static(\"static_rvalue\",\n                                      [](const py::object &) { return UserType(1); });\n\n    // test_metaclass_override\n    struct MetaclassOverride {};\n    py::class_<MetaclassOverride>(m, \"MetaclassOverride\", py::metaclass((PyObject *) &PyType_Type))\n        .def_property_readonly_static(\"readonly\", [](const py::object &) { return 1; });\n\n    // test_overload_ordering\n    m.def(\"overload_order\", [](const std::string &) { return 1; });\n    m.def(\"overload_order\", [](const std::string &) { return 2; });\n    m.def(\"overload_order\", [](int) { return 3; });\n    m.def(\n        \"overload_order\", [](int) { return 4; }, py::prepend{});\n\n#if !defined(PYPY_VERSION)\n    // test_dynamic_attributes\n    class DynamicClass {\n    public:\n        DynamicClass() { print_default_created(this); }\n        DynamicClass(const DynamicClass &) = delete;\n        ~DynamicClass() { print_destroyed(this); }\n    };\n    py::class_<DynamicClass>(m, \"DynamicClass\", py::dynamic_attr()).def(py::init());\n\n    class CppDerivedDynamicClass : public DynamicClass {};\n    py::class_<CppDerivedDynamicClass, DynamicClass>(m, \"CppDerivedDynamicClass\").def(py::init());\n#endif\n\n    // test_bad_arg_default\n    // Issue/PR #648: bad arg default debugging output\n#if !defined(NDEBUG)\n    m.attr(\"debug_enabled\") = true;\n#else\n    m.attr(\"debug_enabled\") = false;\n#endif\n    m.def(\"bad_arg_def_named\", [] {\n        auto m = py::module_::import(\"pybind11_tests\");\n        m.def(\n            \"should_fail\",\n            [](int, UnregisteredType) {},\n            py::arg(),\n            py::arg(\"a\") = UnregisteredType());\n    });\n    m.def(\"bad_arg_def_unnamed\", [] {\n        auto m = py::module_::import(\"pybind11_tests\");\n        m.def(\n            \"should_fail\",\n            [](int, UnregisteredType) {},\n            py::arg(),\n            py::arg() = UnregisteredType());\n    });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // test_accepts_none\n    py::class_<NoneTester, std::shared_ptr<NoneTester>>(m, \"NoneTester\").def(py::init<>());\n    m.def(\"no_none1\", &none1, py::arg{}.none(false));\n    m.def(\"no_none2\", &none2, py::arg{}.none(false));\n    m.def(\"no_none3\", &none3, py::arg{}.none(false));\n    m.def(\"no_none4\", &none4, py::arg{}.none(false));\n    m.def(\"no_none5\", &none5, py::arg{}.none(false));\n    m.def(\"ok_none1\", &none1);\n    m.def(\"ok_none2\", &none2, py::arg{}.none(true));\n    m.def(\"ok_none3\", &none3);\n    m.def(\"ok_none4\", &none4, py::arg{}.none(true));\n    m.def(\"ok_none5\", &none5);\n\n    m.def(\"no_none_kwarg\", &none2, \"a\"_a.none(false));\n    m.def(\"no_none_kwarg_kw_only\", &none2, py::kw_only(), \"a\"_a.none(false));\n\n    // test_casts_none\n    // Issue #2778: implicit casting from None to object (not pointer)\n    py::class_<NoneCastTester>(m, \"NoneCastTester\")\n        .def(py::init<>())\n        .def(py::init<int>())\n        .def(py::init([](py::none const &) { return NoneCastTester{}; }));\n    py::implicitly_convertible<py::none, NoneCastTester>();\n    m.def(\"ok_obj_or_none\", [](NoneCastTester const &foo) { return foo.answer; });\n\n    // test_str_issue\n    // Issue #283: __str__ called on uninitialized instance when constructor arguments invalid\n    py::class_<StrIssue>(m, \"StrIssue\")\n        .def(py::init<int>())\n        .def(py::init<>())\n        .def(\"__str__\",\n             [](const StrIssue &si) { return \"StrIssue[\" + std::to_string(si.val) + \"]\"; });\n\n    // test_unregistered_base_implementations\n    //\n    // Issues #854/910: incompatible function args when member function/pointer is in unregistered\n    // base class The methods and member pointers below actually resolve to members/pointers in\n    // UnregisteredBase; before this test/fix they would be registered via lambda with a first\n    // argument of an unregistered type, and thus uncallable.\n    py::class_<RegisteredDerived>(m, \"RegisteredDerived\")\n        .def(py::init<>())\n        .def(\"do_nothing\", &RegisteredDerived::do_nothing)\n        .def(\"increase_value\", &RegisteredDerived::increase_value)\n        .def_readwrite(\"rw_value\", &RegisteredDerived::rw_value)\n        .def_readonly(\"ro_value\", &RegisteredDerived::ro_value)\n        // Uncommenting the next line should trigger a static_assert:\n        // .def_readwrite(\"fails\", &UserType::value)\n        // Uncommenting the next line should trigger a static_assert:\n        // .def_readonly(\"fails\", &UserType::value)\n        .def_property(\"rw_value_prop\", &RegisteredDerived::get_int, &RegisteredDerived::set_int)\n        .def_property_readonly(\"ro_value_prop\", &RegisteredDerived::get_double)\n        // This one is in the registered class:\n        .def(\"sum\", &RegisteredDerived::sum);\n\n    using Adapted\n        = decltype(py::method_adaptor<RegisteredDerived>(&RegisteredDerived::do_nothing));\n    static_assert(std::is_same<Adapted, void (RegisteredDerived::*)() const>::value, \"\");\n\n    // test_methods_and_attributes\n    py::class_<RefQualified>(m, \"RefQualified\")\n        .def(py::init<>())\n        .def_readonly(\"value\", &RefQualified::value)\n        .def(\"refQualified\", &RefQualified::refQualified)\n        .def(\"constRefQualified\", &RefQualified::constRefQualified);\n\n    py::class_<RValueRefParam>(m, \"RValueRefParam\")\n        .def(py::init<>())\n        .def(\"func1\", &RValueRefParam::func1)\n        .def(\"func2\", &RValueRefParam::func2)\n        .def(\"func3\", &RValueRefParam::func3)\n        .def(\"func4\", &RValueRefParam::func4);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_methods_and_attributes.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import methods_and_attributes as m\n\n\ndef test_methods_and_attributes():\n    instance1 = m.ExampleMandA()\n    instance2 = m.ExampleMandA(32)\n\n    instance1.add1(instance2)\n    instance1.add2(instance2)\n    instance1.add3(instance2)\n    instance1.add4(instance2)\n    instance1.add5(instance2)\n    instance1.add6(32)\n    instance1.add7(32)\n    instance1.add8(32)\n    instance1.add9(32)\n    instance1.add10(32)\n\n    assert str(instance1) == \"ExampleMandA[value=320]\"\n    assert str(instance2) == \"ExampleMandA[value=32]\"\n    assert str(instance1.self1()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self2()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self3()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self4()) == \"ExampleMandA[value=320]\"\n    assert str(instance1.self5()) == \"ExampleMandA[value=320]\"\n\n    assert instance1.internal1() == 320\n    assert instance1.internal2() == 320\n    assert instance1.internal3() == 320\n    assert instance1.internal4() == 320\n    assert instance1.internal5() == 320\n\n    assert instance1.overloaded() == \"()\"\n    assert instance1.overloaded(0) == \"(int)\"\n    assert instance1.overloaded(1, 1.0) == \"(int, float)\"\n    assert instance1.overloaded(2.0, 2) == \"(float, int)\"\n    assert instance1.overloaded(3, 3) == \"(int, int)\"\n    assert instance1.overloaded(4.0, 4.0) == \"(float, float)\"\n    assert instance1.overloaded_const(-3) == \"(int) const\"\n    assert instance1.overloaded_const(5, 5.0) == \"(int, float) const\"\n    assert instance1.overloaded_const(6.0, 6) == \"(float, int) const\"\n    assert instance1.overloaded_const(7, 7) == \"(int, int) const\"\n    assert instance1.overloaded_const(8.0, 8.0) == \"(float, float) const\"\n    assert instance1.overloaded_float(1, 1) == \"(float, float)\"\n    assert instance1.overloaded_float(1, 1.0) == \"(float, float)\"\n    assert instance1.overloaded_float(1.0, 1) == \"(float, float)\"\n    assert instance1.overloaded_float(1.0, 1.0) == \"(float, float)\"\n\n    assert instance1.value == 320\n    instance1.value = 100\n    assert str(instance1) == \"ExampleMandA[value=100]\"\n\n    cstats = ConstructorStats.get(m.ExampleMandA)\n    assert cstats.alive() == 2\n    del instance1, instance2\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"32\"]\n    assert cstats.default_constructions == 1\n    assert cstats.copy_constructions == 2\n    assert cstats.move_constructions >= 2\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_copy_method():\n    \"\"\"Issue #443: calling copied methods fails in Python 3\"\"\"\n\n    m.ExampleMandA.add2c = m.ExampleMandA.add2\n    m.ExampleMandA.add2d = m.ExampleMandA.add2b\n    a = m.ExampleMandA(123)\n    assert a.value == 123\n    a.add2(m.ExampleMandA(-100))\n    assert a.value == 23\n    a.add2b(m.ExampleMandA(20))\n    assert a.value == 43\n    a.add2c(m.ExampleMandA(6))\n    assert a.value == 49\n    a.add2d(m.ExampleMandA(-7))\n    assert a.value == 42\n\n\ndef test_properties():\n    instance = m.TestProperties()\n\n    assert instance.def_readonly == 1\n    with pytest.raises(AttributeError):\n        instance.def_readonly = 2\n\n    instance.def_readwrite = 2\n    assert instance.def_readwrite == 2\n\n    assert instance.def_property_readonly == 2\n    with pytest.raises(AttributeError):\n        instance.def_property_readonly = 3\n\n    instance.def_property = 3\n    assert instance.def_property == 3\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_writeonly  # unused var\n    assert \"unreadable attribute\" in str(excinfo.value)\n\n    instance.def_property_writeonly = 4\n    assert instance.def_property_readonly == 4\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_impossible  # noqa: F841 unused var\n    assert \"unreadable attribute\" in str(excinfo.value)\n\n    with pytest.raises(AttributeError) as excinfo:\n        instance.def_property_impossible = 5\n    assert \"can't set attribute\" in str(excinfo.value)\n\n\ndef test_static_properties():\n    assert m.TestProperties.def_readonly_static == 1\n    with pytest.raises(AttributeError) as excinfo:\n        m.TestProperties.def_readonly_static = 2\n    assert \"can't set attribute\" in str(excinfo.value)\n\n    m.TestProperties.def_readwrite_static = 2\n    assert m.TestProperties.def_readwrite_static == 2\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = m.TestProperties.def_writeonly_static  # unused var\n    assert \"unreadable attribute\" in str(excinfo.value)\n\n    m.TestProperties.def_writeonly_static = 3\n    assert m.TestProperties.def_readonly_static == 3\n\n    assert m.TestProperties.def_property_readonly_static == 3\n    with pytest.raises(AttributeError) as excinfo:\n        m.TestProperties.def_property_readonly_static = 99\n    assert \"can't set attribute\" in str(excinfo.value)\n\n    m.TestProperties.def_property_static = 4\n    assert m.TestProperties.def_property_static == 4\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = m.TestProperties.def_property_writeonly_static\n    assert \"unreadable attribute\" in str(excinfo.value)\n\n    m.TestProperties.def_property_writeonly_static = 5\n    assert m.TestProperties.def_property_static == 5\n\n    # Static property read and write via instance\n    instance = m.TestProperties()\n\n    m.TestProperties.def_readwrite_static = 0\n    assert m.TestProperties.def_readwrite_static == 0\n    assert instance.def_readwrite_static == 0\n\n    instance.def_readwrite_static = 2\n    assert m.TestProperties.def_readwrite_static == 2\n    assert instance.def_readwrite_static == 2\n\n    with pytest.raises(AttributeError) as excinfo:\n        dummy = instance.def_property_writeonly_static  # noqa: F841 unused var\n    assert \"unreadable attribute\" in str(excinfo.value)\n\n    instance.def_property_writeonly_static = 4\n    assert instance.def_property_static == 4\n\n    # It should be possible to override properties in derived classes\n    assert m.TestPropertiesOverride().def_readonly == 99\n    assert m.TestPropertiesOverride.def_readonly_static == 99\n\n    # Only static attributes can be deleted\n    del m.TestPropertiesOverride.def_readonly_static\n    assert (\n        hasattr(m.TestPropertiesOverride, \"def_readonly_static\")\n        and m.TestPropertiesOverride.def_readonly_static\n        is m.TestProperties.def_readonly_static\n    )\n    assert \"def_readonly_static\" not in m.TestPropertiesOverride.__dict__\n    properties_override = m.TestPropertiesOverride()\n    with pytest.raises(AttributeError) as excinfo:\n        del properties_override.def_readonly\n    assert \"can't delete attribute\" in str(excinfo.value)\n\n\ndef test_static_cls():\n    \"\"\"Static property getter and setters expect the type object as the their only argument\"\"\"\n\n    instance = m.TestProperties()\n    assert m.TestProperties.static_cls is m.TestProperties\n    assert instance.static_cls is m.TestProperties\n\n    def check_self(self):\n        assert self is m.TestProperties\n\n    m.TestProperties.static_cls = check_self\n    instance.static_cls = check_self\n\n\ndef test_metaclass_override():\n    \"\"\"Overriding pybind11's default metaclass changes the behavior of `static_property`\"\"\"\n\n    assert type(m.ExampleMandA).__name__ == \"pybind11_type\"\n    assert type(m.MetaclassOverride).__name__ == \"type\"\n\n    assert m.MetaclassOverride.readonly == 1\n    assert (\n        type(m.MetaclassOverride.__dict__[\"readonly\"]).__name__\n        == \"pybind11_static_property\"\n    )\n\n    # Regular `type` replaces the property instead of calling `__set__()`\n    m.MetaclassOverride.readonly = 2\n    assert m.MetaclassOverride.readonly == 2\n    assert isinstance(m.MetaclassOverride.__dict__[\"readonly\"], int)\n\n\ndef test_no_mixed_overloads():\n    from pybind11_tests import debug_enabled\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.ExampleMandA.add_mixed_overloads1()\n    assert str(\n        excinfo.value\n    ) == \"overloading a method with both static and instance methods is not supported; \" + (\n        \"compile in debug mode for more details\"\n        if not debug_enabled\n        else \"error while attempting to bind static method ExampleMandA.overload_mixed1\"\n        \"(arg0: float) -> str\"\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.ExampleMandA.add_mixed_overloads2()\n    assert str(\n        excinfo.value\n    ) == \"overloading a method with both static and instance methods is not supported; \" + (\n        \"compile in debug mode for more details\"\n        if not debug_enabled\n        else \"error while attempting to bind instance method ExampleMandA.overload_mixed2\"\n        \"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)\"\n        \" -> str\"\n    )\n\n\n@pytest.mark.parametrize(\"access\", [\"ro\", \"rw\", \"static_ro\", \"static_rw\"])\ndef test_property_return_value_policies(access):\n    if not access.startswith(\"static\"):\n        obj = m.TestPropRVP()\n    else:\n        obj = m.TestPropRVP\n\n    ref = getattr(obj, access + \"_ref\")\n    assert ref.value == 1\n    ref.value = 2\n    assert getattr(obj, access + \"_ref\").value == 2\n    ref.value = 1  # restore original value for static properties\n\n    copy = getattr(obj, access + \"_copy\")\n    assert copy.value == 1\n    copy.value = 2\n    assert getattr(obj, access + \"_copy\").value == 1\n\n    copy = getattr(obj, access + \"_func\")\n    assert copy.value == 1\n    copy.value = 2\n    assert getattr(obj, access + \"_func\").value == 1\n\n\ndef test_property_rvalue_policy():\n    \"\"\"When returning an rvalue, the return value policy is automatically changed from\n    `reference(_internal)` to `move`. The following would not work otherwise.\"\"\"\n\n    instance = m.TestPropRVP()\n    o = instance.rvalue\n    assert o.value == 1\n\n    os = m.TestPropRVP.static_rvalue\n    assert os.value == 1\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_dynamic_attributes():\n    instance = m.DynamicClass()\n    assert not hasattr(instance, \"foo\")\n    assert \"foo\" not in dir(instance)\n\n    # Dynamically add attribute\n    instance.foo = 42\n    assert hasattr(instance, \"foo\")\n    assert instance.foo == 42\n    assert \"foo\" in dir(instance)\n\n    # __dict__ should be accessible and replaceable\n    assert \"foo\" in instance.__dict__\n    instance.__dict__ = {\"bar\": True}\n    assert not hasattr(instance, \"foo\")\n    assert hasattr(instance, \"bar\")\n\n    with pytest.raises(TypeError) as excinfo:\n        instance.__dict__ = []\n    assert str(excinfo.value) == \"__dict__ must be set to a dictionary, not a 'list'\"\n\n    cstats = ConstructorStats.get(m.DynamicClass)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n    # Derived classes should work as well\n    class PythonDerivedDynamicClass(m.DynamicClass):\n        pass\n\n    for cls in m.CppDerivedDynamicClass, PythonDerivedDynamicClass:\n        derived = cls()\n        derived.foobar = 100\n        assert derived.foobar == 100\n\n        assert cstats.alive() == 1\n        del derived\n        assert cstats.alive() == 0\n\n\n# https://foss.heptapod.net/pypy/pypy/-/issues/2447\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_cyclic_gc():\n    # One object references itself\n    instance = m.DynamicClass()\n    instance.circular_reference = instance\n\n    cstats = ConstructorStats.get(m.DynamicClass)\n    assert cstats.alive() == 1\n    del instance\n    assert cstats.alive() == 0\n\n    # Two object reference each other\n    i1 = m.DynamicClass()\n    i2 = m.DynamicClass()\n    i1.cycle = i2\n    i2.cycle = i1\n\n    assert cstats.alive() == 2\n    del i1, i2\n    assert cstats.alive() == 0\n\n\ndef test_bad_arg_default(msg):\n    from pybind11_tests import debug_enabled\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.bad_arg_def_named()\n    assert msg(excinfo.value) == (\n        \"arg(): could not convert default argument 'a: UnregisteredType' in function \"\n        \"'should_fail' into a Python object (type not registered yet?)\"\n        if debug_enabled\n        else \"arg(): could not convert default argument into a Python object (type not registered \"\n        \"yet?). Compile in debug mode for more information.\"\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.bad_arg_def_unnamed()\n    assert msg(excinfo.value) == (\n        \"arg(): could not convert default argument 'UnregisteredType' in function \"\n        \"'should_fail' into a Python object (type not registered yet?)\"\n        if debug_enabled\n        else \"arg(): could not convert default argument into a Python object (type not registered \"\n        \"yet?). Compile in debug mode for more information.\"\n    )\n\n\ndef test_accepts_none(msg):\n    a = m.NoneTester()\n    assert m.no_none1(a) == 42\n    assert m.no_none2(a) == 42\n    assert m.no_none3(a) == 42\n    assert m.no_none4(a) == 42\n    assert m.no_none5(a) == 42\n    assert m.ok_none1(a) == 42\n    assert m.ok_none2(a) == 42\n    assert m.ok_none3(a) == 42\n    assert m.ok_none4(a) == 42\n    assert m.ok_none5(a) == 42\n\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none1(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none2(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none3(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none4(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none5(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    # The first one still raises because you can't pass None as a lvalue reference arg:\n    with pytest.raises(TypeError) as excinfo:\n        assert m.ok_none1(None) == -1\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        ok_none1(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: m.methods_and_attributes.NoneTester) -> int\n\n        Invoked with: None\n    \"\"\"\n    )\n\n    # The rest take the argument as pointer or holder, and accept None:\n    assert m.ok_none2(None) == -1\n    assert m.ok_none3(None) == -1\n    assert m.ok_none4(None) == -1\n    assert m.ok_none5(None) == -1\n\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg(a=None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg_kw_only(None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    with pytest.raises(TypeError) as excinfo:\n        m.no_none_kwarg_kw_only(a=None)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_casts_none():\n    \"\"\"#2778: implicit casting from None to object (not pointer)\"\"\"\n    a = m.NoneCastTester()\n    assert m.ok_obj_or_none(a) == -1\n    a = m.NoneCastTester(4)\n    assert m.ok_obj_or_none(a) == 4\n    a = m.NoneCastTester(None)\n    assert m.ok_obj_or_none(a) == -1\n    assert m.ok_obj_or_none(None) == -1\n\n\ndef test_str_issue(msg):\n    \"\"\"#283: __str__ called on uninitialized instance when constructor arguments invalid\"\"\"\n\n    assert str(m.StrIssue(3)) == \"StrIssue[3]\"\n\n    with pytest.raises(TypeError) as excinfo:\n        str(m.StrIssue(\"no\", \"such\", \"constructor\"))\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        __init__(): incompatible constructor arguments. The following argument types are supported:\n            1. m.methods_and_attributes.StrIssue(arg0: int)\n            2. m.methods_and_attributes.StrIssue()\n\n        Invoked with: 'no', 'such', 'constructor'\n    \"\"\"\n    )\n\n\ndef test_unregistered_base_implementations():\n    a = m.RegisteredDerived()\n    a.do_nothing()\n    assert a.rw_value == 42\n    assert a.ro_value == 1.25\n    a.rw_value += 5\n    assert a.sum() == 48.25\n    a.increase_value()\n    assert a.rw_value == 48\n    assert a.ro_value == 1.5\n    assert a.sum() == 49.5\n    assert a.rw_value_prop == 48\n    a.rw_value_prop += 1\n    assert a.rw_value_prop == 49\n    a.increase_value()\n    assert a.ro_value_prop == 1.75\n\n\ndef test_ref_qualified():\n    \"\"\"Tests that explicit lvalue ref-qualified methods can be called just like their\n    non ref-qualified counterparts.\"\"\"\n\n    r = m.RefQualified()\n    assert r.value == 0\n    r.refQualified(17)\n    assert r.value == 17\n    assert r.constRefQualified(23) == 40\n\n\ndef test_overload_ordering():\n    \"Check to see if the normal overload order (first defined) and prepend overload order works\"\n    assert m.overload_order(\"string\") == 1\n    assert m.overload_order(0) == 4\n\n    # Different for Python 2 vs. 3\n    uni_name = type(u\"\").__name__\n\n    assert \"1. overload_order(arg0: int) -> int\" in m.overload_order.__doc__\n    assert (\n        \"2. overload_order(arg0: {}) -> int\".format(uni_name)\n        in m.overload_order.__doc__\n    )\n    assert (\n        \"3. overload_order(arg0: {}) -> int\".format(uni_name)\n        in m.overload_order.__doc__\n    )\n    assert \"4. overload_order(arg0: int) -> int\" in m.overload_order.__doc__\n\n    with pytest.raises(TypeError) as err:\n        m.overload_order(1.1)\n\n    assert \"1. (arg0: int) -> int\" in str(err.value)\n    assert \"2. (arg0: {}) -> int\".format(uni_name) in str(err.value)\n    assert \"3. (arg0: {}) -> int\".format(uni_name) in str(err.value)\n    assert \"4. (arg0: int) -> int\" in str(err.value)\n\n\ndef test_rvalue_ref_param():\n    r = m.RValueRefParam()\n    assert r.func1(\"123\") == 3\n    assert r.func2(\"1234\") == 4\n    assert r.func3(\"12345\") == 5\n    assert r.func4(\"123456\") == 6\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_modules.cpp",
    "content": "/*\n    tests/test_modules.cpp -- nested modules, importing modules, and\n                            internal references\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(modules, m) {\n    // test_nested_modules\n    // This is intentionally \"py::module\" to verify it still can be used in place of \"py::module_\"\n    py::module m_sub = m.def_submodule(\"subsubmodule\");\n    m_sub.def(\"submodule_func\", []() { return \"submodule_func()\"; });\n\n    // test_reference_internal\n    class A {\n    public:\n        explicit A(int v) : v(v) { print_created(this, v); }\n        ~A() { print_destroyed(this); }\n        A(const A &) { print_copy_created(this); }\n        A &operator=(const A &copy) {\n            print_copy_assigned(this);\n            v = copy.v;\n            return *this;\n        }\n        std::string toString() const { return \"A[\" + std::to_string(v) + \"]\"; }\n\n    private:\n        int v;\n    };\n    py::class_<A>(m_sub, \"A\").def(py::init<int>()).def(\"__repr__\", &A::toString);\n\n    class B {\n    public:\n        B() { print_default_created(this); }\n        ~B() { print_destroyed(this); }\n        B(const B &) { print_copy_created(this); }\n        B &operator=(const B &copy) {\n            print_copy_assigned(this);\n            a1 = copy.a1;\n            a2 = copy.a2;\n            return *this;\n        }\n        A &get_a1() { return a1; }\n        A &get_a2() { return a2; }\n\n        A a1{1};\n        A a2{2};\n    };\n    py::class_<B>(m_sub, \"B\")\n        .def(py::init<>())\n        .def(\"get_a1\",\n             &B::get_a1,\n             \"Return the internal A 1\",\n             py::return_value_policy::reference_internal)\n        .def(\"get_a2\",\n             &B::get_a2,\n             \"Return the internal A 2\",\n             py::return_value_policy::reference_internal)\n        .def_readwrite(\"a1\", &B::a1) // def_readonly uses an internal\n                                     // reference return policy by default\n        .def_readwrite(\"a2\", &B::a2);\n\n    // This is intentionally \"py::module\" to verify it still can be used in place of \"py::module_\"\n    m.attr(\"OD\") = py::module::import(\"collections\").attr(\"OrderedDict\");\n\n    // test_duplicate_registration\n    // Registering two things with the same name\n    m.def(\"duplicate_registration\", []() {\n        class Dupe1 {};\n        class Dupe2 {};\n        class Dupe3 {};\n        class DupeException {};\n\n        // Go ahead and leak, until we have a non-leaking py::module_ constructor\n        auto dm\n            = py::module_::create_extension_module(\"dummy\", nullptr, new py::module_::module_def);\n        auto failures = py::list();\n\n        py::class_<Dupe1>(dm, \"Dupe1\");\n        py::class_<Dupe2>(dm, \"Dupe2\");\n        dm.def(\"dupe1_factory\", []() { return Dupe1(); });\n        py::exception<DupeException>(dm, \"DupeException\");\n\n        try {\n            py::class_<Dupe1>(dm, \"Dupe1\");\n            failures.append(\"Dupe1 class\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            dm.def(\"Dupe1\", []() { return Dupe1(); });\n            failures.append(\"Dupe1 function\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::class_<Dupe3>(dm, \"dupe1_factory\");\n            failures.append(\"dupe1_factory\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::exception<Dupe3>(dm, \"Dupe2\");\n            failures.append(\"Dupe2\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            dm.def(\"DupeException\", []() { return 30; });\n            failures.append(\"DupeException1\");\n        } catch (std::runtime_error &) {\n        }\n        try {\n            py::class_<DupeException>(dm, \"DupeException\");\n            failures.append(\"DupeException2\");\n        } catch (std::runtime_error &) {\n        }\n\n        return failures;\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_modules.py",
    "content": "# -*- coding: utf-8 -*-\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import modules as m\nfrom pybind11_tests.modules import subsubmodule as ms\n\n\ndef test_nested_modules():\n    import pybind11_tests\n\n    assert pybind11_tests.__name__ == \"pybind11_tests\"\n    assert pybind11_tests.modules.__name__ == \"pybind11_tests.modules\"\n    assert (\n        pybind11_tests.modules.subsubmodule.__name__\n        == \"pybind11_tests.modules.subsubmodule\"\n    )\n    assert m.__name__ == \"pybind11_tests.modules\"\n    assert ms.__name__ == \"pybind11_tests.modules.subsubmodule\"\n\n    assert ms.submodule_func() == \"submodule_func()\"\n\n\ndef test_reference_internal():\n    b = ms.B()\n    assert str(b.get_a1()) == \"A[1]\"\n    assert str(b.a1) == \"A[1]\"\n    assert str(b.get_a2()) == \"A[2]\"\n    assert str(b.a2) == \"A[2]\"\n\n    b.a1 = ms.A(42)\n    b.a2 = ms.A(43)\n    assert str(b.get_a1()) == \"A[42]\"\n    assert str(b.a1) == \"A[42]\"\n    assert str(b.get_a2()) == \"A[43]\"\n    assert str(b.a2) == \"A[43]\"\n\n    astats, bstats = ConstructorStats.get(ms.A), ConstructorStats.get(ms.B)\n    assert astats.alive() == 2\n    assert bstats.alive() == 1\n    del b\n    assert astats.alive() == 0\n    assert bstats.alive() == 0\n    assert astats.values() == [\"1\", \"2\", \"42\", \"43\"]\n    assert bstats.values() == []\n    assert astats.default_constructions == 0\n    assert bstats.default_constructions == 1\n    assert astats.copy_constructions == 0\n    assert bstats.copy_constructions == 0\n    # assert astats.move_constructions >= 0  # Don't invoke any\n    # assert bstats.move_constructions >= 0  # Don't invoke any\n    assert astats.copy_assignments == 2\n    assert bstats.copy_assignments == 0\n    assert astats.move_assignments == 0\n    assert bstats.move_assignments == 0\n\n\ndef test_importing():\n    from collections import OrderedDict\n\n    from pybind11_tests.modules import OD\n\n    assert OD is OrderedDict\n    assert str(OD([(1, \"a\"), (2, \"b\")])) == \"OrderedDict([(1, 'a'), (2, 'b')])\"\n\n\ndef test_pydoc():\n    \"\"\"Pydoc needs to be able to provide help() for everything inside a pybind11 module\"\"\"\n    import pydoc\n\n    import pybind11_tests\n\n    assert pybind11_tests.__name__ == \"pybind11_tests\"\n    assert pybind11_tests.__doc__ == \"pybind11 test module\"\n    assert pydoc.text.docmodule(pybind11_tests)\n\n\ndef test_duplicate_registration():\n    \"\"\"Registering two things with the same name\"\"\"\n\n    assert m.duplicate_registration() == []\n\n\ndef test_builtin_key_type():\n    \"\"\"Test that all the keys in the builtin modules have type str.\n\n    Previous versions of pybind11 would add a unicode key in python 2.\n    \"\"\"\n    if hasattr(__builtins__, \"keys\"):\n        keys = __builtins__.keys()\n    else:  # this is to make pypy happy since builtins is different there.\n        keys = __builtins__.__dict__.keys()\n\n    assert {type(k) for k in keys} == {str}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_multiple_inheritance.cpp",
    "content": "/*\n    tests/test_multiple_inheritance.cpp -- multiple inheritance,\n    implicit MI casts\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\nnamespace {\n\n// Many bases for testing that multiple inheritance from many classes (i.e. requiring extra\n// space for holder constructed flags) works.\ntemplate <int N>\nstruct BaseN {\n    explicit BaseN(int i) : i(i) {}\n    int i;\n};\n\n// test_mi_static_properties\nstruct Vanilla {\n    std::string vanilla() { return \"Vanilla\"; };\n};\nstruct WithStatic1 {\n    static std::string static_func1() { return \"WithStatic1\"; };\n    static int static_value1;\n};\nstruct WithStatic2 {\n    static std::string static_func2() { return \"WithStatic2\"; };\n    static int static_value2;\n};\nstruct VanillaStaticMix1 : Vanilla, WithStatic1, WithStatic2 {\n    static std::string static_func() { return \"VanillaStaticMix1\"; }\n    static int static_value;\n};\nstruct VanillaStaticMix2 : WithStatic1, Vanilla, WithStatic2 {\n    static std::string static_func() { return \"VanillaStaticMix2\"; }\n    static int static_value;\n};\nint WithStatic1::static_value1 = 1;\nint WithStatic2::static_value2 = 2;\nint VanillaStaticMix1::static_value = 12;\nint VanillaStaticMix2::static_value = 12;\n\n// test_multiple_inheritance_virtbase\nstruct Base1a {\n    explicit Base1a(int i) : i(i) {}\n    int foo() const { return i; }\n    int i;\n};\nstruct Base2a {\n    explicit Base2a(int i) : i(i) {}\n    int bar() const { return i; }\n    int i;\n};\nstruct Base12a : Base1a, Base2a {\n    Base12a(int i, int j) : Base1a(i), Base2a(j) {}\n};\n\n// test_mi_unaligned_base\n// test_mi_base_return\nstruct I801B1 {\n    int a = 1;\n    I801B1() = default;\n    I801B1(const I801B1 &) = default;\n    virtual ~I801B1() = default;\n};\nstruct I801B2 {\n    int b = 2;\n    I801B2() = default;\n    I801B2(const I801B2 &) = default;\n    virtual ~I801B2() = default;\n};\nstruct I801C : I801B1, I801B2 {};\nstruct I801D : I801C {}; // Indirect MI\n\n} // namespace\n\nTEST_SUBMODULE(multiple_inheritance, m) {\n    // Please do not interleave `struct` and `class` definitions with bindings code,\n    // but implement `struct`s and `class`es in the anonymous namespace above.\n    // This helps keeping the smart_holder branch in sync with master.\n\n    // test_multiple_inheritance_mix1\n    // test_multiple_inheritance_mix2\n    struct Base1 {\n        explicit Base1(int i) : i(i) {}\n        int foo() const { return i; }\n        int i;\n    };\n    py::class_<Base1> b1(m, \"Base1\");\n    b1.def(py::init<int>()).def(\"foo\", &Base1::foo);\n\n    struct Base2 {\n        explicit Base2(int i) : i(i) {}\n        int bar() const { return i; }\n        int i;\n    };\n    py::class_<Base2> b2(m, \"Base2\");\n    b2.def(py::init<int>()).def(\"bar\", &Base2::bar);\n\n    // test_multiple_inheritance_cpp\n    struct Base12 : Base1, Base2 {\n        Base12(int i, int j) : Base1(i), Base2(j) {}\n    };\n    struct MIType : Base12 {\n        MIType(int i, int j) : Base12(i, j) {}\n    };\n    py::class_<Base12, Base1, Base2>(m, \"Base12\");\n    py::class_<MIType, Base12>(m, \"MIType\").def(py::init<int, int>());\n\n    // test_multiple_inheritance_python_many_bases\n#define PYBIND11_BASEN(N)                                                                         \\\n    py::class_<BaseN<(N)>>(m, \"BaseN\" #N).def(py::init<int>()).def(\"f\" #N, [](BaseN<N> &b) {      \\\n        return b.i + (N);                                                                         \\\n    })\n    PYBIND11_BASEN(1);\n    PYBIND11_BASEN(2);\n    PYBIND11_BASEN(3);\n    PYBIND11_BASEN(4);\n    PYBIND11_BASEN(5);\n    PYBIND11_BASEN(6);\n    PYBIND11_BASEN(7);\n    PYBIND11_BASEN(8);\n    PYBIND11_BASEN(9);\n    PYBIND11_BASEN(10);\n    PYBIND11_BASEN(11);\n    PYBIND11_BASEN(12);\n    PYBIND11_BASEN(13);\n    PYBIND11_BASEN(14);\n    PYBIND11_BASEN(15);\n    PYBIND11_BASEN(16);\n    PYBIND11_BASEN(17);\n\n    // Uncommenting this should result in a compile time failure (MI can only be specified via\n    // template parameters because pybind has to know the types involved; see discussion in #742\n    // for details).\n    //    struct Base12v2 : Base1, Base2 {\n    //        Base12v2(int i, int j) : Base1(i), Base2(j) { }\n    //    };\n    //    py::class_<Base12v2>(m, \"Base12v2\", b1, b2)\n    //        .def(py::init<int, int>());\n\n    // test_multiple_inheritance_virtbase\n    // Test the case where not all base classes are specified, and where pybind11 requires the\n    // py::multiple_inheritance flag to perform proper casting between types.\n    py::class_<Base1a, std::shared_ptr<Base1a>>(m, \"Base1a\")\n        .def(py::init<int>())\n        .def(\"foo\", &Base1a::foo);\n\n    py::class_<Base2a, std::shared_ptr<Base2a>>(m, \"Base2a\")\n        .def(py::init<int>())\n        .def(\"bar\", &Base2a::bar);\n\n    py::class_<Base12a, /* Base1 missing */ Base2a, std::shared_ptr<Base12a>>(\n        m, \"Base12a\", py::multiple_inheritance())\n        .def(py::init<int, int>());\n\n    m.def(\"bar_base2a\", [](Base2a *b) { return b->bar(); });\n    m.def(\"bar_base2a_sharedptr\", [](const std::shared_ptr<Base2a> &b) { return b->bar(); });\n\n    // test_mi_unaligned_base\n    // test_mi_base_return\n    // Issue #801: invalid casting to derived type with MI bases\n    // Unregistered classes:\n    struct I801B3 {\n        int c = 3;\n        virtual ~I801B3() = default;\n    };\n    struct I801E : I801B3, I801D {};\n\n    py::class_<I801B1, std::shared_ptr<I801B1>>(m, \"I801B1\")\n        .def(py::init<>())\n        .def_readonly(\"a\", &I801B1::a);\n    py::class_<I801B2, std::shared_ptr<I801B2>>(m, \"I801B2\")\n        .def(py::init<>())\n        .def_readonly(\"b\", &I801B2::b);\n    py::class_<I801C, I801B1, I801B2, std::shared_ptr<I801C>>(m, \"I801C\").def(py::init<>());\n    py::class_<I801D, I801C, std::shared_ptr<I801D>>(m, \"I801D\").def(py::init<>());\n\n    // Two separate issues here: first, we want to recognize a pointer to a base type as being a\n    // known instance even when the pointer value is unequal (i.e. due to a non-first\n    // multiple-inheritance base class):\n    m.def(\"i801b1_c\", [](I801C *c) { return static_cast<I801B1 *>(c); });\n    m.def(\"i801b2_c\", [](I801C *c) { return static_cast<I801B2 *>(c); });\n    m.def(\"i801b1_d\", [](I801D *d) { return static_cast<I801B1 *>(d); });\n    m.def(\"i801b2_d\", [](I801D *d) { return static_cast<I801B2 *>(d); });\n\n    // Second, when returned a base class pointer to a derived instance, we cannot assume that the\n    // pointer is `reinterpret_cast`able to the derived pointer because, like above, the base class\n    // pointer could be offset.\n    m.def(\"i801c_b1\", []() -> I801B1 * { return new I801C(); });\n    m.def(\"i801c_b2\", []() -> I801B2 * { return new I801C(); });\n    m.def(\"i801d_b1\", []() -> I801B1 * { return new I801D(); });\n    m.def(\"i801d_b2\", []() -> I801B2 * { return new I801D(); });\n\n    // Return a base class pointer to a pybind-registered type when the actual derived type\n    // isn't pybind-registered (and uses multiple-inheritance to offset the pybind base)\n    m.def(\"i801e_c\", []() -> I801C * { return new I801E(); });\n    m.def(\"i801e_b2\", []() -> I801B2 * { return new I801E(); });\n\n    // test_mi_static_properties\n    py::class_<Vanilla>(m, \"Vanilla\").def(py::init<>()).def(\"vanilla\", &Vanilla::vanilla);\n\n    py::class_<WithStatic1>(m, \"WithStatic1\")\n        .def(py::init<>())\n        .def_static(\"static_func1\", &WithStatic1::static_func1)\n        .def_readwrite_static(\"static_value1\", &WithStatic1::static_value1);\n\n    py::class_<WithStatic2>(m, \"WithStatic2\")\n        .def(py::init<>())\n        .def_static(\"static_func2\", &WithStatic2::static_func2)\n        .def_readwrite_static(\"static_value2\", &WithStatic2::static_value2);\n\n    py::class_<VanillaStaticMix1, Vanilla, WithStatic1, WithStatic2>(m, \"VanillaStaticMix1\")\n        .def(py::init<>())\n        .def_static(\"static_func\", &VanillaStaticMix1::static_func)\n        .def_readwrite_static(\"static_value\", &VanillaStaticMix1::static_value);\n\n    py::class_<VanillaStaticMix2, WithStatic1, Vanilla, WithStatic2>(m, \"VanillaStaticMix2\")\n        .def(py::init<>())\n        .def_static(\"static_func\", &VanillaStaticMix2::static_func)\n        .def_readwrite_static(\"static_value\", &VanillaStaticMix2::static_value);\n\n    struct WithDict {};\n    struct VanillaDictMix1 : Vanilla, WithDict {};\n    struct VanillaDictMix2 : WithDict, Vanilla {};\n    py::class_<WithDict>(m, \"WithDict\", py::dynamic_attr()).def(py::init<>());\n    py::class_<VanillaDictMix1, Vanilla, WithDict>(m, \"VanillaDictMix1\").def(py::init<>());\n    py::class_<VanillaDictMix2, WithDict, Vanilla>(m, \"VanillaDictMix2\").def(py::init<>());\n\n    // test_diamond_inheritance\n    // Issue #959: segfault when constructing diamond inheritance instance\n    // All of these have int members so that there will be various unequal pointers involved.\n    struct B {\n        int b;\n        B() = default;\n        B(const B &) = default;\n        virtual ~B() = default;\n    };\n    struct C0 : public virtual B {\n        int c0;\n    };\n    struct C1 : public virtual B {\n        int c1;\n    };\n    struct D : public C0, public C1 {\n        int d;\n    };\n    py::class_<B>(m, \"B\").def(\"b\", [](B *self) { return self; });\n    py::class_<C0, B>(m, \"C0\").def(\"c0\", [](C0 *self) { return self; });\n    py::class_<C1, B>(m, \"C1\").def(\"c1\", [](C1 *self) { return self; });\n    py::class_<D, C0, C1>(m, \"D\").def(py::init<>());\n\n    // test_pr3635_diamond_*\n    // - functions are get_{base}_{var}, return {var}\n    struct MVB {\n        MVB() = default;\n        MVB(const MVB &) = default;\n        virtual ~MVB() = default;\n\n        int b = 1;\n        int get_b_b() const { return b; }\n    };\n    struct MVC : virtual MVB {\n        int c = 2;\n        int get_c_b() const { return b; }\n        int get_c_c() const { return c; }\n    };\n    struct MVD0 : virtual MVC {\n        int d0 = 3;\n        int get_d0_b() const { return b; }\n        int get_d0_c() const { return c; }\n        int get_d0_d0() const { return d0; }\n    };\n    struct MVD1 : virtual MVC {\n        int d1 = 4;\n        int get_d1_b() const { return b; }\n        int get_d1_c() const { return c; }\n        int get_d1_d1() const { return d1; }\n    };\n    struct MVE : virtual MVD0, virtual MVD1 {\n        int e = 5;\n        int get_e_b() const { return b; }\n        int get_e_c() const { return c; }\n        int get_e_d0() const { return d0; }\n        int get_e_d1() const { return d1; }\n        int get_e_e() const { return e; }\n    };\n    struct MVF : virtual MVE {\n        int f = 6;\n        int get_f_b() const { return b; }\n        int get_f_c() const { return c; }\n        int get_f_d0() const { return d0; }\n        int get_f_d1() const { return d1; }\n        int get_f_e() const { return e; }\n        int get_f_f() const { return f; }\n    };\n    py::class_<MVB>(m, \"MVB\")\n        .def(py::init<>())\n        .def(\"get_b_b\", &MVB::get_b_b)\n        .def_readwrite(\"b\", &MVB::b);\n    py::class_<MVC, MVB>(m, \"MVC\")\n        .def(py::init<>())\n        .def(\"get_c_b\", &MVC::get_c_b)\n        .def(\"get_c_c\", &MVC::get_c_c)\n        .def_readwrite(\"c\", &MVC::c);\n    py::class_<MVD0, MVC>(m, \"MVD0\")\n        .def(py::init<>())\n        .def(\"get_d0_b\", &MVD0::get_d0_b)\n        .def(\"get_d0_c\", &MVD0::get_d0_c)\n        .def(\"get_d0_d0\", &MVD0::get_d0_d0)\n        .def_readwrite(\"d0\", &MVD0::d0);\n    py::class_<MVD1, MVC>(m, \"MVD1\")\n        .def(py::init<>())\n        .def(\"get_d1_b\", &MVD1::get_d1_b)\n        .def(\"get_d1_c\", &MVD1::get_d1_c)\n        .def(\"get_d1_d1\", &MVD1::get_d1_d1)\n        .def_readwrite(\"d1\", &MVD1::d1);\n    py::class_<MVE, MVD0, MVD1>(m, \"MVE\")\n        .def(py::init<>())\n        .def(\"get_e_b\", &MVE::get_e_b)\n        .def(\"get_e_c\", &MVE::get_e_c)\n        .def(\"get_e_d0\", &MVE::get_e_d0)\n        .def(\"get_e_d1\", &MVE::get_e_d1)\n        .def(\"get_e_e\", &MVE::get_e_e)\n        .def_readwrite(\"e\", &MVE::e);\n    py::class_<MVF, MVE>(m, \"MVF\")\n        .def(py::init<>())\n        .def(\"get_f_b\", &MVF::get_f_b)\n        .def(\"get_f_c\", &MVF::get_f_c)\n        .def(\"get_f_d0\", &MVF::get_f_d0)\n        .def(\"get_f_d1\", &MVF::get_f_d1)\n        .def(\"get_f_e\", &MVF::get_f_e)\n        .def(\"get_f_f\", &MVF::get_f_f)\n        .def_readwrite(\"f\", &MVF::f);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_multiple_inheritance.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import multiple_inheritance as m\n\n\ndef test_multiple_inheritance_cpp():\n    mt = m.MIType(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\n@pytest.mark.skipif(\"env.PYPY and env.PY2\")\n@pytest.mark.xfail(\"env.PYPY and not env.PY2\")\ndef test_multiple_inheritance_mix1():\n    class Base1:\n        def __init__(self, i):\n            self.i = i\n\n        def foo(self):\n            return self.i\n\n    class MITypePy(Base1, m.Base2):\n        def __init__(self, i, j):\n            Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    mt = MITypePy(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\ndef test_multiple_inheritance_mix2():\n    class Base2:\n        def __init__(self, i):\n            self.i = i\n\n        def bar(self):\n            return self.i\n\n    class MITypePy(m.Base1, Base2):\n        def __init__(self, i, j):\n            m.Base1.__init__(self, i)\n            Base2.__init__(self, j)\n\n    mt = MITypePy(3, 4)\n\n    assert mt.foo() == 3\n    assert mt.bar() == 4\n\n\n@pytest.mark.skipif(\"env.PYPY and env.PY2\")\n@pytest.mark.xfail(\"env.PYPY and not env.PY2\")\ndef test_multiple_inheritance_python():\n    class MI1(m.Base1, m.Base2):\n        def __init__(self, i, j):\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class B1(object):\n        def v(self):\n            return 1\n\n    class MI2(B1, m.Base1, m.Base2):\n        def __init__(self, i, j):\n            B1.__init__(self)\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class MI3(MI2):\n        def __init__(self, i, j):\n            MI2.__init__(self, i, j)\n\n    class MI4(MI3, m.Base2):\n        def __init__(self, i, j):\n            MI3.__init__(self, i, j)\n            # This should be ignored (Base2 is already initialized via MI2):\n            m.Base2.__init__(self, i + 100)\n\n    class MI5(m.Base2, B1, m.Base1):\n        def __init__(self, i, j):\n            B1.__init__(self)\n            m.Base1.__init__(self, i)\n            m.Base2.__init__(self, j)\n\n    class MI6(m.Base2, B1):\n        def __init__(self, i):\n            m.Base2.__init__(self, i)\n            B1.__init__(self)\n\n    class B2(B1):\n        def v(self):\n            return 2\n\n    class B3(object):\n        def v(self):\n            return 3\n\n    class B4(B3, B2):\n        def v(self):\n            return 4\n\n    class MI7(B4, MI6):\n        def __init__(self, i):\n            B4.__init__(self)\n            MI6.__init__(self, i)\n\n    class MI8(MI6, B3):\n        def __init__(self, i):\n            MI6.__init__(self, i)\n            B3.__init__(self)\n\n    class MI8b(B3, MI6):\n        def __init__(self, i):\n            B3.__init__(self)\n            MI6.__init__(self, i)\n\n    mi1 = MI1(1, 2)\n    assert mi1.foo() == 1\n    assert mi1.bar() == 2\n\n    mi2 = MI2(3, 4)\n    assert mi2.v() == 1\n    assert mi2.foo() == 3\n    assert mi2.bar() == 4\n\n    mi3 = MI3(5, 6)\n    assert mi3.v() == 1\n    assert mi3.foo() == 5\n    assert mi3.bar() == 6\n\n    mi4 = MI4(7, 8)\n    assert mi4.v() == 1\n    assert mi4.foo() == 7\n    assert mi4.bar() == 8\n\n    mi5 = MI5(10, 11)\n    assert mi5.v() == 1\n    assert mi5.foo() == 10\n    assert mi5.bar() == 11\n\n    mi6 = MI6(12)\n    assert mi6.v() == 1\n    assert mi6.bar() == 12\n\n    mi7 = MI7(13)\n    assert mi7.v() == 4\n    assert mi7.bar() == 13\n\n    mi8 = MI8(14)\n    assert mi8.v() == 1\n    assert mi8.bar() == 14\n\n    mi8b = MI8b(15)\n    assert mi8b.v() == 3\n    assert mi8b.bar() == 15\n\n\ndef test_multiple_inheritance_python_many_bases():\n    class MIMany14(m.BaseN1, m.BaseN2, m.BaseN3, m.BaseN4):\n        def __init__(self):\n            m.BaseN1.__init__(self, 1)\n            m.BaseN2.__init__(self, 2)\n            m.BaseN3.__init__(self, 3)\n            m.BaseN4.__init__(self, 4)\n\n    class MIMany58(m.BaseN5, m.BaseN6, m.BaseN7, m.BaseN8):\n        def __init__(self):\n            m.BaseN5.__init__(self, 5)\n            m.BaseN6.__init__(self, 6)\n            m.BaseN7.__init__(self, 7)\n            m.BaseN8.__init__(self, 8)\n\n    class MIMany916(\n        m.BaseN9,\n        m.BaseN10,\n        m.BaseN11,\n        m.BaseN12,\n        m.BaseN13,\n        m.BaseN14,\n        m.BaseN15,\n        m.BaseN16,\n    ):\n        def __init__(self):\n            m.BaseN9.__init__(self, 9)\n            m.BaseN10.__init__(self, 10)\n            m.BaseN11.__init__(self, 11)\n            m.BaseN12.__init__(self, 12)\n            m.BaseN13.__init__(self, 13)\n            m.BaseN14.__init__(self, 14)\n            m.BaseN15.__init__(self, 15)\n            m.BaseN16.__init__(self, 16)\n\n    class MIMany19(MIMany14, MIMany58, m.BaseN9):\n        def __init__(self):\n            MIMany14.__init__(self)\n            MIMany58.__init__(self)\n            m.BaseN9.__init__(self, 9)\n\n    class MIMany117(MIMany14, MIMany58, MIMany916, m.BaseN17):\n        def __init__(self):\n            MIMany14.__init__(self)\n            MIMany58.__init__(self)\n            MIMany916.__init__(self)\n            m.BaseN17.__init__(self, 17)\n\n    # Inherits from 4 registered C++ classes: can fit in one pointer on any modern arch:\n    a = MIMany14()\n    for i in range(1, 4):\n        assert getattr(a, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 8: requires 1/2 pointers worth of holder flags on 32/64-bit arch:\n    b = MIMany916()\n    for i in range(9, 16):\n        assert getattr(b, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 9: requires >= 2 pointers worth of holder flags\n    c = MIMany19()\n    for i in range(1, 9):\n        assert getattr(c, \"f\" + str(i))() == 2 * i\n\n    # Inherits from 17: requires >= 3 pointers worth of holder flags\n    d = MIMany117()\n    for i in range(1, 17):\n        assert getattr(d, \"f\" + str(i))() == 2 * i\n\n\ndef test_multiple_inheritance_virtbase():\n    class MITypePy(m.Base12a):\n        def __init__(self, i, j):\n            m.Base12a.__init__(self, i, j)\n\n    mt = MITypePy(3, 4)\n    assert mt.bar() == 4\n    assert m.bar_base2a(mt) == 4\n    assert m.bar_base2a_sharedptr(mt) == 4\n\n\ndef test_mi_static_properties():\n    \"\"\"Mixing bases with and without static properties should be possible\n    and the result should be independent of base definition order\"\"\"\n\n    for d in (m.VanillaStaticMix1(), m.VanillaStaticMix2()):\n        assert d.vanilla() == \"Vanilla\"\n        assert d.static_func1() == \"WithStatic1\"\n        assert d.static_func2() == \"WithStatic2\"\n        assert d.static_func() == d.__class__.__name__\n\n        m.WithStatic1.static_value1 = 1\n        m.WithStatic2.static_value2 = 2\n        assert d.static_value1 == 1\n        assert d.static_value2 == 2\n        assert d.static_value == 12\n\n        d.static_value1 = 0\n        assert d.static_value1 == 0\n        d.static_value2 = 0\n        assert d.static_value2 == 0\n        d.static_value = 0\n        assert d.static_value == 0\n\n\n# Requires PyPy 6+\ndef test_mi_dynamic_attributes():\n    \"\"\"Mixing bases with and without dynamic attribute support\"\"\"\n\n    for d in (m.VanillaDictMix1(), m.VanillaDictMix2()):\n        d.dynamic = 1\n        assert d.dynamic == 1\n\n\ndef test_mi_unaligned_base():\n    \"\"\"Returning an offset (non-first MI) base class pointer should recognize the instance\"\"\"\n\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    c = m.I801C()\n    d = m.I801D()\n    # + 4 below because we have the two instances, and each instance has offset base I801B2\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n    b1c = m.i801b1_c(c)\n    assert b1c is c\n    b2c = m.i801b2_c(c)\n    assert b2c is c\n    b1d = m.i801b1_d(d)\n    assert b1d is d\n    b2d = m.i801b2_d(d)\n    assert b2d is d\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4  # no extra instances\n    del c, b1c, b2c\n    assert ConstructorStats.detail_reg_inst() == n_inst + 2\n    del d, b1d, b2d\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n\ndef test_mi_base_return():\n    \"\"\"Tests returning an offset (non-first MI) base class pointer to a derived instance\"\"\"\n\n    n_inst = ConstructorStats.detail_reg_inst()\n\n    c1 = m.i801c_b1()\n    assert type(c1) is m.I801C\n    assert c1.a == 1\n    assert c1.b == 2\n\n    d1 = m.i801d_b1()\n    assert type(d1) is m.I801D\n    assert d1.a == 1\n    assert d1.b == 2\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 4\n\n    c2 = m.i801c_b2()\n    assert type(c2) is m.I801C\n    assert c2.a == 1\n    assert c2.b == 2\n\n    d2 = m.i801d_b2()\n    assert type(d2) is m.I801D\n    assert d2.a == 1\n    assert d2.b == 2\n\n    assert ConstructorStats.detail_reg_inst() == n_inst + 8\n\n    del c2\n    assert ConstructorStats.detail_reg_inst() == n_inst + 6\n    del c1, d1, d2\n    assert ConstructorStats.detail_reg_inst() == n_inst\n\n    # Returning an unregistered derived type with a registered base; we won't\n    # pick up the derived type, obviously, but should still work (as an object\n    # of whatever type was returned).\n    e1 = m.i801e_c()\n    assert type(e1) is m.I801C\n    assert e1.a == 1\n    assert e1.b == 2\n\n    e2 = m.i801e_b2()\n    assert type(e2) is m.I801B2\n    assert e2.b == 2\n\n\ndef test_diamond_inheritance():\n    \"\"\"Tests that diamond inheritance works as expected (issue #959)\"\"\"\n\n    # Issue #959: this shouldn't segfault:\n    d = m.D()\n\n    # Make sure all the various distinct pointers are all recognized as registered instances:\n    assert d is d.c0()\n    assert d is d.c1()\n    assert d is d.b()\n    assert d is d.c0().b()\n    assert d is d.c1().b()\n    assert d is d.c0().c1().b().c0().b()\n\n\ndef test_pr3635_diamond_b():\n    o = m.MVB()\n    assert o.b == 1\n\n    assert o.get_b_b() == 1\n\n\ndef test_pr3635_diamond_c():\n    o = m.MVC()\n    assert o.b == 1\n    assert o.c == 2\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n\n    assert o.get_c_c() == 2\n\n\ndef test_pr3635_diamond_d0():\n    o = m.MVD0()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n\n    assert o.get_d0_d0() == 3\n\n\ndef test_pr3635_diamond_d1():\n    o = m.MVD1()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d1 == 4\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d1_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d1_c() == 2\n\n    assert o.get_d1_d1() == 4\n\n\ndef test_pr3635_diamond_e():\n    o = m.MVE()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n    assert o.get_d1_b() == 1\n    assert o.get_e_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n    assert o.get_d1_c() == 2\n    assert o.get_e_c() == 2\n\n    assert o.get_d0_d0() == 3\n    assert o.get_e_d0() == 3\n\n    assert o.get_d1_d1() == 4\n    assert o.get_e_d1() == 4\n\n    assert o.get_e_e() == 5\n\n\ndef test_pr3635_diamond_f():\n    o = m.MVF()\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n    assert o.f == 6\n\n    assert o.get_b_b() == 1\n    assert o.get_c_b() == 1\n    assert o.get_d0_b() == 1\n    assert o.get_d1_b() == 1\n    assert o.get_e_b() == 1\n    assert o.get_f_b() == 1\n\n    assert o.get_c_c() == 2\n    assert o.get_d0_c() == 2\n    assert o.get_d1_c() == 2\n    assert o.get_e_c() == 2\n    assert o.get_f_c() == 2\n\n    assert o.get_d0_d0() == 3\n    assert o.get_e_d0() == 3\n    assert o.get_f_d0() == 3\n\n    assert o.get_d1_d1() == 4\n    assert o.get_e_d1() == 4\n    assert o.get_f_d1() == 4\n\n    assert o.get_e_e() == 5\n    assert o.get_f_e() == 5\n\n    assert o.get_f_f() == 6\n\n\ndef test_python_inherit_from_mi():\n    \"\"\"Tests extending a Python class from a single inheritor of a MI class\"\"\"\n\n    class PyMVF(m.MVF):\n        g = 7\n\n        def get_g_g(self):\n            return self.g\n\n    o = PyMVF()\n\n    assert o.b == 1\n    assert o.c == 2\n    assert o.d0 == 3\n    assert o.d1 == 4\n    assert o.e == 5\n    assert o.f == 6\n    assert o.g == 7\n\n    assert o.get_g_g() == 7\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_array.cpp",
    "content": "/*\n    tests/test_numpy_array.cpp -- test core array functionality\n\n    Copyright (c) 2016 Ivan Smirnov <i.s.smirnov@gmail.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\n#include <cstdint>\n#include <utility>\n\n// Size / dtype checks.\nstruct DtypeCheck {\n    py::dtype numpy{};\n    py::dtype pybind11{};\n};\n\ntemplate <typename T>\nDtypeCheck get_dtype_check(const char *name) {\n    py::module_ np = py::module_::import(\"numpy\");\n    DtypeCheck check{};\n    check.numpy = np.attr(\"dtype\")(np.attr(name));\n    check.pybind11 = py::dtype::of<T>();\n    return check;\n}\n\nstd::vector<DtypeCheck> get_concrete_dtype_checks() {\n    return {// Normalization\n            get_dtype_check<std::int8_t>(\"int8\"),\n            get_dtype_check<std::uint8_t>(\"uint8\"),\n            get_dtype_check<std::int16_t>(\"int16\"),\n            get_dtype_check<std::uint16_t>(\"uint16\"),\n            get_dtype_check<std::int32_t>(\"int32\"),\n            get_dtype_check<std::uint32_t>(\"uint32\"),\n            get_dtype_check<std::int64_t>(\"int64\"),\n            get_dtype_check<std::uint64_t>(\"uint64\")};\n}\n\nstruct DtypeSizeCheck {\n    std::string name{};\n    int size_cpp{};\n    int size_numpy{};\n    // For debugging.\n    py::dtype dtype{};\n};\n\ntemplate <typename T>\nDtypeSizeCheck get_dtype_size_check() {\n    DtypeSizeCheck check{};\n    check.name = py::type_id<T>();\n    check.size_cpp = sizeof(T);\n    check.dtype = py::dtype::of<T>();\n    check.size_numpy = check.dtype.attr(\"itemsize\").template cast<int>();\n    return check;\n}\n\nstd::vector<DtypeSizeCheck> get_platform_dtype_size_checks() {\n    return {\n        get_dtype_size_check<short>(),\n        get_dtype_size_check<unsigned short>(),\n        get_dtype_size_check<int>(),\n        get_dtype_size_check<unsigned int>(),\n        get_dtype_size_check<long>(),\n        get_dtype_size_check<unsigned long>(),\n        get_dtype_size_check<long long>(),\n        get_dtype_size_check<unsigned long long>(),\n    };\n}\n\n// Arrays.\nusing arr = py::array;\nusing arr_t = py::array_t<uint16_t, 0>;\nstatic_assert(std::is_same<arr_t::value_type, uint16_t>::value, \"\");\n\ntemplate <typename... Ix>\narr data(const arr &a, Ix... index) {\n    return arr(a.nbytes() - a.offset_at(index...), (const uint8_t *) a.data(index...));\n}\n\ntemplate <typename... Ix>\narr data_t(const arr_t &a, Ix... index) {\n    return arr(a.size() - a.index_at(index...), a.data(index...));\n}\n\ntemplate <typename... Ix>\narr &mutate_data(arr &a, Ix... index) {\n    auto *ptr = (uint8_t *) a.mutable_data(index...);\n    for (py::ssize_t i = 0; i < a.nbytes() - a.offset_at(index...); i++) {\n        ptr[i] = (uint8_t) (ptr[i] * 2);\n    }\n    return a;\n}\n\ntemplate <typename... Ix>\narr_t &mutate_data_t(arr_t &a, Ix... index) {\n    auto ptr = a.mutable_data(index...);\n    for (py::ssize_t i = 0; i < a.size() - a.index_at(index...); i++) {\n        ptr[i]++;\n    }\n    return a;\n}\n\ntemplate <typename... Ix>\npy::ssize_t index_at(const arr &a, Ix... idx) {\n    return a.index_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t index_at_t(const arr_t &a, Ix... idx) {\n    return a.index_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t offset_at(const arr &a, Ix... idx) {\n    return a.offset_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t offset_at_t(const arr_t &a, Ix... idx) {\n    return a.offset_at(idx...);\n}\ntemplate <typename... Ix>\npy::ssize_t at_t(const arr_t &a, Ix... idx) {\n    return a.at(idx...);\n}\ntemplate <typename... Ix>\narr_t &mutate_at_t(arr_t &a, Ix... idx) {\n    a.mutable_at(idx...)++;\n    return a;\n}\n\n#define def_index_fn(name, type)                                                                  \\\n    sm.def(#name, [](type a) { return name(a); });                                                \\\n    sm.def(#name, [](type a, int i) { return name(a, i); });                                      \\\n    sm.def(#name, [](type a, int i, int j) { return name(a, i, j); });                            \\\n    sm.def(#name, [](type a, int i, int j, int k) { return name(a, i, j, k); });\n\ntemplate <typename T, typename T2>\npy::handle auxiliaries(T &&r, T2 &&r2) {\n    if (r.ndim() != 2) {\n        throw std::domain_error(\"error: ndim != 2\");\n    }\n    py::list l;\n    l.append(*r.data(0, 0));\n    l.append(*r2.mutable_data(0, 0));\n    l.append(r.data(0, 1) == r2.mutable_data(0, 1));\n    l.append(r.ndim());\n    l.append(r.itemsize());\n    l.append(r.shape(0));\n    l.append(r.shape(1));\n    l.append(r.size());\n    l.append(r.nbytes());\n    return l.release();\n}\n\n// note: declaration at local scope would create a dangling reference!\nstatic int data_i = 42;\n\nTEST_SUBMODULE(numpy_array, sm) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (...) {\n        return;\n    }\n\n    // test_dtypes\n    py::class_<DtypeCheck>(sm, \"DtypeCheck\")\n        .def_readonly(\"numpy\", &DtypeCheck::numpy)\n        .def_readonly(\"pybind11\", &DtypeCheck::pybind11)\n        .def(\"__repr__\", [](const DtypeCheck &self) {\n            return py::str(\"<DtypeCheck numpy={} pybind11={}>\").format(self.numpy, self.pybind11);\n        });\n    sm.def(\"get_concrete_dtype_checks\", &get_concrete_dtype_checks);\n\n    py::class_<DtypeSizeCheck>(sm, \"DtypeSizeCheck\")\n        .def_readonly(\"name\", &DtypeSizeCheck::name)\n        .def_readonly(\"size_cpp\", &DtypeSizeCheck::size_cpp)\n        .def_readonly(\"size_numpy\", &DtypeSizeCheck::size_numpy)\n        .def(\"__repr__\", [](const DtypeSizeCheck &self) {\n            return py::str(\"<DtypeSizeCheck name='{}' size_cpp={} size_numpy={} dtype={}>\")\n                .format(self.name, self.size_cpp, self.size_numpy, self.dtype);\n        });\n    sm.def(\"get_platform_dtype_size_checks\", &get_platform_dtype_size_checks);\n\n    // test_array_attributes\n    sm.def(\"ndim\", [](const arr &a) { return a.ndim(); });\n    sm.def(\"shape\", [](const arr &a) { return arr(a.ndim(), a.shape()); });\n    sm.def(\"shape\", [](const arr &a, py::ssize_t dim) { return a.shape(dim); });\n    sm.def(\"strides\", [](const arr &a) { return arr(a.ndim(), a.strides()); });\n    sm.def(\"strides\", [](const arr &a, py::ssize_t dim) { return a.strides(dim); });\n    sm.def(\"writeable\", [](const arr &a) { return a.writeable(); });\n    sm.def(\"size\", [](const arr &a) { return a.size(); });\n    sm.def(\"itemsize\", [](const arr &a) { return a.itemsize(); });\n    sm.def(\"nbytes\", [](const arr &a) { return a.nbytes(); });\n    sm.def(\"owndata\", [](const arr &a) { return a.owndata(); });\n\n    // test_index_offset\n    def_index_fn(index_at, const arr &);\n    def_index_fn(index_at_t, const arr_t &);\n    def_index_fn(offset_at, const arr &);\n    def_index_fn(offset_at_t, const arr_t &);\n    // test_data\n    def_index_fn(data, const arr &);\n    def_index_fn(data_t, const arr_t &);\n    // test_mutate_data, test_mutate_readonly\n    def_index_fn(mutate_data, arr &);\n    def_index_fn(mutate_data_t, arr_t &);\n    def_index_fn(at_t, const arr_t &);\n    def_index_fn(mutate_at_t, arr_t &);\n\n    // test_make_c_f_array\n    sm.def(\"make_f_array\", [] { return py::array_t<float>({2, 2}, {4, 8}); });\n    sm.def(\"make_c_array\", [] { return py::array_t<float>({2, 2}, {8, 4}); });\n\n    // test_empty_shaped_array\n    sm.def(\"make_empty_shaped_array\", [] { return py::array(py::dtype(\"f\"), {}, {}); });\n    // test numpy scalars (empty shape, ndim==0)\n    sm.def(\"scalar_int\", []() { return py::array(py::dtype(\"i\"), {}, {}, &data_i); });\n\n    // test_wrap\n    sm.def(\"wrap\", [](const py::array &a) {\n        return py::array(a.dtype(),\n                         {a.shape(), a.shape() + a.ndim()},\n                         {a.strides(), a.strides() + a.ndim()},\n                         a.data(),\n                         a);\n    });\n\n    // test_numpy_view\n    struct ArrayClass {\n        int data[2] = {1, 2};\n        ArrayClass() { py::print(\"ArrayClass()\"); }\n        ~ArrayClass() { py::print(\"~ArrayClass()\"); }\n    };\n    py::class_<ArrayClass>(sm, \"ArrayClass\")\n        .def(py::init<>())\n        .def(\"numpy_view\", [](py::object &obj) {\n            py::print(\"ArrayClass::numpy_view()\");\n            auto &a = obj.cast<ArrayClass &>();\n            return py::array_t<int>({2}, {4}, a.data, obj);\n        });\n\n    // test_cast_numpy_int64_to_uint64\n    sm.def(\"function_taking_uint64\", [](uint64_t) {});\n\n    // test_isinstance\n    sm.def(\"isinstance_untyped\", [](py::object yes, py::object no) {\n        return py::isinstance<py::array>(std::move(yes))\n               && !py::isinstance<py::array>(std::move(no));\n    });\n    sm.def(\"isinstance_typed\", [](const py::object &o) {\n        return py::isinstance<py::array_t<double>>(o) && !py::isinstance<py::array_t<int>>(o);\n    });\n\n    // test_constructors\n    sm.def(\"default_constructors\", []() {\n        return py::dict(\"array\"_a = py::array(),\n                        \"array_t<int32>\"_a = py::array_t<std::int32_t>(),\n                        \"array_t<double>\"_a = py::array_t<double>());\n    });\n    sm.def(\"converting_constructors\", [](const py::object &o) {\n        return py::dict(\"array\"_a = py::array(o),\n                        \"array_t<int32>\"_a = py::array_t<std::int32_t>(o),\n                        \"array_t<double>\"_a = py::array_t<double>(o));\n    });\n\n    // test_overload_resolution\n    sm.def(\"overloaded\", [](const py::array_t<double> &) { return \"double\"; });\n    sm.def(\"overloaded\", [](const py::array_t<float> &) { return \"float\"; });\n    sm.def(\"overloaded\", [](const py::array_t<int> &) { return \"int\"; });\n    sm.def(\"overloaded\", [](const py::array_t<unsigned short> &) { return \"unsigned short\"; });\n    sm.def(\"overloaded\", [](const py::array_t<long long> &) { return \"long long\"; });\n    sm.def(\"overloaded\",\n           [](const py::array_t<std::complex<double>> &) { return \"double complex\"; });\n    sm.def(\"overloaded\", [](const py::array_t<std::complex<float>> &) { return \"float complex\"; });\n\n    sm.def(\"overloaded2\",\n           [](const py::array_t<std::complex<double>> &) { return \"double complex\"; });\n    sm.def(\"overloaded2\", [](const py::array_t<double> &) { return \"double\"; });\n    sm.def(\"overloaded2\",\n           [](const py::array_t<std::complex<float>> &) { return \"float complex\"; });\n    sm.def(\"overloaded2\", [](const py::array_t<float> &) { return \"float\"; });\n\n    // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works.\n\n    // Only accept the exact types:\n    sm.def(\n        \"overloaded3\", [](const py::array_t<int> &) { return \"int\"; }, py::arg{}.noconvert());\n    sm.def(\n        \"overloaded3\",\n        [](const py::array_t<double> &) { return \"double\"; },\n        py::arg{}.noconvert());\n\n    // Make sure we don't do unsafe coercion (e.g. float to int) when not using forcecast, but\n    // rather that float gets converted via the safe (conversion to double) overload:\n    sm.def(\"overloaded4\", [](const py::array_t<long long, 0> &) { return \"long long\"; });\n    sm.def(\"overloaded4\", [](const py::array_t<double, 0> &) { return \"double\"; });\n\n    // But we do allow conversion to int if forcecast is enabled (but only if no overload matches\n    // without conversion)\n    sm.def(\"overloaded5\", [](const py::array_t<unsigned int> &) { return \"unsigned int\"; });\n    sm.def(\"overloaded5\", [](const py::array_t<double> &) { return \"double\"; });\n\n    // test_greedy_string_overload\n    // Issue 685: ndarray shouldn't go to std::string overload\n    sm.def(\"issue685\", [](const std::string &) { return \"string\"; });\n    sm.def(\"issue685\", [](const py::array &) { return \"array\"; });\n    sm.def(\"issue685\", [](const py::object &) { return \"other\"; });\n\n    // test_array_unchecked_fixed_dims\n    sm.def(\n        \"proxy_add2\",\n        [](py::array_t<double> a, double v) {\n            auto r = a.mutable_unchecked<2>();\n            for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                    r(i, j) += v;\n                }\n            }\n        },\n        py::arg{}.noconvert(),\n        py::arg());\n\n    sm.def(\"proxy_init3\", [](double start) {\n        py::array_t<double, py::array::c_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked<3>();\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t k = 0; k < r.shape(2); k++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_init3F\", [](double start) {\n        py::array_t<double, py::array::f_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked<3>();\n        for (py::ssize_t k = 0; k < r.shape(2); k++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_squared_L2_norm\", [](const py::array_t<double> &a) {\n        auto r = a.unchecked<1>();\n        double sumsq = 0;\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            sumsq += r[i] * r(i); // Either notation works for a 1D array\n        }\n        return sumsq;\n    });\n\n    sm.def(\"proxy_auxiliaries2\", [](py::array_t<double> a) {\n        auto r = a.unchecked<2>();\n        auto r2 = a.mutable_unchecked<2>();\n        return auxiliaries(r, r2);\n    });\n\n    sm.def(\"proxy_auxiliaries1_const_ref\", [](py::array_t<double> a) {\n        const auto &r = a.unchecked<1>();\n        const auto &r2 = a.mutable_unchecked<1>();\n        return r(0) == r2(0) && r[0] == r2[0];\n    });\n\n    sm.def(\"proxy_auxiliaries2_const_ref\", [](py::array_t<double> a) {\n        const auto &r = a.unchecked<2>();\n        const auto &r2 = a.mutable_unchecked<2>();\n        return r(0, 0) == r2(0, 0);\n    });\n\n    // test_array_unchecked_dyn_dims\n    // Same as the above, but without a compile-time dimensions specification:\n    sm.def(\n        \"proxy_add2_dyn\",\n        [](py::array_t<double> a, double v) {\n            auto r = a.mutable_unchecked();\n            if (r.ndim() != 2) {\n                throw std::domain_error(\"error: ndim != 2\");\n            }\n            for (py::ssize_t i = 0; i < r.shape(0); i++) {\n                for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                    r(i, j) += v;\n                }\n            }\n        },\n        py::arg{}.noconvert(),\n        py::arg());\n    sm.def(\"proxy_init3_dyn\", [](double start) {\n        py::array_t<double, py::array::c_style> a({3, 3, 3});\n        auto r = a.mutable_unchecked();\n        if (r.ndim() != 3) {\n            throw std::domain_error(\"error: ndim != 3\");\n        }\n        for (py::ssize_t i = 0; i < r.shape(0); i++) {\n            for (py::ssize_t j = 0; j < r.shape(1); j++) {\n                for (py::ssize_t k = 0; k < r.shape(2); k++) {\n                    r(i, j, k) = start++;\n                }\n            }\n        }\n        return a;\n    });\n    sm.def(\"proxy_auxiliaries2_dyn\", [](py::array_t<double> a) {\n        return auxiliaries(a.unchecked(), a.mutable_unchecked());\n    });\n\n    sm.def(\"array_auxiliaries2\", [](py::array_t<double> a) { return auxiliaries(a, a); });\n\n    // test_array_failures\n    // Issue #785: Uninformative \"Unknown internal error\" exception when constructing array from\n    // empty object:\n    sm.def(\"array_fail_test\", []() { return py::array(py::object()); });\n    sm.def(\"array_t_fail_test\", []() { return py::array_t<double>(py::object()); });\n    // Make sure the error from numpy is being passed through:\n    sm.def(\"array_fail_test_negative_size\", []() {\n        int c = 0;\n        return py::array(-1, &c);\n    });\n\n    // test_initializer_list\n    // Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous\n    sm.def(\"array_initializer_list1\", []() { return py::array_t<float>(1); });\n    // { 1 } also works for the above, but clang warns about it\n    sm.def(\"array_initializer_list2\", []() { return py::array_t<float>({1, 2}); });\n    sm.def(\"array_initializer_list3\", []() { return py::array_t<float>({1, 2, 3}); });\n    sm.def(\"array_initializer_list4\", []() { return py::array_t<float>({1, 2, 3, 4}); });\n\n    // test_array_resize\n    // reshape array to 2D without changing size\n    sm.def(\"array_reshape2\", [](py::array_t<double> a) {\n        const auto dim_sz = (py::ssize_t) std::sqrt(a.size());\n        if (dim_sz * dim_sz != a.size()) {\n            throw std::domain_error(\n                \"array_reshape2: input array total size is not a squared integer\");\n        }\n        a.resize({dim_sz, dim_sz});\n    });\n\n    // resize to 3D array with each dimension = N\n    sm.def(\"array_resize3\", [](py::array_t<double> a, size_t N, bool refcheck) {\n        a.resize({N, N, N}, refcheck);\n    });\n\n    // test_array_create_and_resize\n    // return 2D array with Nrows = Ncols = N\n    sm.def(\"create_and_resize\", [](size_t N) {\n        py::array_t<double> a;\n        a.resize({N, N});\n        std::fill(a.mutable_data(), a.mutable_data() + a.size(), 42.);\n        return a;\n    });\n\n    sm.def(\"array_view\",\n           [](py::array_t<uint8_t> a, const std::string &dtype) { return a.view(dtype); });\n\n    sm.def(\"reshape_initializer_list\", [](py::array_t<int> a, size_t N, size_t M, size_t O) {\n        return a.reshape({N, M, O});\n    });\n    sm.def(\"reshape_tuple\", [](py::array_t<int> a, const std::vector<int> &new_shape) {\n        return a.reshape(new_shape);\n    });\n\n    sm.def(\"index_using_ellipsis\",\n           [](const py::array &a) { return a[py::make_tuple(0, py::ellipsis(), 0)]; });\n\n    // test_argument_conversions\n    sm.def(\n        \"accept_double\", [](const py::array_t<double, 0> &) {}, py::arg(\"a\"));\n    sm.def(\n        \"accept_double_forcecast\",\n        [](const py::array_t<double, py::array::forcecast> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_c_style\",\n        [](const py::array_t<double, py::array::c_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_c_style_forcecast\",\n        [](const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_f_style\",\n        [](const py::array_t<double, py::array::f_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_f_style_forcecast\",\n        [](const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},\n        py::arg(\"a\"));\n    sm.def(\n        \"accept_double_noconvert\", [](const py::array_t<double, 0> &) {}, \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_c_style_noconvert\",\n        [](const py::array_t<double, py::array::c_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_c_style_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast | py::array::c_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_f_style_noconvert\",\n        [](const py::array_t<double, py::array::f_style> &) {},\n        \"a\"_a.noconvert());\n    sm.def(\n        \"accept_double_f_style_forcecast_noconvert\",\n        [](const py::array_t<double, py::array::forcecast | py::array::f_style> &) {},\n        \"a\"_a.noconvert());\n\n    // Check that types returns correct npy format descriptor\n    sm.def(\"test_fmt_desc_float\", [](const py::array_t<float> &) {});\n    sm.def(\"test_fmt_desc_double\", [](const py::array_t<double> &) {});\n    sm.def(\"test_fmt_desc_const_float\", [](const py::array_t<const float> &) {});\n    sm.def(\"test_fmt_desc_const_double\", [](const py::array_t<const double> &) {});\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_array.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import numpy_array as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_dtypes():\n    # See issue #1328.\n    # - Platform-dependent sizes.\n    for size_check in m.get_platform_dtype_size_checks():\n        print(size_check)\n        assert size_check.size_cpp == size_check.size_numpy, size_check\n    # - Concrete sizes.\n    for check in m.get_concrete_dtype_checks():\n        print(check)\n        assert check.numpy == check.pybind11, check\n        if check.numpy.num != check.pybind11.num:\n            print(\n                \"NOTE: typenum mismatch for {}: {} != {}\".format(\n                    check, check.numpy.num, check.pybind11.num\n                )\n            )\n\n\n@pytest.fixture(scope=\"function\")\ndef arr():\n    return np.array([[1, 2, 3], [4, 5, 6]], \"=u2\")\n\n\ndef test_array_attributes():\n    a = np.array(0, \"f8\")\n    assert m.ndim(a) == 0\n    assert all(m.shape(a) == [])\n    assert all(m.strides(a) == [])\n    with pytest.raises(IndexError) as excinfo:\n        m.shape(a, 0)\n    assert str(excinfo.value) == \"invalid axis: 0 (ndim = 0)\"\n    with pytest.raises(IndexError) as excinfo:\n        m.strides(a, 0)\n    assert str(excinfo.value) == \"invalid axis: 0 (ndim = 0)\"\n    assert m.writeable(a)\n    assert m.size(a) == 1\n    assert m.itemsize(a) == 8\n    assert m.nbytes(a) == 8\n    assert m.owndata(a)\n\n    a = np.array([[1, 2, 3], [4, 5, 6]], \"u2\").view()\n    a.flags.writeable = False\n    assert m.ndim(a) == 2\n    assert all(m.shape(a) == [2, 3])\n    assert m.shape(a, 0) == 2\n    assert m.shape(a, 1) == 3\n    assert all(m.strides(a) == [6, 2])\n    assert m.strides(a, 0) == 6\n    assert m.strides(a, 1) == 2\n    with pytest.raises(IndexError) as excinfo:\n        m.shape(a, 2)\n    assert str(excinfo.value) == \"invalid axis: 2 (ndim = 2)\"\n    with pytest.raises(IndexError) as excinfo:\n        m.strides(a, 2)\n    assert str(excinfo.value) == \"invalid axis: 2 (ndim = 2)\"\n    assert not m.writeable(a)\n    assert m.size(a) == 6\n    assert m.itemsize(a) == 2\n    assert m.nbytes(a) == 12\n    assert not m.owndata(a)\n\n\n@pytest.mark.parametrize(\n    \"args, ret\", [([], 0), ([0], 0), ([1], 3), ([0, 1], 1), ([1, 2], 5)]\n)\ndef test_index_offset(arr, args, ret):\n    assert m.index_at(arr, *args) == ret\n    assert m.index_at_t(arr, *args) == ret\n    assert m.offset_at(arr, *args) == ret * arr.dtype.itemsize\n    assert m.offset_at_t(arr, *args) == ret * arr.dtype.itemsize\n\n\ndef test_dim_check_fail(arr):\n    for func in (\n        m.index_at,\n        m.index_at_t,\n        m.offset_at,\n        m.offset_at_t,\n        m.data,\n        m.data_t,\n        m.mutate_data,\n        m.mutate_data_t,\n    ):\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 1, 2, 3)\n        assert str(excinfo.value) == \"too many indices for an array: 3 (ndim = 2)\"\n\n\n@pytest.mark.parametrize(\n    \"args, ret\",\n    [\n        ([], [1, 2, 3, 4, 5, 6]),\n        ([1], [4, 5, 6]),\n        ([0, 1], [2, 3, 4, 5, 6]),\n        ([1, 2], [6]),\n    ],\n)\ndef test_data(arr, args, ret):\n    from sys import byteorder\n\n    assert all(m.data_t(arr, *args) == ret)\n    assert all(m.data(arr, *args)[(0 if byteorder == \"little\" else 1) :: 2] == ret)\n    assert all(m.data(arr, *args)[(1 if byteorder == \"little\" else 0) :: 2] == 0)\n\n\n@pytest.mark.parametrize(\"dim\", [0, 1, 3])\ndef test_at_fail(arr, dim):\n    for func in m.at_t, m.mutate_at_t:\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, *([0] * dim))\n        assert str(excinfo.value) == \"index dimension mismatch: {} (ndim = 2)\".format(\n            dim\n        )\n\n\ndef test_at(arr):\n    assert m.at_t(arr, 0, 2) == 3\n    assert m.at_t(arr, 1, 0) == 4\n\n    assert all(m.mutate_at_t(arr, 0, 2).ravel() == [1, 2, 4, 4, 5, 6])\n    assert all(m.mutate_at_t(arr, 1, 0).ravel() == [1, 2, 4, 5, 5, 6])\n\n\ndef test_mutate_readonly(arr):\n    arr.flags.writeable = False\n    for func, args in (\n        (m.mutate_data, ()),\n        (m.mutate_data_t, ()),\n        (m.mutate_at_t, (0, 0)),\n    ):\n        with pytest.raises(ValueError) as excinfo:\n            func(arr, *args)\n        assert str(excinfo.value) == \"array is not writeable\"\n\n\ndef test_mutate_data(arr):\n    assert all(m.mutate_data(arr).ravel() == [2, 4, 6, 8, 10, 12])\n    assert all(m.mutate_data(arr).ravel() == [4, 8, 12, 16, 20, 24])\n    assert all(m.mutate_data(arr, 1).ravel() == [4, 8, 12, 32, 40, 48])\n    assert all(m.mutate_data(arr, 0, 1).ravel() == [4, 16, 24, 64, 80, 96])\n    assert all(m.mutate_data(arr, 1, 2).ravel() == [4, 16, 24, 64, 80, 192])\n\n    assert all(m.mutate_data_t(arr).ravel() == [5, 17, 25, 65, 81, 193])\n    assert all(m.mutate_data_t(arr).ravel() == [6, 18, 26, 66, 82, 194])\n    assert all(m.mutate_data_t(arr, 1).ravel() == [6, 18, 26, 67, 83, 195])\n    assert all(m.mutate_data_t(arr, 0, 1).ravel() == [6, 19, 27, 68, 84, 196])\n    assert all(m.mutate_data_t(arr, 1, 2).ravel() == [6, 19, 27, 68, 84, 197])\n\n\ndef test_bounds_check(arr):\n    for func in (\n        m.index_at,\n        m.index_at_t,\n        m.data,\n        m.data_t,\n        m.mutate_data,\n        m.mutate_data_t,\n        m.at_t,\n        m.mutate_at_t,\n    ):\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 2, 0)\n        assert str(excinfo.value) == \"index 2 is out of bounds for axis 0 with size 2\"\n        with pytest.raises(IndexError) as excinfo:\n            func(arr, 0, 4)\n        assert str(excinfo.value) == \"index 4 is out of bounds for axis 1 with size 3\"\n\n\ndef test_make_c_f_array():\n    assert m.make_c_array().flags.c_contiguous\n    assert not m.make_c_array().flags.f_contiguous\n    assert m.make_f_array().flags.f_contiguous\n    assert not m.make_f_array().flags.c_contiguous\n\n\ndef test_make_empty_shaped_array():\n    m.make_empty_shaped_array()\n\n    # empty shape means numpy scalar, PEP 3118\n    assert m.scalar_int().ndim == 0\n    assert m.scalar_int().shape == ()\n    assert m.scalar_int() == 42\n\n\ndef test_wrap():\n    def assert_references(a, b, base=None):\n        from distutils.version import LooseVersion\n\n        if base is None:\n            base = a\n        assert a is not b\n        assert a.__array_interface__[\"data\"][0] == b.__array_interface__[\"data\"][0]\n        assert a.shape == b.shape\n        assert a.strides == b.strides\n        assert a.flags.c_contiguous == b.flags.c_contiguous\n        assert a.flags.f_contiguous == b.flags.f_contiguous\n        assert a.flags.writeable == b.flags.writeable\n        assert a.flags.aligned == b.flags.aligned\n        if LooseVersion(np.__version__) >= LooseVersion(\"1.14.0\"):\n            assert a.flags.writebackifcopy == b.flags.writebackifcopy\n        else:\n            assert a.flags.updateifcopy == b.flags.updateifcopy\n        assert np.all(a == b)\n        assert not b.flags.owndata\n        assert b.base is base\n        if a.flags.writeable and a.ndim == 2:\n            a[0, 0] = 1234\n            assert b[0, 0] == 1234\n\n    a1 = np.array([1, 2], dtype=np.int16)\n    assert a1.flags.owndata and a1.base is None\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order=\"F\")\n    assert a1.flags.owndata and a1.base is None\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.array([[1, 2], [3, 4]], dtype=np.float32, order=\"C\")\n    a1.flags.writeable = False\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1 = np.random.random((4, 4, 4))\n    a2 = m.wrap(a1)\n    assert_references(a1, a2)\n\n    a1t = a1.transpose()\n    a2 = m.wrap(a1t)\n    assert_references(a1t, a2, a1)\n\n    a1d = a1.diagonal()\n    a2 = m.wrap(a1d)\n    assert_references(a1d, a2, a1)\n\n    a1m = a1[::-1, ::-1, ::-1]\n    a2 = m.wrap(a1m)\n    assert_references(a1m, a2, a1)\n\n\ndef test_numpy_view(capture):\n    with capture:\n        ac = m.ArrayClass()\n        ac_view_1 = ac.numpy_view()\n        ac_view_2 = ac.numpy_view()\n        assert np.all(ac_view_1 == np.array([1, 2], dtype=np.int32))\n        del ac\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        ArrayClass()\n        ArrayClass::numpy_view()\n        ArrayClass::numpy_view()\n    \"\"\"\n    )\n    ac_view_1[0] = 4\n    ac_view_1[1] = 3\n    assert ac_view_2[0] == 4\n    assert ac_view_2[1] == 3\n    with capture:\n        del ac_view_1\n        del ac_view_2\n        pytest.gc_collect()\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        ~ArrayClass()\n    \"\"\"\n    )\n\n\ndef test_cast_numpy_int64_to_uint64():\n    m.function_taking_uint64(123)\n    m.function_taking_uint64(np.uint64(123))\n\n\ndef test_isinstance():\n    assert m.isinstance_untyped(np.array([1, 2, 3]), \"not an array\")\n    assert m.isinstance_typed(np.array([1.0, 2.0, 3.0]))\n\n\ndef test_constructors():\n    defaults = m.default_constructors()\n    for a in defaults.values():\n        assert a.size == 0\n    assert defaults[\"array\"].dtype == np.array([]).dtype\n    assert defaults[\"array_t<int32>\"].dtype == np.int32\n    assert defaults[\"array_t<double>\"].dtype == np.float64\n\n    results = m.converting_constructors([1, 2, 3])\n    for a in results.values():\n        np.testing.assert_array_equal(a, [1, 2, 3])\n    assert results[\"array\"].dtype == np.int_\n    assert results[\"array_t<int32>\"].dtype == np.int32\n    assert results[\"array_t<double>\"].dtype == np.float64\n\n\ndef test_overload_resolution(msg):\n    # Exact overload matches:\n    assert m.overloaded(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded(np.array([1], dtype=\"float32\")) == \"float\"\n    assert m.overloaded(np.array([1], dtype=\"ushort\")) == \"unsigned short\"\n    assert m.overloaded(np.array([1], dtype=\"intc\")) == \"int\"\n    assert m.overloaded(np.array([1], dtype=\"longlong\")) == \"long long\"\n    assert m.overloaded(np.array([1], dtype=\"complex\")) == \"double complex\"\n    assert m.overloaded(np.array([1], dtype=\"csingle\")) == \"float complex\"\n\n    # No exact match, should call first convertible version:\n    assert m.overloaded(np.array([1], dtype=\"uint8\")) == \"double\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded(\"not an array\")\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        overloaded(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.float64]) -> str\n            2. (arg0: numpy.ndarray[numpy.float32]) -> str\n            3. (arg0: numpy.ndarray[numpy.int32]) -> str\n            4. (arg0: numpy.ndarray[numpy.uint16]) -> str\n            5. (arg0: numpy.ndarray[numpy.int64]) -> str\n            6. (arg0: numpy.ndarray[numpy.complex128]) -> str\n            7. (arg0: numpy.ndarray[numpy.complex64]) -> str\n\n        Invoked with: 'not an array'\n    \"\"\"\n    )\n\n    assert m.overloaded2(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded2(np.array([1], dtype=\"float32\")) == \"float\"\n    assert m.overloaded2(np.array([1], dtype=\"complex64\")) == \"float complex\"\n    assert m.overloaded2(np.array([1], dtype=\"complex128\")) == \"double complex\"\n    assert m.overloaded2(np.array([1], dtype=\"float32\")) == \"float\"\n\n    assert m.overloaded3(np.array([1], dtype=\"float64\")) == \"double\"\n    assert m.overloaded3(np.array([1], dtype=\"intc\")) == \"int\"\n    expected_exc = \"\"\"\n        overloaded3(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: numpy.ndarray[numpy.int32]) -> str\n            2. (arg0: numpy.ndarray[numpy.float64]) -> str\n\n        Invoked with: \"\"\"\n\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"uintc\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1], dtype=\"uint32\"))\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"float32\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1.0], dtype=\"float32\"))\n    with pytest.raises(TypeError) as excinfo:\n        m.overloaded3(np.array([1], dtype=\"complex\"))\n    assert msg(excinfo.value) == expected_exc + repr(np.array([1.0 + 0.0j]))\n\n    # Exact matches:\n    assert m.overloaded4(np.array([1], dtype=\"double\")) == \"double\"\n    assert m.overloaded4(np.array([1], dtype=\"longlong\")) == \"long long\"\n    # Non-exact matches requiring conversion.  Since float to integer isn't a\n    # save conversion, it should go to the double overload, but short can go to\n    # either (and so should end up on the first-registered, the long long).\n    assert m.overloaded4(np.array([1], dtype=\"float32\")) == \"double\"\n    assert m.overloaded4(np.array([1], dtype=\"short\")) == \"long long\"\n\n    assert m.overloaded5(np.array([1], dtype=\"double\")) == \"double\"\n    assert m.overloaded5(np.array([1], dtype=\"uintc\")) == \"unsigned int\"\n    assert m.overloaded5(np.array([1], dtype=\"float32\")) == \"unsigned int\"\n\n\ndef test_greedy_string_overload():\n    \"\"\"Tests fix for #685 - ndarray shouldn't go to std::string overload\"\"\"\n\n    assert m.issue685(\"abc\") == \"string\"\n    assert m.issue685(np.array([97, 98, 99], dtype=\"b\")) == \"array\"\n    assert m.issue685(123) == \"other\"\n\n\ndef test_array_unchecked_fixed_dims(msg):\n    z1 = np.array([[1, 2], [3, 4]], dtype=\"float64\")\n    m.proxy_add2(z1, 10)\n    assert np.all(z1 == [[11, 12], [13, 14]])\n\n    with pytest.raises(ValueError) as excinfo:\n        m.proxy_add2(np.array([1.0, 2, 3]), 5.0)\n    assert (\n        msg(excinfo.value) == \"array has incorrect number of dimensions: 1; expected 2\"\n    )\n\n    expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype=\"int\")\n    assert np.all(m.proxy_init3(3.0) == expect_c)\n    expect_f = np.transpose(expect_c)\n    assert np.all(m.proxy_init3F(3.0) == expect_f)\n\n    assert m.proxy_squared_L2_norm(np.array(range(6))) == 55\n    assert m.proxy_squared_L2_norm(np.array(range(6), dtype=\"float64\")) == 55\n\n    assert m.proxy_auxiliaries2(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]\n    assert m.proxy_auxiliaries2(z1) == m.array_auxiliaries2(z1)\n\n    assert m.proxy_auxiliaries1_const_ref(z1[0, :])\n    assert m.proxy_auxiliaries2_const_ref(z1)\n\n\ndef test_array_unchecked_dyn_dims():\n    z1 = np.array([[1, 2], [3, 4]], dtype=\"float64\")\n    m.proxy_add2_dyn(z1, 10)\n    assert np.all(z1 == [[11, 12], [13, 14]])\n\n    expect_c = np.ndarray(shape=(3, 3, 3), buffer=np.array(range(3, 30)), dtype=\"int\")\n    assert np.all(m.proxy_init3_dyn(3.0) == expect_c)\n\n    assert m.proxy_auxiliaries2_dyn(z1) == [11, 11, True, 2, 8, 2, 2, 4, 32]\n    assert m.proxy_auxiliaries2_dyn(z1) == m.array_auxiliaries2(z1)\n\n\ndef test_array_failure():\n    with pytest.raises(ValueError) as excinfo:\n        m.array_fail_test()\n    assert str(excinfo.value) == \"cannot create a pybind11::array from a nullptr\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.array_t_fail_test()\n    assert str(excinfo.value) == \"cannot create a pybind11::array_t from a nullptr\"\n\n    with pytest.raises(ValueError) as excinfo:\n        m.array_fail_test_negative_size()\n    assert str(excinfo.value) == \"negative dimensions are not allowed\"\n\n\ndef test_initializer_list():\n    assert m.array_initializer_list1().shape == (1,)\n    assert m.array_initializer_list2().shape == (1, 2)\n    assert m.array_initializer_list3().shape == (1, 2, 3)\n    assert m.array_initializer_list4().shape == (1, 2, 3, 4)\n\n\ndef test_array_resize():\n    a = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=\"float64\")\n    m.array_reshape2(a)\n    assert a.size == 9\n    assert np.all(a == [[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n\n    # total size change should succced with refcheck off\n    m.array_resize3(a, 4, False)\n    assert a.size == 64\n    # ... and fail with refcheck on\n    try:\n        m.array_resize3(a, 3, True)\n    except ValueError as e:\n        assert str(e).startswith(\"cannot resize an array\")\n    # transposed array doesn't own data\n    b = a.transpose()\n    try:\n        m.array_resize3(b, 3, False)\n    except ValueError as e:\n        assert str(e).startswith(\"cannot resize this array: it does not own its data\")\n    # ... but reshape should be fine\n    m.array_reshape2(b)\n    assert b.shape == (8, 8)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_array_create_and_resize():\n    a = m.create_and_resize(2)\n    assert a.size == 4\n    assert np.all(a == 42.0)\n\n\ndef test_array_view():\n    a = np.ones(100 * 4).astype(\"uint8\")\n    a_float_view = m.array_view(a, \"float32\")\n    assert a_float_view.shape == (100 * 1,)  # 1 / 4 bytes = 8 / 32\n\n    a_int16_view = m.array_view(a, \"int16\")  # 1 / 2 bytes = 16 / 32\n    assert a_int16_view.shape == (100 * 2,)\n\n\ndef test_array_view_invalid():\n    a = np.ones(100 * 4).astype(\"uint8\")\n    with pytest.raises(TypeError):\n        m.array_view(a, \"deadly_dtype\")\n\n\ndef test_reshape_initializer_list():\n    a = np.arange(2 * 7 * 3) + 1\n    x = m.reshape_initializer_list(a, 2, 7, 3)\n    assert x.shape == (2, 7, 3)\n    assert list(x[1][4]) == [34, 35, 36]\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_initializer_list(a, 1, 7, 3)\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape (1,7,3)\"\n\n\ndef test_reshape_tuple():\n    a = np.arange(3 * 7 * 2) + 1\n    x = m.reshape_tuple(a, (3, 7, 2))\n    assert x.shape == (3, 7, 2)\n    assert list(x[1][4]) == [23, 24]\n    y = m.reshape_tuple(x, (x.size,))\n    assert y.shape == (42,)\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_tuple(a, (3, 7, 1))\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape (3,7,1)\"\n    with pytest.raises(ValueError) as excinfo:\n        m.reshape_tuple(a, ())\n    assert str(excinfo.value) == \"cannot reshape array of size 42 into shape ()\"\n\n\ndef test_index_using_ellipsis():\n    a = m.index_using_ellipsis(np.zeros((5, 6, 7)))\n    assert a.shape == (6,)\n\n\n@pytest.mark.parametrize(\n    \"test_func\",\n    [\n        m.test_fmt_desc_float,\n        m.test_fmt_desc_double,\n        m.test_fmt_desc_const_float,\n        m.test_fmt_desc_const_double,\n    ],\n)\ndef test_format_descriptors_for_floating_point_types(test_func):\n    assert \"numpy.ndarray[numpy.float\" in test_func.__doc__\n\n\n@pytest.mark.parametrize(\"forcecast\", [False, True])\n@pytest.mark.parametrize(\"contiguity\", [None, \"C\", \"F\"])\n@pytest.mark.parametrize(\"noconvert\", [False, True])\n@pytest.mark.filterwarnings(\n    \"ignore:Casting complex values to real discards the imaginary part:numpy.ComplexWarning\"\n)\ndef test_argument_conversions(forcecast, contiguity, noconvert):\n    function_name = \"accept_double\"\n    if contiguity == \"C\":\n        function_name += \"_c_style\"\n    elif contiguity == \"F\":\n        function_name += \"_f_style\"\n    if forcecast:\n        function_name += \"_forcecast\"\n    if noconvert:\n        function_name += \"_noconvert\"\n    function = getattr(m, function_name)\n\n    for dtype in [np.dtype(\"float32\"), np.dtype(\"float64\"), np.dtype(\"complex128\")]:\n        for order in [\"C\", \"F\"]:\n            for shape in [(2, 2), (1, 3, 1, 1), (1, 1, 1), (0,)]:\n                if not noconvert:\n                    # If noconvert is not passed, only complex128 needs to be truncated and\n                    # \"cannot be safely obtained\". So without `forcecast`, the argument shouldn't\n                    # be accepted.\n                    should_raise = dtype.name == \"complex128\" and not forcecast\n                else:\n                    # If noconvert is passed, only float64 and the matching order is accepted.\n                    # If at most one dimension has a size greater than 1, the array is also\n                    # trivially contiguous.\n                    trivially_contiguous = sum(1 for d in shape if d > 1) <= 1\n                    should_raise = dtype.name != \"float64\" or (\n                        contiguity is not None\n                        and contiguity != order\n                        and not trivially_contiguous\n                    )\n\n                array = np.zeros(shape, dtype=dtype, order=order)\n                if not should_raise:\n                    function(array)\n                else:\n                    with pytest.raises(\n                        TypeError, match=\"incompatible function arguments\"\n                    ):\n                        function(array)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_dtype_refcount_leak():\n    from sys import getrefcount\n\n    dtype = np.dtype(np.float_)\n    a = np.array([1], dtype=dtype)\n    before = getrefcount(dtype)\n    m.ndim(a)\n    after = getrefcount(dtype)\n    assert after == before\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_dtypes.cpp",
    "content": "/*\n  tests/test_numpy_dtypes.cpp -- Structured and compound NumPy dtypes\n\n  Copyright (c) 2016 Ivan Smirnov\n\n  All rights reserved. Use of this source code is governed by a\n  BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n\n#include \"pybind11_tests.h\"\n\n#ifdef __GNUC__\n#    define PYBIND11_PACKED(cls) cls __attribute__((__packed__))\n#else\n#    define PYBIND11_PACKED(cls) __pragma(pack(push, 1)) cls __pragma(pack(pop))\n#endif\n\nnamespace py = pybind11;\n\nstruct SimpleStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    long double ldbl_;\n};\n\nstd::ostream &operator<<(std::ostream &os, const SimpleStruct &v) {\n    return os << \"s:\" << v.bool_ << \",\" << v.uint_ << \",\" << v.float_ << \",\" << v.ldbl_;\n}\n\nstruct SimpleStructReordered {\n    bool bool_;\n    float float_;\n    uint32_t uint_;\n    long double ldbl_;\n};\n\nPYBIND11_PACKED(struct PackedStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    long double ldbl_;\n});\n\nstd::ostream &operator<<(std::ostream &os, const PackedStruct &v) {\n    return os << \"p:\" << v.bool_ << \",\" << v.uint_ << \",\" << v.float_ << \",\" << v.ldbl_;\n}\n\nPYBIND11_PACKED(struct NestedStruct {\n    SimpleStruct a;\n    PackedStruct b;\n});\n\nstd::ostream &operator<<(std::ostream &os, const NestedStruct &v) {\n    return os << \"n:a=\" << v.a << \";b=\" << v.b;\n}\n\nstruct PartialStruct {\n    bool bool_;\n    uint32_t uint_;\n    float float_;\n    uint64_t dummy2;\n    long double ldbl_;\n};\n\nstruct PartialNestedStruct {\n    uint64_t dummy1;\n    PartialStruct a;\n    uint64_t dummy2;\n};\n\nstruct UnboundStruct {};\n\nstruct StringStruct {\n    char a[3];\n    std::array<char, 3> b;\n};\n\nstruct ComplexStruct {\n    std::complex<float> cflt;\n    std::complex<double> cdbl;\n};\n\nstd::ostream &operator<<(std::ostream &os, const ComplexStruct &v) {\n    return os << \"c:\" << v.cflt << \",\" << v.cdbl;\n}\n\nstruct ArrayStruct {\n    char a[3][4];\n    int32_t b[2];\n    std::array<uint8_t, 3> c;\n    std::array<float, 2> d[4];\n};\n\nPYBIND11_PACKED(struct StructWithUglyNames {\n    int8_t __x__;\n    uint64_t __y__;\n});\n\nenum class E1 : int64_t { A = -1, B = 1 };\nenum E2 : uint8_t { X = 1, Y = 2 };\n\nPYBIND11_PACKED(struct EnumStruct {\n    E1 e1;\n    E2 e2;\n});\n\nstd::ostream &operator<<(std::ostream &os, const StringStruct &v) {\n    os << \"a='\";\n    for (size_t i = 0; i < 3 && (v.a[i] != 0); i++) {\n        os << v.a[i];\n    }\n    os << \"',b='\";\n    for (size_t i = 0; i < 3 && (v.b[i] != 0); i++) {\n        os << v.b[i];\n    }\n    return os << \"'\";\n}\n\nstd::ostream &operator<<(std::ostream &os, const ArrayStruct &v) {\n    os << \"a={\";\n    for (int i = 0; i < 3; i++) {\n        if (i > 0) {\n            os << ',';\n        }\n        os << '{';\n        for (int j = 0; j < 3; j++) {\n            os << v.a[i][j] << ',';\n        }\n        os << v.a[i][3] << '}';\n    }\n    os << \"},b={\" << v.b[0] << ',' << v.b[1];\n    os << \"},c={\" << int(v.c[0]) << ',' << int(v.c[1]) << ',' << int(v.c[2]);\n    os << \"},d={\";\n    for (int i = 0; i < 4; i++) {\n        if (i > 0) {\n            os << ',';\n        }\n        os << '{' << v.d[i][0] << ',' << v.d[i][1] << '}';\n    }\n    return os << '}';\n}\n\nstd::ostream &operator<<(std::ostream &os, const EnumStruct &v) {\n    return os << \"e1=\" << (v.e1 == E1::A ? \"A\" : \"B\") << \",e2=\" << (v.e2 == E2::X ? \"X\" : \"Y\");\n}\n\ntemplate <typename T>\npy::array mkarray_via_buffer(size_t n) {\n    return py::array(py::buffer_info(\n        nullptr, sizeof(T), py::format_descriptor<T>::format(), 1, {n}, {sizeof(T)}));\n}\n\n#define SET_TEST_VALS(s, i)                                                                       \\\n    do {                                                                                          \\\n        (s).bool_ = (i) % 2 != 0;                                                                 \\\n        (s).uint_ = (uint32_t) (i);                                                               \\\n        (s).float_ = (float) (i) *1.5f;                                                           \\\n        (s).ldbl_ = (long double) (i) * -2.5L;                                                    \\\n    } while (0)\n\ntemplate <typename S>\npy::array_t<S, 0> create_recarray(size_t n) {\n    auto arr = mkarray_via_buffer<S>(n);\n    auto req = arr.request();\n    auto *ptr = static_cast<S *>(req.ptr);\n    for (size_t i = 0; i < n; i++) {\n        SET_TEST_VALS(ptr[i], i);\n    }\n    return arr;\n}\n\ntemplate <typename S>\npy::list print_recarray(py::array_t<S, 0> arr) {\n    const auto req = arr.request();\n    auto *const ptr = static_cast<S *>(req.ptr);\n    auto l = py::list();\n    for (py::ssize_t i = 0; i < req.size; i++) {\n        std::stringstream ss;\n        ss << ptr[i];\n        l.append(py::str(ss.str()));\n    }\n    return l;\n}\n\npy::array_t<int32_t, 0> test_array_ctors(int i) {\n    using arr_t = py::array_t<int32_t, 0>;\n\n    std::vector<int32_t> data{1, 2, 3, 4, 5, 6};\n    std::vector<py::ssize_t> shape{3, 2};\n    std::vector<py::ssize_t> strides{8, 4};\n\n    auto *ptr = data.data();\n    auto *vptr = (void *) ptr;\n    auto dtype = py::dtype(\"int32\");\n\n    py::buffer_info buf_ndim1(vptr, 4, \"i\", 6);\n    py::buffer_info buf_ndim1_null(nullptr, 4, \"i\", 6);\n    py::buffer_info buf_ndim2(vptr, 4, \"i\", 2, shape, strides);\n    py::buffer_info buf_ndim2_null(nullptr, 4, \"i\", 2, shape, strides);\n\n    auto fill = [](py::array arr) {\n        auto req = arr.request();\n        for (int i = 0; i < 6; i++) {\n            ((int32_t *) req.ptr)[i] = i + 1;\n        }\n        return arr;\n    };\n\n    switch (i) {\n        // shape: (3, 2)\n        case 10:\n            return arr_t(shape, strides, ptr);\n        case 11:\n            return py::array(shape, strides, ptr);\n        case 12:\n            return py::array(dtype, shape, strides, vptr);\n        case 13:\n            return arr_t(shape, ptr);\n        case 14:\n            return py::array(shape, ptr);\n        case 15:\n            return py::array(dtype, shape, vptr);\n        case 16:\n            return arr_t(buf_ndim2);\n        case 17:\n            return py::array(buf_ndim2);\n        // shape: (3, 2) - post-fill\n        case 20:\n            return fill(arr_t(shape, strides));\n        case 21:\n            return py::array(shape, strides, ptr); // can't have nullptr due to templated ctor\n        case 22:\n            return fill(py::array(dtype, shape, strides));\n        case 23:\n            return fill(arr_t(shape));\n        case 24:\n            return py::array(shape, ptr); // can't have nullptr due to templated ctor\n        case 25:\n            return fill(py::array(dtype, shape));\n        case 26:\n            return fill(arr_t(buf_ndim2_null));\n        case 27:\n            return fill(py::array(buf_ndim2_null));\n        // shape: (6, )\n        case 30:\n            return arr_t(6, ptr);\n        case 31:\n            return py::array(6, ptr);\n        case 32:\n            return py::array(dtype, 6, vptr);\n        case 33:\n            return arr_t(buf_ndim1);\n        case 34:\n            return py::array(buf_ndim1);\n        // shape: (6, )\n        case 40:\n            return fill(arr_t(6));\n        case 41:\n            return py::array(6, ptr); // can't have nullptr due to templated ctor\n        case 42:\n            return fill(py::array(dtype, 6));\n        case 43:\n            return fill(arr_t(buf_ndim1_null));\n        case 44:\n            return fill(py::array(buf_ndim1_null));\n    }\n    return arr_t();\n}\n\npy::list test_dtype_ctors() {\n    py::list list;\n    list.append(py::dtype(\"int32\"));\n    list.append(py::dtype(std::string(\"float64\")));\n    list.append(py::dtype::from_args(py::str(\"bool\")));\n    py::list names, offsets, formats;\n    py::dict dict;\n    names.append(py::str(\"a\"));\n    names.append(py::str(\"b\"));\n    dict[\"names\"] = names;\n    offsets.append(py::int_(1));\n    offsets.append(py::int_(10));\n    dict[\"offsets\"] = offsets;\n    formats.append(py::dtype(\"int32\"));\n    formats.append(py::dtype(\"float64\"));\n    dict[\"formats\"] = formats;\n    dict[\"itemsize\"] = py::int_(20);\n    list.append(py::dtype::from_args(dict));\n    list.append(py::dtype(names, formats, offsets, 20));\n    list.append(py::dtype(py::buffer_info((void *) 0, sizeof(unsigned int), \"I\", 1)));\n    list.append(py::dtype(py::buffer_info((void *) 0, 0, \"T{i:a:f:b:}\", 1)));\n    return list;\n}\n\nstruct A {};\nstruct B {};\n\nTEST_SUBMODULE(numpy_dtypes, m) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (...) {\n        return;\n    }\n\n    // typeinfo may be registered before the dtype descriptor for scalar casts to work...\n    py::class_<SimpleStruct>(m, \"SimpleStruct\")\n        // Explicit construct to ensure zero-valued initialization.\n        .def(py::init([]() { return SimpleStruct(); }))\n        .def_readwrite(\"bool_\", &SimpleStruct::bool_)\n        .def_readwrite(\"uint_\", &SimpleStruct::uint_)\n        .def_readwrite(\"float_\", &SimpleStruct::float_)\n        .def_readwrite(\"ldbl_\", &SimpleStruct::ldbl_)\n        .def(\"astuple\",\n             [](const SimpleStruct &self) {\n                 return py::make_tuple(self.bool_, self.uint_, self.float_, self.ldbl_);\n             })\n        .def_static(\"fromtuple\", [](const py::tuple &tup) {\n            if (py::len(tup) != 4) {\n                throw py::cast_error(\"Invalid size\");\n            }\n            return SimpleStruct{tup[0].cast<bool>(),\n                                tup[1].cast<uint32_t>(),\n                                tup[2].cast<float>(),\n                                tup[3].cast<long double>()};\n        });\n\n    PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(SimpleStructReordered, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(PackedStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(NestedStruct, a, b);\n    PYBIND11_NUMPY_DTYPE(PartialStruct, bool_, uint_, float_, ldbl_);\n    PYBIND11_NUMPY_DTYPE(PartialNestedStruct, a);\n    PYBIND11_NUMPY_DTYPE(StringStruct, a, b);\n    PYBIND11_NUMPY_DTYPE(ArrayStruct, a, b, c, d);\n    PYBIND11_NUMPY_DTYPE(EnumStruct, e1, e2);\n    PYBIND11_NUMPY_DTYPE(ComplexStruct, cflt, cdbl);\n\n    // ... or after\n    py::class_<PackedStruct>(m, \"PackedStruct\");\n\n    PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, \"x\", __y__, \"y\");\n\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n    // If enabled, this should produce a static_assert failure telling the user that the struct\n    // is not a POD type\n    struct NotPOD {\n        std::string v;\n        NotPOD() : v(\"hi\"){};\n    };\n    PYBIND11_NUMPY_DTYPE(NotPOD, v);\n#endif\n\n    // Check that dtypes can be registered programmatically, both from\n    // initializer lists of field descriptors and from other containers.\n    py::detail::npy_format_descriptor<A>::register_dtype({});\n    py::detail::npy_format_descriptor<B>::register_dtype(\n        std::vector<py::detail::field_descriptor>{});\n\n    // test_recarray, test_scalar_conversion\n    m.def(\"create_rec_simple\", &create_recarray<SimpleStruct>);\n    m.def(\"create_rec_packed\", &create_recarray<PackedStruct>);\n    m.def(\"create_rec_nested\", [](size_t n) { // test_signature\n        py::array_t<NestedStruct, 0> arr = mkarray_via_buffer<NestedStruct>(n);\n        auto req = arr.request();\n        auto *ptr = static_cast<NestedStruct *>(req.ptr);\n        for (size_t i = 0; i < n; i++) {\n            SET_TEST_VALS(ptr[i].a, i);\n            SET_TEST_VALS(ptr[i].b, i + 1);\n        }\n        return arr;\n    });\n    m.def(\"create_rec_partial\", &create_recarray<PartialStruct>);\n    m.def(\"create_rec_partial_nested\", [](size_t n) {\n        py::array_t<PartialNestedStruct, 0> arr = mkarray_via_buffer<PartialNestedStruct>(n);\n        auto req = arr.request();\n        auto *ptr = static_cast<PartialNestedStruct *>(req.ptr);\n        for (size_t i = 0; i < n; i++) {\n            SET_TEST_VALS(ptr[i].a, i);\n        }\n        return arr;\n    });\n    m.def(\"print_rec_simple\", &print_recarray<SimpleStruct>);\n    m.def(\"print_rec_packed\", &print_recarray<PackedStruct>);\n    m.def(\"print_rec_nested\", &print_recarray<NestedStruct>);\n\n    // test_format_descriptors\n    m.def(\"get_format_unbound\", []() { return py::format_descriptor<UnboundStruct>::format(); });\n    m.def(\"print_format_descriptors\", []() {\n        py::list l;\n        for (const auto &fmt : {py::format_descriptor<SimpleStruct>::format(),\n                                py::format_descriptor<PackedStruct>::format(),\n                                py::format_descriptor<NestedStruct>::format(),\n                                py::format_descriptor<PartialStruct>::format(),\n                                py::format_descriptor<PartialNestedStruct>::format(),\n                                py::format_descriptor<StringStruct>::format(),\n                                py::format_descriptor<ArrayStruct>::format(),\n                                py::format_descriptor<EnumStruct>::format(),\n                                py::format_descriptor<ComplexStruct>::format()}) {\n            l.append(py::cast(fmt));\n        }\n        return l;\n    });\n\n    // test_dtype\n    std::vector<const char *> dtype_names{\n        \"byte\",    \"short\",   \"intc\",        \"int_\",  \"longlong\",   \"ubyte\",       \"ushort\",\n        \"uintc\",   \"uint\",    \"ulonglong\",   \"half\",  \"single\",     \"double\",      \"longdouble\",\n        \"csingle\", \"cdouble\", \"clongdouble\", \"bool_\", \"datetime64\", \"timedelta64\", \"object_\"};\n\n    m.def(\"print_dtypes\", []() {\n        py::list l;\n        for (const py::handle &d : {py::dtype::of<SimpleStruct>(),\n                                    py::dtype::of<PackedStruct>(),\n                                    py::dtype::of<NestedStruct>(),\n                                    py::dtype::of<PartialStruct>(),\n                                    py::dtype::of<PartialNestedStruct>(),\n                                    py::dtype::of<StringStruct>(),\n                                    py::dtype::of<ArrayStruct>(),\n                                    py::dtype::of<EnumStruct>(),\n                                    py::dtype::of<StructWithUglyNames>(),\n                                    py::dtype::of<ComplexStruct>()}) {\n            l.append(py::str(d));\n        }\n        return l;\n    });\n    m.def(\"test_dtype_ctors\", &test_dtype_ctors);\n    m.def(\"test_dtype_kind\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).kind());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_char_\", [dtype_names]() {\n        py::list list;\n        for (const auto &dt_name : dtype_names) {\n            list.append(py::dtype(dt_name).char_());\n        }\n        return list;\n    });\n    m.def(\"test_dtype_methods\", []() {\n        py::list list;\n        auto dt1 = py::dtype::of<int32_t>();\n        auto dt2 = py::dtype::of<SimpleStruct>();\n        list.append(dt1);\n        list.append(dt2);\n        list.append(py::bool_(dt1.has_fields()));\n        list.append(py::bool_(dt2.has_fields()));\n        list.append(py::int_(dt1.itemsize()));\n        list.append(py::int_(dt2.itemsize()));\n        return list;\n    });\n    struct TrailingPaddingStruct {\n        int32_t a;\n        char b;\n    };\n    PYBIND11_NUMPY_DTYPE(TrailingPaddingStruct, a, b);\n    m.def(\"trailing_padding_dtype\", []() { return py::dtype::of<TrailingPaddingStruct>(); });\n\n    // test_string_array\n    m.def(\"create_string_array\", [](bool non_empty) {\n        py::array_t<StringStruct, 0> arr = mkarray_via_buffer<StringStruct>(non_empty ? 4 : 0);\n        if (non_empty) {\n            auto req = arr.request();\n            auto *ptr = static_cast<StringStruct *>(req.ptr);\n            for (py::ssize_t i = 0; i < req.size * req.itemsize; i++) {\n                static_cast<char *>(req.ptr)[i] = 0;\n            }\n            ptr[1].a[0] = 'a';\n            ptr[1].b[0] = 'a';\n            ptr[2].a[0] = 'a';\n            ptr[2].b[0] = 'a';\n            ptr[3].a[0] = 'a';\n            ptr[3].b[0] = 'a';\n\n            ptr[2].a[1] = 'b';\n            ptr[2].b[1] = 'b';\n            ptr[3].a[1] = 'b';\n            ptr[3].b[1] = 'b';\n\n            ptr[3].a[2] = 'c';\n            ptr[3].b[2] = 'c';\n        }\n        return arr;\n    });\n    m.def(\"print_string_array\", &print_recarray<StringStruct>);\n\n    // test_array_array\n    m.def(\"create_array_array\", [](size_t n) {\n        py::array_t<ArrayStruct, 0> arr = mkarray_via_buffer<ArrayStruct>(n);\n        auto *ptr = (ArrayStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            for (size_t j = 0; j < 3; j++) {\n                for (size_t k = 0; k < 4; k++) {\n                    ptr[i].a[j][k] = char('A' + (i * 100 + j * 10 + k) % 26);\n                }\n            }\n            for (size_t j = 0; j < 2; j++) {\n                ptr[i].b[j] = int32_t(i * 1000 + j);\n            }\n            for (size_t j = 0; j < 3; j++) {\n                ptr[i].c[j] = uint8_t(i * 10 + j);\n            }\n            for (size_t j = 0; j < 4; j++) {\n                for (size_t k = 0; k < 2; k++) {\n                    ptr[i].d[j][k] = float(i) * 100.0f + float(j) * 10.0f + float(k);\n                }\n            }\n        }\n        return arr;\n    });\n    m.def(\"print_array_array\", &print_recarray<ArrayStruct>);\n\n    // test_enum_array\n    m.def(\"create_enum_array\", [](size_t n) {\n        py::array_t<EnumStruct, 0> arr = mkarray_via_buffer<EnumStruct>(n);\n        auto *ptr = (EnumStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            ptr[i].e1 = static_cast<E1>(-1 + ((int) i % 2) * 2);\n            ptr[i].e2 = static_cast<E2>(1 + (i % 2));\n        }\n        return arr;\n    });\n    m.def(\"print_enum_array\", &print_recarray<EnumStruct>);\n\n    // test_complex_array\n    m.def(\"create_complex_array\", [](size_t n) {\n        py::array_t<ComplexStruct, 0> arr = mkarray_via_buffer<ComplexStruct>(n);\n        auto *ptr = (ComplexStruct *) arr.mutable_data();\n        for (size_t i = 0; i < n; i++) {\n            ptr[i].cflt.real(float(i));\n            ptr[i].cflt.imag(float(i) + 0.25f);\n            ptr[i].cdbl.real(double(i) + 0.5);\n            ptr[i].cdbl.imag(double(i) + 0.75);\n        }\n        return arr;\n    });\n    m.def(\"print_complex_array\", &print_recarray<ComplexStruct>);\n\n    // test_array_constructors\n    m.def(\"test_array_ctors\", &test_array_ctors);\n\n    // test_compare_buffer_info\n    struct CompareStruct {\n        bool x;\n        uint32_t y;\n        float z;\n    };\n    PYBIND11_NUMPY_DTYPE(CompareStruct, x, y, z);\n    m.def(\"compare_buffer_info\", []() {\n        py::list list;\n        list.append(py::bool_(py::detail::compare_buffer_info<float>::compare(\n            py::buffer_info(nullptr, sizeof(float), \"f\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<unsigned>::compare(\n            py::buffer_info(nullptr, sizeof(int), \"I\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<long>::compare(\n            py::buffer_info(nullptr, sizeof(long), \"l\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<long>::compare(\n            py::buffer_info(nullptr, sizeof(long), sizeof(long) == sizeof(int) ? \"i\" : \"q\", 1))));\n        list.append(py::bool_(py::detail::compare_buffer_info<CompareStruct>::compare(\n            py::buffer_info(nullptr, sizeof(CompareStruct), \"T{?:x:3xI:y:f:z:}\", 1))));\n        return list;\n    });\n    m.def(\"buffer_to_dtype\", [](py::buffer &buf) { return py::dtype(buf.request()); });\n\n    // test_scalar_conversion\n    auto f_simple = [](SimpleStruct s) { return s.uint_ * 10; };\n    m.def(\"f_simple\", f_simple);\n    m.def(\"f_packed\", [](PackedStruct s) { return s.uint_ * 10; });\n    m.def(\"f_nested\", [](NestedStruct s) { return s.a.uint_ * 10; });\n\n    // test_vectorize\n    m.def(\"f_simple_vectorized\", py::vectorize(f_simple));\n    auto f_simple_pass_thru = [](SimpleStruct s) { return s; };\n    m.def(\"f_simple_pass_thru_vectorized\", py::vectorize(f_simple_pass_thru));\n\n    // test_register_dtype\n    m.def(\"register_dtype\",\n          []() { PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_); });\n\n    // test_str_leak\n    m.def(\"dtype_wrapper\", [](py::object d) { return py::dtype::from_args(std::move(d)); });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_dtypes.py",
    "content": "# -*- coding: utf-8 -*-\nimport re\n\nimport pytest\n\nimport env  # noqa: F401\nfrom pybind11_tests import numpy_dtypes as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\n@pytest.fixture(scope=\"module\")\ndef simple_dtype():\n    ld = np.dtype(\"longdouble\")\n    return np.dtype(\n        {\n            \"names\": [\"bool_\", \"uint_\", \"float_\", \"ldbl_\"],\n            \"formats\": [\"?\", \"u4\", \"f4\", \"f{}\".format(ld.itemsize)],\n            \"offsets\": [0, 4, 8, (16 if ld.alignment > 4 else 12)],\n        }\n    )\n\n\n@pytest.fixture(scope=\"module\")\ndef packed_dtype():\n    return np.dtype([(\"bool_\", \"?\"), (\"uint_\", \"u4\"), (\"float_\", \"f4\"), (\"ldbl_\", \"g\")])\n\n\ndef dt_fmt():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n    return (\n        \"{{'names':['bool_','uint_','float_','ldbl_'],\"\n        \"'formats':['?','\" + e + \"u4','\" + e + \"f4','\" + e + \"f{}'],\"\n        \"'offsets':[0,4,8,{}],'itemsize':{}}}\"\n    )\n\n\ndef simple_dtype_fmt():\n    ld = np.dtype(\"longdouble\")\n    simple_ld_off = 12 + 4 * (ld.alignment > 4)\n    return dt_fmt().format(ld.itemsize, simple_ld_off, simple_ld_off + ld.itemsize)\n\n\ndef packed_dtype_fmt():\n    from sys import byteorder\n\n    return \"[('bool_','?'),('uint_','{e}u4'),('float_','{e}f4'),('ldbl_','{e}f{}')]\".format(\n        np.dtype(\"longdouble\").itemsize, e=\"<\" if byteorder == \"little\" else \">\"\n    )\n\n\ndef partial_ld_offset():\n    return (\n        12\n        + 4 * (np.dtype(\"uint64\").alignment > 4)\n        + 8\n        + 8 * (np.dtype(\"longdouble\").alignment > 8)\n    )\n\n\ndef partial_dtype_fmt():\n    ld = np.dtype(\"longdouble\")\n    partial_ld_off = partial_ld_offset()\n    partial_size = partial_ld_off + ld.itemsize\n    partial_end_padding = partial_size % np.dtype(\"uint64\").alignment\n    return dt_fmt().format(\n        ld.itemsize, partial_ld_off, partial_size + partial_end_padding\n    )\n\n\ndef partial_nested_fmt():\n    ld = np.dtype(\"longdouble\")\n    partial_nested_off = 8 + 8 * (ld.alignment > 8)\n    partial_ld_off = partial_ld_offset()\n    partial_size = partial_ld_off + ld.itemsize\n    partial_end_padding = partial_size % np.dtype(\"uint64\").alignment\n    partial_nested_size = partial_nested_off * 2 + partial_size + partial_end_padding\n    return \"{{'names':['a'],'formats':[{}],'offsets':[{}],'itemsize':{}}}\".format(\n        partial_dtype_fmt(), partial_nested_off, partial_nested_size\n    )\n\n\ndef assert_equal(actual, expected_data, expected_dtype):\n    np.testing.assert_equal(actual, np.array(expected_data, dtype=expected_dtype))\n\n\ndef test_format_descriptors():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.get_format_unbound()\n    assert re.match(\n        \"^NumPy type info missing for .*UnboundStruct.*$\", str(excinfo.value)\n    )\n\n    ld = np.dtype(\"longdouble\")\n    ldbl_fmt = (\"4x\" if ld.alignment > 4 else \"\") + ld.char\n    ss_fmt = \"^T{?:bool_:3xI:uint_:f:float_:\" + ldbl_fmt + \":ldbl_:}\"\n    dbl = np.dtype(\"double\")\n    end_padding = ld.itemsize % np.dtype(\"uint64\").alignment\n    partial_fmt = (\n        \"^T{?:bool_:3xI:uint_:f:float_:\"\n        + str(4 * (dbl.alignment > 4) + dbl.itemsize + 8 * (ld.alignment > 8))\n        + \"xg:ldbl_:\"\n        + (str(end_padding) + \"x}\" if end_padding > 0 else \"}\")\n    )\n    nested_extra = str(max(8, ld.alignment))\n    assert m.print_format_descriptors() == [\n        ss_fmt,\n        \"^T{?:bool_:I:uint_:f:float_:g:ldbl_:}\",\n        \"^T{\" + ss_fmt + \":a:^T{?:bool_:I:uint_:f:float_:g:ldbl_:}:b:}\",\n        partial_fmt,\n        \"^T{\" + nested_extra + \"x\" + partial_fmt + \":a:\" + nested_extra + \"x}\",\n        \"^T{3s:a:3s:b:}\",\n        \"^T{(3)4s:a:(2)i:b:(3)B:c:1x(4, 2)f:d:}\",\n        \"^T{q:e1:B:e2:}\",\n        \"^T{Zf:cflt:Zd:cdbl:}\",\n    ]\n\n\ndef test_dtype(simple_dtype):\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    assert [x.replace(\" \", \"\") for x in m.print_dtypes()] == [\n        simple_dtype_fmt(),\n        packed_dtype_fmt(),\n        \"[('a',{}),('b',{})]\".format(simple_dtype_fmt(), packed_dtype_fmt()),\n        partial_dtype_fmt(),\n        partial_nested_fmt(),\n        \"[('a','S3'),('b','S3')]\",\n        (\n            \"{{'names':['a','b','c','d'],\"\n            + \"'formats':[('S4',(3,)),('\"\n            + e\n            + \"i4',(2,)),('u1',(3,)),('\"\n            + e\n            + \"f4',(4,2))],\"\n            + \"'offsets':[0,12,20,24],'itemsize':56}}\"\n        ).format(e=e),\n        \"[('e1','\" + e + \"i8'),('e2','u1')]\",\n        \"[('x','i1'),('y','\" + e + \"u8')]\",\n        \"[('cflt','\" + e + \"c8'),('cdbl','\" + e + \"c16')]\",\n    ]\n\n    d1 = np.dtype(\n        {\n            \"names\": [\"a\", \"b\"],\n            \"formats\": [\"int32\", \"float64\"],\n            \"offsets\": [1, 10],\n            \"itemsize\": 20,\n        }\n    )\n    d2 = np.dtype([(\"a\", \"i4\"), (\"b\", \"f4\")])\n    assert m.test_dtype_ctors() == [\n        np.dtype(\"int32\"),\n        np.dtype(\"float64\"),\n        np.dtype(\"bool\"),\n        d1,\n        d1,\n        np.dtype(\"uint32\"),\n        d2,\n    ]\n\n    assert m.test_dtype_methods() == [\n        np.dtype(\"int32\"),\n        simple_dtype,\n        False,\n        True,\n        np.dtype(\"int32\").itemsize,\n        simple_dtype.itemsize,\n    ]\n\n    assert m.trailing_padding_dtype() == m.buffer_to_dtype(\n        np.zeros(1, m.trailing_padding_dtype())\n    )\n\n    assert m.test_dtype_kind() == list(\"iiiiiuuuuuffffcccbMmO\")\n    assert m.test_dtype_char_() == list(\"bhilqBHILQefdgFDG?MmO\")\n\n\ndef test_recarray(simple_dtype, packed_dtype):\n    elements = [(False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)]\n\n    for func, dtype in [\n        (m.create_rec_simple, simple_dtype),\n        (m.create_rec_packed, packed_dtype),\n    ]:\n        arr = func(0)\n        assert arr.dtype == dtype\n        assert_equal(arr, [], simple_dtype)\n        assert_equal(arr, [], packed_dtype)\n\n        arr = func(3)\n        assert arr.dtype == dtype\n        assert_equal(arr, elements, simple_dtype)\n        assert_equal(arr, elements, packed_dtype)\n\n        # Show what recarray's look like in NumPy.\n        assert type(arr[0]) == np.void\n        assert type(arr[0].item()) == tuple\n\n        if dtype == simple_dtype:\n            assert m.print_rec_simple(arr) == [\n                \"s:0,0,0,-0\",\n                \"s:1,1,1.5,-2.5\",\n                \"s:0,2,3,-5\",\n            ]\n        else:\n            assert m.print_rec_packed(arr) == [\n                \"p:0,0,0,-0\",\n                \"p:1,1,1.5,-2.5\",\n                \"p:0,2,3,-5\",\n            ]\n\n    nested_dtype = np.dtype([(\"a\", simple_dtype), (\"b\", packed_dtype)])\n\n    arr = m.create_rec_nested(0)\n    assert arr.dtype == nested_dtype\n    assert_equal(arr, [], nested_dtype)\n\n    arr = m.create_rec_nested(3)\n    assert arr.dtype == nested_dtype\n    assert_equal(\n        arr,\n        [\n            ((False, 0, 0.0, -0.0), (True, 1, 1.5, -2.5)),\n            ((True, 1, 1.5, -2.5), (False, 2, 3.0, -5.0)),\n            ((False, 2, 3.0, -5.0), (True, 3, 4.5, -7.5)),\n        ],\n        nested_dtype,\n    )\n    assert m.print_rec_nested(arr) == [\n        \"n:a=s:0,0,0,-0;b=p:1,1,1.5,-2.5\",\n        \"n:a=s:1,1,1.5,-2.5;b=p:0,2,3,-5\",\n        \"n:a=s:0,2,3,-5;b=p:1,3,4.5,-7.5\",\n    ]\n\n    arr = m.create_rec_partial(3)\n    assert str(arr.dtype).replace(\" \", \"\") == partial_dtype_fmt()\n    partial_dtype = arr.dtype\n    assert \"\" not in arr.dtype.fields\n    assert partial_dtype.itemsize > simple_dtype.itemsize\n    assert_equal(arr, elements, simple_dtype)\n    assert_equal(arr, elements, packed_dtype)\n\n    arr = m.create_rec_partial_nested(3)\n    assert str(arr.dtype).replace(\" \", \"\") == partial_nested_fmt()\n    assert \"\" not in arr.dtype.fields\n    assert \"\" not in arr.dtype.fields[\"a\"][0].fields\n    assert arr.dtype.itemsize > partial_dtype.itemsize\n    np.testing.assert_equal(arr[\"a\"], m.create_rec_partial(3))\n\n\ndef test_array_constructors():\n    data = np.arange(1, 7, dtype=\"int32\")\n    for i in range(8):\n        np.testing.assert_array_equal(m.test_array_ctors(10 + i), data.reshape((3, 2)))\n        np.testing.assert_array_equal(m.test_array_ctors(20 + i), data.reshape((3, 2)))\n    for i in range(5):\n        np.testing.assert_array_equal(m.test_array_ctors(30 + i), data)\n        np.testing.assert_array_equal(m.test_array_ctors(40 + i), data)\n\n\ndef test_string_array():\n    arr = m.create_string_array(True)\n    assert str(arr.dtype) == \"[('a', 'S3'), ('b', 'S3')]\"\n    assert m.print_string_array(arr) == [\n        \"a='',b=''\",\n        \"a='a',b='a'\",\n        \"a='ab',b='ab'\",\n        \"a='abc',b='abc'\",\n    ]\n    dtype = arr.dtype\n    assert arr[\"a\"].tolist() == [b\"\", b\"a\", b\"ab\", b\"abc\"]\n    assert arr[\"b\"].tolist() == [b\"\", b\"a\", b\"ab\", b\"abc\"]\n    arr = m.create_string_array(False)\n    assert dtype == arr.dtype\n\n\ndef test_array_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_array_array(3)\n    assert str(arr.dtype).replace(\" \", \"\") == (\n        \"{{'names':['a','b','c','d'],\"\n        + \"'formats':[('S4',(3,)),('\"\n        + e\n        + \"i4',(2,)),('u1',(3,)),('{e}f4',(4,2))],\"\n        + \"'offsets':[0,12,20,24],'itemsize':56}}\"\n    ).format(e=e)\n    assert m.print_array_array(arr) == [\n        \"a={{A,B,C,D},{K,L,M,N},{U,V,W,X}},b={0,1},\"\n        + \"c={0,1,2},d={{0,1},{10,11},{20,21},{30,31}}\",\n        \"a={{W,X,Y,Z},{G,H,I,J},{Q,R,S,T}},b={1000,1001},\"\n        + \"c={10,11,12},d={{100,101},{110,111},{120,121},{130,131}}\",\n        \"a={{S,T,U,V},{C,D,E,F},{M,N,O,P}},b={2000,2001},\"\n        + \"c={20,21,22},d={{200,201},{210,211},{220,221},{230,231}}\",\n    ]\n    assert arr[\"a\"].tolist() == [\n        [b\"ABCD\", b\"KLMN\", b\"UVWX\"],\n        [b\"WXYZ\", b\"GHIJ\", b\"QRST\"],\n        [b\"STUV\", b\"CDEF\", b\"MNOP\"],\n    ]\n    assert arr[\"b\"].tolist() == [[0, 1], [1000, 1001], [2000, 2001]]\n    assert m.create_array_array(0).dtype == arr.dtype\n\n\ndef test_enum_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_enum_array(3)\n    dtype = arr.dtype\n    assert dtype == np.dtype([(\"e1\", e + \"i8\"), (\"e2\", \"u1\")])\n    assert m.print_enum_array(arr) == [\"e1=A,e2=X\", \"e1=B,e2=Y\", \"e1=A,e2=X\"]\n    assert arr[\"e1\"].tolist() == [-1, 1, -1]\n    assert arr[\"e2\"].tolist() == [1, 2, 1]\n    assert m.create_enum_array(0).dtype == dtype\n\n\ndef test_complex_array():\n    from sys import byteorder\n\n    e = \"<\" if byteorder == \"little\" else \">\"\n\n    arr = m.create_complex_array(3)\n    dtype = arr.dtype\n    assert dtype == np.dtype([(\"cflt\", e + \"c8\"), (\"cdbl\", e + \"c16\")])\n    assert m.print_complex_array(arr) == [\n        \"c:(0,0.25),(0.5,0.75)\",\n        \"c:(1,1.25),(1.5,1.75)\",\n        \"c:(2,2.25),(2.5,2.75)\",\n    ]\n    assert arr[\"cflt\"].tolist() == [0.0 + 0.25j, 1.0 + 1.25j, 2.0 + 2.25j]\n    assert arr[\"cdbl\"].tolist() == [0.5 + 0.75j, 1.5 + 1.75j, 2.5 + 2.75j]\n    assert m.create_complex_array(0).dtype == dtype\n\n\ndef test_signature(doc):\n    assert (\n        doc(m.create_rec_nested)\n        == \"create_rec_nested(arg0: int) -> numpy.ndarray[NestedStruct]\"\n    )\n\n\ndef test_scalar_conversion():\n    n = 3\n    arrays = [\n        m.create_rec_simple(n),\n        m.create_rec_packed(n),\n        m.create_rec_nested(n),\n        m.create_enum_array(n),\n    ]\n    funcs = [m.f_simple, m.f_packed, m.f_nested]\n\n    for i, func in enumerate(funcs):\n        for j, arr in enumerate(arrays):\n            if i == j and i < 2:\n                assert [func(arr[k]) for k in range(n)] == [k * 10 for k in range(n)]\n            else:\n                with pytest.raises(TypeError) as excinfo:\n                    func(arr[0])\n                assert \"incompatible function arguments\" in str(excinfo.value)\n\n\ndef test_vectorize():\n    n = 3\n    array = m.create_rec_simple(n)\n    values = m.f_simple_vectorized(array)\n    np.testing.assert_array_equal(values, [0, 10, 20])\n    array_2 = m.f_simple_pass_thru_vectorized(array)\n    np.testing.assert_array_equal(array, array_2)\n\n\ndef test_cls_and_dtype_conversion(simple_dtype):\n    s = m.SimpleStruct()\n    assert s.astuple() == (False, 0, 0.0, 0.0)\n    assert m.SimpleStruct.fromtuple(s.astuple()).astuple() == s.astuple()\n\n    s.uint_ = 2\n    assert m.f_simple(s) == 20\n\n    # Try as recarray of shape==(1,).\n    s_recarray = np.array([(False, 2, 0.0, 0.0)], dtype=simple_dtype)\n    # Show that this will work for vectorized case.\n    np.testing.assert_array_equal(m.f_simple_vectorized(s_recarray), [20])\n\n    # Show as a scalar that inherits from np.generic.\n    s_scalar = s_recarray[0]\n    assert isinstance(s_scalar, np.void)\n    assert m.f_simple(s_scalar) == 20\n\n    # Show that an *array* scalar (np.ndarray.shape == ()) does not convert.\n    # More specifically, conversion to SimpleStruct is not implicit.\n    s_recarray_scalar = s_recarray.reshape(())\n    assert isinstance(s_recarray_scalar, np.ndarray)\n    assert s_recarray_scalar.dtype == simple_dtype\n    with pytest.raises(TypeError) as excinfo:\n        m.f_simple(s_recarray_scalar)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    # Explicitly convert to m.SimpleStruct.\n    assert m.f_simple(m.SimpleStruct.fromtuple(s_recarray_scalar.item())) == 20\n\n    # Show that an array of dtype=object does *not* convert.\n    s_array_object = np.array([s])\n    assert s_array_object.dtype == object\n    with pytest.raises(TypeError) as excinfo:\n        m.f_simple_vectorized(s_array_object)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n    # Explicitly convert to `np.array(..., dtype=simple_dtype)`\n    s_array = np.array([s.astuple()], dtype=simple_dtype)\n    np.testing.assert_array_equal(m.f_simple_vectorized(s_array), [20])\n\n\ndef test_register_dtype():\n    with pytest.raises(RuntimeError) as excinfo:\n        m.register_dtype()\n    assert \"dtype is already registered\" in str(excinfo.value)\n\n\n@pytest.mark.xfail(\"env.PYPY\")\ndef test_str_leak():\n    from sys import getrefcount\n\n    fmt = \"f4\"\n    pytest.gc_collect()\n    start = getrefcount(fmt)\n    d = m.dtype_wrapper(fmt)\n    assert d is np.dtype(\"f4\")\n    del d\n    pytest.gc_collect()\n    assert getrefcount(fmt) == start\n\n\ndef test_compare_buffer_info():\n    assert all(m.compare_buffer_info())\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_vectorize.cpp",
    "content": "/*\n    tests/test_numpy_vectorize.cpp -- auto-vectorize functions over NumPy array\n    arguments\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\ndouble my_func(int x, float y, double z) {\n    py::print(\"my_func(x:int={}, y:float={:.0f}, z:float={:.0f})\"_s.format(x, y, z));\n    return (float) x * y * z;\n}\n\nTEST_SUBMODULE(numpy_vectorize, m) {\n    try {\n        py::module_::import(\"numpy\");\n    } catch (...) {\n        return;\n    }\n\n    // test_vectorize, test_docs, test_array_collapse\n    // Vectorize all arguments of a function (though non-vector arguments are also allowed)\n    m.def(\"vectorized_func\", py::vectorize(my_func));\n\n    // Vectorize a lambda function with a capture object (e.g. to exclude some arguments from the\n    // vectorization)\n    m.def(\"vectorized_func2\", [](py::array_t<int> x, py::array_t<float> y, float z) {\n        return py::vectorize([z](int x, float y) { return my_func(x, y, z); })(std::move(x),\n                                                                               std::move(y));\n    });\n\n    // Vectorize a complex-valued function\n    m.def(\"vectorized_func3\",\n          py::vectorize([](std::complex<double> c) { return c * std::complex<double>(2.f); }));\n\n    // test_type_selection\n    // NumPy function which only accepts specific data types\n    // A lot of these no lints could be replaced with const refs, and probably should at some\n    // point.\n    m.def(\"selective_func\",\n          [](const py::array_t<int, py::array::c_style> &) { return \"Int branch taken.\"; });\n    m.def(\"selective_func\",\n          [](const py::array_t<float, py::array::c_style> &) { return \"Float branch taken.\"; });\n    m.def(\"selective_func\", [](const py::array_t<std::complex<float>, py::array::c_style> &) {\n        return \"Complex float branch taken.\";\n    });\n\n    // test_passthrough_arguments\n    // Passthrough test: references and non-pod types should be automatically passed through (in\n    // the function definition below, only `b`, `d`, and `g` are vectorized):\n    struct NonPODClass {\n        explicit NonPODClass(int v) : value{v} {}\n        int value;\n    };\n    py::class_<NonPODClass>(m, \"NonPODClass\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &NonPODClass::value);\n    m.def(\"vec_passthrough\",\n          py::vectorize([](const double *a,\n                           double b,\n                           // Changing this broke things\n                           // NOLINTNEXTLINE(performance-unnecessary-value-param)\n                           py::array_t<double> c,\n                           const int &d,\n                           int &e,\n                           NonPODClass f,\n                           const double g) { return *a + b + c.at(0) + d + e + f.value + g; }));\n\n    // test_method_vectorization\n    struct VectorizeTestClass {\n        explicit VectorizeTestClass(int v) : value{v} {};\n        float method(int x, float y) const { return y + (float) (x + value); }\n        int value = 0;\n    };\n    py::class_<VectorizeTestClass> vtc(m, \"VectorizeTestClass\");\n    vtc.def(py::init<int>()).def_readwrite(\"value\", &VectorizeTestClass::value);\n\n    // Automatic vectorizing of methods\n    vtc.def(\"method\", py::vectorize(&VectorizeTestClass::method));\n\n    // test_trivial_broadcasting\n    // Internal optimization test for whether the input is trivially broadcastable:\n    py::enum_<py::detail::broadcast_trivial>(m, \"trivial\")\n        .value(\"f_trivial\", py::detail::broadcast_trivial::f_trivial)\n        .value(\"c_trivial\", py::detail::broadcast_trivial::c_trivial)\n        .value(\"non_trivial\", py::detail::broadcast_trivial::non_trivial);\n    m.def(\"vectorized_is_trivial\",\n          [](const py::array_t<int, py::array::forcecast> &arg1,\n             const py::array_t<float, py::array::forcecast> &arg2,\n             const py::array_t<double, py::array::forcecast> &arg3) {\n              py::ssize_t ndim = 0;\n              std::vector<py::ssize_t> shape;\n              std::array<py::buffer_info, 3> buffers{\n                  {arg1.request(), arg2.request(), arg3.request()}};\n              return py::detail::broadcast(buffers, ndim, shape);\n          });\n\n    m.def(\"add_to\", py::vectorize([](NonPODClass &x, int a) { x.value += a; }));\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_numpy_vectorize.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import numpy_vectorize as m\n\nnp = pytest.importorskip(\"numpy\")\n\n\ndef test_vectorize(capture):\n    assert np.isclose(m.vectorized_func3(np.array(3 + 7j)), [6 + 14j])\n\n    for f in [m.vectorized_func, m.vectorized_func2]:\n        with capture:\n            assert np.isclose(f(1, 2, 3), 6)\n        assert capture == \"my_func(x:int=1, y:float=2, z:float=3)\"\n        with capture:\n            assert np.isclose(f(np.array(1), np.array(2), 3), 6)\n        assert capture == \"my_func(x:int=1, y:float=2, z:float=3)\"\n        with capture:\n            assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=3)\n            my_func(x:int=3, y:float=4, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a = np.array([[1, 2], [3, 4]], order=\"F\")\n            b = np.array([[10, 20], [30, 40]], order=\"F\")\n            c = 3\n            result = f(a, b, c)\n            assert np.allclose(result, a * b * c)\n            assert result.flags.f_contiguous\n        # All inputs are F order and full or singletons, so we the result is in col-major order:\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=10, z:float=3)\n            my_func(x:int=3, y:float=30, z:float=3)\n            my_func(x:int=2, y:float=20, z:float=3)\n            my_func(x:int=4, y:float=40, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 3, 5], [7, 9, 11]]),\n                np.array([[2, 4, 6], [8, 10, 12]]),\n                3,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=3)\n            my_func(x:int=3, y:float=4, z:float=3)\n            my_func(x:int=5, y:float=6, z:float=3)\n            my_func(x:int=7, y:float=8, z:float=3)\n            my_func(x:int=9, y:float=10, z:float=3)\n            my_func(x:int=11, y:float=12, z:float=3)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=3, z:float=2)\n            my_func(x:int=3, y:float=4, z:float=2)\n            my_func(x:int=4, y:float=2, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=4, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 2, 3], [4, 5, 6]], order=\"F\"),\n                np.array([[2], [3]]),\n                2,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=2, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=5, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = np.array([[1, 2, 3], [4, 5, 6]])[::, ::2], np.array([[2], [3]]), 2\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n        with capture:\n            a, b, c = (\n                np.array([[1, 2, 3], [4, 5, 6]], order=\"F\")[::, ::2],\n                np.array([[2], [3]]),\n                2,\n            )\n            assert np.allclose(f(a, b, c), a * b * c)\n        assert (\n            capture\n            == \"\"\"\n            my_func(x:int=1, y:float=2, z:float=2)\n            my_func(x:int=3, y:float=2, z:float=2)\n            my_func(x:int=4, y:float=3, z:float=2)\n            my_func(x:int=6, y:float=3, z:float=2)\n        \"\"\"\n        )\n\n\ndef test_type_selection():\n    assert m.selective_func(np.array([1], dtype=np.int32)) == \"Int branch taken.\"\n    assert m.selective_func(np.array([1.0], dtype=np.float32)) == \"Float branch taken.\"\n    assert (\n        m.selective_func(np.array([1.0j], dtype=np.complex64))\n        == \"Complex float branch taken.\"\n    )\n\n\ndef test_docs(doc):\n    assert (\n        doc(m.vectorized_func)\n        == \"\"\"\n        vectorized_func(arg0: numpy.ndarray[numpy.int32], arg1: numpy.ndarray[numpy.float32], arg2: numpy.ndarray[numpy.float64]) -> object\n    \"\"\"  # noqa: E501 line too long\n    )\n\n\ndef test_trivial_broadcasting():\n    trivial, vectorized_is_trivial = m.trivial, m.vectorized_is_trivial\n\n    assert vectorized_is_trivial(1, 2, 3) == trivial.c_trivial\n    assert vectorized_is_trivial(np.array(1), np.array(2), 3) == trivial.c_trivial\n    assert (\n        vectorized_is_trivial(np.array([1, 3]), np.array([2, 4]), 3)\n        == trivial.c_trivial\n    )\n    assert trivial.c_trivial == vectorized_is_trivial(\n        np.array([[1, 3, 5], [7, 9, 11]]), np.array([[2, 4, 6], [8, 10, 12]]), 3\n    )\n    assert (\n        vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([2, 3, 4]), 2)\n        == trivial.non_trivial\n    )\n    assert (\n        vectorized_is_trivial(np.array([[1, 2, 3], [4, 5, 6]]), np.array([[2], [3]]), 2)\n        == trivial.non_trivial\n    )\n    z1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]], dtype=\"int32\")\n    z2 = np.array(z1, dtype=\"float32\")\n    z3 = np.array(z1, dtype=\"float64\")\n    assert vectorized_is_trivial(z1, z2, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(1, z2, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(z1, 1, z3) == trivial.c_trivial\n    assert vectorized_is_trivial(z1, z2, 1) == trivial.c_trivial\n    assert vectorized_is_trivial(z1[::2, ::2], 1, 1) == trivial.non_trivial\n    assert vectorized_is_trivial(1, 1, z1[::2, ::2]) == trivial.c_trivial\n    assert vectorized_is_trivial(1, 1, z3[::2, ::2]) == trivial.non_trivial\n    assert vectorized_is_trivial(z1, 1, z3[1::4, 1::4]) == trivial.c_trivial\n\n    y1 = np.array(z1, order=\"F\")\n    y2 = np.array(y1)\n    y3 = np.array(y1)\n    assert vectorized_is_trivial(y1, y2, y3) == trivial.f_trivial\n    assert vectorized_is_trivial(y1, 1, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(1, y2, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(1, 1, y3) == trivial.f_trivial\n    assert vectorized_is_trivial(y1, z2, 1) == trivial.non_trivial\n    assert vectorized_is_trivial(z1[1::4, 1::4], y2, 1) == trivial.f_trivial\n    assert vectorized_is_trivial(y1[1::4, 1::4], z2, 1) == trivial.c_trivial\n\n    assert m.vectorized_func(z1, z2, z3).flags.c_contiguous\n    assert m.vectorized_func(y1, y2, y3).flags.f_contiguous\n    assert m.vectorized_func(z1, 1, 1).flags.c_contiguous\n    assert m.vectorized_func(1, y2, 1).flags.f_contiguous\n    assert m.vectorized_func(z1[1::4, 1::4], y2, 1).flags.f_contiguous\n    assert m.vectorized_func(y1[1::4, 1::4], z2, 1).flags.c_contiguous\n\n\ndef test_passthrough_arguments(doc):\n    assert doc(m.vec_passthrough) == (\n        \"vec_passthrough(\"\n        + \", \".join(\n            [\n                \"arg0: float\",\n                \"arg1: numpy.ndarray[numpy.float64]\",\n                \"arg2: numpy.ndarray[numpy.float64]\",\n                \"arg3: numpy.ndarray[numpy.int32]\",\n                \"arg4: int\",\n                \"arg5: m.numpy_vectorize.NonPODClass\",\n                \"arg6: numpy.ndarray[numpy.float64]\",\n            ]\n        )\n        + \") -> object\"\n    )\n\n    b = np.array([[10, 20, 30]], dtype=\"float64\")\n    c = np.array([100, 200])  # NOT a vectorized argument\n    d = np.array([[1000], [2000], [3000]], dtype=\"int\")\n    g = np.array([[1000000, 2000000, 3000000]], dtype=\"int\")  # requires casting\n    assert np.all(\n        m.vec_passthrough(1, b, c, d, 10000, m.NonPODClass(100000), g)\n        == np.array(\n            [\n                [1111111, 2111121, 3111131],\n                [1112111, 2112121, 3112131],\n                [1113111, 2113121, 3113131],\n            ]\n        )\n    )\n\n\ndef test_method_vectorization():\n    o = m.VectorizeTestClass(3)\n    x = np.array([1, 2], dtype=\"int\")\n    y = np.array([[10], [20]], dtype=\"float32\")\n    assert np.all(o.method(x, y) == [[14, 15], [24, 25]])\n\n\ndef test_array_collapse():\n    assert not isinstance(m.vectorized_func(1, 2, 3), np.ndarray)\n    assert not isinstance(m.vectorized_func(np.array(1), 2, 3), np.ndarray)\n    z = m.vectorized_func([1], 2, 3)\n    assert isinstance(z, np.ndarray)\n    assert z.shape == (1,)\n    z = m.vectorized_func(1, [[[2]]], 3)\n    assert isinstance(z, np.ndarray)\n    assert z.shape == (1, 1, 1)\n\n\ndef test_vectorized_noreturn():\n    x = m.NonPODClass(0)\n    assert x.value == 0\n    m.add_to(x, [1, 2, 3, 4])\n    assert x.value == 10\n    m.add_to(x, 1)\n    assert x.value == 11\n    m.add_to(x, [[1, 1], [2, 3]])\n    assert x.value == 18\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_opaque_types.cpp",
    "content": "/*\n    tests/test_opaque_types.cpp -- opaque types, passing void pointers\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\n#include <vector>\n\n// IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures\n//\n// This also deliberately doesn't use the below StringList type alias to test\n// that MAKE_OPAQUE can handle a type containing a `,`.  (The `std::allocator`\n// bit is just the default `std::vector` allocator).\nPYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);\n\nusing StringList = std::vector<std::string, std::allocator<std::string>>;\n\nTEST_SUBMODULE(opaque_types, m) {\n    // test_string_list\n    py::class_<StringList>(m, \"StringList\")\n        .def(py::init<>())\n        .def(\"pop_back\", &StringList::pop_back)\n        /* There are multiple versions of push_back(), etc. Select the right ones. */\n        .def(\"push_back\", (void(StringList::*)(const std::string &)) & StringList::push_back)\n        .def(\"back\", (std::string & (StringList::*) ()) & StringList::back)\n        .def(\"__len__\", [](const StringList &v) { return v.size(); })\n        .def(\n            \"__iter__\",\n            [](StringList &v) { return py::make_iterator(v.begin(), v.end()); },\n            py::keep_alive<0, 1>());\n\n    class ClassWithSTLVecProperty {\n    public:\n        StringList stringList;\n    };\n    py::class_<ClassWithSTLVecProperty>(m, \"ClassWithSTLVecProperty\")\n        .def(py::init<>())\n        .def_readwrite(\"stringList\", &ClassWithSTLVecProperty::stringList);\n\n    m.def(\"print_opaque_list\", [](const StringList &l) {\n        std::string ret = \"Opaque list: [\";\n        bool first = true;\n        for (const auto &entry : l) {\n            if (!first) {\n                ret += \", \";\n            }\n            ret += entry;\n            first = false;\n        }\n        return ret + \"]\";\n    });\n\n    // test_pointers\n    m.def(\"return_void_ptr\", []() { return (void *) 0x1234; });\n    m.def(\"get_void_ptr_value\", [](void *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });\n    m.def(\"return_null_str\", []() { return (char *) nullptr; });\n    m.def(\"get_null_str_value\", [](char *ptr) { return reinterpret_cast<std::intptr_t>(ptr); });\n\n    m.def(\"return_unique_ptr\", []() -> std::unique_ptr<StringList> {\n        auto *result = new StringList();\n        result->push_back(\"some value\");\n        return std::unique_ptr<StringList>(result);\n    });\n\n    // test unions\n    py::class_<IntFloat>(m, \"IntFloat\")\n        .def(py::init<>())\n        .def_readwrite(\"i\", &IntFloat::i)\n        .def_readwrite(\"f\", &IntFloat::f);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_opaque_types.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import opaque_types as m\n\n\ndef test_string_list():\n    lst = m.StringList()\n    lst.push_back(\"Element 1\")\n    lst.push_back(\"Element 2\")\n    assert m.print_opaque_list(lst) == \"Opaque list: [Element 1, Element 2]\"\n    assert lst.back() == \"Element 2\"\n\n    for i, k in enumerate(lst, start=1):\n        assert k == \"Element {}\".format(i)\n    lst.pop_back()\n    assert m.print_opaque_list(lst) == \"Opaque list: [Element 1]\"\n\n    cvp = m.ClassWithSTLVecProperty()\n    assert m.print_opaque_list(cvp.stringList) == \"Opaque list: []\"\n\n    cvp.stringList = lst\n    cvp.stringList.push_back(\"Element 3\")\n    assert m.print_opaque_list(cvp.stringList) == \"Opaque list: [Element 1, Element 3]\"\n\n\ndef test_pointers(msg):\n    living_before = ConstructorStats.get(UserType).alive()\n    assert m.get_void_ptr_value(m.return_void_ptr()) == 0x1234\n    assert m.get_void_ptr_value(UserType())  # Should also work for other C++ types\n    assert ConstructorStats.get(UserType).alive() == living_before\n\n    with pytest.raises(TypeError) as excinfo:\n        m.get_void_ptr_value([1, 2, 3])  # This should not work\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        get_void_ptr_value(): incompatible function arguments. The following argument types are supported:\n            1. (arg0: capsule) -> int\n\n        Invoked with: [1, 2, 3]\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    assert m.return_null_str() is None\n    assert m.get_null_str_value(m.return_null_str()) is not None\n\n    ptr = m.return_unique_ptr()\n    assert \"StringList\" in repr(ptr)\n    assert m.print_opaque_list(ptr) == \"Opaque list: [some value]\"\n\n\ndef test_unions():\n    int_float_union = m.IntFloat()\n    int_float_union.i = 42\n    assert int_float_union.i == 42\n    int_float_union.f = 3.0\n    assert int_float_union.f == 3.0\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_operator_overloading.cpp",
    "content": "/*\n    tests/test_operator_overloading.cpp -- operator overloading\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/operators.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <functional>\n\nclass Vector2 {\npublic:\n    Vector2(float x, float y) : x(x), y(y) { print_created(this, toString()); }\n    Vector2(const Vector2 &v) : x(v.x), y(v.y) { print_copy_created(this); }\n    Vector2(Vector2 &&v) noexcept : x(v.x), y(v.y) {\n        print_move_created(this);\n        v.x = v.y = 0;\n    }\n    Vector2 &operator=(const Vector2 &v) {\n        x = v.x;\n        y = v.y;\n        print_copy_assigned(this);\n        return *this;\n    }\n    Vector2 &operator=(Vector2 &&v) noexcept {\n        x = v.x;\n        y = v.y;\n        v.x = v.y = 0;\n        print_move_assigned(this);\n        return *this;\n    }\n    ~Vector2() { print_destroyed(this); }\n\n    std::string toString() const {\n        return \"[\" + std::to_string(x) + \", \" + std::to_string(y) + \"]\";\n    }\n\n    Vector2 operator-() const { return Vector2(-x, -y); }\n    Vector2 operator+(const Vector2 &v) const { return Vector2(x + v.x, y + v.y); }\n    Vector2 operator-(const Vector2 &v) const { return Vector2(x - v.x, y - v.y); }\n    Vector2 operator-(float value) const { return Vector2(x - value, y - value); }\n    Vector2 operator+(float value) const { return Vector2(x + value, y + value); }\n    Vector2 operator*(float value) const { return Vector2(x * value, y * value); }\n    Vector2 operator/(float value) const { return Vector2(x / value, y / value); }\n    Vector2 operator*(const Vector2 &v) const { return Vector2(x * v.x, y * v.y); }\n    Vector2 operator/(const Vector2 &v) const { return Vector2(x / v.x, y / v.y); }\n    Vector2 &operator+=(const Vector2 &v) {\n        x += v.x;\n        y += v.y;\n        return *this;\n    }\n    Vector2 &operator-=(const Vector2 &v) {\n        x -= v.x;\n        y -= v.y;\n        return *this;\n    }\n    Vector2 &operator*=(float v) {\n        x *= v;\n        y *= v;\n        return *this;\n    }\n    Vector2 &operator/=(float v) {\n        x /= v;\n        y /= v;\n        return *this;\n    }\n    Vector2 &operator*=(const Vector2 &v) {\n        x *= v.x;\n        y *= v.y;\n        return *this;\n    }\n    Vector2 &operator/=(const Vector2 &v) {\n        x /= v.x;\n        y /= v.y;\n        return *this;\n    }\n\n    friend Vector2 operator+(float f, const Vector2 &v) { return Vector2(f + v.x, f + v.y); }\n    friend Vector2 operator-(float f, const Vector2 &v) { return Vector2(f - v.x, f - v.y); }\n    friend Vector2 operator*(float f, const Vector2 &v) { return Vector2(f * v.x, f * v.y); }\n    friend Vector2 operator/(float f, const Vector2 &v) { return Vector2(f / v.x, f / v.y); }\n\n    bool operator==(const Vector2 &v) const { return x == v.x && y == v.y; }\n    bool operator!=(const Vector2 &v) const { return x != v.x || y != v.y; }\n\nprivate:\n    float x, y;\n};\n\nclass C1 {};\nclass C2 {};\n\nint operator+(const C1 &, const C1 &) { return 11; }\nint operator+(const C2 &, const C2 &) { return 22; }\nint operator+(const C2 &, const C1 &) { return 21; }\nint operator+(const C1 &, const C2 &) { return 12; }\n\nstruct HashMe {\n    std::string member;\n};\n\nbool operator==(const HashMe &lhs, const HashMe &rhs) { return lhs.member == rhs.member; }\n\n// Note: Specializing explicit within `namespace std { ... }` is done due to a\n// bug in GCC<7. If you are supporting compilers later than this, consider\n// specializing `using template<> struct std::hash<...>` in the global\n// namespace instead, per this recommendation:\n// https://en.cppreference.com/w/cpp/language/extending_std#Adding_template_specializations\nnamespace std {\ntemplate <>\nstruct hash<Vector2> {\n    // Not a good hash function, but easy to test\n    size_t operator()(const Vector2 &) { return 4; }\n};\n\n// HashMe has a hash function in C++ but no `__hash__` for Python.\ntemplate <>\nstruct hash<HashMe> {\n    std::size_t operator()(const HashMe &selector) const {\n        return std::hash<std::string>()(selector.member);\n    }\n};\n} // namespace std\n\n// Not a good abs function, but easy to test.\nstd::string abs(const Vector2 &) { return \"abs(Vector2)\"; }\n\n// MSVC & Intel warns about unknown pragmas, and warnings are errors.\n#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic push\n// clang 7.0.0 and Apple LLVM 10.0.1 introduce `-Wself-assign-overloaded` to\n// `-Wall`, which is used here for overloading (e.g. `py::self += py::self `).\n// Here, we suppress the warning using `#pragma diagnostic`.\n// Taken from: https://github.com/RobotLocomotion/drake/commit/aaf84b46\n// TODO(eric): This could be resolved using a function / functor (e.g. `py::self()`).\n#    if defined(__APPLE__) && defined(__clang__)\n#        if (__clang_major__ >= 10)\n#            pragma GCC diagnostic ignored \"-Wself-assign-overloaded\"\n#        endif\n#    elif defined(__clang__)\n#        if (__clang_major__ >= 7)\n#            pragma GCC diagnostic ignored \"-Wself-assign-overloaded\"\n#        endif\n#    endif\n#endif\n\nTEST_SUBMODULE(operators, m) {\n\n    // test_operator_overloading\n    py::class_<Vector2>(m, \"Vector2\")\n        .def(py::init<float, float>())\n        .def(py::self + py::self)\n        .def(py::self + float())\n        .def(py::self - py::self)\n        .def(py::self - float())\n        .def(py::self * float())\n        .def(py::self / float())\n        .def(py::self * py::self)\n        .def(py::self / py::self)\n        .def(py::self += py::self)\n        .def(py::self -= py::self)\n        .def(py::self *= float())\n        .def(py::self /= float())\n        .def(py::self *= py::self)\n        .def(py::self /= py::self)\n        .def(float() + py::self)\n        .def(float() - py::self)\n        .def(float() * py::self)\n        .def(float() / py::self)\n        .def(-py::self)\n        .def(\"__str__\", &Vector2::toString)\n        .def(\"__repr__\", &Vector2::toString)\n        .def(py::self == py::self)\n        .def(py::self != py::self)\n        .def(py::hash(py::self))\n        // N.B. See warning about usage of `py::detail::abs(py::self)` in\n        // `operators.h`.\n        .def(\"__abs__\", [](const Vector2 &v) { return abs(v); });\n\n    m.attr(\"Vector\") = m.attr(\"Vector2\");\n\n    // test_operators_notimplemented\n    // #393: need to return NotSupported to ensure correct arithmetic operator behavior\n    py::class_<C1>(m, \"C1\").def(py::init<>()).def(py::self + py::self);\n\n    py::class_<C2>(m, \"C2\")\n        .def(py::init<>())\n        .def(py::self + py::self)\n        .def(\"__add__\", [](const C2 &c2, const C1 &c1) { return c2 + c1; })\n        .def(\"__radd__\", [](const C2 &c2, const C1 &c1) { return c1 + c2; });\n\n    // test_nested\n    // #328: first member in a class can't be used in operators\n    struct NestABase {\n        int value = -2;\n    };\n    py::class_<NestABase>(m, \"NestABase\")\n        .def(py::init<>())\n        .def_readwrite(\"value\", &NestABase::value);\n\n    struct NestA : NestABase {\n        int value = 3;\n        NestA &operator+=(int i) {\n            value += i;\n            return *this;\n        }\n    };\n    py::class_<NestA>(m, \"NestA\")\n        .def(py::init<>())\n        .def(py::self += int())\n        .def(\n            \"as_base\",\n            [](NestA &a) -> NestABase & { return (NestABase &) a; },\n            py::return_value_policy::reference_internal);\n    m.def(\"get_NestA\", [](const NestA &a) { return a.value; });\n\n    struct NestB {\n        NestA a;\n        int value = 4;\n        NestB &operator-=(int i) {\n            value -= i;\n            return *this;\n        }\n    };\n    py::class_<NestB>(m, \"NestB\")\n        .def(py::init<>())\n        .def(py::self -= int())\n        .def_readwrite(\"a\", &NestB::a);\n    m.def(\"get_NestB\", [](const NestB &b) { return b.value; });\n\n    struct NestC {\n        NestB b;\n        int value = 5;\n        NestC &operator*=(int i) {\n            value *= i;\n            return *this;\n        }\n    };\n    py::class_<NestC>(m, \"NestC\")\n        .def(py::init<>())\n        .def(py::self *= int())\n        .def_readwrite(\"b\", &NestC::b);\n    m.def(\"get_NestC\", [](const NestC &c) { return c.value; });\n\n    // test_overriding_eq_reset_hash\n    // #2191 Overriding __eq__ should set __hash__ to None\n    struct Comparable {\n        int value;\n        bool operator==(const Comparable &rhs) const { return value == rhs.value; }\n    };\n\n    struct Hashable : Comparable {\n        explicit Hashable(int value) : Comparable{value} {};\n        size_t hash() const { return static_cast<size_t>(value); }\n    };\n\n    struct Hashable2 : Hashable {\n        using Hashable::Hashable;\n    };\n\n    py::class_<Comparable>(m, \"Comparable\").def(py::init<int>()).def(py::self == py::self);\n\n    py::class_<Hashable>(m, \"Hashable\")\n        .def(py::init<int>())\n        .def(py::self == py::self)\n        .def(\"__hash__\", &Hashable::hash);\n\n    // define __hash__ before __eq__\n    py::class_<Hashable2>(m, \"Hashable2\")\n        .def(\"__hash__\", &Hashable::hash)\n        .def(py::init<int>())\n        .def(py::self == py::self);\n\n    // define __eq__ but not __hash__\n    py::class_<HashMe>(m, \"HashMe\").def(py::self == py::self);\n\n    m.def(\"get_unhashable_HashMe_set\", []() { return std::unordered_set<HashMe>{{\"one\"}}; });\n}\n#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)\n#    pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_operator_overloading.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import operators as m\n\n\ndef test_operator_overloading():\n    v1 = m.Vector2(1, 2)\n    v2 = m.Vector(3, -1)\n    v3 = m.Vector2(1, 2)  # Same value as v1, but different instance.\n    assert v1 is not v3\n\n    assert str(v1) == \"[1.000000, 2.000000]\"\n    assert str(v2) == \"[3.000000, -1.000000]\"\n\n    assert str(-v2) == \"[-3.000000, 1.000000]\"\n\n    assert str(v1 + v2) == \"[4.000000, 1.000000]\"\n    assert str(v1 - v2) == \"[-2.000000, 3.000000]\"\n    assert str(v1 - 8) == \"[-7.000000, -6.000000]\"\n    assert str(v1 + 8) == \"[9.000000, 10.000000]\"\n    assert str(v1 * 8) == \"[8.000000, 16.000000]\"\n    assert str(v1 / 8) == \"[0.125000, 0.250000]\"\n    assert str(8 - v1) == \"[7.000000, 6.000000]\"\n    assert str(8 + v1) == \"[9.000000, 10.000000]\"\n    assert str(8 * v1) == \"[8.000000, 16.000000]\"\n    assert str(8 / v1) == \"[8.000000, 4.000000]\"\n    assert str(v1 * v2) == \"[3.000000, -2.000000]\"\n    assert str(v2 / v1) == \"[3.000000, -0.500000]\"\n\n    assert v1 == v3\n    assert v1 != v2\n    assert hash(v1) == 4\n    # TODO(eric.cousineau): Make this work.\n    # assert abs(v1) == \"abs(Vector2)\"\n\n    v1 += 2 * v2\n    assert str(v1) == \"[7.000000, 0.000000]\"\n    v1 -= v2\n    assert str(v1) == \"[4.000000, 1.000000]\"\n    v1 *= 2\n    assert str(v1) == \"[8.000000, 2.000000]\"\n    v1 /= 16\n    assert str(v1) == \"[0.500000, 0.125000]\"\n    v1 *= v2\n    assert str(v1) == \"[1.500000, -0.125000]\"\n    v2 /= v1\n    assert str(v2) == \"[2.000000, 8.000000]\"\n\n    cstats = ConstructorStats.get(m.Vector2)\n    assert cstats.alive() == 3\n    del v1\n    assert cstats.alive() == 2\n    del v2\n    assert cstats.alive() == 1\n    del v3\n    assert cstats.alive() == 0\n    assert cstats.values() == [\n        \"[1.000000, 2.000000]\",\n        \"[3.000000, -1.000000]\",\n        \"[1.000000, 2.000000]\",\n        \"[-3.000000, 1.000000]\",\n        \"[4.000000, 1.000000]\",\n        \"[-2.000000, 3.000000]\",\n        \"[-7.000000, -6.000000]\",\n        \"[9.000000, 10.000000]\",\n        \"[8.000000, 16.000000]\",\n        \"[0.125000, 0.250000]\",\n        \"[7.000000, 6.000000]\",\n        \"[9.000000, 10.000000]\",\n        \"[8.000000, 16.000000]\",\n        \"[8.000000, 4.000000]\",\n        \"[3.000000, -2.000000]\",\n        \"[3.000000, -0.500000]\",\n        \"[6.000000, -2.000000]\",\n    ]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 10\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_operators_notimplemented():\n    \"\"\"#393: need to return NotSupported to ensure correct arithmetic operator behavior\"\"\"\n\n    c1, c2 = m.C1(), m.C2()\n    assert c1 + c1 == 11\n    assert c2 + c2 == 22\n    assert c2 + c1 == 21\n    assert c1 + c2 == 12\n\n\ndef test_nested():\n    \"\"\"#328: first member in a class can't be used in operators\"\"\"\n\n    a = m.NestA()\n    b = m.NestB()\n    c = m.NestC()\n\n    a += 10\n    assert m.get_NestA(a) == 13\n    b.a += 100\n    assert m.get_NestA(b.a) == 103\n    c.b.a += 1000\n    assert m.get_NestA(c.b.a) == 1003\n    b -= 1\n    assert m.get_NestB(b) == 3\n    c.b -= 3\n    assert m.get_NestB(c.b) == 1\n    c *= 7\n    assert m.get_NestC(c) == 35\n\n    abase = a.as_base()\n    assert abase.value == -2\n    a.as_base().value += 44\n    assert abase.value == 42\n    assert c.b.a.as_base().value == -2\n    c.b.a.as_base().value += 44\n    assert c.b.a.as_base().value == 42\n\n    del c\n    pytest.gc_collect()\n    del a  # Shouldn't delete while abase is still alive\n    pytest.gc_collect()\n\n    assert abase.value == 42\n    del abase, b\n    pytest.gc_collect()\n\n\ndef test_overriding_eq_reset_hash():\n\n    assert m.Comparable(15) is not m.Comparable(15)\n    assert m.Comparable(15) == m.Comparable(15)\n\n    with pytest.raises(TypeError) as excinfo:\n        hash(m.Comparable(15))\n    assert str(excinfo.value).startswith(\"unhashable type:\")\n\n    for hashable in (m.Hashable, m.Hashable2):\n        assert hashable(15) is not hashable(15)\n        assert hashable(15) == hashable(15)\n\n        assert hash(hashable(15)) == 15\n        assert hash(hashable(15)) == hash(hashable(15))\n\n\ndef test_return_set_of_unhashable():\n    with pytest.raises(TypeError) as excinfo:\n        m.get_unhashable_HashMe_set()\n    if not env.PY2:\n        assert str(excinfo.value.__cause__).startswith(\"unhashable type:\")\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_pickling.cpp",
    "content": "// clang-format off\n/*\n    tests/test_pickling.cpp -- pickle support\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n    Copyright (c) 2021 The Pybind Development Team.\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n// clang-format on\n\n#include <memory>\n#include <stdexcept>\n#include <utility>\n\nnamespace exercise_trampoline {\n\nstruct SimpleBase {\n    int num = 0;\n    virtual ~SimpleBase() = default;\n\n    // For compatibility with old clang versions:\n    SimpleBase() = default;\n    SimpleBase(const SimpleBase &) = default;\n};\n\nstruct SimpleBaseTrampoline : SimpleBase {};\n\nstruct SimpleCppDerived : SimpleBase {};\n\nvoid wrap(py::module m) {\n    py::class_<SimpleBase, SimpleBaseTrampoline>(m, \"SimpleBase\")\n        .def(py::init<>())\n        .def_readwrite(\"num\", &SimpleBase::num)\n        .def(py::pickle(\n            [](const py::object &self) {\n                py::dict d;\n                if (py::hasattr(self, \"__dict__\")) {\n                    d = self.attr(\"__dict__\");\n                }\n                return py::make_tuple(self.attr(\"num\"), d);\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 2) {\n                    throw std::runtime_error(\"Invalid state!\");\n                }\n                auto cpp_state = std::unique_ptr<SimpleBase>(new SimpleBaseTrampoline);\n                cpp_state->num = t[0].cast<int>();\n                auto py_state = t[1].cast<py::dict>();\n                return std::make_pair(std::move(cpp_state), py_state);\n            }));\n\n    m.def(\"make_SimpleCppDerivedAsBase\",\n          []() { return std::unique_ptr<SimpleBase>(new SimpleCppDerived); });\n    m.def(\"check_dynamic_cast_SimpleCppDerived\", [](const SimpleBase *base_ptr) {\n        return dynamic_cast<const SimpleCppDerived *>(base_ptr) != nullptr;\n    });\n}\n\n} // namespace exercise_trampoline\n\n// clang-format off\n\nTEST_SUBMODULE(pickling, m) {\n    // test_roundtrip\n    class Pickleable {\n    public:\n        explicit Pickleable(const std::string &value) : m_value(value) { }\n        const std::string &value() const { return m_value; }\n\n        void setExtra1(int extra1) { m_extra1 = extra1; }\n        void setExtra2(int extra2) { m_extra2 = extra2; }\n        int extra1() const { return m_extra1; }\n        int extra2() const { return m_extra2; }\n    private:\n        std::string m_value;\n        int m_extra1 = 0;\n        int m_extra2 = 0;\n    };\n\n    class PickleableNew : public Pickleable {\n    public:\n        using Pickleable::Pickleable;\n    };\n\n    py::class_<Pickleable> pyPickleable(m, \"Pickleable\");\n    pyPickleable\n        .def(py::init<std::string>())\n        .def(\"value\", &Pickleable::value)\n        .def(\"extra1\", &Pickleable::extra1)\n        .def(\"extra2\", &Pickleable::extra2)\n        .def(\"setExtra1\", &Pickleable::setExtra1)\n        .def(\"setExtra2\", &Pickleable::setExtra2)\n        // For details on the methods below, refer to\n        // http://docs.python.org/3/library/pickle.html#pickling-class-instances\n        .def(\"__getstate__\", [](const Pickleable &p) {\n            /* Return a tuple that fully encodes the state of the object */\n            return py::make_tuple(p.value(), p.extra1(), p.extra2());\n        });\n    ignoreOldStyleInitWarnings([&pyPickleable]() {\n        pyPickleable.def(\"__setstate__\", [](Pickleable &p, const py::tuple &t) {\n            if (t.size() != 3) {\n                throw std::runtime_error(\"Invalid state!\");\n}\n            /* Invoke the constructor (need to use in-place version) */\n            new (&p) Pickleable(t[0].cast<std::string>());\n\n            /* Assign any additional state */\n            p.setExtra1(t[1].cast<int>());\n            p.setExtra2(t[2].cast<int>());\n        });\n    });\n\n    py::class_<PickleableNew, Pickleable>(m, \"PickleableNew\")\n        .def(py::init<std::string>())\n        .def(py::pickle(\n            [](const PickleableNew &p) {\n                return py::make_tuple(p.value(), p.extra1(), p.extra2());\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 3) {\n                    throw std::runtime_error(\"Invalid state!\");\n}\n                auto p = PickleableNew(t[0].cast<std::string>());\n\n                p.setExtra1(t[1].cast<int>());\n                p.setExtra2(t[2].cast<int>());\n                return p;\n            }));\n\n#if !defined(PYPY_VERSION)\n    // test_roundtrip_with_dict\n    class PickleableWithDict {\n    public:\n        explicit PickleableWithDict(const std::string &value) : value(value) { }\n\n        std::string value;\n        int extra;\n    };\n\n    class PickleableWithDictNew : public PickleableWithDict {\n    public:\n        using PickleableWithDict::PickleableWithDict;\n    };\n\n    py::class_<PickleableWithDict> pyPickleableWithDict(m, \"PickleableWithDict\", py::dynamic_attr());\n    pyPickleableWithDict.def(py::init<std::string>())\n        .def_readwrite(\"value\", &PickleableWithDict::value)\n        .def_readwrite(\"extra\", &PickleableWithDict::extra)\n        .def(\"__getstate__\", [](const py::object &self) {\n            /* Also include __dict__ in state */\n            return py::make_tuple(self.attr(\"value\"), self.attr(\"extra\"), self.attr(\"__dict__\"));\n        });\n    ignoreOldStyleInitWarnings([&pyPickleableWithDict]() {\n        pyPickleableWithDict.def(\"__setstate__\", [](const py::object &self, const py::tuple &t) {\n            if (t.size() != 3) {\n                throw std::runtime_error(\"Invalid state!\");\n}\n            /* Cast and construct */\n            auto &p = self.cast<PickleableWithDict &>();\n            new (&p) PickleableWithDict(t[0].cast<std::string>());\n\n            /* Assign C++ state */\n            p.extra = t[1].cast<int>();\n\n            /* Assign Python state */\n            self.attr(\"__dict__\") = t[2];\n        });\n    });\n\n    py::class_<PickleableWithDictNew, PickleableWithDict>(m, \"PickleableWithDictNew\")\n        .def(py::init<std::string>())\n        .def(py::pickle(\n            [](const py::object &self) {\n                return py::make_tuple(self.attr(\"value\"), self.attr(\"extra\"), self.attr(\"__dict__\"));\n            },\n            [](const py::tuple &t) {\n                if (t.size() != 3) {\n                    throw std::runtime_error(\"Invalid state!\");\n}\n\n                auto cpp_state = PickleableWithDictNew(t[0].cast<std::string>());\n                cpp_state.extra = t[1].cast<int>();\n\n                auto py_state = t[2].cast<py::dict>();\n                return std::make_pair(cpp_state, py_state);\n            }));\n#endif\n\n    exercise_trampoline::wrap(m);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_pickling.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import pickling as m\n\ntry:\n    import cPickle as pickle  # Use cPickle on Python 2.7\nexcept ImportError:\n    import pickle\n\n\n@pytest.mark.parametrize(\"cls_name\", [\"Pickleable\", \"PickleableNew\"])\ndef test_roundtrip(cls_name):\n    cls = getattr(m, cls_name)\n    p = cls(\"test_value\")\n    p.setExtra1(15)\n    p.setExtra2(48)\n\n    data = pickle.dumps(p, 2)  # Must use pickle protocol >= 2\n    p2 = pickle.loads(data)\n    assert p2.value() == p.value()\n    assert p2.extra1() == p.extra1()\n    assert p2.extra2() == p.extra2()\n\n\n@pytest.mark.xfail(\"env.PYPY\")\n@pytest.mark.parametrize(\"cls_name\", [\"PickleableWithDict\", \"PickleableWithDictNew\"])\ndef test_roundtrip_with_dict(cls_name):\n    cls = getattr(m, cls_name)\n    p = cls(\"test_value\")\n    p.extra = 15\n    p.dynamic = \"Attribute\"\n\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert p2.value == p.value\n    assert p2.extra == p.extra\n    assert p2.dynamic == p.dynamic\n\n\ndef test_enum_pickle():\n    from pybind11_tests import enums as e\n\n    data = pickle.dumps(e.EOne, 2)\n    assert e.EOne == pickle.loads(data)\n\n\n#\n# exercise_trampoline\n#\nclass SimplePyDerived(m.SimpleBase):\n    pass\n\n\ndef test_roundtrip_simple_py_derived():\n    p = SimplePyDerived()\n    p.num = 202\n    p.stored_in_dict = 303\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert isinstance(p2, SimplePyDerived)\n    assert p2.num == 202\n    assert p2.stored_in_dict == 303\n\n\ndef test_roundtrip_simple_cpp_derived():\n    p = m.make_SimpleCppDerivedAsBase()\n    assert m.check_dynamic_cast_SimpleCppDerived(p)\n    p.num = 404\n    if not env.PYPY:\n        # To ensure that this unit test is not accidentally invalidated.\n        with pytest.raises(AttributeError):\n            # Mimics the `setstate` C++ implementation.\n            setattr(p, \"__dict__\", {})  # noqa: B010\n    data = pickle.dumps(p, pickle.HIGHEST_PROTOCOL)\n    p2 = pickle.loads(data)\n    assert isinstance(p2, m.SimpleBase)\n    assert p2.num == 404\n    # Issue #3062: pickleable base C++ classes can incur object slicing\n    #              if derived typeid is not registered with pybind11\n    assert not m.check_dynamic_cast_SimpleCppDerived(p2)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_pytypes.cpp",
    "content": "/*\n    tests/test_pytypes.cpp -- Python type casters\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\n#include <utility>\n\nTEST_SUBMODULE(pytypes, m) {\n    // test_bool\n    m.def(\"get_bool\", [] { return py::bool_(false); });\n    // test_int\n    m.def(\"get_int\", [] { return py::int_(0); });\n    // test_iterator\n    m.def(\"get_iterator\", [] { return py::iterator(); });\n    // test_iterable\n    m.def(\"get_iterable\", [] { return py::iterable(); });\n    // test_float\n    m.def(\"get_float\", [] { return py::float_(0.0f); });\n    // test_list\n    m.def(\"list_no_args\", []() { return py::list{}; });\n    m.def(\"list_ssize_t\", []() { return py::list{(py::ssize_t) 0}; });\n    m.def(\"list_size_t\", []() { return py::list{(py::size_t) 0}; });\n    m.def(\"list_insert_ssize_t\", [](py::list *l) { return l->insert((py::ssize_t) 1, 83); });\n    m.def(\"list_insert_size_t\", [](py::list *l) { return l->insert((py::size_t) 3, 57); });\n    m.def(\"get_list\", []() {\n        py::list list;\n        list.append(\"value\");\n        py::print(\"Entry at position 0:\", list[0]);\n        list[0] = py::str(\"overwritten\");\n        list.insert(0, \"inserted-0\");\n        list.insert(2, \"inserted-2\");\n        return list;\n    });\n    m.def(\"print_list\", [](const py::list &list) {\n        int index = 0;\n        for (auto item : list) {\n            py::print(\"list item {}: {}\"_s.format(index++, item));\n        }\n    });\n    // test_none\n    m.def(\"get_none\", [] { return py::none(); });\n    m.def(\"print_none\", [](const py::none &none) { py::print(\"none: {}\"_s.format(none)); });\n\n    // test_set\n    m.def(\"get_set\", []() {\n        py::set set;\n        set.add(py::str(\"key1\"));\n        set.add(\"key2\");\n        set.add(std::string(\"key3\"));\n        return set;\n    });\n    m.def(\"print_set\", [](const py::set &set) {\n        for (auto item : set) {\n            py::print(\"key:\", item);\n        }\n    });\n    m.def(\"set_contains\",\n          [](const py::set &set, const py::object &key) { return set.contains(key); });\n    m.def(\"set_contains\", [](const py::set &set, const char *key) { return set.contains(key); });\n\n    // test_dict\n    m.def(\"get_dict\", []() { return py::dict(\"key\"_a = \"value\"); });\n    m.def(\"print_dict\", [](const py::dict &dict) {\n        for (auto item : dict) {\n            py::print(\"key: {}, value={}\"_s.format(item.first, item.second));\n        }\n    });\n    m.def(\"dict_keyword_constructor\", []() {\n        auto d1 = py::dict(\"x\"_a = 1, \"y\"_a = 2);\n        auto d2 = py::dict(\"z\"_a = 3, **d1);\n        return d2;\n    });\n    m.def(\"dict_contains\",\n          [](const py::dict &dict, py::object val) { return dict.contains(val); });\n    m.def(\"dict_contains\",\n          [](const py::dict &dict, const char *val) { return dict.contains(val); });\n\n    // test_tuple\n    m.def(\"tuple_no_args\", []() { return py::tuple{}; });\n    m.def(\"tuple_ssize_t\", []() { return py::tuple{(py::ssize_t) 0}; });\n    m.def(\"tuple_size_t\", []() { return py::tuple{(py::size_t) 0}; });\n    m.def(\"get_tuple\", []() { return py::make_tuple(42, py::none(), \"spam\"); });\n\n#if PY_VERSION_HEX >= 0x03030000\n    // test_simple_namespace\n    m.def(\"get_simple_namespace\", []() {\n        auto ns = py::module_::import(\"types\").attr(\"SimpleNamespace\")(\n            \"attr\"_a = 42, \"x\"_a = \"foo\", \"wrong\"_a = 1);\n        py::delattr(ns, \"wrong\");\n        py::setattr(ns, \"right\", py::int_(2));\n        return ns;\n    });\n#endif\n\n    // test_str\n    m.def(\"str_from_char_ssize_t\", []() { return py::str{\"red\", (py::ssize_t) 3}; });\n    m.def(\"str_from_char_size_t\", []() { return py::str{\"blue\", (py::size_t) 4}; });\n    m.def(\"str_from_string\", []() { return py::str(std::string(\"baz\")); });\n    m.def(\"str_from_bytes\", []() { return py::str(py::bytes(\"boo\", 3)); });\n    m.def(\"str_from_object\", [](const py::object &obj) { return py::str(obj); });\n    m.def(\"repr_from_object\", [](const py::object &obj) { return py::repr(obj); });\n    m.def(\"str_from_handle\", [](py::handle h) { return py::str(h); });\n    m.def(\"str_from_string_from_str\",\n          [](const py::str &obj) { return py::str(static_cast<std::string>(obj)); });\n\n    m.def(\"str_format\", []() {\n        auto s1 = \"{} + {} = {}\"_s.format(1, 2, 3);\n        auto s2 = \"{a} + {b} = {c}\"_s.format(\"a\"_a = 1, \"b\"_a = 2, \"c\"_a = 3);\n        return py::make_tuple(s1, s2);\n    });\n\n    // test_bytes\n    m.def(\"bytes_from_char_ssize_t\", []() { return py::bytes{\"green\", (py::ssize_t) 5}; });\n    m.def(\"bytes_from_char_size_t\", []() { return py::bytes{\"purple\", (py::size_t) 6}; });\n    m.def(\"bytes_from_string\", []() { return py::bytes(std::string(\"foo\")); });\n    m.def(\"bytes_from_str\", []() { return py::bytes(py::str(\"bar\", 3)); });\n\n    // test bytearray\n    m.def(\"bytearray_from_char_ssize_t\", []() { return py::bytearray{\"$%\", (py::ssize_t) 2}; });\n    m.def(\"bytearray_from_char_size_t\", []() { return py::bytearray{\"@$!\", (py::size_t) 3}; });\n    m.def(\"bytearray_from_string\", []() { return py::bytearray(std::string(\"foo\")); });\n    m.def(\"bytearray_size\", []() { return py::bytearray(\"foo\").size(); });\n\n    // test_capsule\n    m.def(\"return_capsule_with_destructor\", []() {\n        py::print(\"creating capsule\");\n        return py::capsule([]() { py::print(\"destructing capsule\"); });\n    });\n\n    m.def(\"return_capsule_with_destructor_2\", []() {\n        py::print(\"creating capsule\");\n        return py::capsule((void *) 1234, [](void *ptr) {\n            py::print(\"destructing capsule: {}\"_s.format((size_t) ptr));\n        });\n    });\n\n    m.def(\"return_capsule_with_name_and_destructor\", []() {\n        auto capsule = py::capsule((void *) 12345, \"pointer type description\", [](PyObject *ptr) {\n            if (ptr) {\n                const auto *name = PyCapsule_GetName(ptr);\n                py::print(\"destructing capsule ({}, '{}')\"_s.format(\n                    (size_t) PyCapsule_GetPointer(ptr, name), name));\n            }\n        });\n\n        capsule.set_pointer((void *) 1234);\n\n        // Using get_pointer<T>()\n        void *contents1 = static_cast<void *>(capsule);\n        void *contents2 = capsule.get_pointer();\n        void *contents3 = capsule.get_pointer<void>();\n\n        auto result1 = reinterpret_cast<size_t>(contents1);\n        auto result2 = reinterpret_cast<size_t>(contents2);\n        auto result3 = reinterpret_cast<size_t>(contents3);\n\n        py::print(\n            \"created capsule ({}, '{}')\"_s.format(result1 & result2 & result3, capsule.name()));\n        return capsule;\n    });\n\n    // test_accessors\n    m.def(\"accessor_api\", [](const py::object &o) {\n        auto d = py::dict();\n\n        d[\"basic_attr\"] = o.attr(\"basic_attr\");\n\n        auto l = py::list();\n        for (auto item : o.attr(\"begin_end\")) {\n            l.append(item);\n        }\n        d[\"begin_end\"] = l;\n\n        d[\"operator[object]\"] = o.attr(\"d\")[\"operator[object]\"_s];\n        d[\"operator[char *]\"] = o.attr(\"d\")[\"operator[char *]\"];\n\n        d[\"attr(object)\"] = o.attr(\"sub\").attr(\"attr_obj\");\n        d[\"attr(char *)\"] = o.attr(\"sub\").attr(\"attr_char\");\n        try {\n            o.attr(\"sub\").attr(\"missing\").ptr();\n        } catch (const py::error_already_set &) {\n            d[\"missing_attr_ptr\"] = \"raised\"_s;\n        }\n        try {\n            o.attr(\"missing\").attr(\"doesn't matter\");\n        } catch (const py::error_already_set &) {\n            d[\"missing_attr_chain\"] = \"raised\"_s;\n        }\n\n        d[\"is_none\"] = o.attr(\"basic_attr\").is_none();\n\n        d[\"operator()\"] = o.attr(\"func\")(1);\n        d[\"operator*\"] = o.attr(\"func\")(*o.attr(\"begin_end\"));\n\n        // Test implicit conversion\n        py::list implicit_list = o.attr(\"begin_end\");\n        d[\"implicit_list\"] = implicit_list;\n        py::dict implicit_dict = o.attr(\"__dict__\");\n        d[\"implicit_dict\"] = implicit_dict;\n\n        return d;\n    });\n\n    m.def(\"tuple_accessor\", [](const py::tuple &existing_t) {\n        try {\n            existing_t[0] = 1;\n        } catch (const py::error_already_set &) {\n            // --> Python system error\n            // Only new tuples (refcount == 1) are mutable\n            auto new_t = py::tuple(3);\n            for (size_t i = 0; i < new_t.size(); ++i) {\n                new_t[i] = i;\n            }\n            return new_t;\n        }\n        return py::tuple();\n    });\n\n    m.def(\"accessor_assignment\", []() {\n        auto l = py::list(1);\n        l[0] = 0;\n\n        auto d = py::dict();\n        d[\"get\"] = l[0];\n        auto var = l[0];\n        d[\"deferred_get\"] = var;\n        l[0] = 1;\n        d[\"set\"] = l[0];\n        var = 99; // this assignment should not overwrite l[0]\n        d[\"deferred_set\"] = l[0];\n        d[\"var\"] = var;\n\n        return d;\n    });\n\n    // test_constructors\n    m.def(\"default_constructors\", []() {\n        return py::dict(\"bytes\"_a = py::bytes(),\n                        \"bytearray\"_a = py::bytearray(),\n                        \"str\"_a = py::str(),\n                        \"bool\"_a = py::bool_(),\n                        \"int\"_a = py::int_(),\n                        \"float\"_a = py::float_(),\n                        \"tuple\"_a = py::tuple(),\n                        \"list\"_a = py::list(),\n                        \"dict\"_a = py::dict(),\n                        \"set\"_a = py::set());\n    });\n\n    m.def(\"converting_constructors\", [](const py::dict &d) {\n        return py::dict(\"bytes\"_a = py::bytes(d[\"bytes\"]),\n                        \"bytearray\"_a = py::bytearray(d[\"bytearray\"]),\n                        \"str\"_a = py::str(d[\"str\"]),\n                        \"bool\"_a = py::bool_(d[\"bool\"]),\n                        \"int\"_a = py::int_(d[\"int\"]),\n                        \"float\"_a = py::float_(d[\"float\"]),\n                        \"tuple\"_a = py::tuple(d[\"tuple\"]),\n                        \"list\"_a = py::list(d[\"list\"]),\n                        \"dict\"_a = py::dict(d[\"dict\"]),\n                        \"set\"_a = py::set(d[\"set\"]),\n                        \"memoryview\"_a = py::memoryview(d[\"memoryview\"]));\n    });\n\n    m.def(\"cast_functions\", [](const py::dict &d) {\n        // When converting between Python types, obj.cast<T>() should be the same as T(obj)\n        return py::dict(\"bytes\"_a = d[\"bytes\"].cast<py::bytes>(),\n                        \"bytearray\"_a = d[\"bytearray\"].cast<py::bytearray>(),\n                        \"str\"_a = d[\"str\"].cast<py::str>(),\n                        \"bool\"_a = d[\"bool\"].cast<py::bool_>(),\n                        \"int\"_a = d[\"int\"].cast<py::int_>(),\n                        \"float\"_a = d[\"float\"].cast<py::float_>(),\n                        \"tuple\"_a = d[\"tuple\"].cast<py::tuple>(),\n                        \"list\"_a = d[\"list\"].cast<py::list>(),\n                        \"dict\"_a = d[\"dict\"].cast<py::dict>(),\n                        \"set\"_a = d[\"set\"].cast<py::set>(),\n                        \"memoryview\"_a = d[\"memoryview\"].cast<py::memoryview>());\n    });\n\n    m.def(\"convert_to_pybind11_str\", [](const py::object &o) { return py::str(o); });\n\n    m.def(\"nonconverting_constructor\",\n          [](const std::string &type, py::object value, bool move) -> py::object {\n              if (type == \"bytes\") {\n                  return move ? py::bytes(std::move(value)) : py::bytes(value);\n              }\n              if (type == \"none\") {\n                  return move ? py::none(std::move(value)) : py::none(value);\n              }\n              if (type == \"ellipsis\") {\n                  return move ? py::ellipsis(std::move(value)) : py::ellipsis(value);\n              }\n              if (type == \"type\") {\n                  return move ? py::type(std::move(value)) : py::type(value);\n              }\n              throw std::runtime_error(\"Invalid type\");\n          });\n\n    m.def(\"get_implicit_casting\", []() {\n        py::dict d;\n        d[\"char*_i1\"] = \"abc\";\n        const char *c2 = \"abc\";\n        d[\"char*_i2\"] = c2;\n        d[\"char*_e\"] = py::cast(c2);\n        d[\"char*_p\"] = py::str(c2);\n\n        d[\"int_i1\"] = 42;\n        int i = 42;\n        d[\"int_i2\"] = i;\n        i++;\n        d[\"int_e\"] = py::cast(i);\n        i++;\n        d[\"int_p\"] = py::int_(i);\n\n        d[\"str_i1\"] = std::string(\"str\");\n        std::string s2(\"str1\");\n        d[\"str_i2\"] = s2;\n        s2[3] = '2';\n        d[\"str_e\"] = py::cast(s2);\n        s2[3] = '3';\n        d[\"str_p\"] = py::str(s2);\n\n        py::list l(2);\n        l[0] = 3;\n        l[1] = py::cast(6);\n        l.append(9);\n        l.append(py::cast(12));\n        l.append(py::int_(15));\n\n        return py::dict(\"d\"_a = d, \"l\"_a = l);\n    });\n\n    // test_print\n    m.def(\"print_function\", []() {\n        py::print(\"Hello, World!\");\n        py::print(1, 2.0, \"three\", true, std::string(\"-- multiple args\"));\n        auto args = py::make_tuple(\"and\", \"a\", \"custom\", \"separator\");\n        py::print(\"*args\", *args, \"sep\"_a = \"-\");\n        py::print(\"no new line here\", \"end\"_a = \" -- \");\n        py::print(\"next print\");\n\n        auto py_stderr = py::module_::import(\"sys\").attr(\"stderr\");\n        py::print(\"this goes to stderr\", \"file\"_a = py_stderr);\n\n        py::print(\"flush\", \"flush\"_a = true);\n\n        py::print(\n            \"{a} + {b} = {c}\"_s.format(\"a\"_a = \"py::print\", \"b\"_a = \"str.format\", \"c\"_a = \"this\"));\n    });\n\n    m.def(\"print_failure\", []() { py::print(42, UnregisteredType()); });\n\n    m.def(\"hash_function\", [](py::object obj) { return py::hash(std::move(obj)); });\n\n    m.def(\"test_number_protocol\", [](const py::object &a, const py::object &b) {\n        py::list l;\n        l.append(a.equal(b));\n        l.append(a.not_equal(b));\n        l.append(a < b);\n        l.append(a <= b);\n        l.append(a > b);\n        l.append(a >= b);\n        l.append(a + b);\n        l.append(a - b);\n        l.append(a * b);\n        l.append(a / b);\n        l.append(a | b);\n        l.append(a & b);\n        l.append(a ^ b);\n        l.append(a >> b);\n        l.append(a << b);\n        return l;\n    });\n\n    m.def(\"test_list_slicing\", [](const py::list &a) { return a[py::slice(0, -1, 2)]; });\n\n    // See #2361\n    m.def(\"issue2361_str_implicit_copy_none\", []() {\n        py::str is_this_none = py::none();\n        return is_this_none;\n    });\n    m.def(\"issue2361_dict_implicit_copy_none\", []() {\n        py::dict is_this_none = py::none();\n        return is_this_none;\n    });\n\n    m.def(\"test_memoryview_object\", [](const py::buffer &b) { return py::memoryview(b); });\n\n    m.def(\"test_memoryview_buffer_info\",\n          [](const py::buffer &b) { return py::memoryview(b.request()); });\n\n    m.def(\"test_memoryview_from_buffer\", [](bool is_unsigned) {\n        static const int16_t si16[] = {3, 1, 4, 1, 5};\n        static const uint16_t ui16[] = {2, 7, 1, 8};\n        if (is_unsigned) {\n            return py::memoryview::from_buffer(ui16, {4}, {sizeof(uint16_t)});\n        }\n        return py::memoryview::from_buffer(si16, {5}, {sizeof(int16_t)});\n    });\n\n    m.def(\"test_memoryview_from_buffer_nativeformat\", []() {\n        static const char *format = \"@i\";\n        static const int32_t arr[] = {4, 7, 5};\n        return py::memoryview::from_buffer(arr, sizeof(int32_t), format, {3}, {sizeof(int32_t)});\n    });\n\n    m.def(\"test_memoryview_from_buffer_empty_shape\", []() {\n        static const char *buf = \"\";\n        return py::memoryview::from_buffer(buf, 1, \"B\", {}, {});\n    });\n\n    m.def(\"test_memoryview_from_buffer_invalid_strides\", []() {\n        static const char *buf = \"\\x02\\x03\\x04\";\n        return py::memoryview::from_buffer(buf, 1, \"B\", {3}, {});\n    });\n\n    m.def(\"test_memoryview_from_buffer_nullptr\", []() {\n        return py::memoryview::from_buffer(static_cast<void *>(nullptr), 1, \"B\", {}, {});\n    });\n\n#if PY_MAJOR_VERSION >= 3\n    m.def(\"test_memoryview_from_memory\", []() {\n        const char *buf = \"\\xff\\xe1\\xab\\x37\";\n        return py::memoryview::from_memory(buf, static_cast<py::ssize_t>(strlen(buf)));\n    });\n#endif\n\n    // test_builtin_functions\n    m.def(\"get_len\", [](py::handle h) { return py::len(h); });\n\n#ifdef PYBIND11_STR_LEGACY_PERMISSIVE\n    m.attr(\"PYBIND11_STR_LEGACY_PERMISSIVE\") = true;\n#endif\n\n    m.def(\"isinstance_pybind11_bytes\",\n          [](py::object o) { return py::isinstance<py::bytes>(std::move(o)); });\n    m.def(\"isinstance_pybind11_str\",\n          [](py::object o) { return py::isinstance<py::str>(std::move(o)); });\n\n    m.def(\"pass_to_pybind11_bytes\", [](py::bytes b) { return py::len(std::move(b)); });\n    m.def(\"pass_to_pybind11_str\", [](py::str s) { return py::len(std::move(s)); });\n    m.def(\"pass_to_std_string\", [](const std::string &s) { return s.size(); });\n\n    // test_weakref\n    m.def(\"weakref_from_handle\", [](py::handle h) { return py::weakref(h); });\n    m.def(\"weakref_from_handle_and_function\",\n          [](py::handle h, py::function f) { return py::weakref(h, std::move(f)); });\n    m.def(\"weakref_from_object\", [](const py::object &o) { return py::weakref(o); });\n    m.def(\"weakref_from_object_and_function\",\n          [](py::object o, py::function f) { return py::weakref(std::move(o), std::move(f)); });\n\n// See PR #3263 for background (https://github.com/pybind/pybind11/pull/3263):\n// pytypes.h could be changed to enforce the \"most correct\" user code below, by removing\n// `const` from iterator `reference` using type aliases, but that will break existing\n// user code.\n#if (defined(__APPLE__) && defined(__clang__)) || defined(PYPY_VERSION)\n// This is \"most correct\" and enforced on these platforms.\n#    define PYBIND11_AUTO_IT auto it\n#else\n// This works on many platforms and is (unfortunately) reflective of existing user code.\n// NOLINTNEXTLINE(bugprone-macro-parentheses)\n#    define PYBIND11_AUTO_IT auto &it\n#endif\n\n    m.def(\"tuple_iterator\", []() {\n        auto tup = py::make_tuple(5, 7);\n        int tup_sum = 0;\n        for (PYBIND11_AUTO_IT : tup) {\n            tup_sum += it.cast<int>();\n        }\n        return tup_sum;\n    });\n\n    m.def(\"dict_iterator\", []() {\n        py::dict dct;\n        dct[py::int_(3)] = 5;\n        dct[py::int_(7)] = 11;\n        int kv_sum = 0;\n        for (PYBIND11_AUTO_IT : dct) {\n            kv_sum += it.first.cast<int>() * 100 + it.second.cast<int>();\n        }\n        return kv_sum;\n    });\n\n    m.def(\"passed_iterator\", [](const py::iterator &py_it) {\n        int elem_sum = 0;\n        for (PYBIND11_AUTO_IT : py_it) {\n            elem_sum += it.cast<int>();\n        }\n        return elem_sum;\n    });\n\n#undef PYBIND11_AUTO_IT\n\n    // Tests below this line are for pybind11 IMPLEMENTATION DETAILS:\n\n    m.def(\"sequence_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::sequence_item::get(o, (py::ssize_t) 1);\n    });\n    m.def(\"sequence_item_set_ssize_t\", [](const py::object &o) {\n        auto s = py::str{\"peppa\", 5};\n        py::detail::accessor_policies::sequence_item::set(o, (py::ssize_t) 1, s);\n    });\n    m.def(\"sequence_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::sequence_item::get(o, (py::size_t) 2);\n    });\n    m.def(\"sequence_item_set_size_t\", [](const py::object &o) {\n        auto s = py::str{\"george\", 6};\n        py::detail::accessor_policies::sequence_item::set(o, (py::size_t) 2, s);\n    });\n    m.def(\"list_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::list_item::get(o, (py::ssize_t) 3);\n    });\n    m.def(\"list_item_set_ssize_t\", [](const py::object &o) {\n        auto s = py::str{\"rebecca\", 7};\n        py::detail::accessor_policies::list_item::set(o, (py::ssize_t) 3, s);\n    });\n    m.def(\"list_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::list_item::get(o, (py::size_t) 4);\n    });\n    m.def(\"list_item_set_size_t\", [](const py::object &o) {\n        auto s = py::str{\"richard\", 7};\n        py::detail::accessor_policies::list_item::set(o, (py::size_t) 4, s);\n    });\n    m.def(\"tuple_item_get_ssize_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::tuple_item::get(o, (py::ssize_t) 5);\n    });\n    m.def(\"tuple_item_set_ssize_t\", []() {\n        auto s0 = py::str{\"emely\", 5};\n        auto s1 = py::str{\"edmond\", 6};\n        auto o = py::tuple{2};\n        py::detail::accessor_policies::tuple_item::set(o, (py::ssize_t) 0, s0);\n        py::detail::accessor_policies::tuple_item::set(o, (py::ssize_t) 1, s1);\n        return o;\n    });\n    m.def(\"tuple_item_get_size_t\", [](const py::object &o) {\n        return py::detail::accessor_policies::tuple_item::get(o, (py::size_t) 6);\n    });\n    m.def(\"tuple_item_set_size_t\", []() {\n        auto s0 = py::str{\"candy\", 5};\n        auto s1 = py::str{\"cat\", 3};\n        auto o = py::tuple{2};\n        py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 1, s1);\n        py::detail::accessor_policies::tuple_item::set(o, (py::size_t) 0, s0);\n        return o;\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_pytypes.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import division\n\nimport sys\n\nimport pytest\n\nimport env\nfrom pybind11_tests import debug_enabled\nfrom pybind11_tests import pytypes as m\n\n\ndef test_bool(doc):\n    assert doc(m.get_bool) == \"get_bool() -> bool\"\n\n\ndef test_int(doc):\n    assert doc(m.get_int) == \"get_int() -> int\"\n\n\ndef test_iterator(doc):\n    assert doc(m.get_iterator) == \"get_iterator() -> Iterator\"\n\n\ndef test_iterable(doc):\n    assert doc(m.get_iterable) == \"get_iterable() -> Iterable\"\n\n\ndef test_float(doc):\n    assert doc(m.get_float) == \"get_float() -> float\"\n\n\ndef test_list(capture, doc):\n    assert m.list_no_args() == []\n    assert m.list_ssize_t() == []\n    assert m.list_size_t() == []\n    lins = [1, 2]\n    m.list_insert_ssize_t(lins)\n    assert lins == [1, 83, 2]\n    m.list_insert_size_t(lins)\n    assert lins == [1, 83, 2, 57]\n\n    with capture:\n        lst = m.get_list()\n        assert lst == [\"inserted-0\", \"overwritten\", \"inserted-2\"]\n\n        lst.append(\"value2\")\n        m.print_list(lst)\n    assert (\n        capture.unordered\n        == \"\"\"\n        Entry at position 0: value\n        list item 0: inserted-0\n        list item 1: overwritten\n        list item 2: inserted-2\n        list item 3: value2\n    \"\"\"\n    )\n\n    assert doc(m.get_list) == \"get_list() -> list\"\n    assert doc(m.print_list) == \"print_list(arg0: list) -> None\"\n\n\ndef test_none(capture, doc):\n    assert doc(m.get_none) == \"get_none() -> None\"\n    assert doc(m.print_none) == \"print_none(arg0: None) -> None\"\n\n\ndef test_set(capture, doc):\n    s = m.get_set()\n    assert s == {\"key1\", \"key2\", \"key3\"}\n\n    with capture:\n        s.add(\"key4\")\n        m.print_set(s)\n    assert (\n        capture.unordered\n        == \"\"\"\n        key: key1\n        key: key2\n        key: key3\n        key: key4\n    \"\"\"\n    )\n\n    assert not m.set_contains(set(), 42)\n    assert m.set_contains({42}, 42)\n    assert m.set_contains({\"foo\"}, \"foo\")\n\n    assert doc(m.get_list) == \"get_list() -> list\"\n    assert doc(m.print_list) == \"print_list(arg0: list) -> None\"\n\n\ndef test_dict(capture, doc):\n    d = m.get_dict()\n    assert d == {\"key\": \"value\"}\n\n    with capture:\n        d[\"key2\"] = \"value2\"\n        m.print_dict(d)\n    assert (\n        capture.unordered\n        == \"\"\"\n        key: key, value=value\n        key: key2, value=value2\n    \"\"\"\n    )\n\n    assert not m.dict_contains({}, 42)\n    assert m.dict_contains({42: None}, 42)\n    assert m.dict_contains({\"foo\": None}, \"foo\")\n\n    assert doc(m.get_dict) == \"get_dict() -> dict\"\n    assert doc(m.print_dict) == \"print_dict(arg0: dict) -> None\"\n\n    assert m.dict_keyword_constructor() == {\"x\": 1, \"y\": 2, \"z\": 3}\n\n\ndef test_tuple():\n    assert m.tuple_no_args() == ()\n    assert m.tuple_ssize_t() == ()\n    assert m.tuple_size_t() == ()\n    assert m.get_tuple() == (42, None, \"spam\")\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_simple_namespace():\n    ns = m.get_simple_namespace()\n    assert ns.attr == 42\n    assert ns.x == \"foo\"\n    assert ns.right == 2\n    assert not hasattr(ns, \"wrong\")\n\n\ndef test_str(doc):\n    assert m.str_from_char_ssize_t().encode().decode() == \"red\"\n    assert m.str_from_char_size_t().encode().decode() == \"blue\"\n    assert m.str_from_string().encode().decode() == \"baz\"\n    assert m.str_from_bytes().encode().decode() == \"boo\"\n\n    assert doc(m.str_from_bytes) == \"str_from_bytes() -> str\"\n\n    class A(object):\n        def __str__(self):\n            return \"this is a str\"\n\n        def __repr__(self):\n            return \"this is a repr\"\n\n    assert m.str_from_object(A()) == \"this is a str\"\n    assert m.repr_from_object(A()) == \"this is a repr\"\n    assert m.str_from_handle(A()) == \"this is a str\"\n\n    s1, s2 = m.str_format()\n    assert s1 == \"1 + 2 = 3\"\n    assert s1 == s2\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.str_from_object(malformed_utf8) is malformed_utf8\n    elif env.PY2:\n        with pytest.raises(UnicodeDecodeError):\n            m.str_from_object(malformed_utf8)\n    else:\n        assert m.str_from_object(malformed_utf8) == \"b'\\\\x80'\"\n    if env.PY2:\n        with pytest.raises(UnicodeDecodeError):\n            m.str_from_handle(malformed_utf8)\n    else:\n        assert m.str_from_handle(malformed_utf8) == \"b'\\\\x80'\"\n\n    assert m.str_from_string_from_str(\"this is a str\") == \"this is a str\"\n    ucs_surrogates_str = u\"\\udcc3\"\n    if env.PY2:\n        assert u\"\\udcc3\" == m.str_from_string_from_str(ucs_surrogates_str)\n    else:\n        with pytest.raises(UnicodeEncodeError):\n            m.str_from_string_from_str(ucs_surrogates_str)\n\n\ndef test_bytes(doc):\n    assert m.bytes_from_char_ssize_t().decode() == \"green\"\n    assert m.bytes_from_char_size_t().decode() == \"purple\"\n    assert m.bytes_from_string().decode() == \"foo\"\n    assert m.bytes_from_str().decode() == \"bar\"\n\n    assert doc(m.bytes_from_str) == \"bytes_from_str() -> {}\".format(\n        \"str\" if env.PY2 else \"bytes\"\n    )\n\n\ndef test_bytearray(doc):\n    assert m.bytearray_from_char_ssize_t().decode() == \"$%\"\n    assert m.bytearray_from_char_size_t().decode() == \"@$!\"\n    assert m.bytearray_from_string().decode() == \"foo\"\n    assert m.bytearray_size() == len(\"foo\")\n\n\ndef test_capsule(capture):\n    pytest.gc_collect()\n    with capture:\n        a = m.return_capsule_with_destructor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        destructing capsule\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_capsule_with_destructor_2()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        creating capsule\n        destructing capsule: 1234\n    \"\"\"\n    )\n\n    with capture:\n        a = m.return_capsule_with_name_and_destructor()\n        del a\n        pytest.gc_collect()\n    assert (\n        capture.unordered\n        == \"\"\"\n        created capsule (1234, 'pointer type description')\n        destructing capsule (1234, 'pointer type description')\n    \"\"\"\n    )\n\n\ndef test_accessors():\n    class SubTestObject:\n        attr_obj = 1\n        attr_char = 2\n\n    class TestObject:\n        basic_attr = 1\n        begin_end = [1, 2, 3]\n        d = {\"operator[object]\": 1, \"operator[char *]\": 2}\n        sub = SubTestObject()\n\n        def func(self, x, *args):\n            return self.basic_attr + x + sum(args)\n\n    d = m.accessor_api(TestObject())\n    assert d[\"basic_attr\"] == 1\n    assert d[\"begin_end\"] == [1, 2, 3]\n    assert d[\"operator[object]\"] == 1\n    assert d[\"operator[char *]\"] == 2\n    assert d[\"attr(object)\"] == 1\n    assert d[\"attr(char *)\"] == 2\n    assert d[\"missing_attr_ptr\"] == \"raised\"\n    assert d[\"missing_attr_chain\"] == \"raised\"\n    assert d[\"is_none\"] is False\n    assert d[\"operator()\"] == 2\n    assert d[\"operator*\"] == 7\n    assert d[\"implicit_list\"] == [1, 2, 3]\n    assert all(x in TestObject.__dict__ for x in d[\"implicit_dict\"])\n\n    assert m.tuple_accessor(tuple()) == (0, 1, 2)\n\n    d = m.accessor_assignment()\n    assert d[\"get\"] == 0\n    assert d[\"deferred_get\"] == 0\n    assert d[\"set\"] == 1\n    assert d[\"deferred_set\"] == 1\n    assert d[\"var\"] == 99\n\n\ndef test_constructors():\n    \"\"\"C++ default and converting constructors are equivalent to type calls in Python\"\"\"\n    types = [bytes, bytearray, str, bool, int, float, tuple, list, dict, set]\n    expected = {t.__name__: t() for t in types}\n    if env.PY2:\n        # Note that bytes.__name__ == 'str' in Python 2.\n        # pybind11::str is unicode even under Python 2.\n        expected[\"bytes\"] = bytes()\n        expected[\"str\"] = unicode()  # noqa: F821\n    assert m.default_constructors() == expected\n\n    data = {\n        bytes: b\"41\",  # Currently no supported or working conversions.\n        bytearray: bytearray(b\"41\"),\n        str: 42,\n        bool: \"Not empty\",\n        int: \"42\",\n        float: \"+1e3\",\n        tuple: range(3),\n        list: range(3),\n        dict: [(\"two\", 2), (\"one\", 1), (\"three\", 3)],\n        set: [4, 4, 5, 6, 6, 6],\n        memoryview: b\"abc\",\n    }\n    inputs = {k.__name__: v for k, v in data.items()}\n    expected = {k.__name__: k(v) for k, v in data.items()}\n    if env.PY2:  # Similar to the above. See comments above.\n        inputs[\"bytes\"] = b\"41\"\n        inputs[\"str\"] = 42\n        expected[\"bytes\"] = b\"41\"\n        expected[\"str\"] = u\"42\"\n\n    assert m.converting_constructors(inputs) == expected\n    assert m.cast_functions(inputs) == expected\n\n    # Converting constructors and cast functions should just reference rather\n    # than copy when no conversion is needed:\n    noconv1 = m.converting_constructors(expected)\n    for k in noconv1:\n        assert noconv1[k] is expected[k]\n\n    noconv2 = m.cast_functions(expected)\n    for k in noconv2:\n        assert noconv2[k] is expected[k]\n\n\ndef test_non_converting_constructors():\n    non_converting_test_cases = [\n        (\"bytes\", range(10)),\n        (\"none\", 42),\n        (\"ellipsis\", 42),\n        (\"type\", 42),\n    ]\n    for t, v in non_converting_test_cases:\n        for move in [True, False]:\n            with pytest.raises(TypeError) as excinfo:\n                m.nonconverting_constructor(t, v, move)\n            expected_error = \"Object of type '{}' is not an instance of '{}'\".format(\n                type(v).__name__, t\n            )\n            assert str(excinfo.value) == expected_error\n\n\ndef test_pybind11_str_raw_str():\n    # specifically to exercise pybind11::str::raw_str\n    cvt = m.convert_to_pybind11_str\n    assert cvt(u\"Str\") == u\"Str\"\n    assert cvt(b\"Bytes\") == u\"Bytes\" if env.PY2 else \"b'Bytes'\"\n    assert cvt(None) == u\"None\"\n    assert cvt(False) == u\"False\"\n    assert cvt(True) == u\"True\"\n    assert cvt(42) == u\"42\"\n    assert cvt(2 ** 65) == u\"36893488147419103232\"\n    assert cvt(-1.50) == u\"-1.5\"\n    assert cvt(()) == u\"()\"\n    assert cvt((18,)) == u\"(18,)\"\n    assert cvt([]) == u\"[]\"\n    assert cvt([28]) == u\"[28]\"\n    assert cvt({}) == u\"{}\"\n    assert cvt({3: 4}) == u\"{3: 4}\"\n    assert cvt(set()) == u\"set([])\" if env.PY2 else \"set()\"\n    assert cvt({3, 3}) == u\"set([3])\" if env.PY2 else \"{3}\"\n\n    valid_orig = u\"Ǳ\"\n    valid_utf8 = valid_orig.encode(\"utf-8\")\n    valid_cvt = cvt(valid_utf8)\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert valid_cvt is valid_utf8\n    else:\n        assert type(valid_cvt) is unicode if env.PY2 else str  # noqa: F821\n        if env.PY2:\n            assert valid_cvt == valid_orig\n        else:\n            assert valid_cvt == \"b'\\\\xc7\\\\xb1'\"\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert cvt(malformed_utf8) is malformed_utf8\n    else:\n        if env.PY2:\n            with pytest.raises(UnicodeDecodeError):\n                cvt(malformed_utf8)\n        else:\n            malformed_cvt = cvt(malformed_utf8)\n            assert type(malformed_cvt) is str\n            assert malformed_cvt == \"b'\\\\x80'\"\n\n\ndef test_implicit_casting():\n    \"\"\"Tests implicit casting when assigning or appending to dicts and lists.\"\"\"\n    z = m.get_implicit_casting()\n    assert z[\"d\"] == {\n        \"char*_i1\": \"abc\",\n        \"char*_i2\": \"abc\",\n        \"char*_e\": \"abc\",\n        \"char*_p\": \"abc\",\n        \"str_i1\": \"str\",\n        \"str_i2\": \"str1\",\n        \"str_e\": \"str2\",\n        \"str_p\": \"str3\",\n        \"int_i1\": 42,\n        \"int_i2\": 42,\n        \"int_e\": 43,\n        \"int_p\": 44,\n    }\n    assert z[\"l\"] == [3, 6, 9, 12, 15]\n\n\ndef test_print(capture):\n    with capture:\n        m.print_function()\n    assert (\n        capture\n        == \"\"\"\n        Hello, World!\n        1 2.0 three True -- multiple args\n        *args-and-a-custom-separator\n        no new line here -- next print\n        flush\n        py::print + str.format = this\n    \"\"\"\n    )\n    assert capture.stderr == \"this goes to stderr\"\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.print_failure()\n    assert str(excinfo.value) == \"Unable to convert call argument \" + (\n        \"'1' of type 'UnregisteredType' to Python object\"\n        if debug_enabled\n        else \"to Python object (compile in debug mode for details)\"\n    )\n\n\ndef test_hash():\n    class Hashable(object):\n        def __init__(self, value):\n            self.value = value\n\n        def __hash__(self):\n            return self.value\n\n    class Unhashable(object):\n        __hash__ = None\n\n    assert m.hash_function(Hashable(42)) == 42\n    with pytest.raises(TypeError):\n        m.hash_function(Unhashable())\n\n\ndef test_number_protocol():\n    for a, b in [(1, 1), (3, 5)]:\n        li = [\n            a == b,\n            a != b,\n            a < b,\n            a <= b,\n            a > b,\n            a >= b,\n            a + b,\n            a - b,\n            a * b,\n            a / b,\n            a | b,\n            a & b,\n            a ^ b,\n            a >> b,\n            a << b,\n        ]\n        assert m.test_number_protocol(a, b) == li\n\n\ndef test_list_slicing():\n    li = list(range(100))\n    assert li[::2] == m.test_list_slicing(li)\n\n\ndef test_issue2361():\n    # See issue #2361\n    assert m.issue2361_str_implicit_copy_none() == \"None\"\n    with pytest.raises(TypeError) as excinfo:\n        assert m.issue2361_dict_implicit_copy_none()\n    assert \"NoneType\" in str(excinfo.value)\n    assert \"iterable\" in str(excinfo.value)\n\n\n@pytest.mark.parametrize(\n    \"method, args, fmt, expected_view\",\n    [\n        (m.test_memoryview_object, (b\"red\",), \"B\", b\"red\"),\n        (m.test_memoryview_buffer_info, (b\"green\",), \"B\", b\"green\"),\n        (m.test_memoryview_from_buffer, (False,), \"h\", [3, 1, 4, 1, 5]),\n        (m.test_memoryview_from_buffer, (True,), \"H\", [2, 7, 1, 8]),\n        (m.test_memoryview_from_buffer_nativeformat, (), \"@i\", [4, 7, 5]),\n    ],\n)\ndef test_memoryview(method, args, fmt, expected_view):\n    view = method(*args)\n    assert isinstance(view, memoryview)\n    assert view.format == fmt\n    if isinstance(expected_view, bytes) or not env.PY2:\n        view_as_list = list(view)\n    else:\n        # Using max to pick non-zero byte (big-endian vs little-endian).\n        view_as_list = [max(ord(c) for c in s) for s in view]\n    assert view_as_list == list(expected_view)\n\n\n@pytest.mark.xfail(\"env.PYPY\", reason=\"getrefcount is not available\")\n@pytest.mark.parametrize(\n    \"method\",\n    [\n        m.test_memoryview_object,\n        m.test_memoryview_buffer_info,\n    ],\n)\ndef test_memoryview_refcount(method):\n    buf = b\"\\x0a\\x0b\\x0c\\x0d\"\n    ref_before = sys.getrefcount(buf)\n    view = method(buf)\n    ref_after = sys.getrefcount(buf)\n    assert ref_before < ref_after\n    assert list(view) == list(buf)\n\n\ndef test_memoryview_from_buffer_empty_shape():\n    view = m.test_memoryview_from_buffer_empty_shape()\n    assert isinstance(view, memoryview)\n    assert view.format == \"B\"\n    if env.PY2:\n        # Python 2 behavior is weird, but Python 3 (the future) is fine.\n        # PyPy3 has <memoryview, while CPython 2 has <memory\n        assert bytes(view).startswith(b\"<memory\")\n    else:\n        assert bytes(view) == b\"\"\n\n\ndef test_test_memoryview_from_buffer_invalid_strides():\n    with pytest.raises(RuntimeError):\n        m.test_memoryview_from_buffer_invalid_strides()\n\n\ndef test_test_memoryview_from_buffer_nullptr():\n    if env.PY2:\n        m.test_memoryview_from_buffer_nullptr()\n    else:\n        with pytest.raises(ValueError):\n            m.test_memoryview_from_buffer_nullptr()\n\n\n@pytest.mark.skipif(\"env.PY2\")\ndef test_memoryview_from_memory():\n    view = m.test_memoryview_from_memory()\n    assert isinstance(view, memoryview)\n    assert view.format == \"B\"\n    assert bytes(view) == b\"\\xff\\xe1\\xab\\x37\"\n\n\ndef test_builtin_functions():\n    assert m.get_len([i for i in range(42)]) == 42\n    with pytest.raises(TypeError) as exc_info:\n        m.get_len(i for i in range(42))\n    assert str(exc_info.value) in [\n        \"object of type 'generator' has no len()\",\n        \"'generator' has no length\",\n    ]  # PyPy\n\n\ndef test_isinstance_string_types():\n    assert m.isinstance_pybind11_bytes(b\"\")\n    assert not m.isinstance_pybind11_bytes(u\"\")\n\n    assert m.isinstance_pybind11_str(u\"\")\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.isinstance_pybind11_str(b\"\")\n    else:\n        assert not m.isinstance_pybind11_str(b\"\")\n\n\ndef test_pass_bytes_or_unicode_to_string_types():\n    assert m.pass_to_pybind11_bytes(b\"Bytes\") == 5\n    with pytest.raises(TypeError):\n        m.pass_to_pybind11_bytes(u\"Str\")\n\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\") or env.PY2:\n        assert m.pass_to_pybind11_str(b\"Bytes\") == 5\n    else:\n        with pytest.raises(TypeError):\n            m.pass_to_pybind11_str(b\"Bytes\")\n    assert m.pass_to_pybind11_str(u\"Str\") == 3\n\n    assert m.pass_to_std_string(b\"Bytes\") == 5\n    assert m.pass_to_std_string(u\"Str\") == 3\n\n    malformed_utf8 = b\"\\x80\"\n    if hasattr(m, \"PYBIND11_STR_LEGACY_PERMISSIVE\"):\n        assert m.pass_to_pybind11_str(malformed_utf8) == 1\n    elif env.PY2:\n        with pytest.raises(UnicodeDecodeError):\n            m.pass_to_pybind11_str(malformed_utf8)\n    else:\n        with pytest.raises(TypeError):\n            m.pass_to_pybind11_str(malformed_utf8)\n\n\n@pytest.mark.parametrize(\n    \"create_weakref, create_weakref_with_callback\",\n    [\n        (m.weakref_from_handle, m.weakref_from_handle_and_function),\n        (m.weakref_from_object, m.weakref_from_object_and_function),\n    ],\n)\ndef test_weakref(create_weakref, create_weakref_with_callback):\n    from weakref import getweakrefcount\n\n    # Apparently, you cannot weakly reference an object()\n    class WeaklyReferenced(object):\n        pass\n\n    def callback(wr):\n        # No `nonlocal` in Python 2\n        callback.called = True\n\n    obj = WeaklyReferenced()\n    assert getweakrefcount(obj) == 0\n    wr = create_weakref(obj)\n    assert getweakrefcount(obj) == 1\n\n    obj = WeaklyReferenced()\n    assert getweakrefcount(obj) == 0\n    callback.called = False\n    wr = create_weakref_with_callback(obj, callback)  # noqa: F841\n    assert getweakrefcount(obj) == 1\n    assert not callback.called\n    del obj\n    pytest.gc_collect()\n    assert callback.called\n\n\ndef test_cpp_iterators():\n    assert m.tuple_iterator() == 12\n    assert m.dict_iterator() == 305 + 711\n    assert m.passed_iterator(iter((-7, 3))) == -4\n\n\ndef test_implementation_details():\n    lst = [39, 43, 92, 49, 22, 29, 93, 98, 26, 57, 8]\n    tup = tuple(lst)\n    assert m.sequence_item_get_ssize_t(lst) == 43\n    assert m.sequence_item_set_ssize_t(lst) is None\n    assert lst[1] == \"peppa\"\n    assert m.sequence_item_get_size_t(lst) == 92\n    assert m.sequence_item_set_size_t(lst) is None\n    assert lst[2] == \"george\"\n    assert m.list_item_get_ssize_t(lst) == 49\n    assert m.list_item_set_ssize_t(lst) is None\n    assert lst[3] == \"rebecca\"\n    assert m.list_item_get_size_t(lst) == 22\n    assert m.list_item_set_size_t(lst) is None\n    assert lst[4] == \"richard\"\n    assert m.tuple_item_get_ssize_t(tup) == 29\n    assert m.tuple_item_set_ssize_t() == (\"emely\", \"edmond\")\n    assert m.tuple_item_get_size_t(tup) == 93\n    assert m.tuple_item_set_size_t() == (\"candy\", \"cat\")\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_sequences_and_iterators.cpp",
    "content": "/*\n    tests/test_sequences_and_iterators.cpp -- supporting Pythons' sequence protocol, iterators,\n    etc.\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/operators.h>\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <algorithm>\n#include <utility>\n#include <vector>\n\n#ifdef PYBIND11_HAS_OPTIONAL\n#    include <optional>\n#endif // PYBIND11_HAS_OPTIONAL\n\ntemplate <typename T>\nclass NonZeroIterator {\n    const T *ptr_;\n\npublic:\n    explicit NonZeroIterator(const T *ptr) : ptr_(ptr) {}\n    const T &operator*() const { return *ptr_; }\n    NonZeroIterator &operator++() {\n        ++ptr_;\n        return *this;\n    }\n};\n\nclass NonZeroSentinel {};\n\ntemplate <typename A, typename B>\nbool operator==(const NonZeroIterator<std::pair<A, B>> &it, const NonZeroSentinel &) {\n    return !(*it).first || !(*it).second;\n}\n\n/* Iterator where dereferencing returns prvalues instead of references. */\ntemplate <typename T>\nclass NonRefIterator {\n    const T *ptr_;\n\npublic:\n    explicit NonRefIterator(const T *ptr) : ptr_(ptr) {}\n    T operator*() const { return T(*ptr_); }\n    NonRefIterator &operator++() {\n        ++ptr_;\n        return *this;\n    }\n    bool operator==(const NonRefIterator &other) const { return ptr_ == other.ptr_; }\n};\n\nclass NonCopyableInt {\npublic:\n    explicit NonCopyableInt(int value) : value_(value) {}\n    NonCopyableInt(const NonCopyableInt &) = delete;\n    NonCopyableInt(NonCopyableInt &&other) noexcept : value_(other.value_) {\n        other.value_ = -1; // detect when an unwanted move occurs\n    }\n    NonCopyableInt &operator=(const NonCopyableInt &) = delete;\n    NonCopyableInt &operator=(NonCopyableInt &&other) noexcept {\n        value_ = other.value_;\n        other.value_ = -1; // detect when an unwanted move occurs\n        return *this;\n    }\n    int get() const { return value_; }\n    void set(int value) { value_ = value; }\n    ~NonCopyableInt() = default;\n\nprivate:\n    int value_;\n};\nusing NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;\nPYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);\nPYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);\n\ntemplate <typename PythonType>\npy::list test_random_access_iterator(PythonType x) {\n    if (x.size() < 5) {\n        throw py::value_error(\"Please provide at least 5 elements for testing.\");\n    }\n\n    auto checks = py::list();\n    auto assert_equal = [&checks](py::handle a, py::handle b) {\n        auto result = PyObject_RichCompareBool(a.ptr(), b.ptr(), Py_EQ);\n        if (result == -1) {\n            throw py::error_already_set();\n        }\n        checks.append(result != 0);\n    };\n\n    auto it = x.begin();\n    assert_equal(x[0], *it);\n    assert_equal(x[0], it[0]);\n    assert_equal(x[1], it[1]);\n\n    assert_equal(x[1], *(++it));\n    assert_equal(x[1], *(it++));\n    assert_equal(x[2], *it);\n    assert_equal(x[3], *(it += 1));\n    assert_equal(x[2], *(--it));\n    assert_equal(x[2], *(it--));\n    assert_equal(x[1], *it);\n    assert_equal(x[0], *(it -= 1));\n\n    assert_equal(it->attr(\"real\"), x[0].attr(\"real\"));\n    assert_equal((it + 1)->attr(\"real\"), x[1].attr(\"real\"));\n\n    assert_equal(x[1], *(it + 1));\n    assert_equal(x[1], *(1 + it));\n    it += 3;\n    assert_equal(x[1], *(it - 2));\n\n    checks.append(static_cast<std::size_t>(x.end() - x.begin()) == x.size());\n    checks.append((x.begin() + static_cast<std::ptrdiff_t>(x.size())) == x.end());\n    checks.append(x.begin() < x.end());\n\n    return checks;\n}\n\nTEST_SUBMODULE(sequences_and_iterators, m) {\n    // test_sliceable\n    class Sliceable {\n    public:\n        explicit Sliceable(int n) : size(n) {}\n        int start, stop, step;\n        int size;\n    };\n    py::class_<Sliceable>(m, \"Sliceable\")\n        .def(py::init<int>())\n        .def(\"__getitem__\", [](const Sliceable &s, const py::slice &slice) {\n            py::ssize_t start = 0, stop = 0, step = 0, slicelength = 0;\n            if (!slice.compute(s.size, &start, &stop, &step, &slicelength)) {\n                throw py::error_already_set();\n            }\n            int istart = static_cast<int>(start);\n            int istop = static_cast<int>(stop);\n            int istep = static_cast<int>(step);\n            return std::make_tuple(istart, istop, istep);\n        });\n\n    m.def(\"make_forward_slice_size_t\", []() { return py::slice(0, -1, 1); });\n    m.def(\"make_reversed_slice_object\",\n          []() { return py::slice(py::none(), py::none(), py::int_(-1)); });\n#ifdef PYBIND11_HAS_OPTIONAL\n    m.attr(\"has_optional\") = true;\n    m.def(\"make_reversed_slice_size_t_optional_verbose\",\n          []() { return py::slice(std::nullopt, std::nullopt, -1); });\n    // Warning: The following spelling may still compile if optional<> is not present and give\n    // wrong answers. Please use with caution.\n    m.def(\"make_reversed_slice_size_t_optional\", []() { return py::slice({}, {}, -1); });\n#else\n    m.attr(\"has_optional\") = false;\n#endif\n\n    // test_sequence\n    class Sequence {\n    public:\n        explicit Sequence(size_t size) : m_size(size) {\n            print_created(this, \"of size\", m_size);\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[size];\n            memset(m_data, 0, sizeof(float) * size);\n        }\n        explicit Sequence(const std::vector<float> &value) : m_size(value.size()) {\n            print_created(this, \"of size\", m_size, \"from std::vector\");\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[m_size];\n            memcpy(m_data, &value[0], sizeof(float) * m_size);\n        }\n        Sequence(const Sequence &s) : m_size(s.m_size) {\n            print_copy_created(this);\n            // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer)\n            m_data = new float[m_size];\n            memcpy(m_data, s.m_data, sizeof(float) * m_size);\n        }\n        Sequence(Sequence &&s) noexcept : m_size(s.m_size), m_data(s.m_data) {\n            print_move_created(this);\n            s.m_size = 0;\n            s.m_data = nullptr;\n        }\n\n        ~Sequence() {\n            print_destroyed(this);\n            delete[] m_data;\n        }\n\n        Sequence &operator=(const Sequence &s) {\n            if (&s != this) {\n                delete[] m_data;\n                m_size = s.m_size;\n                m_data = new float[m_size];\n                memcpy(m_data, s.m_data, sizeof(float) * m_size);\n            }\n            print_copy_assigned(this);\n            return *this;\n        }\n\n        Sequence &operator=(Sequence &&s) noexcept {\n            if (&s != this) {\n                delete[] m_data;\n                m_size = s.m_size;\n                m_data = s.m_data;\n                s.m_size = 0;\n                s.m_data = nullptr;\n            }\n            print_move_assigned(this);\n            return *this;\n        }\n\n        bool operator==(const Sequence &s) const {\n            if (m_size != s.size()) {\n                return false;\n            }\n            for (size_t i = 0; i < m_size; ++i) {\n                if (m_data[i] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        }\n        bool operator!=(const Sequence &s) const { return !operator==(s); }\n\n        float operator[](size_t index) const { return m_data[index]; }\n        float &operator[](size_t index) { return m_data[index]; }\n\n        bool contains(float v) const {\n            for (size_t i = 0; i < m_size; ++i) {\n                if (v == m_data[i]) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        Sequence reversed() const {\n            Sequence result(m_size);\n            for (size_t i = 0; i < m_size; ++i) {\n                result[m_size - i - 1] = m_data[i];\n            }\n            return result;\n        }\n\n        size_t size() const { return m_size; }\n\n        const float *begin() const { return m_data; }\n        const float *end() const { return m_data + m_size; }\n\n    private:\n        size_t m_size;\n        float *m_data;\n    };\n    py::class_<Sequence>(m, \"Sequence\")\n        .def(py::init<size_t>())\n        .def(py::init<const std::vector<float> &>())\n        /// Bare bones interface\n        .def(\"__getitem__\",\n             [](const Sequence &s, size_t i) {\n                 if (i >= s.size()) {\n                     throw py::index_error();\n                 }\n                 return s[i];\n             })\n        .def(\"__setitem__\",\n             [](Sequence &s, size_t i, float v) {\n                 if (i >= s.size()) {\n                     throw py::index_error();\n                 }\n                 s[i] = v;\n             })\n        .def(\"__len__\", &Sequence::size)\n        /// Optional sequence protocol operations\n        .def(\n            \"__iter__\",\n            [](const Sequence &s) { return py::make_iterator(s.begin(), s.end()); },\n            py::keep_alive<0, 1>() /* Essential: keep object alive while iterator exists */)\n        .def(\"__contains__\", [](const Sequence &s, float v) { return s.contains(v); })\n        .def(\"__reversed__\", [](const Sequence &s) -> Sequence { return s.reversed(); })\n        /// Slicing protocol (optional)\n        .def(\"__getitem__\",\n             [](const Sequence &s, const py::slice &slice) -> Sequence * {\n                 size_t start = 0, stop = 0, step = 0, slicelength = 0;\n                 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) {\n                     throw py::error_already_set();\n                 }\n                 auto *seq = new Sequence(slicelength);\n                 for (size_t i = 0; i < slicelength; ++i) {\n                     (*seq)[i] = s[start];\n                     start += step;\n                 }\n                 return seq;\n             })\n        .def(\"__setitem__\",\n             [](Sequence &s, const py::slice &slice, const Sequence &value) {\n                 size_t start = 0, stop = 0, step = 0, slicelength = 0;\n                 if (!slice.compute(s.size(), &start, &stop, &step, &slicelength)) {\n                     throw py::error_already_set();\n                 }\n                 if (slicelength != value.size()) {\n                     throw std::runtime_error(\n                         \"Left and right hand size of slice assignment have different sizes!\");\n                 }\n                 for (size_t i = 0; i < slicelength; ++i) {\n                     s[start] = value[i];\n                     start += step;\n                 }\n             })\n        /// Comparisons\n        .def(py::self == py::self)\n        .def(py::self != py::self)\n        // Could also define py::self + py::self for concatenation, etc.\n        ;\n\n    // test_map_iterator\n    // Interface of a map-like object that isn't (directly) an unordered_map, but provides some\n    // basic map-like functionality.\n    class StringMap {\n    public:\n        StringMap() = default;\n        explicit StringMap(std::unordered_map<std::string, std::string> init)\n            : map(std::move(init)) {}\n\n        void set(const std::string &key, std::string val) { map[key] = std::move(val); }\n        std::string get(const std::string &key) const { return map.at(key); }\n        size_t size() const { return map.size(); }\n\n    private:\n        std::unordered_map<std::string, std::string> map;\n\n    public:\n        decltype(map.cbegin()) begin() const { return map.cbegin(); }\n        decltype(map.cend()) end() const { return map.cend(); }\n    };\n    py::class_<StringMap>(m, \"StringMap\")\n        .def(py::init<>())\n        .def(py::init<std::unordered_map<std::string, std::string>>())\n        .def(\"__getitem__\",\n             [](const StringMap &map, const std::string &key) {\n                 try {\n                     return map.get(key);\n                 } catch (const std::out_of_range &) {\n                     throw py::key_error(\"key '\" + key + \"' does not exist\");\n                 }\n             })\n        .def(\"__setitem__\", &StringMap::set)\n        .def(\"__len__\", &StringMap::size)\n        .def(\n            \"__iter__\",\n            [](const StringMap &map) { return py::make_key_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"items\",\n            [](const StringMap &map) { return py::make_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"values\",\n            [](const StringMap &map) { return py::make_value_iterator(map.begin(), map.end()); },\n            py::keep_alive<0, 1>());\n\n    // test_generalized_iterators\n    class IntPairs {\n    public:\n        explicit IntPairs(std::vector<std::pair<int, int>> data) : data_(std::move(data)) {}\n        const std::pair<int, int> *begin() const { return data_.data(); }\n        // .end() only required for py::make_iterator(self) overload\n        const std::pair<int, int> *end() const { return data_.data() + data_.size(); }\n\n    private:\n        std::vector<std::pair<int, int>> data_;\n    };\n    py::class_<IntPairs>(m, \"IntPairs\")\n        .def(py::init<std::vector<std::pair<int, int>>>())\n        .def(\n            \"nonzero\",\n            [](const IntPairs &s) {\n                return py::make_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                         NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonzero_keys\",\n            [](const IntPairs &s) {\n                return py::make_key_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                             NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonzero_values\",\n            [](const IntPairs &s) {\n                return py::make_value_iterator(NonZeroIterator<std::pair<int, int>>(s.begin()),\n                                               NonZeroSentinel());\n            },\n            py::keep_alive<0, 1>())\n\n        // test iterator that returns values instead of references\n        .def(\n            \"nonref\",\n            [](const IntPairs &s) {\n                return py::make_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                         NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonref_keys\",\n            [](const IntPairs &s) {\n                return py::make_key_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                             NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n        .def(\n            \"nonref_values\",\n            [](const IntPairs &s) {\n                return py::make_value_iterator(NonRefIterator<std::pair<int, int>>(s.begin()),\n                                               NonRefIterator<std::pair<int, int>>(s.end()));\n            },\n            py::keep_alive<0, 1>())\n\n        // test single-argument make_iterator\n        .def(\n            \"simple_iterator\",\n            [](IntPairs &self) { return py::make_iterator(self); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"simple_keys\",\n            [](IntPairs &self) { return py::make_key_iterator(self); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"simple_values\",\n            [](IntPairs &self) { return py::make_value_iterator(self); },\n            py::keep_alive<0, 1>())\n\n        // Test iterator with an Extra (doesn't do anything useful, so not used\n        // at runtime, but tests need to be able to compile with the correct\n        // overload. See PR #3293.\n        .def(\n            \"_make_iterator_extras\",\n            [](IntPairs &self) { return py::make_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"_make_key_extras\",\n            [](IntPairs &self) { return py::make_key_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>())\n        .def(\n            \"_make_value_extras\",\n            [](IntPairs &self) { return py::make_value_iterator(self, py::call_guard<int>()); },\n            py::keep_alive<0, 1>());\n\n    // test_iterator_referencing\n    py::class_<NonCopyableInt>(m, \"NonCopyableInt\")\n        .def(py::init<int>())\n        .def(\"set\", &NonCopyableInt::set)\n        .def(\"__int__\", &NonCopyableInt::get);\n    py::class_<std::vector<NonCopyableInt>>(m, \"VectorNonCopyableInt\")\n        .def(py::init<>())\n        .def(\"append\",\n             [](std::vector<NonCopyableInt> &vec, int value) { vec.emplace_back(value); })\n        .def(\"__iter__\", [](std::vector<NonCopyableInt> &vec) {\n            return py::make_iterator(vec.begin(), vec.end());\n        });\n    py::class_<std::vector<NonCopyableIntPair>>(m, \"VectorNonCopyableIntPair\")\n        .def(py::init<>())\n        .def(\"append\",\n             [](std::vector<NonCopyableIntPair> &vec, const std::pair<int, int> &value) {\n                 vec.emplace_back(NonCopyableInt(value.first), NonCopyableInt(value.second));\n             })\n        .def(\"keys\",\n             [](std::vector<NonCopyableIntPair> &vec) {\n                 return py::make_key_iterator(vec.begin(), vec.end());\n             })\n        .def(\"values\", [](std::vector<NonCopyableIntPair> &vec) {\n            return py::make_value_iterator(vec.begin(), vec.end());\n        });\n\n#if 0\n    // Obsolete: special data structure for exposing custom iterator types to python\n    // kept here for illustrative purposes because there might be some use cases which\n    // are not covered by the much simpler py::make_iterator\n\n    struct PySequenceIterator {\n        PySequenceIterator(const Sequence &seq, py::object ref) : seq(seq), ref(ref) { }\n\n        float next() {\n            if (index == seq.size())\n                throw py::stop_iteration();\n            return seq[index++];\n        }\n\n        const Sequence &seq;\n        py::object ref; // keep a reference\n        size_t index = 0;\n    };\n\n    py::class_<PySequenceIterator>(seq, \"Iterator\")\n        .def(\"__iter__\", [](PySequenceIterator &it) -> PySequenceIterator& { return it; })\n        .def(\"__next__\", &PySequenceIterator::next);\n\n    On the actual Sequence object, the iterator would be constructed as follows:\n    .def(\"__iter__\", [](py::object s) { return PySequenceIterator(s.cast<const Sequence &>(), s); })\n#endif\n\n    // test_python_iterator_in_cpp\n    m.def(\"object_to_list\", [](const py::object &o) {\n        auto l = py::list();\n        for (auto item : o) {\n            l.append(item);\n        }\n        return l;\n    });\n\n    m.def(\"iterator_to_list\", [](py::iterator it) {\n        auto l = py::list();\n        while (it != py::iterator::sentinel()) {\n            l.append(*it);\n            ++it;\n        }\n        return l;\n    });\n\n    // test_sequence_length: check that Python sequences can be converted to py::sequence.\n    m.def(\"sequence_length\", [](const py::sequence &seq) { return seq.size(); });\n\n    // Make sure that py::iterator works with std algorithms\n    m.def(\"count_none\", [](const py::object &o) {\n        return std::count_if(o.begin(), o.end(), [](py::handle h) { return h.is_none(); });\n    });\n\n    m.def(\"find_none\", [](const py::object &o) {\n        auto it = std::find_if(o.begin(), o.end(), [](py::handle h) { return h.is_none(); });\n        return it->is_none();\n    });\n\n    m.def(\"count_nonzeros\", [](const py::dict &d) {\n        return std::count_if(d.begin(), d.end(), [](std::pair<py::handle, py::handle> p) {\n            return p.second.cast<int>() != 0;\n        });\n    });\n\n    m.def(\"tuple_iterator\", &test_random_access_iterator<py::tuple>);\n    m.def(\"list_iterator\", &test_random_access_iterator<py::list>);\n    m.def(\"sequence_iterator\", &test_random_access_iterator<py::sequence>);\n\n    // test_iterator_passthrough\n    // #181: iterator passthrough did not compile\n    m.def(\"iterator_passthrough\", [](py::iterator s) -> py::iterator {\n        return py::make_iterator(std::begin(s), std::end(s));\n    });\n\n    // test_iterator_rvp\n    // #388: Can't make iterators via make_iterator() with different r/v policies\n    static std::vector<int> list = {1, 2, 3};\n    m.def(\"make_iterator_1\",\n          []() { return py::make_iterator<py::return_value_policy::copy>(list); });\n    m.def(\"make_iterator_2\",\n          []() { return py::make_iterator<py::return_value_policy::automatic>(list); });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_sequences_and_iterators.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import ConstructorStats\nfrom pybind11_tests import sequences_and_iterators as m\n\n\ndef isclose(a, b, rel_tol=1e-05, abs_tol=0.0):\n    \"\"\"Like math.isclose() from Python 3.5\"\"\"\n    return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)\n\n\ndef allclose(a_list, b_list, rel_tol=1e-05, abs_tol=0.0):\n    return all(\n        isclose(a, b, rel_tol=rel_tol, abs_tol=abs_tol) for a, b in zip(a_list, b_list)\n    )\n\n\ndef test_slice_constructors():\n    assert m.make_forward_slice_size_t() == slice(0, -1, 1)\n    assert m.make_reversed_slice_object() == slice(None, None, -1)\n\n\n@pytest.mark.skipif(not m.has_optional, reason=\"no <optional>\")\ndef test_slice_constructors_explicit_optional():\n    assert m.make_reversed_slice_size_t_optional() == slice(None, None, -1)\n    assert m.make_reversed_slice_size_t_optional_verbose() == slice(None, None, -1)\n\n\ndef test_generalized_iterators():\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero()) == [(1, 2), (3, 4)]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero()) == [(1, 2)]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero()) == []\n\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_keys()) == [1, 3]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_keys()) == [1]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_keys()) == []\n\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).nonzero_values()) == [2, 4]\n    assert list(m.IntPairs([(1, 2), (2, 0), (0, 3), (4, 5)]).nonzero_values()) == [2]\n    assert list(m.IntPairs([(0, 3), (1, 2), (3, 4)]).nonzero_values()) == []\n\n    # __next__ must continue to raise StopIteration\n    it = m.IntPairs([(0, 0)]).nonzero()\n    for _ in range(3):\n        with pytest.raises(StopIteration):\n            next(it)\n\n    it = m.IntPairs([(0, 0)]).nonzero_keys()\n    for _ in range(3):\n        with pytest.raises(StopIteration):\n            next(it)\n\n\ndef test_nonref_iterators():\n    pairs = m.IntPairs([(1, 2), (3, 4), (0, 5)])\n    assert list(pairs.nonref()) == [(1, 2), (3, 4), (0, 5)]\n    assert list(pairs.nonref_keys()) == [1, 3, 0]\n    assert list(pairs.nonref_values()) == [2, 4, 5]\n\n\ndef test_generalized_iterators_simple():\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_iterator()) == [\n        (1, 2),\n        (3, 4),\n        (0, 5),\n    ]\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_keys()) == [1, 3, 0]\n    assert list(m.IntPairs([(1, 2), (3, 4), (0, 5)]).simple_values()) == [2, 4, 5]\n\n\ndef test_iterator_referencing():\n    \"\"\"Test that iterators reference rather than copy their referents.\"\"\"\n    vec = m.VectorNonCopyableInt()\n    vec.append(3)\n    vec.append(5)\n    assert [int(x) for x in vec] == [3, 5]\n    # Increment everything to make sure the referents can be mutated\n    for x in vec:\n        x.set(int(x) + 1)\n    assert [int(x) for x in vec] == [4, 6]\n\n    vec = m.VectorNonCopyableIntPair()\n    vec.append([3, 4])\n    vec.append([5, 7])\n    assert [int(x) for x in vec.keys()] == [3, 5]\n    assert [int(x) for x in vec.values()] == [4, 7]\n    for x in vec.keys():\n        x.set(int(x) + 1)\n    for x in vec.values():\n        x.set(int(x) + 10)\n    assert [int(x) for x in vec.keys()] == [4, 6]\n    assert [int(x) for x in vec.values()] == [14, 17]\n\n\ndef test_sliceable():\n    sliceable = m.Sliceable(100)\n    assert sliceable[::] == (0, 100, 1)\n    assert sliceable[10::] == (10, 100, 1)\n    assert sliceable[:10:] == (0, 10, 1)\n    assert sliceable[::10] == (0, 100, 10)\n    assert sliceable[-10::] == (90, 100, 1)\n    assert sliceable[:-10:] == (0, 90, 1)\n    assert sliceable[::-10] == (99, -1, -10)\n    assert sliceable[50:60:1] == (50, 60, 1)\n    assert sliceable[50:60:-1] == (50, 60, -1)\n\n\ndef test_sequence():\n    cstats = ConstructorStats.get(m.Sequence)\n\n    s = m.Sequence(5)\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    assert \"Sequence\" in repr(s)\n    assert len(s) == 5\n    assert s[0] == 0 and s[3] == 0\n    assert 12.34 not in s\n    s[0], s[3] = 12.34, 56.78\n    assert 12.34 in s\n    assert isclose(s[0], 12.34) and isclose(s[3], 56.78)\n\n    rev = reversed(s)\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    rev2 = s[::-1]\n    assert cstats.values() == [\"of size\", \"5\"]\n\n    it = iter(m.Sequence(0))\n    for _ in range(3):  # __next__ must continue to raise StopIteration\n        with pytest.raises(StopIteration):\n            next(it)\n    assert cstats.values() == [\"of size\", \"0\"]\n\n    expected = [0, 56.78, 0, 0, 12.34]\n    assert allclose(rev, expected)\n    assert allclose(rev2, expected)\n    assert rev == rev2\n\n    rev[0::2] = m.Sequence([2.0, 2.0, 2.0])\n    assert cstats.values() == [\"of size\", \"3\", \"from std::vector\"]\n\n    assert allclose(rev, [2, 56.78, 2, 0, 2])\n\n    assert cstats.alive() == 4\n    del it\n    assert cstats.alive() == 3\n    del s\n    assert cstats.alive() == 2\n    del rev\n    assert cstats.alive() == 1\n    del rev2\n    assert cstats.alive() == 0\n\n    assert cstats.values() == []\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 1\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n\ndef test_sequence_length():\n    \"\"\"#2076: Exception raised by len(arg) should be propagated\"\"\"\n\n    class BadLen(RuntimeError):\n        pass\n\n    class SequenceLike:\n        def __getitem__(self, i):\n            return None\n\n        def __len__(self):\n            raise BadLen()\n\n    with pytest.raises(BadLen):\n        m.sequence_length(SequenceLike())\n\n    assert m.sequence_length([1, 2, 3]) == 3\n    assert m.sequence_length(\"hello\") == 5\n\n\ndef test_map_iterator():\n    sm = m.StringMap({\"hi\": \"bye\", \"black\": \"white\"})\n    assert sm[\"hi\"] == \"bye\"\n    assert len(sm) == 2\n    assert sm[\"black\"] == \"white\"\n\n    with pytest.raises(KeyError):\n        assert sm[\"orange\"]\n    sm[\"orange\"] = \"banana\"\n    assert sm[\"orange\"] == \"banana\"\n\n    expected = {\"hi\": \"bye\", \"black\": \"white\", \"orange\": \"banana\"}\n    for k in sm:\n        assert sm[k] == expected[k]\n    for k, v in sm.items():\n        assert v == expected[k]\n    assert list(sm.values()) == [expected[k] for k in sm]\n\n    it = iter(m.StringMap({}))\n    for _ in range(3):  # __next__ must continue to raise StopIteration\n        with pytest.raises(StopIteration):\n            next(it)\n\n\ndef test_python_iterator_in_cpp():\n    t = (1, 2, 3)\n    assert m.object_to_list(t) == [1, 2, 3]\n    assert m.object_to_list(iter(t)) == [1, 2, 3]\n    assert m.iterator_to_list(iter(t)) == [1, 2, 3]\n\n    with pytest.raises(TypeError) as excinfo:\n        m.object_to_list(1)\n    assert \"object is not iterable\" in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        m.iterator_to_list(1)\n    assert \"incompatible function arguments\" in str(excinfo.value)\n\n    def bad_next_call():\n        raise RuntimeError(\"py::iterator::advance() should propagate errors\")\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.iterator_to_list(iter(bad_next_call, None))\n    assert str(excinfo.value) == \"py::iterator::advance() should propagate errors\"\n\n    lst = [1, None, 0, None]\n    assert m.count_none(lst) == 2\n    assert m.find_none(lst) is True\n    assert m.count_nonzeros({\"a\": 0, \"b\": 1, \"c\": 2}) == 2\n\n    r = range(5)\n    assert all(m.tuple_iterator(tuple(r)))\n    assert all(m.list_iterator(list(r)))\n    assert all(m.sequence_iterator(r))\n\n\ndef test_iterator_passthrough():\n    \"\"\"#181: iterator passthrough did not compile\"\"\"\n    from pybind11_tests.sequences_and_iterators import iterator_passthrough\n\n    values = [3, 5, 7, 9, 11, 13, 15]\n    assert list(iterator_passthrough(iter(values))) == values\n\n\ndef test_iterator_rvp():\n    \"\"\"#388: Can't make iterators via make_iterator() with different r/v policies\"\"\"\n    import pybind11_tests.sequences_and_iterators as m\n\n    assert list(m.make_iterator_1()) == [1, 2, 3]\n    assert list(m.make_iterator_2()) == [1, 2, 3]\n    assert not isinstance(m.make_iterator_1(), type(m.make_iterator_2()))\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_smart_ptr.cpp",
    "content": "/*\n    tests/test_smart_ptr.cpp -- binding classes with custom reference counting,\n    implicit conversions between types\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#if defined(_MSC_VER) && _MSC_VER < 1910 // VS 2015's MSVC\n#    pragma warning(disable : 4702)      // unreachable code in system header (xatomic.h(382))\n#endif\n\n#include \"object.h\"\n#include \"pybind11_tests.h\"\n\nnamespace {\n\n// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the\n// holder size to trigger the non-simple-layout internal instance layout for single inheritance\n// with large holder type:\ntemplate <typename T>\nclass huge_unique_ptr {\n    std::unique_ptr<T> ptr;\n    uint64_t padding[10];\n\npublic:\n    explicit huge_unique_ptr(T *p) : ptr(p) {}\n    T *get() { return ptr.get(); }\n};\n\n// Simple custom holder that works like unique_ptr\ntemplate <typename T>\nclass custom_unique_ptr {\n    std::unique_ptr<T> impl;\n\npublic:\n    explicit custom_unique_ptr(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T *release_ptr() { return impl.release(); }\n};\n\n// Simple custom holder that works like shared_ptr and has operator& overload\n// To obtain address of an instance of this holder pybind should use std::addressof\n// Attempt to get address via operator& may leads to segmentation fault\ntemplate <typename T>\nclass shared_ptr_with_addressof_operator {\n    std::shared_ptr<T> impl;\n\npublic:\n    shared_ptr_with_addressof_operator() = default;\n    explicit shared_ptr_with_addressof_operator(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T **operator&() { throw std::logic_error(\"Call of overloaded operator& is not expected\"); }\n};\n\n// Simple custom holder that works like unique_ptr and has operator& overload\n// To obtain address of an instance of this holder pybind should use std::addressof\n// Attempt to get address via operator& may leads to segmentation fault\ntemplate <typename T>\nclass unique_ptr_with_addressof_operator {\n    std::unique_ptr<T> impl;\n\npublic:\n    unique_ptr_with_addressof_operator() = default;\n    explicit unique_ptr_with_addressof_operator(T *p) : impl(p) {}\n    T *get() const { return impl.get(); }\n    T *release_ptr() { return impl.release(); }\n    T **operator&() { throw std::logic_error(\"Call of overloaded operator& is not expected\"); }\n};\n\n// Custom object with builtin reference counting (see 'object.h' for the implementation)\nclass MyObject1 : public Object {\npublic:\n    explicit MyObject1(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const override { return \"MyObject1[\" + std::to_string(value) + \"]\"; }\n\nprotected:\n    ~MyObject1() override { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// Object managed by a std::shared_ptr<>\nclass MyObject2 {\npublic:\n    MyObject2(const MyObject2 &) = default;\n    explicit MyObject2(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const { return \"MyObject2[\" + std::to_string(value) + \"]\"; }\n    virtual ~MyObject2() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// Object managed by a std::shared_ptr<>, additionally derives from std::enable_shared_from_this<>\nclass MyObject3 : public std::enable_shared_from_this<MyObject3> {\npublic:\n    MyObject3(const MyObject3 &) = default;\n    explicit MyObject3(int value) : value(value) { print_created(this, toString()); }\n    std::string toString() const { return \"MyObject3[\" + std::to_string(value) + \"]\"; }\n    virtual ~MyObject3() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\n// test_unique_nodelete\n// Object with a private destructor\nclass MyObject4;\nstd::unordered_set<MyObject4 *> myobject4_instances;\nclass MyObject4 {\npublic:\n    explicit MyObject4(int value) : value{value} {\n        print_created(this);\n        myobject4_instances.insert(this);\n    }\n    int value;\n\n    static void cleanupAllInstances() {\n        auto tmp = std::move(myobject4_instances);\n        myobject4_instances.clear();\n        for (auto *o : tmp) {\n            delete o;\n        }\n    }\n\nprivate:\n    ~MyObject4() {\n        myobject4_instances.erase(this);\n        print_destroyed(this);\n    }\n};\n\n// test_unique_deleter\n// Object with std::unique_ptr<T, D> where D is not matching the base class\n// Object with a protected destructor\nclass MyObject4a;\nstd::unordered_set<MyObject4a *> myobject4a_instances;\nclass MyObject4a {\npublic:\n    explicit MyObject4a(int i) : value{i} {\n        print_created(this);\n        myobject4a_instances.insert(this);\n    };\n    int value;\n\n    static void cleanupAllInstances() {\n        auto tmp = std::move(myobject4a_instances);\n        myobject4a_instances.clear();\n        for (auto *o : tmp) {\n            delete o;\n        }\n    }\n\nprotected:\n    virtual ~MyObject4a() {\n        myobject4a_instances.erase(this);\n        print_destroyed(this);\n    }\n};\n\n// Object derived but with public destructor and no Deleter in default holder\nclass MyObject4b : public MyObject4a {\npublic:\n    explicit MyObject4b(int i) : MyObject4a(i) { print_created(this); }\n    ~MyObject4b() override { print_destroyed(this); }\n};\n\n// test_large_holder\nclass MyObject5 { // managed by huge_unique_ptr\npublic:\n    explicit MyObject5(int value) : value{value} { print_created(this); }\n    ~MyObject5() { print_destroyed(this); }\n    int value;\n};\n\n// test_shared_ptr_and_references\nstruct SharedPtrRef {\n    struct A {\n        A() { print_created(this); }\n        A(const A &) { print_copy_created(this); }\n        A(A &&) noexcept { print_move_created(this); }\n        ~A() { print_destroyed(this); }\n    };\n\n    A value = {};\n    std::shared_ptr<A> shared = std::make_shared<A>();\n};\n\n// test_shared_ptr_from_this_and_references\nstruct SharedFromThisRef {\n    struct B : std::enable_shared_from_this<B> {\n        B() { print_created(this); }\n        // NOLINTNEXTLINE(bugprone-copy-constructor-init)\n        B(const B &) : std::enable_shared_from_this<B>() { print_copy_created(this); }\n        B(B &&) noexcept : std::enable_shared_from_this<B>() { print_move_created(this); }\n        ~B() { print_destroyed(this); }\n    };\n\n    B value = {};\n    std::shared_ptr<B> shared = std::make_shared<B>();\n};\n\n// Issue #865: shared_from_this doesn't work with virtual inheritance\nstruct SharedFromThisVBase : std::enable_shared_from_this<SharedFromThisVBase> {\n    SharedFromThisVBase() = default;\n    SharedFromThisVBase(const SharedFromThisVBase &) = default;\n    virtual ~SharedFromThisVBase() = default;\n};\nstruct SharedFromThisVirt : virtual SharedFromThisVBase {};\n\n// test_move_only_holder\nstruct C {\n    C() { print_created(this); }\n    ~C() { print_destroyed(this); }\n};\n\n// test_holder_with_addressof_operator\nstruct TypeForHolderWithAddressOf {\n    TypeForHolderWithAddressOf() { print_created(this); }\n    TypeForHolderWithAddressOf(const TypeForHolderWithAddressOf &) { print_copy_created(this); }\n    TypeForHolderWithAddressOf(TypeForHolderWithAddressOf &&) noexcept {\n        print_move_created(this);\n    }\n    ~TypeForHolderWithAddressOf() { print_destroyed(this); }\n    std::string toString() const {\n        return \"TypeForHolderWithAddressOf[\" + std::to_string(value) + \"]\";\n    }\n    int value = 42;\n};\n\n// test_move_only_holder_with_addressof_operator\nstruct TypeForMoveOnlyHolderWithAddressOf {\n    explicit TypeForMoveOnlyHolderWithAddressOf(int value) : value{value} { print_created(this); }\n    ~TypeForMoveOnlyHolderWithAddressOf() { print_destroyed(this); }\n    std::string toString() const {\n        return \"MoveOnlyHolderWithAddressOf[\" + std::to_string(value) + \"]\";\n    }\n    int value;\n};\n\n// test_smart_ptr_from_default\nstruct HeldByDefaultHolder {};\n\n// test_shared_ptr_gc\n// #187: issue involving std::shared_ptr<> return value policy & garbage collection\nstruct ElementBase {\n    virtual ~ElementBase() = default; /* Force creation of virtual table */\n    ElementBase() = default;\n    ElementBase(const ElementBase &) = delete;\n};\n\nstruct ElementA : ElementBase {\n    explicit ElementA(int v) : v(v) {}\n    int value() const { return v; }\n    int v;\n};\n\nstruct ElementList {\n    void add(const std::shared_ptr<ElementBase> &e) { l.push_back(e); }\n    std::vector<std::shared_ptr<ElementBase>> l;\n};\n\n} // namespace\n\n// ref<T> is a wrapper for 'Object' which uses intrusive reference counting\n// It is always possible to construct a ref<T> from an Object* pointer without\n// possible inconsistencies, hence the 'true' argument at the end.\n// Make pybind11 aware of the non-standard getter member function\nnamespace pybind11 {\nnamespace detail {\ntemplate <typename T>\nstruct holder_helper<ref<T>> {\n    static const T *get(const ref<T> &p) { return p.get_ptr(); }\n};\n} // namespace detail\n} // namespace pybind11\n\n// Make pybind aware of the ref-counted wrapper type (s):\nPYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);\n// The following is not required anymore for std::shared_ptr, but it should compile without error:\nPYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>);\nPYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);\n\nTEST_SUBMODULE(smart_ptr, m) {\n    // Please do not interleave `struct` and `class` definitions with bindings code,\n    // but implement `struct`s and `class`es in the anonymous namespace above.\n    // This helps keeping the smart_holder branch in sync with master.\n\n    // test_smart_ptr\n\n    // Object implementation in `object.h`\n    py::class_<Object, ref<Object>> obj(m, \"Object\");\n    obj.def(\"getRefCount\", &Object::getRefCount);\n\n    py::class_<MyObject1, ref<MyObject1>>(m, \"MyObject1\", obj).def(py::init<int>());\n    py::implicitly_convertible<py::int_, MyObject1>();\n\n    m.def(\"make_object_1\", []() -> Object * { return new MyObject1(1); });\n    m.def(\"make_object_2\", []() -> ref<Object> { return ref<Object>(new MyObject1(2)); });\n    m.def(\"make_myobject1_1\", []() -> MyObject1 * { return new MyObject1(4); });\n    m.def(\"make_myobject1_2\", []() -> ref<MyObject1> { return ref<MyObject1>(new MyObject1(5)); });\n    m.def(\"print_object_1\", [](const Object *obj) { py::print(obj->toString()); });\n    m.def(\"print_object_2\", [](ref<Object> obj) { py::print(obj->toString()); });\n    m.def(\"print_object_3\", [](const ref<Object> &obj) { py::print(obj->toString()); });\n    m.def(\"print_object_4\", [](const ref<Object> *obj) { py::print((*obj)->toString()); });\n    m.def(\"print_myobject1_1\", [](const MyObject1 *obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_2\", [](ref<MyObject1> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_3\", [](const ref<MyObject1> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject1_4\", [](const ref<MyObject1> *obj) { py::print((*obj)->toString()); });\n\n    // Expose constructor stats for the ref type\n    m.def(\"cstats_ref\", &ConstructorStats::get<ref_tag>);\n\n    py::class_<MyObject2, std::shared_ptr<MyObject2>>(m, \"MyObject2\").def(py::init<int>());\n    m.def(\"make_myobject2_1\", []() { return new MyObject2(6); });\n    m.def(\"make_myobject2_2\", []() { return std::make_shared<MyObject2>(7); });\n    m.def(\"print_myobject2_1\", [](const MyObject2 *obj) { py::print(obj->toString()); });\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"print_myobject2_2\", [](std::shared_ptr<MyObject2> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject2_3\",\n          [](const std::shared_ptr<MyObject2> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject2_4\",\n          [](const std::shared_ptr<MyObject2> *obj) { py::print((*obj)->toString()); });\n\n    py::class_<MyObject3, std::shared_ptr<MyObject3>>(m, \"MyObject3\").def(py::init<int>());\n    m.def(\"make_myobject3_1\", []() { return new MyObject3(8); });\n    m.def(\"make_myobject3_2\", []() { return std::make_shared<MyObject3>(9); });\n    m.def(\"print_myobject3_1\", [](const MyObject3 *obj) { py::print(obj->toString()); });\n    // NOLINTNEXTLINE(performance-unnecessary-value-param)\n    m.def(\"print_myobject3_2\", [](std::shared_ptr<MyObject3> obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject3_3\",\n          [](const std::shared_ptr<MyObject3> &obj) { py::print(obj->toString()); });\n    m.def(\"print_myobject3_4\",\n          [](const std::shared_ptr<MyObject3> *obj) { py::print((*obj)->toString()); });\n\n    // test_smart_ptr_refcounting\n    m.def(\"test_object1_refcounting\", []() {\n        auto o = ref<MyObject1>(new MyObject1(0));\n        bool good = o->getRefCount() == 1;\n        py::object o2 = py::cast(o, py::return_value_policy::reference);\n        // always request (partial) ownership for objects with intrusive\n        // reference counting even when using the 'reference' RVP\n        good &= o->getRefCount() == 2;\n        return good;\n    });\n\n    // test_unique_nodelete\n    py::class_<MyObject4, std::unique_ptr<MyObject4, py::nodelete>>(m, \"MyObject4\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject4::value)\n        .def_static(\"cleanup_all_instances\", &MyObject4::cleanupAllInstances);\n\n    // test_unique_deleter\n    py::class_<MyObject4a, std::unique_ptr<MyObject4a, py::nodelete>>(m, \"MyObject4a\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject4a::value)\n        .def_static(\"cleanup_all_instances\", &MyObject4a::cleanupAllInstances);\n\n    py::class_<MyObject4b, MyObject4a, std::unique_ptr<MyObject4b>>(m, \"MyObject4b\")\n        .def(py::init<int>());\n\n    // test_large_holder\n    py::class_<MyObject5, huge_unique_ptr<MyObject5>>(m, \"MyObject5\")\n        .def(py::init<int>())\n        .def_readwrite(\"value\", &MyObject5::value);\n\n    // test_shared_ptr_and_references\n    using A = SharedPtrRef::A;\n    py::class_<A, std::shared_ptr<A>>(m, \"A\");\n    py::class_<SharedPtrRef, std::unique_ptr<SharedPtrRef>>(m, \"SharedPtrRef\")\n        .def(py::init<>())\n        .def_readonly(\"ref\", &SharedPtrRef::value)\n        .def_property_readonly(\n            \"copy\", [](const SharedPtrRef &s) { return s.value; }, py::return_value_policy::copy)\n        .def_readonly(\"holder_ref\", &SharedPtrRef::shared)\n        .def_property_readonly(\n            \"holder_copy\",\n            [](const SharedPtrRef &s) { return s.shared; },\n            py::return_value_policy::copy)\n        .def(\"set_ref\", [](SharedPtrRef &, const A &) { return true; })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"set_holder\", [](SharedPtrRef &, std::shared_ptr<A>) { return true; });\n\n    // test_shared_ptr_from_this_and_references\n    using B = SharedFromThisRef::B;\n    py::class_<B, std::shared_ptr<B>>(m, \"B\");\n    py::class_<SharedFromThisRef, std::unique_ptr<SharedFromThisRef>>(m, \"SharedFromThisRef\")\n        .def(py::init<>())\n        .def_readonly(\"bad_wp\", &SharedFromThisRef::value)\n        .def_property_readonly(\"ref\",\n                               [](const SharedFromThisRef &s) -> const B & { return *s.shared; })\n        .def_property_readonly(\n            \"copy\",\n            [](const SharedFromThisRef &s) { return s.value; },\n            py::return_value_policy::copy)\n        .def_readonly(\"holder_ref\", &SharedFromThisRef::shared)\n        .def_property_readonly(\n            \"holder_copy\",\n            [](const SharedFromThisRef &s) { return s.shared; },\n            py::return_value_policy::copy)\n        .def(\"set_ref\", [](SharedFromThisRef &, const B &) { return true; })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"set_holder\", [](SharedFromThisRef &, std::shared_ptr<B>) { return true; });\n\n    // Issue #865: shared_from_this doesn't work with virtual inheritance\n    static std::shared_ptr<SharedFromThisVirt> sft(new SharedFromThisVirt());\n    py::class_<SharedFromThisVirt, std::shared_ptr<SharedFromThisVirt>>(m, \"SharedFromThisVirt\")\n        .def_static(\"get\", []() { return sft.get(); });\n\n    // test_move_only_holder\n    py::class_<C, custom_unique_ptr<C>>(m, \"TypeWithMoveOnlyHolder\")\n        .def_static(\"make\", []() { return custom_unique_ptr<C>(new C); })\n        .def_static(\"make_as_object\", []() { return py::cast(custom_unique_ptr<C>(new C)); });\n\n    // test_holder_with_addressof_operator\n    using HolderWithAddressOf = shared_ptr_with_addressof_operator<TypeForHolderWithAddressOf>;\n    py::class_<TypeForHolderWithAddressOf, HolderWithAddressOf>(m, \"TypeForHolderWithAddressOf\")\n        .def_static(\"make\", []() { return HolderWithAddressOf(new TypeForHolderWithAddressOf); })\n        .def(\"get\", [](const HolderWithAddressOf &self) { return self.get(); })\n        .def(\"print_object_1\",\n             [](const TypeForHolderWithAddressOf *obj) { py::print(obj->toString()); })\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def(\"print_object_2\", [](HolderWithAddressOf obj) { py::print(obj.get()->toString()); })\n        .def(\"print_object_3\",\n             [](const HolderWithAddressOf &obj) { py::print(obj.get()->toString()); })\n        .def(\"print_object_4\",\n             [](const HolderWithAddressOf *obj) { py::print((*obj).get()->toString()); });\n\n    // test_move_only_holder_with_addressof_operator\n    using MoveOnlyHolderWithAddressOf\n        = unique_ptr_with_addressof_operator<TypeForMoveOnlyHolderWithAddressOf>;\n    py::class_<TypeForMoveOnlyHolderWithAddressOf, MoveOnlyHolderWithAddressOf>(\n        m, \"TypeForMoveOnlyHolderWithAddressOf\")\n        .def_static(\"make\",\n                    []() {\n                        return MoveOnlyHolderWithAddressOf(\n                            new TypeForMoveOnlyHolderWithAddressOf(0));\n                    })\n        .def_readwrite(\"value\", &TypeForMoveOnlyHolderWithAddressOf::value)\n        .def(\"print_object\",\n             [](const TypeForMoveOnlyHolderWithAddressOf *obj) { py::print(obj->toString()); });\n\n    // test_smart_ptr_from_default\n    py::class_<HeldByDefaultHolder, std::unique_ptr<HeldByDefaultHolder>>(m, \"HeldByDefaultHolder\")\n        .def(py::init<>())\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        .def_static(\"load_shared_ptr\", [](std::shared_ptr<HeldByDefaultHolder>) {});\n\n    // test_shared_ptr_gc\n    // #187: issue involving std::shared_ptr<> return value policy & garbage collection\n    py::class_<ElementBase, std::shared_ptr<ElementBase>>(m, \"ElementBase\");\n\n    py::class_<ElementA, ElementBase, std::shared_ptr<ElementA>>(m, \"ElementA\")\n        .def(py::init<int>())\n        .def(\"value\", &ElementA::value);\n\n    py::class_<ElementList, std::shared_ptr<ElementList>>(m, \"ElementList\")\n        .def(py::init<>())\n        .def(\"add\", &ElementList::add)\n        .def(\"get\", [](ElementList &el) {\n            py::list list;\n            for (auto &e : el.l) {\n                list.append(py::cast(e));\n            }\n            return list;\n        });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_smart_ptr.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nm = pytest.importorskip(\"pybind11_tests.smart_ptr\")\nfrom pybind11_tests import ConstructorStats  # noqa: E402\n\n\ndef test_smart_ptr(capture):\n    # Object1\n    for i, o in enumerate(\n        [m.make_object_1(), m.make_object_2(), m.MyObject1(3)], start=1\n    ):\n        assert o.getRefCount() == 1\n        with capture:\n            m.print_object_1(o)\n            m.print_object_2(o)\n            m.print_object_3(o)\n            m.print_object_4(o)\n        assert capture == \"MyObject1[{i}]\\n\".format(i=i) * 4\n\n    for i, o in enumerate(\n        [m.make_myobject1_1(), m.make_myobject1_2(), m.MyObject1(6), 7], start=4\n    ):\n        print(o)\n        with capture:\n            if not isinstance(o, int):\n                m.print_object_1(o)\n                m.print_object_2(o)\n                m.print_object_3(o)\n                m.print_object_4(o)\n            m.print_myobject1_1(o)\n            m.print_myobject1_2(o)\n            m.print_myobject1_3(o)\n            m.print_myobject1_4(o)\n\n        times = 4 if isinstance(o, int) else 8\n        assert capture == \"MyObject1[{i}]\\n\".format(i=i) * times\n\n    cstats = ConstructorStats.get(m.MyObject1)\n    assert cstats.alive() == 0\n    expected_values = [\"MyObject1[{}]\".format(i) for i in range(1, 7)] + [\n        \"MyObject1[7]\"\n    ] * 4\n    assert cstats.values() == expected_values\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object2\n    for i, o in zip(\n        [8, 6, 7], [m.MyObject2(8), m.make_myobject2_1(), m.make_myobject2_2()]\n    ):\n        print(o)\n        with capture:\n            m.print_myobject2_1(o)\n            m.print_myobject2_2(o)\n            m.print_myobject2_3(o)\n            m.print_myobject2_4(o)\n        assert capture == \"MyObject2[{i}]\\n\".format(i=i) * 4\n\n    cstats = ConstructorStats.get(m.MyObject2)\n    assert cstats.alive() == 1\n    o = None\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"MyObject2[8]\", \"MyObject2[6]\", \"MyObject2[7]\"]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object3\n    for i, o in zip(\n        [9, 8, 9], [m.MyObject3(9), m.make_myobject3_1(), m.make_myobject3_2()]\n    ):\n        print(o)\n        with capture:\n            m.print_myobject3_1(o)\n            m.print_myobject3_2(o)\n            m.print_myobject3_3(o)\n            m.print_myobject3_4(o)\n        assert capture == \"MyObject3[{i}]\\n\".format(i=i) * 4\n\n    cstats = ConstructorStats.get(m.MyObject3)\n    assert cstats.alive() == 1\n    o = None\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"MyObject3[9]\", \"MyObject3[8]\", \"MyObject3[9]\"]\n    assert cstats.default_constructions == 0\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # Object\n    cstats = ConstructorStats.get(m.Object)\n    assert cstats.alive() == 0\n    assert cstats.values() == []\n    assert cstats.default_constructions == 10\n    assert cstats.copy_constructions == 0\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 0\n    assert cstats.move_assignments == 0\n\n    # ref<>\n    cstats = m.cstats_ref()\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"from pointer\"] * 10\n    assert cstats.default_constructions == 30\n    assert cstats.copy_constructions == 12\n    # assert cstats.move_constructions >= 0 # Doesn't invoke any\n    assert cstats.copy_assignments == 30\n    assert cstats.move_assignments == 0\n\n\ndef test_smart_ptr_refcounting():\n    assert m.test_object1_refcounting()\n\n\ndef test_unique_nodelete():\n    o = m.MyObject4(23)\n    assert o.value == 23\n    cstats = ConstructorStats.get(m.MyObject4)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 1\n    m.MyObject4.cleanup_all_instances()\n    assert cstats.alive() == 0\n\n\ndef test_unique_nodelete4a():\n    o = m.MyObject4a(23)\n    assert o.value == 23\n    cstats = ConstructorStats.get(m.MyObject4a)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 1\n    m.MyObject4a.cleanup_all_instances()\n    assert cstats.alive() == 0\n\n\ndef test_unique_deleter():\n    m.MyObject4a(0)\n    o = m.MyObject4b(23)\n    assert o.value == 23\n    cstats4a = ConstructorStats.get(m.MyObject4a)\n    assert cstats4a.alive() == 2\n    cstats4b = ConstructorStats.get(m.MyObject4b)\n    assert cstats4b.alive() == 1\n    del o\n    assert cstats4a.alive() == 1  # Should now only be one leftover\n    assert cstats4b.alive() == 0  # Should be deleted\n    m.MyObject4a.cleanup_all_instances()\n    assert cstats4a.alive() == 0\n    assert cstats4b.alive() == 0\n\n\ndef test_large_holder():\n    o = m.MyObject5(5)\n    assert o.value == 5\n    cstats = ConstructorStats.get(m.MyObject5)\n    assert cstats.alive() == 1\n    del o\n    assert cstats.alive() == 0\n\n\ndef test_shared_ptr_and_references():\n    s = m.SharedPtrRef()\n    stats = ConstructorStats.get(m.A)\n    assert stats.alive() == 2\n\n    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false)\n    assert stats.alive() == 2\n    assert s.set_ref(ref)\n    with pytest.raises(RuntimeError) as excinfo:\n        assert s.set_holder(ref)\n    assert \"Unable to cast from non-held to held instance\" in str(excinfo.value)\n\n    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true)\n    assert stats.alive() == 3\n    assert s.set_ref(copy)\n    assert s.set_holder(copy)\n\n    holder_ref = s.holder_ref  # init_holder_helper(holder_ptr=true, owned=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_ref)\n    assert s.set_holder(holder_ref)\n\n    holder_copy = s.holder_copy  # init_holder_helper(holder_ptr=true, owned=true)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_copy)\n    assert s.set_holder(holder_copy)\n\n    del ref, copy, holder_ref, holder_copy, s\n    assert stats.alive() == 0\n\n\ndef test_shared_ptr_from_this_and_references():\n    s = m.SharedFromThisRef()\n    stats = ConstructorStats.get(m.B)\n    assert stats.alive() == 2\n\n    ref = s.ref  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=false)\n    assert stats.alive() == 2\n    assert s.set_ref(ref)\n    assert s.set_holder(\n        ref\n    )  # std::enable_shared_from_this can create a holder from a reference\n\n    bad_wp = s.bad_wp  # init_holder_helper(holder_ptr=false, owned=false, bad_wp=true)\n    assert stats.alive() == 2\n    assert s.set_ref(bad_wp)\n    with pytest.raises(RuntimeError) as excinfo:\n        assert s.set_holder(bad_wp)\n    assert \"Unable to cast from non-held to held instance\" in str(excinfo.value)\n\n    copy = s.copy  # init_holder_helper(holder_ptr=false, owned=true, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(copy)\n    assert s.set_holder(copy)\n\n    holder_ref = (\n        s.holder_ref\n    )  # init_holder_helper(holder_ptr=true, owned=false, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_ref)\n    assert s.set_holder(holder_ref)\n\n    holder_copy = (\n        s.holder_copy\n    )  # init_holder_helper(holder_ptr=true, owned=true, bad_wp=false)\n    assert stats.alive() == 3\n    assert s.set_ref(holder_copy)\n    assert s.set_holder(holder_copy)\n\n    del ref, bad_wp, copy, holder_ref, holder_copy, s\n    assert stats.alive() == 0\n\n    z = m.SharedFromThisVirt.get()\n    y = m.SharedFromThisVirt.get()\n    assert y is z\n\n\ndef test_move_only_holder():\n    a = m.TypeWithMoveOnlyHolder.make()\n    b = m.TypeWithMoveOnlyHolder.make_as_object()\n    stats = ConstructorStats.get(m.TypeWithMoveOnlyHolder)\n    assert stats.alive() == 2\n    del b\n    assert stats.alive() == 1\n    del a\n    assert stats.alive() == 0\n\n\ndef test_holder_with_addressof_operator():\n    # this test must not throw exception from c++\n    a = m.TypeForHolderWithAddressOf.make()\n    a.print_object_1()\n    a.print_object_2()\n    a.print_object_3()\n    a.print_object_4()\n\n    stats = ConstructorStats.get(m.TypeForHolderWithAddressOf)\n    assert stats.alive() == 1\n\n    np = m.TypeForHolderWithAddressOf.make()\n    assert stats.alive() == 2\n    del a\n    assert stats.alive() == 1\n    del np\n    assert stats.alive() == 0\n\n    b = m.TypeForHolderWithAddressOf.make()\n    c = b\n    assert b.get() is c.get()\n    assert stats.alive() == 1\n\n    del b\n    assert stats.alive() == 1\n\n    del c\n    assert stats.alive() == 0\n\n\ndef test_move_only_holder_with_addressof_operator():\n    a = m.TypeForMoveOnlyHolderWithAddressOf.make()\n    a.print_object()\n\n    stats = ConstructorStats.get(m.TypeForMoveOnlyHolderWithAddressOf)\n    assert stats.alive() == 1\n\n    a.value = 42\n    assert a.value == 42\n\n    del a\n    assert stats.alive() == 0\n\n\ndef test_smart_ptr_from_default():\n    instance = m.HeldByDefaultHolder()\n    with pytest.raises(RuntimeError) as excinfo:\n        m.HeldByDefaultHolder.load_shared_ptr(instance)\n    assert (\n        \"Unable to load a custom holder type from a \"\n        \"default-holder instance\" in str(excinfo.value)\n    )\n\n\ndef test_shared_ptr_gc():\n    \"\"\"#187: issue involving std::shared_ptr<> return value policy & garbage collection\"\"\"\n    el = m.ElementList()\n    for i in range(10):\n        el.add(m.ElementA(i))\n    pytest.gc_collect()\n    for i, v in enumerate(el.get()):\n        assert i == v.value()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_stl.cpp",
    "content": "/*\n    tests/test_stl.cpp -- STL type casters\n\n    Copyright (c) 2017 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#ifndef PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL\n#    define PYBIND11_HAS_FILESYSTEM_IS_OPTIONAL\n#endif\n#include <pybind11/stl/filesystem.h>\n\n#include <string>\n#include <vector>\n\n#if defined(PYBIND11_TEST_BOOST)\n#    include <boost/optional.hpp>\n\nnamespace pybind11 {\nnamespace detail {\ntemplate <typename T>\nstruct type_caster<boost::optional<T>> : optional_caster<boost::optional<T>> {};\n\ntemplate <>\nstruct type_caster<boost::none_t> : void_caster<boost::none_t> {};\n} // namespace detail\n} // namespace pybind11\n#endif\n\n// Test with `std::variant` in C++17 mode, or with `boost::variant` in C++11/14\n#if defined(PYBIND11_HAS_VARIANT)\nusing std::variant;\n#elif defined(PYBIND11_TEST_BOOST) && (!defined(_MSC_VER) || _MSC_VER >= 1910)\n#    include <boost/variant.hpp>\n#    define PYBIND11_HAS_VARIANT 1\nusing boost::variant;\n\nnamespace pybind11 {\nnamespace detail {\ntemplate <typename... Ts>\nstruct type_caster<boost::variant<Ts...>> : variant_caster<boost::variant<Ts...>> {};\n\ntemplate <>\nstruct visit_helper<boost::variant> {\n    template <typename... Args>\n    static auto call(Args &&...args) -> decltype(boost::apply_visitor(args...)) {\n        return boost::apply_visitor(args...);\n    }\n};\n} // namespace detail\n} // namespace pybind11\n#endif\n\nPYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);\n\n/// Issue #528: templated constructor\nstruct TplCtorClass {\n    template <typename T>\n    explicit TplCtorClass(const T &) {}\n    bool operator==(const TplCtorClass &) const { return true; }\n};\n\nnamespace std {\ntemplate <>\nstruct hash<TplCtorClass> {\n    size_t operator()(const TplCtorClass &) const { return 0; }\n};\n} // namespace std\n\ntemplate <template <typename> class OptionalImpl, typename T>\nstruct OptionalHolder {\n    // NOLINTNEXTLINE(modernize-use-equals-default): breaks GCC 4.8\n    OptionalHolder(){};\n    bool member_initialized() const { return member && member->initialized; }\n    OptionalImpl<T> member = T{};\n};\n\nenum class EnumType {\n    kSet = 42,\n    kUnset = 85,\n};\n\n// This is used to test that return-by-ref and return-by-copy policies are\n// handled properly for optional types. This is a regression test for a dangling\n// reference issue. The issue seemed to require the enum value type to\n// reproduce - it didn't seem to happen if the value type is just an integer.\ntemplate <template <typename> class OptionalImpl>\nclass OptionalProperties {\npublic:\n    using OptionalEnumValue = OptionalImpl<EnumType>;\n\n    OptionalProperties() : value(EnumType::kSet) {}\n    ~OptionalProperties() {\n        // Reset value to detect use-after-destruction.\n        // This is set to a specific value rather than nullopt to ensure that\n        // the memory that contains the value gets re-written.\n        value = EnumType::kUnset;\n    }\n\n    OptionalEnumValue &access_by_ref() { return value; }\n    OptionalEnumValue access_by_copy() { return value; }\n\nprivate:\n    OptionalEnumValue value;\n};\n\n// This type mimics aspects of boost::optional from old versions of Boost,\n// which exposed a dangling reference bug in Pybind11. Recent versions of\n// boost::optional, as well as libstdc++'s std::optional, don't seem to be\n// affected by the same issue. This is meant to be a minimal implementation\n// required to reproduce the issue, not fully standard-compliant.\n// See issue #3330 for more details.\ntemplate <typename T>\nclass ReferenceSensitiveOptional {\npublic:\n    using value_type = T;\n\n    ReferenceSensitiveOptional() = default;\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    ReferenceSensitiveOptional(const T &value) : storage{value} {}\n    // NOLINTNEXTLINE(google-explicit-constructor)\n    ReferenceSensitiveOptional(T &&value) : storage{std::move(value)} {}\n    ReferenceSensitiveOptional &operator=(const T &value) {\n        storage = {value};\n        return *this;\n    }\n    ReferenceSensitiveOptional &operator=(T &&value) {\n        storage = {std::move(value)};\n        return *this;\n    }\n\n    template <typename... Args>\n    T &emplace(Args &&...args) {\n        storage.clear();\n        storage.emplace_back(std::forward<Args>(args)...);\n        return storage.back();\n    }\n\n    const T &value() const noexcept {\n        assert(!storage.empty());\n        return storage[0];\n    }\n\n    const T &operator*() const noexcept { return value(); }\n\n    const T *operator->() const noexcept { return &value(); }\n\n    explicit operator bool() const noexcept { return !storage.empty(); }\n\nprivate:\n    std::vector<T> storage;\n};\n\nnamespace pybind11 {\nnamespace detail {\ntemplate <typename T>\nstruct type_caster<ReferenceSensitiveOptional<T>>\n    : optional_caster<ReferenceSensitiveOptional<T>> {};\n} // namespace detail\n} // namespace pybind11\n\nTEST_SUBMODULE(stl, m) {\n    // test_vector\n    m.def(\"cast_vector\", []() { return std::vector<int>{1}; });\n    m.def(\"load_vector\", [](const std::vector<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });\n    // `std::vector<bool>` is special because it returns proxy objects instead of references\n    m.def(\"cast_bool_vector\", []() { return std::vector<bool>{true, false}; });\n    m.def(\"load_bool_vector\",\n          [](const std::vector<bool> &v) { return v.at(0) == true && v.at(1) == false; });\n    // Unnumbered regression (caused by #936): pointers to stl containers aren't castable\n    static std::vector<RValueCaster> lvv{2};\n    m.def(\"cast_ptr_vector\", []() { return &lvv; });\n\n    // test_deque\n    m.def(\"cast_deque\", []() { return std::deque<int>{1}; });\n    m.def(\"load_deque\", [](const std::deque<int> &v) { return v.at(0) == 1 && v.at(1) == 2; });\n\n    // test_array\n    m.def(\"cast_array\", []() { return std::array<int, 2>{{1, 2}}; });\n    m.def(\"load_array\", [](const std::array<int, 2> &a) { return a[0] == 1 && a[1] == 2; });\n\n    // test_valarray\n    m.def(\"cast_valarray\", []() { return std::valarray<int>{1, 4, 9}; });\n    m.def(\"load_valarray\", [](const std::valarray<int> &v) {\n        return v.size() == 3 && v[0] == 1 && v[1] == 4 && v[2] == 9;\n    });\n\n    // test_map\n    m.def(\"cast_map\", []() { return std::map<std::string, std::string>{{\"key\", \"value\"}}; });\n    m.def(\"load_map\", [](const std::map<std::string, std::string> &map) {\n        return map.at(\"key\") == \"value\" && map.at(\"key2\") == \"value2\";\n    });\n\n    // test_set\n    m.def(\"cast_set\", []() { return std::set<std::string>{\"key1\", \"key2\"}; });\n    m.def(\"load_set\", [](const std::set<std::string> &set) {\n        return (set.count(\"key1\") != 0u) && (set.count(\"key2\") != 0u) && (set.count(\"key3\") != 0u);\n    });\n\n    // test_recursive_casting\n    m.def(\"cast_rv_vector\", []() { return std::vector<RValueCaster>{2}; });\n    m.def(\"cast_rv_array\", []() { return std::array<RValueCaster, 3>(); });\n    // NB: map and set keys are `const`, so while we technically do move them (as `const Type &&`),\n    // casters don't typically do anything with that, which means they fall to the `const Type &`\n    // caster.\n    m.def(\"cast_rv_map\", []() {\n        return std::unordered_map<std::string, RValueCaster>{{\"a\", RValueCaster{}}};\n    });\n    m.def(\"cast_rv_nested\", []() {\n        std::vector<std::array<std::list<std::unordered_map<std::string, RValueCaster>>, 2>> v;\n        v.emplace_back();           // add an array\n        v.back()[0].emplace_back(); // add a map to the array\n        v.back()[0].back().emplace(\"b\", RValueCaster{});\n        v.back()[0].back().emplace(\"c\", RValueCaster{});\n        v.back()[1].emplace_back(); // add a map to the array\n        v.back()[1].back().emplace(\"a\", RValueCaster{});\n        return v;\n    });\n    static std::array<RValueCaster, 2> lva;\n    static std::unordered_map<std::string, RValueCaster> lvm{{\"a\", RValueCaster{}},\n                                                             {\"b\", RValueCaster{}}};\n    static std::unordered_map<std::string, std::vector<std::list<std::array<RValueCaster, 2>>>>\n        lvn;\n    lvn[\"a\"].emplace_back();        // add a list\n    lvn[\"a\"].back().emplace_back(); // add an array\n    lvn[\"a\"].emplace_back();        // another list\n    lvn[\"a\"].back().emplace_back(); // add an array\n    lvn[\"b\"].emplace_back();        // add a list\n    lvn[\"b\"].back().emplace_back(); // add an array\n    lvn[\"b\"].back().emplace_back(); // add another array\n    m.def(\"cast_lv_vector\", []() -> const decltype(lvv) & { return lvv; });\n    m.def(\"cast_lv_array\", []() -> const decltype(lva) & { return lva; });\n    m.def(\"cast_lv_map\", []() -> const decltype(lvm) & { return lvm; });\n    m.def(\"cast_lv_nested\", []() -> const decltype(lvn) & { return lvn; });\n    // #853:\n    m.def(\"cast_unique_ptr_vector\", []() {\n        std::vector<std::unique_ptr<UserType>> v;\n        v.emplace_back(new UserType{7});\n        v.emplace_back(new UserType{42});\n        return v;\n    });\n\n    pybind11::enum_<EnumType>(m, \"EnumType\")\n        .value(\"kSet\", EnumType::kSet)\n        .value(\"kUnset\", EnumType::kUnset);\n\n    // test_move_out_container\n    struct MoveOutContainer {\n        struct Value {\n            int value;\n        };\n        std::list<Value> move_list() const { return {{0}, {1}, {2}}; }\n    };\n    py::class_<MoveOutContainer::Value>(m, \"MoveOutContainerValue\")\n        .def_readonly(\"value\", &MoveOutContainer::Value::value);\n    py::class_<MoveOutContainer>(m, \"MoveOutContainer\")\n        .def(py::init<>())\n        .def_property_readonly(\"move_list\", &MoveOutContainer::move_list);\n\n    // Class that can be move- and copy-constructed, but not assigned\n    struct NoAssign {\n        int value;\n\n        explicit NoAssign(int value = 0) : value(value) {}\n        NoAssign(const NoAssign &) = default;\n        NoAssign(NoAssign &&) = default;\n\n        NoAssign &operator=(const NoAssign &) = delete;\n        NoAssign &operator=(NoAssign &&) = delete;\n    };\n    py::class_<NoAssign>(m, \"NoAssign\", \"Class with no C++ assignment operators\")\n        .def(py::init<>())\n        .def(py::init<int>());\n\n    struct MoveOutDetector {\n        MoveOutDetector() = default;\n        MoveOutDetector(const MoveOutDetector &) = default;\n        MoveOutDetector(MoveOutDetector &&other) noexcept : initialized(other.initialized) {\n            // steal underlying resource\n            other.initialized = false;\n        }\n        bool initialized = true;\n    };\n    py::class_<MoveOutDetector>(m, \"MoveOutDetector\", \"Class with move tracking\")\n        .def(py::init<>())\n        .def_readonly(\"initialized\", &MoveOutDetector::initialized);\n\n#ifdef PYBIND11_HAS_OPTIONAL\n    // test_optional\n    m.attr(\"has_optional\") = true;\n\n    using opt_int = std::optional<int>;\n    using opt_no_assign = std::optional<NoAssign>;\n    m.def(\"double_or_zero\", [](const opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none\", [](int x) -> opt_int { return x != 0 ? opt_int(x / 2) : opt_int(); });\n    m.def(\n        \"test_nullopt\",\n        [](opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", std::nullopt, \"None\"));\n    m.def(\n        \"test_no_assign\",\n        [](const opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", std::nullopt, \"None\"));\n\n    m.def(\"nodefer_none_optional\", [](std::optional<int>) { return true; });\n    m.def(\"nodefer_none_optional\", [](const py::none &) { return false; });\n\n    using opt_holder = OptionalHolder<std::optional, MoveOutDetector>;\n    py::class_<opt_holder>(m, \"OptionalHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_holder::member)\n        .def(\"member_initialized\", &opt_holder::member_initialized);\n\n    using opt_props = OptionalProperties<std::optional>;\n    pybind11::class_<opt_props>(m, \"OptionalProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_props::access_by_copy);\n#endif\n\n#ifdef PYBIND11_HAS_EXP_OPTIONAL\n    // test_exp_optional\n    m.attr(\"has_exp_optional\") = true;\n\n    using exp_opt_int = std::experimental::optional<int>;\n    using exp_opt_no_assign = std::experimental::optional<NoAssign>;\n    m.def(\"double_or_zero_exp\", [](const exp_opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none_exp\",\n          [](int x) -> exp_opt_int { return x ? exp_opt_int(x / 2) : exp_opt_int(); });\n    m.def(\n        \"test_nullopt_exp\",\n        [](exp_opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", std::experimental::nullopt, \"None\"));\n    m.def(\n        \"test_no_assign_exp\",\n        [](const exp_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", std::experimental::nullopt, \"None\"));\n\n    using opt_exp_holder = OptionalHolder<std::experimental::optional, MoveOutDetector>;\n    py::class_<opt_exp_holder>(m, \"OptionalExpHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_exp_holder::member)\n        .def(\"member_initialized\", &opt_exp_holder::member_initialized);\n\n    using opt_exp_props = OptionalProperties<std::experimental::optional>;\n    pybind11::class_<opt_exp_props>(m, \"OptionalExpProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_exp_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_exp_props::access_by_copy);\n#endif\n\n#if defined(PYBIND11_TEST_BOOST)\n    // test_boost_optional\n    m.attr(\"has_boost_optional\") = true;\n\n    using boost_opt_int = boost::optional<int>;\n    using boost_opt_no_assign = boost::optional<NoAssign>;\n    m.def(\"double_or_zero_boost\", [](const boost_opt_int &x) -> int { return x.value_or(0) * 2; });\n    m.def(\"half_or_none_boost\",\n          [](int x) -> boost_opt_int { return x != 0 ? boost_opt_int(x / 2) : boost_opt_int(); });\n    m.def(\n        \"test_nullopt_boost\",\n        [](boost_opt_int x) { return x.value_or(42); },\n        py::arg_v(\"x\", boost::none, \"None\"));\n    m.def(\n        \"test_no_assign_boost\",\n        [](const boost_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", boost::none, \"None\"));\n\n    using opt_boost_holder = OptionalHolder<boost::optional, MoveOutDetector>;\n    py::class_<opt_boost_holder>(m, \"OptionalBoostHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_boost_holder::member)\n        .def(\"member_initialized\", &opt_boost_holder::member_initialized);\n\n    using opt_boost_props = OptionalProperties<boost::optional>;\n    pybind11::class_<opt_boost_props>(m, \"OptionalBoostProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_boost_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_boost_props::access_by_copy);\n#endif\n\n    // test_refsensitive_optional\n    using refsensitive_opt_int = ReferenceSensitiveOptional<int>;\n    using refsensitive_opt_no_assign = ReferenceSensitiveOptional<NoAssign>;\n    m.def(\"double_or_zero_refsensitive\",\n          [](const refsensitive_opt_int &x) -> int { return (x ? x.value() : 0) * 2; });\n    m.def(\"half_or_none_refsensitive\", [](int x) -> refsensitive_opt_int {\n        return x != 0 ? refsensitive_opt_int(x / 2) : refsensitive_opt_int();\n    });\n    m.def(\n        \"test_nullopt_refsensitive\",\n        // NOLINTNEXTLINE(performance-unnecessary-value-param)\n        [](refsensitive_opt_int x) { return x ? x.value() : 42; },\n        py::arg_v(\"x\", refsensitive_opt_int(), \"None\"));\n    m.def(\n        \"test_no_assign_refsensitive\",\n        [](const refsensitive_opt_no_assign &x) { return x ? x->value : 42; },\n        py::arg_v(\"x\", refsensitive_opt_no_assign(), \"None\"));\n\n    using opt_refsensitive_holder = OptionalHolder<ReferenceSensitiveOptional, MoveOutDetector>;\n    py::class_<opt_refsensitive_holder>(\n        m, \"OptionalRefSensitiveHolder\", \"Class with optional member\")\n        .def(py::init<>())\n        .def_readonly(\"member\", &opt_refsensitive_holder::member)\n        .def(\"member_initialized\", &opt_refsensitive_holder::member_initialized);\n\n    using opt_refsensitive_props = OptionalProperties<ReferenceSensitiveOptional>;\n    pybind11::class_<opt_refsensitive_props>(m, \"OptionalRefSensitiveProperties\")\n        .def(pybind11::init<>())\n        .def_property_readonly(\"access_by_ref\", &opt_refsensitive_props::access_by_ref)\n        .def_property_readonly(\"access_by_copy\", &opt_refsensitive_props::access_by_copy);\n\n#ifdef PYBIND11_HAS_FILESYSTEM\n    // test_fs_path\n    m.attr(\"has_filesystem\") = true;\n    m.def(\"parent_path\", [](const std::filesystem::path &p) { return p.parent_path(); });\n#endif\n\n#ifdef PYBIND11_HAS_VARIANT\n    static_assert(std::is_same<py::detail::variant_caster_visitor::result_type, py::handle>::value,\n                  \"visitor::result_type is required by boost::variant in C++11 mode\");\n\n    struct visitor {\n        using result_type = const char *;\n\n        result_type operator()(int) { return \"int\"; }\n        result_type operator()(const std::string &) { return \"std::string\"; }\n        result_type operator()(double) { return \"double\"; }\n        result_type operator()(std::nullptr_t) { return \"std::nullptr_t\"; }\n    };\n\n    // test_variant\n    m.def(\"load_variant\", [](const variant<int, std::string, double, std::nullptr_t> &v) {\n        return py::detail::visit_helper<variant>::call(visitor(), v);\n    });\n    m.def(\"load_variant_2pass\", [](variant<double, int> v) {\n        return py::detail::visit_helper<variant>::call(visitor(), v);\n    });\n    m.def(\"cast_variant\", []() {\n        using V = variant<int, std::string>;\n        return py::make_tuple(V(5), V(\"Hello\"));\n    });\n#endif\n\n    // #528: templated constructor\n    // (no python tests: the test here is that this compiles)\n    m.def(\"tpl_ctor_vector\", [](std::vector<TplCtorClass> &) {});\n    m.def(\"tpl_ctor_map\", [](std::unordered_map<TplCtorClass, TplCtorClass> &) {});\n    m.def(\"tpl_ctor_set\", [](std::unordered_set<TplCtorClass> &) {});\n#if defined(PYBIND11_HAS_OPTIONAL)\n    m.def(\"tpl_constr_optional\", [](std::optional<TplCtorClass> &) {});\n#endif\n#if defined(PYBIND11_HAS_EXP_OPTIONAL)\n    m.def(\"tpl_constr_optional_exp\", [](std::experimental::optional<TplCtorClass> &) {});\n#endif\n#if defined(PYBIND11_TEST_BOOST)\n    m.def(\"tpl_constr_optional_boost\", [](boost::optional<TplCtorClass> &) {});\n#endif\n\n    // test_vec_of_reference_wrapper\n    // #171: Can't return STL structures containing reference wrapper\n    m.def(\"return_vec_of_reference_wrapper\", [](std::reference_wrapper<UserType> p4) {\n        static UserType p1{1}, p2{2}, p3{3};\n        return std::vector<std::reference_wrapper<UserType>>{\n            std::ref(p1), std::ref(p2), std::ref(p3), p4};\n    });\n\n    // test_stl_pass_by_pointer\n    m.def(\n        \"stl_pass_by_pointer\", [](std::vector<int> *v) { return *v; }, \"v\"_a = nullptr);\n\n    // #1258: pybind11/stl.h converts string to vector<string>\n    m.def(\"func_with_string_or_vector_string_arg_overload\",\n          [](const std::vector<std::string> &) { return 1; });\n    m.def(\"func_with_string_or_vector_string_arg_overload\",\n          [](const std::list<std::string> &) { return 2; });\n    m.def(\"func_with_string_or_vector_string_arg_overload\", [](const std::string &) { return 3; });\n\n    class Placeholder {\n    public:\n        Placeholder() { print_created(this); }\n        Placeholder(const Placeholder &) = delete;\n        ~Placeholder() { print_destroyed(this); }\n    };\n    py::class_<Placeholder>(m, \"Placeholder\");\n\n    /// test_stl_vector_ownership\n    m.def(\n        \"test_stl_ownership\",\n        []() {\n            std::vector<Placeholder *> result;\n            result.push_back(new Placeholder());\n            return result;\n        },\n        py::return_value_policy::take_ownership);\n\n    m.def(\"array_cast_sequence\", [](std::array<int, 3> x) { return x; });\n\n    /// test_issue_1561\n    struct Issue1561Inner {\n        std::string data;\n    };\n    struct Issue1561Outer {\n        std::vector<Issue1561Inner> list;\n    };\n\n    py::class_<Issue1561Inner>(m, \"Issue1561Inner\")\n        .def(py::init<std::string>())\n        .def_readwrite(\"data\", &Issue1561Inner::data);\n\n    py::class_<Issue1561Outer>(m, \"Issue1561Outer\")\n        .def(py::init<>())\n        .def_readwrite(\"list\", &Issue1561Outer::list);\n\n    m.def(\n        \"return_vector_bool_raw_ptr\",\n        []() { return new std::vector<bool>(4513); },\n        // Without explicitly specifying `take_ownership`, this function leaks.\n        py::return_value_policy::take_ownership);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_stl.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nfrom pybind11_tests import ConstructorStats, UserType\nfrom pybind11_tests import stl as m\n\n\ndef test_vector(doc):\n    \"\"\"std::vector <-> list\"\"\"\n    lst = m.cast_vector()\n    assert lst == [1]\n    lst.append(2)\n    assert m.load_vector(lst)\n    assert m.load_vector(tuple(lst))\n\n    assert m.cast_bool_vector() == [True, False]\n    assert m.load_bool_vector([True, False])\n\n    assert doc(m.cast_vector) == \"cast_vector() -> List[int]\"\n    assert doc(m.load_vector) == \"load_vector(arg0: List[int]) -> bool\"\n\n    # Test regression caused by 936: pointers to stl containers weren't castable\n    assert m.cast_ptr_vector() == [\"lvalue\", \"lvalue\"]\n\n\ndef test_deque(doc):\n    \"\"\"std::deque <-> list\"\"\"\n    lst = m.cast_deque()\n    assert lst == [1]\n    lst.append(2)\n    assert m.load_deque(lst)\n    assert m.load_deque(tuple(lst))\n\n\ndef test_array(doc):\n    \"\"\"std::array <-> list\"\"\"\n    lst = m.cast_array()\n    assert lst == [1, 2]\n    assert m.load_array(lst)\n\n    assert doc(m.cast_array) == \"cast_array() -> List[int[2]]\"\n    assert doc(m.load_array) == \"load_array(arg0: List[int[2]]) -> bool\"\n\n\ndef test_valarray(doc):\n    \"\"\"std::valarray <-> list\"\"\"\n    lst = m.cast_valarray()\n    assert lst == [1, 4, 9]\n    assert m.load_valarray(lst)\n\n    assert doc(m.cast_valarray) == \"cast_valarray() -> List[int]\"\n    assert doc(m.load_valarray) == \"load_valarray(arg0: List[int]) -> bool\"\n\n\ndef test_map(doc):\n    \"\"\"std::map <-> dict\"\"\"\n    d = m.cast_map()\n    assert d == {\"key\": \"value\"}\n    assert \"key\" in d\n    d[\"key2\"] = \"value2\"\n    assert \"key2\" in d\n    assert m.load_map(d)\n\n    assert doc(m.cast_map) == \"cast_map() -> Dict[str, str]\"\n    assert doc(m.load_map) == \"load_map(arg0: Dict[str, str]) -> bool\"\n\n\ndef test_set(doc):\n    \"\"\"std::set <-> set\"\"\"\n    s = m.cast_set()\n    assert s == {\"key1\", \"key2\"}\n    s.add(\"key3\")\n    assert m.load_set(s)\n\n    assert doc(m.cast_set) == \"cast_set() -> Set[str]\"\n    assert doc(m.load_set) == \"load_set(arg0: Set[str]) -> bool\"\n\n\ndef test_recursive_casting():\n    \"\"\"Tests that stl casters preserve lvalue/rvalue context for container values\"\"\"\n    assert m.cast_rv_vector() == [\"rvalue\", \"rvalue\"]\n    assert m.cast_lv_vector() == [\"lvalue\", \"lvalue\"]\n    assert m.cast_rv_array() == [\"rvalue\", \"rvalue\", \"rvalue\"]\n    assert m.cast_lv_array() == [\"lvalue\", \"lvalue\"]\n    assert m.cast_rv_map() == {\"a\": \"rvalue\"}\n    assert m.cast_lv_map() == {\"a\": \"lvalue\", \"b\": \"lvalue\"}\n    assert m.cast_rv_nested() == [[[{\"b\": \"rvalue\", \"c\": \"rvalue\"}], [{\"a\": \"rvalue\"}]]]\n    assert m.cast_lv_nested() == {\n        \"a\": [[[\"lvalue\", \"lvalue\"]], [[\"lvalue\", \"lvalue\"]]],\n        \"b\": [[[\"lvalue\", \"lvalue\"], [\"lvalue\", \"lvalue\"]]],\n    }\n\n    # Issue #853 test case:\n    z = m.cast_unique_ptr_vector()\n    assert z[0].value == 7 and z[1].value == 42\n\n\ndef test_move_out_container():\n    \"\"\"Properties use the `reference_internal` policy by default. If the underlying function\n    returns an rvalue, the policy is automatically changed to `move` to avoid referencing\n    a temporary. In case the return value is a container of user-defined types, the policy\n    also needs to be applied to the elements, not just the container.\"\"\"\n    c = m.MoveOutContainer()\n    moved_out_list = c.move_list\n    assert [x.value for x in moved_out_list] == [0, 1, 2]\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_optional\"), reason=\"no <optional>\")\ndef test_optional():\n    assert m.double_or_zero(None) == 0\n    assert m.double_or_zero(42) == 84\n    pytest.raises(TypeError, m.double_or_zero, \"foo\")\n\n    assert m.half_or_none(0) is None\n    assert m.half_or_none(42) == 21\n    pytest.raises(TypeError, m.half_or_none, \"foo\")\n\n    assert m.test_nullopt() == 42\n    assert m.test_nullopt(None) == 42\n    assert m.test_nullopt(42) == 42\n    assert m.test_nullopt(43) == 43\n\n    assert m.test_no_assign() == 42\n    assert m.test_no_assign(None) == 42\n    assert m.test_no_assign(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign, 43)\n\n    assert m.nodefer_none_optional(None)\n\n    holder = m.OptionalHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(\n    not hasattr(m, \"has_exp_optional\"), reason=\"no <experimental/optional>\"\n)\ndef test_exp_optional():\n    assert m.double_or_zero_exp(None) == 0\n    assert m.double_or_zero_exp(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_exp, \"foo\")\n\n    assert m.half_or_none_exp(0) is None\n    assert m.half_or_none_exp(42) == 21\n    pytest.raises(TypeError, m.half_or_none_exp, \"foo\")\n\n    assert m.test_nullopt_exp() == 42\n    assert m.test_nullopt_exp(None) == 42\n    assert m.test_nullopt_exp(42) == 42\n    assert m.test_nullopt_exp(43) == 43\n\n    assert m.test_no_assign_exp() == 42\n    assert m.test_no_assign_exp(None) == 42\n    assert m.test_no_assign_exp(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_exp, 43)\n\n    holder = m.OptionalExpHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalExpProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_boost_optional\"), reason=\"no <boost/optional>\")\ndef test_boost_optional():\n    assert m.double_or_zero_boost(None) == 0\n    assert m.double_or_zero_boost(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_boost, \"foo\")\n\n    assert m.half_or_none_boost(0) is None\n    assert m.half_or_none_boost(42) == 21\n    pytest.raises(TypeError, m.half_or_none_boost, \"foo\")\n\n    assert m.test_nullopt_boost() == 42\n    assert m.test_nullopt_boost(None) == 42\n    assert m.test_nullopt_boost(42) == 42\n    assert m.test_nullopt_boost(43) == 43\n\n    assert m.test_no_assign_boost() == 42\n    assert m.test_no_assign_boost(None) == 42\n    assert m.test_no_assign_boost(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_boost, 43)\n\n    holder = m.OptionalBoostHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalBoostProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\ndef test_reference_sensitive_optional():\n    assert m.double_or_zero_refsensitive(None) == 0\n    assert m.double_or_zero_refsensitive(42) == 84\n    pytest.raises(TypeError, m.double_or_zero_refsensitive, \"foo\")\n\n    assert m.half_or_none_refsensitive(0) is None\n    assert m.half_or_none_refsensitive(42) == 21\n    pytest.raises(TypeError, m.half_or_none_refsensitive, \"foo\")\n\n    assert m.test_nullopt_refsensitive() == 42\n    assert m.test_nullopt_refsensitive(None) == 42\n    assert m.test_nullopt_refsensitive(42) == 42\n    assert m.test_nullopt_refsensitive(43) == 43\n\n    assert m.test_no_assign_refsensitive() == 42\n    assert m.test_no_assign_refsensitive(None) == 42\n    assert m.test_no_assign_refsensitive(m.NoAssign(43)) == 43\n    pytest.raises(TypeError, m.test_no_assign_refsensitive, 43)\n\n    holder = m.OptionalRefSensitiveHolder()\n    mvalue = holder.member\n    assert mvalue.initialized\n    assert holder.member_initialized()\n\n    props = m.OptionalRefSensitiveProperties()\n    assert int(props.access_by_ref) == 42\n    assert int(props.access_by_copy) == 42\n\n\n@pytest.mark.skipif(not hasattr(m, \"has_filesystem\"), reason=\"no <filesystem>\")\ndef test_fs_path():\n    from pathlib import Path\n\n    class PseudoStrPath:\n        def __fspath__(self):\n            return \"foo/bar\"\n\n    class PseudoBytesPath:\n        def __fspath__(self):\n            return b\"foo/bar\"\n\n    assert m.parent_path(Path(\"foo/bar\")) == Path(\"foo\")\n    assert m.parent_path(\"foo/bar\") == Path(\"foo\")\n    assert m.parent_path(b\"foo/bar\") == Path(\"foo\")\n    assert m.parent_path(PseudoStrPath()) == Path(\"foo\")\n    assert m.parent_path(PseudoBytesPath()) == Path(\"foo\")\n\n\n@pytest.mark.skipif(not hasattr(m, \"load_variant\"), reason=\"no <variant>\")\ndef test_variant(doc):\n    assert m.load_variant(1) == \"int\"\n    assert m.load_variant(\"1\") == \"std::string\"\n    assert m.load_variant(1.0) == \"double\"\n    assert m.load_variant(None) == \"std::nullptr_t\"\n\n    assert m.load_variant_2pass(1) == \"int\"\n    assert m.load_variant_2pass(1.0) == \"double\"\n\n    assert m.cast_variant() == (5, \"Hello\")\n\n    assert (\n        doc(m.load_variant) == \"load_variant(arg0: Union[int, str, float, None]) -> str\"\n    )\n\n\ndef test_vec_of_reference_wrapper():\n    \"\"\"#171: Can't return reference wrappers (or STL structures containing them)\"\"\"\n    assert (\n        str(m.return_vec_of_reference_wrapper(UserType(4)))\n        == \"[UserType(1), UserType(2), UserType(3), UserType(4)]\"\n    )\n\n\ndef test_stl_pass_by_pointer(msg):\n    \"\"\"Passing nullptr or None to an STL container pointer is not expected to work\"\"\"\n    with pytest.raises(TypeError) as excinfo:\n        m.stl_pass_by_pointer()  # default value is `nullptr`\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:\n            1. (v: List[int] = None) -> List[int]\n\n        Invoked with:\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        m.stl_pass_by_pointer(None)\n    assert (\n        msg(excinfo.value)\n        == \"\"\"\n        stl_pass_by_pointer(): incompatible function arguments. The following argument types are supported:\n            1. (v: List[int] = None) -> List[int]\n\n        Invoked with: None\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    assert m.stl_pass_by_pointer([1, 2, 3]) == [1, 2, 3]\n\n\ndef test_missing_header_message():\n    \"\"\"Trying convert `list` to a `std::vector`, or vice versa, without including\n    <pybind11/stl.h> should result in a helpful suggestion in the error message\"\"\"\n    import pybind11_cross_module_tests as cm\n\n    expected_message = (\n        \"Did you forget to `#include <pybind11/stl.h>`? Or <pybind11/complex.h>,\\n\"\n        \"<pybind11/functional.h>, <pybind11/chrono.h>, etc. Some automatic\\n\"\n        \"conversions are optional and require extra headers to be included\\n\"\n        \"when compiling your pybind11 module.\"\n    )\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.missing_header_arg([1.0, 2.0, 3.0])\n    assert expected_message in str(excinfo.value)\n\n    with pytest.raises(TypeError) as excinfo:\n        cm.missing_header_return()\n    assert expected_message in str(excinfo.value)\n\n\ndef test_function_with_string_and_vector_string_arg():\n    \"\"\"Check if a string is NOT implicitly converted to a list, which was the\n    behavior before fix of issue #1258\"\"\"\n    assert m.func_with_string_or_vector_string_arg_overload((\"A\", \"B\")) == 2\n    assert m.func_with_string_or_vector_string_arg_overload([\"A\", \"B\"]) == 2\n    assert m.func_with_string_or_vector_string_arg_overload(\"A\") == 3\n\n\ndef test_stl_ownership():\n    cstats = ConstructorStats.get(m.Placeholder)\n    assert cstats.alive() == 0\n    r = m.test_stl_ownership()\n    assert len(r) == 1\n    del r\n    assert cstats.alive() == 0\n\n\ndef test_array_cast_sequence():\n    assert m.array_cast_sequence((1, 2, 3)) == [1, 2, 3]\n\n\ndef test_issue_1561():\n    \"\"\"check fix for issue #1561\"\"\"\n    bar = m.Issue1561Outer()\n    bar.list = [m.Issue1561Inner(\"bar\")]\n    bar.list\n    assert bar.list[0].data == \"bar\"\n\n\ndef test_return_vector_bool_raw_ptr():\n    # Add `while True:` for manual leak checking.\n    v = m.return_vector_bool_raw_ptr()\n    assert isinstance(v, list)\n    assert len(v) == 4513\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_stl_binders.cpp",
    "content": "/*\n    tests/test_stl_binders.cpp -- Usage of stl_binders functions\n\n    Copyright (c) 2016 Sergey Lyskov\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/numpy.h>\n#include <pybind11/stl_bind.h>\n\n#include \"pybind11_tests.h\"\n\n#include <deque>\n#include <map>\n#include <unordered_map>\n\nclass El {\npublic:\n    El() = delete;\n    explicit El(int v) : a(v) {}\n\n    int a;\n};\n\nstd::ostream &operator<<(std::ostream &s, El const &v) {\n    s << \"El{\" << v.a << '}';\n    return s;\n}\n\n/// Issue #487: binding std::vector<E> with E non-copyable\nclass E_nc {\npublic:\n    explicit E_nc(int i) : value{i} {}\n    E_nc(const E_nc &) = delete;\n    E_nc &operator=(const E_nc &) = delete;\n    E_nc(E_nc &&) = default;\n    E_nc &operator=(E_nc &&) = default;\n\n    int value;\n};\n\ntemplate <class Container>\nContainer *one_to_n(int n) {\n    auto *v = new Container();\n    for (int i = 1; i <= n; i++) {\n        v->emplace_back(i);\n    }\n    return v;\n}\n\ntemplate <class Map>\nMap *times_ten(int n) {\n    auto *m = new Map();\n    for (int i = 1; i <= n; i++) {\n        m->emplace(int(i), E_nc(10 * i));\n    }\n    return m;\n}\n\ntemplate <class NestMap>\nNestMap *times_hundred(int n) {\n    auto *m = new NestMap();\n    for (int i = 1; i <= n; i++) {\n        for (int j = 1; j <= n; j++) {\n            (*m)[i].emplace(int(j * 10), E_nc(100 * j));\n        }\n    }\n    return m;\n}\n\nTEST_SUBMODULE(stl_binders, m) {\n    // test_vector_int\n    py::bind_vector<std::vector<unsigned int>>(m, \"VectorInt\", py::buffer_protocol());\n\n    // test_vector_custom\n    py::class_<El>(m, \"El\").def(py::init<int>());\n    py::bind_vector<std::vector<El>>(m, \"VectorEl\");\n    py::bind_vector<std::vector<std::vector<El>>>(m, \"VectorVectorEl\");\n\n    // test_map_string_double\n    py::bind_map<std::map<std::string, double>>(m, \"MapStringDouble\");\n    py::bind_map<std::unordered_map<std::string, double>>(m, \"UnorderedMapStringDouble\");\n\n    // test_map_string_double_const\n    py::bind_map<std::map<std::string, double const>>(m, \"MapStringDoubleConst\");\n    py::bind_map<std::unordered_map<std::string, double const>>(m,\n                                                                \"UnorderedMapStringDoubleConst\");\n\n    py::class_<E_nc>(m, \"ENC\").def(py::init<int>()).def_readwrite(\"value\", &E_nc::value);\n\n    // test_noncopyable_containers\n    py::bind_vector<std::vector<E_nc>>(m, \"VectorENC\");\n    m.def(\"get_vnc\", &one_to_n<std::vector<E_nc>>);\n    py::bind_vector<std::deque<E_nc>>(m, \"DequeENC\");\n    m.def(\"get_dnc\", &one_to_n<std::deque<E_nc>>);\n    py::bind_map<std::map<int, E_nc>>(m, \"MapENC\");\n    m.def(\"get_mnc\", &times_ten<std::map<int, E_nc>>);\n    py::bind_map<std::unordered_map<int, E_nc>>(m, \"UmapENC\");\n    m.def(\"get_umnc\", &times_ten<std::unordered_map<int, E_nc>>);\n    // Issue #1885: binding nested std::map<X, Container<E>> with E non-copyable\n    py::bind_map<std::map<int, std::vector<E_nc>>>(m, \"MapVecENC\");\n    m.def(\"get_nvnc\", [](int n) {\n        auto *m = new std::map<int, std::vector<E_nc>>();\n        for (int i = 1; i <= n; i++) {\n            for (int j = 1; j <= n; j++) {\n                (*m)[i].emplace_back(j);\n            }\n        }\n        return m;\n    });\n    py::bind_map<std::map<int, std::map<int, E_nc>>>(m, \"MapMapENC\");\n    m.def(\"get_nmnc\", &times_hundred<std::map<int, std::map<int, E_nc>>>);\n    py::bind_map<std::unordered_map<int, std::unordered_map<int, E_nc>>>(m, \"UmapUmapENC\");\n    m.def(\"get_numnc\", &times_hundred<std::unordered_map<int, std::unordered_map<int, E_nc>>>);\n\n    // test_vector_buffer\n    py::bind_vector<std::vector<unsigned char>>(m, \"VectorUChar\", py::buffer_protocol());\n    // no dtype declared for this version:\n    struct VUndeclStruct {\n        bool w;\n        uint32_t x;\n        double y;\n        bool z;\n    };\n    m.def(\"create_undeclstruct\", [m]() mutable {\n        py::bind_vector<std::vector<VUndeclStruct>>(\n            m, \"VectorUndeclStruct\", py::buffer_protocol());\n    });\n\n    // The rest depends on numpy:\n    try {\n        py::module_::import(\"numpy\");\n    } catch (...) {\n        return;\n    }\n\n    // test_vector_buffer_numpy\n    struct VStruct {\n        bool w;\n        uint32_t x;\n        double y;\n        bool z;\n    };\n    PYBIND11_NUMPY_DTYPE(VStruct, w, x, y, z);\n    py::class_<VStruct>(m, \"VStruct\").def_readwrite(\"x\", &VStruct::x);\n    py::bind_vector<std::vector<VStruct>>(m, \"VectorStruct\", py::buffer_protocol());\n    m.def(\"get_vectorstruct\", [] {\n        return std::vector<VStruct>{{false, 5, 3.0, true}, {true, 30, -1e4, false}};\n    });\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_stl_binders.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env\nfrom pybind11_tests import stl_binders as m\n\n\ndef test_vector_int():\n    v_int = m.VectorInt([0, 0])\n    assert len(v_int) == 2\n    assert bool(v_int) is True\n\n    # test construction from a generator\n    v_int1 = m.VectorInt(x for x in range(5))\n    assert v_int1 == m.VectorInt([0, 1, 2, 3, 4])\n\n    v_int2 = m.VectorInt([0, 0])\n    assert v_int == v_int2\n    v_int2[1] = 1\n    assert v_int != v_int2\n\n    v_int2.append(2)\n    v_int2.insert(0, 1)\n    v_int2.insert(0, 2)\n    v_int2.insert(0, 3)\n    v_int2.insert(6, 3)\n    assert str(v_int2) == \"VectorInt[3, 2, 1, 0, 1, 2, 3]\"\n    with pytest.raises(IndexError):\n        v_int2.insert(8, 4)\n\n    v_int.append(99)\n    v_int2[2:-2] = v_int\n    assert v_int2 == m.VectorInt([3, 2, 0, 0, 99, 2, 3])\n    del v_int2[1:3]\n    assert v_int2 == m.VectorInt([3, 0, 99, 2, 3])\n    del v_int2[0]\n    assert v_int2 == m.VectorInt([0, 99, 2, 3])\n\n    v_int2.extend(m.VectorInt([4, 5]))\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5])\n\n    v_int2.extend([6, 7])\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])\n\n    # test error handling, and that the vector is unchanged\n    with pytest.raises(RuntimeError):\n        v_int2.extend([8, \"a\"])\n\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7])\n\n    # test extending from a generator\n    v_int2.extend(x for x in range(5))\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4])\n\n    # test negative indexing\n    assert v_int2[-1] == 4\n\n    # insert with negative index\n    v_int2.insert(-1, 88)\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88, 4])\n\n    # delete negative index\n    del v_int2[-1]\n    assert v_int2 == m.VectorInt([0, 99, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 88])\n\n    v_int2.clear()\n    assert len(v_int2) == 0\n\n\n# Older PyPy's failed here, related to the PyPy's buffer protocol.\ndef test_vector_buffer():\n    b = bytearray([1, 2, 3, 4])\n    v = m.VectorUChar(b)\n    assert v[1] == 2\n    v[2] = 5\n    mv = memoryview(v)  # We expose the buffer interface\n    if not env.PY2:\n        assert mv[2] == 5\n        mv[2] = 6\n    else:\n        assert mv[2] == \"\\x05\"\n        mv[2] = \"\\x06\"\n    assert v[2] == 6\n\n    if not env.PY2:\n        mv = memoryview(b)\n        v = m.VectorUChar(mv[::2])\n        assert v[1] == 3\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.create_undeclstruct()  # Undeclared struct contents, no buffer interface\n    assert \"NumPy type info missing for \" in str(excinfo.value)\n\n\ndef test_vector_buffer_numpy():\n    np = pytest.importorskip(\"numpy\")\n    a = np.array([1, 2, 3, 4], dtype=np.int32)\n    with pytest.raises(TypeError):\n        m.VectorInt(a)\n\n    a = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], dtype=np.uintc)\n    v = m.VectorInt(a[0, :])\n    assert len(v) == 4\n    assert v[2] == 3\n    ma = np.asarray(v)\n    ma[2] = 5\n    assert v[2] == 5\n\n    v = m.VectorInt(a[:, 1])\n    assert len(v) == 3\n    assert v[2] == 10\n\n    v = m.get_vectorstruct()\n    assert v[0].x == 5\n    ma = np.asarray(v)\n    ma[1][\"x\"] = 99\n    assert v[1].x == 99\n\n    v = m.VectorStruct(\n        np.zeros(\n            3,\n            dtype=np.dtype(\n                [(\"w\", \"bool\"), (\"x\", \"I\"), (\"y\", \"float64\"), (\"z\", \"bool\")], align=True\n            ),\n        )\n    )\n    assert len(v) == 3\n\n    b = np.array([1, 2, 3, 4], dtype=np.uint8)\n    v = m.VectorUChar(b[::2])\n    assert v[1] == 3\n\n\ndef test_vector_bool():\n    import pybind11_cross_module_tests as cm\n\n    vv_c = cm.VectorBool()\n    for i in range(10):\n        vv_c.append(i % 2 == 0)\n    for i in range(10):\n        assert vv_c[i] == (i % 2 == 0)\n    assert str(vv_c) == \"VectorBool[1, 0, 1, 0, 1, 0, 1, 0, 1, 0]\"\n\n\ndef test_vector_custom():\n    v_a = m.VectorEl()\n    v_a.append(m.El(1))\n    v_a.append(m.El(2))\n    assert str(v_a) == \"VectorEl[El{1}, El{2}]\"\n\n    vv_a = m.VectorVectorEl()\n    vv_a.append(v_a)\n    vv_b = vv_a[0]\n    assert str(vv_b) == \"VectorEl[El{1}, El{2}]\"\n\n\ndef test_map_string_double():\n    mm = m.MapStringDouble()\n    mm[\"a\"] = 1\n    mm[\"b\"] = 2.5\n\n    assert list(mm) == [\"a\", \"b\"]\n    assert str(mm) == \"MapStringDouble{a: 1, b: 2.5}\"\n    assert \"b\" in mm\n    assert \"c\" not in mm\n    assert 123 not in mm\n\n    # Check that keys, values, items are views, not merely iterable\n    keys = mm.keys()\n    values = mm.values()\n    items = mm.items()\n    assert list(keys) == [\"a\", \"b\"]\n    assert len(keys) == 2\n    assert \"a\" in keys\n    assert \"c\" not in keys\n    assert 123 not in keys\n    assert list(items) == [(\"a\", 1), (\"b\", 2.5)]\n    assert len(items) == 2\n    assert (\"b\", 2.5) in items\n    assert \"hello\" not in items\n    assert (\"b\", 2.5, None) not in items\n    assert list(values) == [1, 2.5]\n    assert len(values) == 2\n    assert 1 in values\n    assert 2 not in values\n    # Check that views update when the map is updated\n    mm[\"c\"] = -1\n    assert list(keys) == [\"a\", \"b\", \"c\"]\n    assert list(values) == [1, 2.5, -1]\n    assert list(items) == [(\"a\", 1), (\"b\", 2.5), (\"c\", -1)]\n\n    um = m.UnorderedMapStringDouble()\n    um[\"ua\"] = 1.1\n    um[\"ub\"] = 2.6\n\n    assert sorted(list(um)) == [\"ua\", \"ub\"]\n    assert list(um.keys()) == list(um)\n    assert sorted(list(um.items())) == [(\"ua\", 1.1), (\"ub\", 2.6)]\n    assert list(zip(um.keys(), um.values())) == list(um.items())\n    assert \"UnorderedMapStringDouble\" in str(um)\n\n\ndef test_map_string_double_const():\n    mc = m.MapStringDoubleConst()\n    mc[\"a\"] = 10\n    mc[\"b\"] = 20.5\n    assert str(mc) == \"MapStringDoubleConst{a: 10, b: 20.5}\"\n\n    umc = m.UnorderedMapStringDoubleConst()\n    umc[\"a\"] = 11\n    umc[\"b\"] = 21.5\n\n    str(umc)\n\n\ndef test_noncopyable_containers():\n    # std::vector\n    vnc = m.get_vnc(5)\n    for i in range(0, 5):\n        assert vnc[i].value == i + 1\n\n    for i, j in enumerate(vnc, start=1):\n        assert j.value == i\n\n    # std::deque\n    dnc = m.get_dnc(5)\n    for i in range(0, 5):\n        assert dnc[i].value == i + 1\n\n    i = 1\n    for j in dnc:\n        assert j.value == i\n        i += 1\n\n    # std::map\n    mnc = m.get_mnc(5)\n    for i in range(1, 6):\n        assert mnc[i].value == 10 * i\n\n    vsum = 0\n    for k, v in mnc.items():\n        assert v.value == 10 * k\n        vsum += v.value\n\n    assert vsum == 150\n\n    # std::unordered_map\n    mnc = m.get_umnc(5)\n    for i in range(1, 6):\n        assert mnc[i].value == 10 * i\n\n    vsum = 0\n    for k, v in mnc.items():\n        assert v.value == 10 * k\n        vsum += v.value\n\n    assert vsum == 150\n\n    # nested std::map<std::vector>\n    nvnc = m.get_nvnc(5)\n    for i in range(1, 6):\n        for j in range(0, 5):\n            assert nvnc[i][j].value == j + 1\n\n    # Note: maps do not have .values()\n    for _, v in nvnc.items():\n        for i, j in enumerate(v, start=1):\n            assert j.value == i\n\n    # nested std::map<std::map>\n    nmnc = m.get_nmnc(5)\n    for i in range(1, 6):\n        for j in range(10, 60, 10):\n            assert nmnc[i][j].value == 10 * j\n\n    vsum = 0\n    for _, v_o in nmnc.items():\n        for k_i, v_i in v_o.items():\n            assert v_i.value == 10 * k_i\n            vsum += v_i.value\n\n    assert vsum == 7500\n\n    # nested std::unordered_map<std::unordered_map>\n    numnc = m.get_numnc(5)\n    for i in range(1, 6):\n        for j in range(10, 60, 10):\n            assert numnc[i][j].value == 10 * j\n\n    vsum = 0\n    for _, v_o in numnc.items():\n        for k_i, v_i in v_o.items():\n            assert v_i.value == 10 * k_i\n            vsum += v_i.value\n\n    assert vsum == 7500\n\n\ndef test_map_delitem():\n    mm = m.MapStringDouble()\n    mm[\"a\"] = 1\n    mm[\"b\"] = 2.5\n\n    assert list(mm) == [\"a\", \"b\"]\n    assert list(mm.items()) == [(\"a\", 1), (\"b\", 2.5)]\n    del mm[\"a\"]\n    assert list(mm) == [\"b\"]\n    assert list(mm.items()) == [(\"b\", 2.5)]\n\n    um = m.UnorderedMapStringDouble()\n    um[\"ua\"] = 1.1\n    um[\"ub\"] = 2.6\n\n    assert sorted(list(um)) == [\"ua\", \"ub\"]\n    assert sorted(list(um.items())) == [(\"ua\", 1.1), (\"ub\", 2.6)]\n    del um[\"ua\"]\n    assert sorted(list(um)) == [\"ub\"]\n    assert sorted(list(um.items())) == [(\"ub\", 2.6)]\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_tagbased_polymorphic.cpp",
    "content": "/*\n    tests/test_tagbased_polymorphic.cpp -- test of polymorphic_type_hook\n\n    Copyright (c) 2018 Hudson River Trading LLC <opensource@hudson-trading.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/stl.h>\n\n#include \"pybind11_tests.h\"\n\nstruct Animal {\n    // Make this type also a \"standard\" polymorphic type, to confirm that\n    // specializing polymorphic_type_hook using enable_if_t still works\n    // (https://github.com/pybind/pybind11/pull/2016/).\n    virtual ~Animal() = default;\n\n    // Enum for tag-based polymorphism.\n    enum class Kind {\n        Unknown = 0,\n        Dog = 100,\n        Labrador,\n        Chihuahua,\n        LastDog = 199,\n        Cat = 200,\n        Panther,\n        LastCat = 299\n    };\n    static const std::type_info *type_of_kind(Kind kind);\n    static std::string name_of_kind(Kind kind);\n\n    const Kind kind;\n    const std::string name;\n\nprotected:\n    Animal(const std::string &_name, Kind _kind) : kind(_kind), name(_name) {}\n};\n\nstruct Dog : Animal {\n    explicit Dog(const std::string &_name, Kind _kind = Kind::Dog) : Animal(_name, _kind) {}\n    std::string bark() const { return name_of_kind(kind) + \" \" + name + \" goes \" + sound; }\n    std::string sound = \"WOOF!\";\n};\n\nstruct Labrador : Dog {\n    explicit Labrador(const std::string &_name, int _excitement = 9001)\n        : Dog(_name, Kind::Labrador), excitement(_excitement) {}\n    int excitement;\n};\n\nstruct Chihuahua : Dog {\n    explicit Chihuahua(const std::string &_name) : Dog(_name, Kind::Chihuahua) {\n        sound = \"iyiyiyiyiyi\";\n    }\n    std::string bark() const { return Dog::bark() + \" and runs in circles\"; }\n};\n\nstruct Cat : Animal {\n    explicit Cat(const std::string &_name, Kind _kind = Kind::Cat) : Animal(_name, _kind) {}\n    std::string purr() const { return \"mrowr\"; }\n};\n\nstruct Panther : Cat {\n    explicit Panther(const std::string &_name) : Cat(_name, Kind::Panther) {}\n    std::string purr() const { return \"mrrrRRRRRR\"; }\n};\n\nstd::vector<std::unique_ptr<Animal>> create_zoo() {\n    std::vector<std::unique_ptr<Animal>> ret;\n    ret.emplace_back(new Labrador(\"Fido\", 15000));\n\n    // simulate some new type of Dog that the Python bindings\n    // haven't been updated for; it should still be considered\n    // a Dog, not just an Animal.\n    ret.emplace_back(new Dog(\"Ginger\", Dog::Kind(150)));\n\n    ret.emplace_back(new Chihuahua(\"Hertzl\"));\n    ret.emplace_back(new Cat(\"Tiger\", Cat::Kind::Cat));\n    ret.emplace_back(new Panther(\"Leo\"));\n    return ret;\n}\n\nconst std::type_info *Animal::type_of_kind(Kind kind) {\n    switch (kind) {\n        case Kind::Unknown:\n        case Kind::Dog:\n            break;\n\n        case Kind::Labrador:\n            return &typeid(Labrador);\n        case Kind::Chihuahua:\n            return &typeid(Chihuahua);\n\n        case Kind::LastDog:\n        case Kind::Cat:\n            break;\n        case Kind::Panther:\n            return &typeid(Panther);\n        case Kind::LastCat:\n            break;\n    }\n\n    if (kind >= Kind::Dog && kind <= Kind::LastDog) {\n        return &typeid(Dog);\n    }\n    if (kind >= Kind::Cat && kind <= Kind::LastCat) {\n        return &typeid(Cat);\n    }\n    return nullptr;\n}\n\nstd::string Animal::name_of_kind(Kind kind) {\n    std::string raw_name = type_of_kind(kind)->name();\n    py::detail::clean_type_id(raw_name);\n    return raw_name;\n}\n\nnamespace pybind11 {\ntemplate <typename itype>\nstruct polymorphic_type_hook<itype, detail::enable_if_t<std::is_base_of<Animal, itype>::value>> {\n    static const void *get(const itype *src, const std::type_info *&type) {\n        type = src ? Animal::type_of_kind(src->kind) : nullptr;\n        return src;\n    }\n};\n} // namespace pybind11\n\nTEST_SUBMODULE(tagbased_polymorphic, m) {\n    py::class_<Animal>(m, \"Animal\").def_readonly(\"name\", &Animal::name);\n    py::class_<Dog, Animal>(m, \"Dog\")\n        .def(py::init<std::string>())\n        .def_readwrite(\"sound\", &Dog::sound)\n        .def(\"bark\", &Dog::bark);\n    py::class_<Labrador, Dog>(m, \"Labrador\")\n        .def(py::init<std::string, int>(), \"name\"_a, \"excitement\"_a = 9001)\n        .def_readwrite(\"excitement\", &Labrador::excitement);\n    py::class_<Chihuahua, Dog>(m, \"Chihuahua\")\n        .def(py::init<std::string>())\n        .def(\"bark\", &Chihuahua::bark);\n    py::class_<Cat, Animal>(m, \"Cat\").def(py::init<std::string>()).def(\"purr\", &Cat::purr);\n    py::class_<Panther, Cat>(m, \"Panther\")\n        .def(py::init<std::string>())\n        .def(\"purr\", &Panther::purr);\n    m.def(\"create_zoo\", &create_zoo);\n};\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_tagbased_polymorphic.py",
    "content": "# -*- coding: utf-8 -*-\nfrom pybind11_tests import tagbased_polymorphic as m\n\n\ndef test_downcast():\n    zoo = m.create_zoo()\n    assert [type(animal) for animal in zoo] == [\n        m.Labrador,\n        m.Dog,\n        m.Chihuahua,\n        m.Cat,\n        m.Panther,\n    ]\n    assert [animal.name for animal in zoo] == [\n        \"Fido\",\n        \"Ginger\",\n        \"Hertzl\",\n        \"Tiger\",\n        \"Leo\",\n    ]\n    zoo[1].sound = \"woooooo\"\n    assert [dog.bark() for dog in zoo[:3]] == [\n        \"Labrador Fido goes WOOF!\",\n        \"Dog Ginger goes woooooo\",\n        \"Chihuahua Hertzl goes iyiyiyiyiyi and runs in circles\",\n    ]\n    assert [cat.purr() for cat in zoo[3:]] == [\"mrowr\", \"mrrrRRRRRR\"]\n    zoo[0].excitement -= 1000\n    assert zoo[0].excitement == 14000\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_thread.cpp",
    "content": "/*\n    tests/test_thread.cpp -- call pybind11 bound methods in threads\n\n    Copyright (c) 2021 Laramie Leavitt (Google LLC) <lar@google.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/cast.h>\n#include <pybind11/pybind11.h>\n\n#include \"pybind11_tests.h\"\n\n#include <chrono>\n#include <thread>\n\nnamespace py = pybind11;\n\nnamespace {\n\nstruct IntStruct {\n    explicit IntStruct(int v) : value(v){};\n    ~IntStruct() { value = -value; }\n    IntStruct(const IntStruct &) = default;\n    IntStruct &operator=(const IntStruct &) = default;\n\n    int value;\n};\n\n} // namespace\n\nTEST_SUBMODULE(thread, m) {\n\n    py::class_<IntStruct>(m, \"IntStruct\").def(py::init([](const int i) { return IntStruct(i); }));\n\n    // implicitly_convertible uses loader_life_support when an implicit\n    // conversion is required in order to lifetime extend the reference.\n    //\n    // This test should be run with ASAN for better effectiveness.\n    py::implicitly_convertible<int, IntStruct>();\n\n    m.def(\"test\", [](int expected, const IntStruct &in) {\n        {\n            py::gil_scoped_release release;\n            std::this_thread::sleep_for(std::chrono::milliseconds(5));\n        }\n\n        if (in.value != expected) {\n            throw std::runtime_error(\"Value changed!!\");\n        }\n    });\n\n    m.def(\n        \"test_no_gil\",\n        [](int expected, const IntStruct &in) {\n            std::this_thread::sleep_for(std::chrono::milliseconds(5));\n            if (in.value != expected) {\n                throw std::runtime_error(\"Value changed!!\");\n            }\n        },\n        py::call_guard<py::gil_scoped_release>());\n\n    // NOTE: std::string_view also uses loader_life_support to ensure that\n    // the string contents remain alive, but that's a C++ 17 feature.\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_thread.py",
    "content": "# -*- coding: utf-8 -*-\n\nimport threading\n\nfrom pybind11_tests import thread as m\n\n\nclass Thread(threading.Thread):\n    def __init__(self, fn):\n        super(Thread, self).__init__()\n        self.fn = fn\n        self.e = None\n\n    def run(self):\n        try:\n            for i in range(10):\n                self.fn(i, i)\n        except Exception as e:\n            self.e = e\n\n    def join(self):\n        super(Thread, self).join()\n        if self.e:\n            raise self.e\n\n\ndef test_implicit_conversion():\n    a = Thread(m.test)\n    b = Thread(m.test)\n    c = Thread(m.test)\n    for x in [a, b, c]:\n        x.start()\n    for x in [c, b, a]:\n        x.join()\n\n\ndef test_implicit_conversion_no_gil():\n    a = Thread(m.test_no_gil)\n    b = Thread(m.test_no_gil)\n    c = Thread(m.test_no_gil)\n    for x in [a, b, c]:\n        x.start()\n    for x in [c, b, a]:\n        x.join()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_union.cpp",
    "content": "/*\n    tests/test_class.cpp -- test py::class_ definitions and basic functionality\n\n    Copyright (c) 2019 Roland Dreier <roland.dreier@gmail.com>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include \"pybind11_tests.h\"\n\nTEST_SUBMODULE(union_, m) {\n    union TestUnion {\n        int value_int;\n        unsigned value_uint;\n    };\n\n    py::class_<TestUnion>(m, \"TestUnion\")\n        .def(py::init<>())\n        .def_readonly(\"as_int\", &TestUnion::value_int)\n        .def_readwrite(\"as_uint\", &TestUnion::value_uint);\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_union.py",
    "content": "# -*- coding: utf-8 -*-\nfrom pybind11_tests import union_ as m\n\n\ndef test_union():\n    instance = m.TestUnion()\n\n    instance.as_uint = 10\n    assert instance.as_int == 10\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_virtual_functions.cpp",
    "content": "/*\n    tests/test_virtual_functions.cpp -- overriding virtual functions from Python\n\n    Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>\n\n    All rights reserved. Use of this source code is governed by a\n    BSD-style license that can be found in the LICENSE file.\n*/\n\n#include <pybind11/functional.h>\n\n#include \"constructor_stats.h\"\n#include \"pybind11_tests.h\"\n\n#include <thread>\n\n/* This is an example class that we'll want to be able to extend from Python */\nclass ExampleVirt {\npublic:\n    explicit ExampleVirt(int state) : state(state) { print_created(this, state); }\n    ExampleVirt(const ExampleVirt &e) : state(e.state) { print_copy_created(this); }\n    ExampleVirt(ExampleVirt &&e) noexcept : state(e.state) {\n        print_move_created(this);\n        e.state = 0;\n    }\n    virtual ~ExampleVirt() { print_destroyed(this); }\n\n    virtual int run(int value) {\n        py::print(\"Original implementation of \"\n                  \"ExampleVirt::run(state={}, value={}, str1={}, str2={})\"_s.format(\n                      state, value, get_string1(), *get_string2()));\n        return state + value;\n    }\n\n    virtual bool run_bool() = 0;\n    virtual void pure_virtual() = 0;\n\n    // Returning a reference/pointer to a type converted from python (numbers, strings, etc.) is a\n    // bit trickier, because the actual int& or std::string& or whatever only exists temporarily,\n    // so we have to handle it specially in the trampoline class (see below).\n    virtual const std::string &get_string1() { return str1; }\n    virtual const std::string *get_string2() { return &str2; }\n\nprivate:\n    int state;\n    const std::string str1{\"default1\"}, str2{\"default2\"};\n};\n\n/* This is a wrapper class that must be generated */\nclass PyExampleVirt : public ExampleVirt {\npublic:\n    using ExampleVirt::ExampleVirt; /* Inherit constructors */\n\n    int run(int value) override {\n        /* Generate wrapping code that enables native function overloading */\n        PYBIND11_OVERRIDE(int,         /* Return type */\n                          ExampleVirt, /* Parent class */\n                          run,         /* Name of function */\n                          value        /* Argument(s) */\n        );\n    }\n\n    bool run_bool() override {\n        PYBIND11_OVERRIDE_PURE(bool,        /* Return type */\n                               ExampleVirt, /* Parent class */\n                               run_bool,    /* Name of function */\n                                            /* This function has no arguments. The trailing comma\n                                               in the previous line is needed for some compilers */\n        );\n    }\n\n    void pure_virtual() override {\n        PYBIND11_OVERRIDE_PURE(void,         /* Return type */\n                               ExampleVirt,  /* Parent class */\n                               pure_virtual, /* Name of function */\n                                             /* This function has no arguments. The trailing comma\n                                                in the previous line is needed for some compilers */\n        );\n    }\n\n    // We can return reference types for compatibility with C++ virtual interfaces that do so, but\n    // note they have some significant limitations (see the documentation).\n    const std::string &get_string1() override {\n        PYBIND11_OVERRIDE(const std::string &, /* Return type */\n                          ExampleVirt,         /* Parent class */\n                          get_string1,         /* Name of function */\n                                               /* (no arguments) */\n        );\n    }\n\n    const std::string *get_string2() override {\n        PYBIND11_OVERRIDE(const std::string *, /* Return type */\n                          ExampleVirt,         /* Parent class */\n                          get_string2,         /* Name of function */\n                                               /* (no arguments) */\n        );\n    }\n};\n\nclass NonCopyable {\npublic:\n    NonCopyable(int a, int b) : value{new int(a * b)} { print_created(this, a, b); }\n    NonCopyable(NonCopyable &&o) noexcept : value{std::move(o.value)} { print_move_created(this); }\n    NonCopyable(const NonCopyable &) = delete;\n    NonCopyable() = delete;\n    void operator=(const NonCopyable &) = delete;\n    void operator=(NonCopyable &&) = delete;\n    std::string get_value() const {\n        if (value) {\n            return std::to_string(*value);\n        }\n        return \"(null)\";\n    }\n    ~NonCopyable() { print_destroyed(this); }\n\nprivate:\n    std::unique_ptr<int> value;\n};\n\n// This is like the above, but is both copy and movable.  In effect this means it should get moved\n// when it is not referenced elsewhere, but copied if it is still referenced.\nclass Movable {\npublic:\n    Movable(int a, int b) : value{a + b} { print_created(this, a, b); }\n    Movable(const Movable &m) : value{m.value} { print_copy_created(this); }\n    Movable(Movable &&m) noexcept : value{m.value} { print_move_created(this); }\n    std::string get_value() const { return std::to_string(value); }\n    ~Movable() { print_destroyed(this); }\n\nprivate:\n    int value;\n};\n\nclass NCVirt {\npublic:\n    virtual ~NCVirt() = default;\n    NCVirt() = default;\n    NCVirt(const NCVirt &) = delete;\n    virtual NonCopyable get_noncopyable(int a, int b) { return NonCopyable(a, b); }\n    virtual Movable get_movable(int a, int b) = 0;\n\n    std::string print_nc(int a, int b) { return get_noncopyable(a, b).get_value(); }\n    std::string print_movable(int a, int b) { return get_movable(a, b).get_value(); }\n};\nclass NCVirtTrampoline : public NCVirt {\n#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)\n    NonCopyable get_noncopyable(int a, int b) override {\n        PYBIND11_OVERRIDE(NonCopyable, NCVirt, get_noncopyable, a, b);\n    }\n#endif\n    Movable get_movable(int a, int b) override {\n        PYBIND11_OVERRIDE_PURE(Movable, NCVirt, get_movable, a, b);\n    }\n};\n\nstruct Base {\n    /* for some reason MSVC2015 can't compile this if the function is pure virtual */\n    virtual std::string dispatch() const { return {}; };\n    virtual ~Base() = default;\n    Base() = default;\n    Base(const Base &) = delete;\n};\n\nstruct DispatchIssue : Base {\n    std::string dispatch() const override {\n        PYBIND11_OVERRIDE_PURE(std::string, Base, dispatch, /* no arguments */);\n    }\n};\n\n// An abstract adder class that uses visitor pattern to add two data\n// objects and send the result to the visitor functor\nstruct AdderBase {\n    struct Data {};\n    using DataVisitor = std::function<void(const Data &)>;\n\n    virtual void\n    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const = 0;\n    virtual ~AdderBase() = default;\n    AdderBase() = default;\n    AdderBase(const AdderBase &) = delete;\n};\n\nstruct Adder : AdderBase {\n    void\n    operator()(const Data &first, const Data &second, const DataVisitor &visitor) const override {\n        PYBIND11_OVERRIDE_PURE_NAME(\n            void, AdderBase, \"__call__\", operator(), first, second, visitor);\n    }\n};\n\nstatic void test_gil() {\n    {\n        py::gil_scoped_acquire lock;\n        py::print(\"1st lock acquired\");\n    }\n\n    {\n        py::gil_scoped_acquire lock;\n        py::print(\"2nd lock acquired\");\n    }\n}\n\nstatic void test_gil_from_thread() {\n    py::gil_scoped_release release;\n\n    std::thread t(test_gil);\n    t.join();\n}\n\nclass test_override_cache_helper {\n\npublic:\n    virtual int func() { return 0; }\n\n    test_override_cache_helper() = default;\n    virtual ~test_override_cache_helper() = default;\n    // Non-copyable\n    test_override_cache_helper &operator=(test_override_cache_helper const &Right) = delete;\n    test_override_cache_helper(test_override_cache_helper const &Copy) = delete;\n};\n\nclass test_override_cache_helper_trampoline : public test_override_cache_helper {\n    int func() override { PYBIND11_OVERRIDE(int, test_override_cache_helper, func); }\n};\n\ninline int test_override_cache(std::shared_ptr<test_override_cache_helper> const &instance) {\n    return instance->func();\n}\n\n// Forward declaration (so that we can put the main tests here; the inherited virtual approaches\n// are rather long).\nvoid initialize_inherited_virtuals(py::module_ &m);\n\nTEST_SUBMODULE(virtual_functions, m) {\n    // test_override\n    py::class_<ExampleVirt, PyExampleVirt>(m, \"ExampleVirt\")\n        .def(py::init<int>())\n        /* Reference original class in function definitions */\n        .def(\"run\", &ExampleVirt::run)\n        .def(\"run_bool\", &ExampleVirt::run_bool)\n        .def(\"pure_virtual\", &ExampleVirt::pure_virtual);\n\n    py::class_<NonCopyable>(m, \"NonCopyable\").def(py::init<int, int>());\n\n    py::class_<Movable>(m, \"Movable\").def(py::init<int, int>());\n\n    // test_move_support\n#if !defined(__INTEL_COMPILER) && !defined(__CUDACC__) && !defined(__PGIC__)\n    py::class_<NCVirt, NCVirtTrampoline>(m, \"NCVirt\")\n        .def(py::init<>())\n        .def(\"get_noncopyable\", &NCVirt::get_noncopyable)\n        .def(\"get_movable\", &NCVirt::get_movable)\n        .def(\"print_nc\", &NCVirt::print_nc)\n        .def(\"print_movable\", &NCVirt::print_movable);\n#endif\n\n    m.def(\"runExampleVirt\", [](ExampleVirt *ex, int value) { return ex->run(value); });\n    m.def(\"runExampleVirtBool\", [](ExampleVirt *ex) { return ex->run_bool(); });\n    m.def(\"runExampleVirtVirtual\", [](ExampleVirt *ex) { ex->pure_virtual(); });\n\n    m.def(\"cstats_debug\", &ConstructorStats::get<ExampleVirt>);\n    initialize_inherited_virtuals(m);\n\n    // test_alias_delay_initialization1\n    // don't invoke Python dispatch classes by default when instantiating C++ classes\n    // that were not extended on the Python side\n    struct A {\n        A() = default;\n        A(const A &) = delete;\n        virtual ~A() = default;\n        virtual void f() { py::print(\"A.f()\"); }\n    };\n\n    struct PyA : A {\n        PyA() { py::print(\"PyA.PyA()\"); }\n        PyA(const PyA &) = delete;\n        ~PyA() override { py::print(\"PyA.~PyA()\"); }\n\n        void f() override {\n            py::print(\"PyA.f()\");\n            // This convolution just gives a `void`, but tests that PYBIND11_TYPE() works to\n            // protect a type containing a ,\n            PYBIND11_OVERRIDE(PYBIND11_TYPE(typename std::enable_if<true, void>::type), A, f);\n        }\n    };\n\n    py::class_<A, PyA>(m, \"A\").def(py::init<>()).def(\"f\", &A::f);\n\n    m.def(\"call_f\", [](A *a) { a->f(); });\n\n    // test_alias_delay_initialization2\n    // ... unless we explicitly request it, as in this example:\n    struct A2 {\n        A2() = default;\n        A2(const A2 &) = delete;\n        virtual ~A2() = default;\n        virtual void f() { py::print(\"A2.f()\"); }\n    };\n\n    struct PyA2 : A2 {\n        PyA2() { py::print(\"PyA2.PyA2()\"); }\n        PyA2(const PyA2 &) = delete;\n        ~PyA2() override { py::print(\"PyA2.~PyA2()\"); }\n        void f() override {\n            py::print(\"PyA2.f()\");\n            PYBIND11_OVERRIDE(void, A2, f);\n        }\n    };\n\n    py::class_<A2, PyA2>(m, \"A2\")\n        .def(py::init_alias<>())\n        .def(py::init([](int) { return new PyA2(); }))\n        .def(\"f\", &A2::f);\n\n    m.def(\"call_f\", [](A2 *a2) { a2->f(); });\n\n    // test_dispatch_issue\n    // #159: virtual function dispatch has problems with similar-named functions\n    py::class_<Base, DispatchIssue>(m, \"DispatchIssue\")\n        .def(py::init<>())\n        .def(\"dispatch\", &Base::dispatch);\n\n    m.def(\"dispatch_issue_go\", [](const Base *b) { return b->dispatch(); });\n\n    // test_recursive_dispatch_issue\n    // #3357: Recursive dispatch fails to find python function override\n    pybind11::class_<AdderBase, Adder>(m, \"Adder\")\n        .def(pybind11::init<>())\n        .def(\"__call__\", &AdderBase::operator());\n\n    pybind11::class_<AdderBase::Data>(m, \"Data\").def(pybind11::init<>());\n\n    m.def(\"add2\",\n          [](const AdderBase::Data &first,\n             const AdderBase::Data &second,\n             const AdderBase &adder,\n             const AdderBase::DataVisitor &visitor) { adder(first, second, visitor); });\n\n    m.def(\"add3\",\n          [](const AdderBase::Data &first,\n             const AdderBase::Data &second,\n             const AdderBase::Data &third,\n             const AdderBase &adder,\n             const AdderBase::DataVisitor &visitor) {\n              adder(first, second, [&](const AdderBase::Data &first_plus_second) {\n                  adder(first_plus_second,\n                        third,\n                        visitor); // NOLINT(readability-suspicious-call-argument)\n              });\n          });\n\n    // test_override_ref\n    // #392/397: overriding reference-returning functions\n    class OverrideTest {\n    public:\n        struct A {\n            std::string value = \"hi\";\n        };\n        std::string v;\n        A a;\n        explicit OverrideTest(const std::string &v) : v{v} {}\n        OverrideTest() = default;\n        OverrideTest(const OverrideTest &) = delete;\n        virtual std::string str_value() { return v; }\n        virtual std::string &str_ref() { return v; }\n        virtual A A_value() { return a; }\n        virtual A &A_ref() { return a; }\n        virtual ~OverrideTest() = default;\n    };\n\n    class PyOverrideTest : public OverrideTest {\n    public:\n        using OverrideTest::OverrideTest;\n        std::string str_value() override {\n            PYBIND11_OVERRIDE(std::string, OverrideTest, str_value);\n        }\n        // Not allowed (enabling the below should hit a static_assert failure): we can't get a\n        // reference to a python numeric value, since we only copy values in the numeric type\n        // caster:\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n        std::string &str_ref() override {\n            PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref);\n        }\n#endif\n        // But we can work around it like this:\n    private:\n        std::string _tmp;\n        std::string str_ref_helper() { PYBIND11_OVERRIDE(std::string, OverrideTest, str_ref); }\n\n    public:\n        std::string &str_ref() override { return _tmp = str_ref_helper(); }\n\n        A A_value() override { PYBIND11_OVERRIDE(A, OverrideTest, A_value); }\n        A &A_ref() override { PYBIND11_OVERRIDE(A &, OverrideTest, A_ref); }\n    };\n\n    py::class_<OverrideTest::A>(m, \"OverrideTest_A\")\n        .def_readwrite(\"value\", &OverrideTest::A::value);\n    py::class_<OverrideTest, PyOverrideTest>(m, \"OverrideTest\")\n        .def(py::init<const std::string &>())\n        .def(\"str_value\", &OverrideTest::str_value)\n#ifdef PYBIND11_NEVER_DEFINED_EVER\n        .def(\"str_ref\", &OverrideTest::str_ref)\n#endif\n        .def(\"A_value\", &OverrideTest::A_value)\n        .def(\"A_ref\", &OverrideTest::A_ref);\n\n    py::class_<test_override_cache_helper,\n               test_override_cache_helper_trampoline,\n               std::shared_ptr<test_override_cache_helper>>(m, \"test_override_cache_helper\")\n        .def(py::init_alias<>())\n        .def(\"func\", &test_override_cache_helper::func);\n\n    m.def(\"test_override_cache\", test_override_cache);\n}\n\n// Inheriting virtual methods.  We do two versions here: the repeat-everything version and the\n// templated trampoline versions mentioned in docs/advanced.rst.\n//\n// These base classes are exactly the same, but we technically need distinct\n// classes for this example code because we need to be able to bind them\n// properly (pybind11, sensibly, doesn't allow us to bind the same C++ class to\n// multiple python classes).\nclass A_Repeat {\n#define A_METHODS                                                                                 \\\npublic:                                                                                           \\\n    virtual int unlucky_number() = 0;                                                             \\\n    virtual std::string say_something(unsigned times) {                                           \\\n        std::string s = \"\";                                                                       \\\n        for (unsigned i = 0; i < times; ++i)                                                      \\\n            s += \"hi\";                                                                            \\\n        return s;                                                                                 \\\n    }                                                                                             \\\n    std::string say_everything() {                                                                \\\n        return say_something(1) + \" \" + std::to_string(unlucky_number());                         \\\n    }\n    A_METHODS\n    A_Repeat() = default;\n    A_Repeat(const A_Repeat &) = delete;\n    virtual ~A_Repeat() = default;\n};\nclass B_Repeat : public A_Repeat {\n#define B_METHODS                                                                                 \\\npublic:                                                                                           \\\n    int unlucky_number() override { return 13; }                                                  \\\n    std::string say_something(unsigned times) override {                                          \\\n        return \"B says hi \" + std::to_string(times) + \" times\";                                   \\\n    }                                                                                             \\\n    virtual double lucky_number() { return 7.0; }\n    B_METHODS\n};\nclass C_Repeat : public B_Repeat {\n#define C_METHODS                                                                                 \\\npublic:                                                                                           \\\n    int unlucky_number() override { return 4444; }                                                \\\n    double lucky_number() override { return 888; }\n    C_METHODS\n};\nclass D_Repeat : public C_Repeat {\n#define D_METHODS // Nothing overridden.\n    D_METHODS\n};\n\n// Base classes for templated inheritance trampolines.  Identical to the repeat-everything version:\nclass A_Tpl {\n    A_METHODS;\n    A_Tpl() = default;\n    A_Tpl(const A_Tpl &) = delete;\n    virtual ~A_Tpl() = default;\n};\nclass B_Tpl : public A_Tpl {\n    B_METHODS\n};\nclass C_Tpl : public B_Tpl {\n    C_METHODS\n};\nclass D_Tpl : public C_Tpl {\n    D_METHODS\n};\n\n// Inheritance approach 1: each trampoline gets every virtual method (11 in total)\nclass PyA_Repeat : public A_Repeat {\npublic:\n    using A_Repeat::A_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, A_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, A_Repeat, say_something, times);\n    }\n};\nclass PyB_Repeat : public B_Repeat {\npublic:\n    using B_Repeat::B_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, B_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, B_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, B_Repeat, lucky_number, ); }\n};\nclass PyC_Repeat : public C_Repeat {\npublic:\n    using C_Repeat::C_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, C_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, C_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, C_Repeat, lucky_number, ); }\n};\nclass PyD_Repeat : public D_Repeat {\npublic:\n    using D_Repeat::D_Repeat;\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, D_Repeat, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, D_Repeat, say_something, times);\n    }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, D_Repeat, lucky_number, ); }\n};\n\n// Inheritance approach 2: templated trampoline classes.\n//\n// Advantages:\n// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one\n//   for any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes\n//   and 11 methods (repeat).\n// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and\n//   can properly inherit constructors.\n//\n// Disadvantage:\n// - the compiler must still generate and compile 14 different methods (more, even, than the 11\n//   required for the repeat approach) instead of the 6 required for MI.  (If there was no pure\n//   method (or no pure method override), the number would drop down to the same 11 as the repeat\n//   approach).\ntemplate <class Base = A_Tpl>\nclass PyA_Tpl : public Base {\npublic:\n    using Base::Base; // Inherit constructors\n    int unlucky_number() override { PYBIND11_OVERRIDE_PURE(int, Base, unlucky_number, ); }\n    std::string say_something(unsigned times) override {\n        PYBIND11_OVERRIDE(std::string, Base, say_something, times);\n    }\n};\ntemplate <class Base = B_Tpl>\nclass PyB_Tpl : public PyA_Tpl<Base> {\npublic:\n    using PyA_Tpl<Base>::PyA_Tpl; // Inherit constructors (via PyA_Tpl's inherited constructors)\n    // NOLINTNEXTLINE(bugprone-parent-virtual-call)\n    int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }\n    double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }\n};\n// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these\n// (we can use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):\n/*\ntemplate <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> {\npublic:\n    using PyB_Tpl<Base>::PyB_Tpl;\n};\ntemplate <class Base = D_Tpl> class PyD_Tpl : public PyC_Tpl<Base> {\npublic:\n    using PyC_Tpl<Base>::PyC_Tpl;\n};\n*/\n\nvoid initialize_inherited_virtuals(py::module_ &m) {\n    // test_inherited_virtuals\n\n    // Method 1: repeat\n    py::class_<A_Repeat, PyA_Repeat>(m, \"A_Repeat\")\n        .def(py::init<>())\n        .def(\"unlucky_number\", &A_Repeat::unlucky_number)\n        .def(\"say_something\", &A_Repeat::say_something)\n        .def(\"say_everything\", &A_Repeat::say_everything);\n    py::class_<B_Repeat, A_Repeat, PyB_Repeat>(m, \"B_Repeat\")\n        .def(py::init<>())\n        .def(\"lucky_number\", &B_Repeat::lucky_number);\n    py::class_<C_Repeat, B_Repeat, PyC_Repeat>(m, \"C_Repeat\").def(py::init<>());\n    py::class_<D_Repeat, C_Repeat, PyD_Repeat>(m, \"D_Repeat\").def(py::init<>());\n\n    // test_\n    // Method 2: Templated trampolines\n    py::class_<A_Tpl, PyA_Tpl<>>(m, \"A_Tpl\")\n        .def(py::init<>())\n        .def(\"unlucky_number\", &A_Tpl::unlucky_number)\n        .def(\"say_something\", &A_Tpl::say_something)\n        .def(\"say_everything\", &A_Tpl::say_everything);\n    py::class_<B_Tpl, A_Tpl, PyB_Tpl<>>(m, \"B_Tpl\")\n        .def(py::init<>())\n        .def(\"lucky_number\", &B_Tpl::lucky_number);\n    py::class_<C_Tpl, B_Tpl, PyB_Tpl<C_Tpl>>(m, \"C_Tpl\").def(py::init<>());\n    py::class_<D_Tpl, C_Tpl, PyB_Tpl<D_Tpl>>(m, \"D_Tpl\").def(py::init<>());\n\n    // Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)\n    m.def(\"test_gil\", &test_gil);\n    m.def(\"test_gil_from_thread\", &test_gil_from_thread);\n};\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/test_virtual_functions.py",
    "content": "# -*- coding: utf-8 -*-\nimport pytest\n\nimport env  # noqa: F401\n\nm = pytest.importorskip(\"pybind11_tests.virtual_functions\")\nfrom pybind11_tests import ConstructorStats  # noqa: E402\n\n\ndef test_override(capture, msg):\n    class ExtendedExampleVirt(m.ExampleVirt):\n        def __init__(self, state):\n            super(ExtendedExampleVirt, self).__init__(state + 1)\n            self.data = \"Hello world\"\n\n        def run(self, value):\n            print(\"ExtendedExampleVirt::run(%i), calling parent..\" % value)\n            return super(ExtendedExampleVirt, self).run(value + 1)\n\n        def run_bool(self):\n            print(\"ExtendedExampleVirt::run_bool()\")\n            return False\n\n        def get_string1(self):\n            return \"override1\"\n\n        def pure_virtual(self):\n            print(\"ExtendedExampleVirt::pure_virtual(): %s\" % self.data)\n\n    class ExtendedExampleVirt2(ExtendedExampleVirt):\n        def __init__(self, state):\n            super(ExtendedExampleVirt2, self).__init__(state + 1)\n\n        def get_string2(self):\n            return \"override2\"\n\n    ex12 = m.ExampleVirt(10)\n    with capture:\n        assert m.runExampleVirt(ex12, 20) == 30\n    assert (\n        capture\n        == \"\"\"\n        Original implementation of ExampleVirt::run(state=10, value=20, str1=default1, str2=default2)\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    with pytest.raises(RuntimeError) as excinfo:\n        m.runExampleVirtVirtual(ex12)\n    assert (\n        msg(excinfo.value)\n        == 'Tried to call pure virtual function \"ExampleVirt::pure_virtual\"'\n    )\n\n    ex12p = ExtendedExampleVirt(10)\n    with capture:\n        assert m.runExampleVirt(ex12p, 20) == 32\n    assert (\n        capture\n        == \"\"\"\n        ExtendedExampleVirt::run(20), calling parent..\n        Original implementation of ExampleVirt::run(state=11, value=21, str1=override1, str2=default2)\n    \"\"\"  # noqa: E501 line too long\n    )\n    with capture:\n        assert m.runExampleVirtBool(ex12p) is False\n    assert capture == \"ExtendedExampleVirt::run_bool()\"\n    with capture:\n        m.runExampleVirtVirtual(ex12p)\n    assert capture == \"ExtendedExampleVirt::pure_virtual(): Hello world\"\n\n    ex12p2 = ExtendedExampleVirt2(15)\n    with capture:\n        assert m.runExampleVirt(ex12p2, 50) == 68\n    assert (\n        capture\n        == \"\"\"\n        ExtendedExampleVirt::run(50), calling parent..\n        Original implementation of ExampleVirt::run(state=17, value=51, str1=override1, str2=override2)\n    \"\"\"  # noqa: E501 line too long\n    )\n\n    cstats = ConstructorStats.get(m.ExampleVirt)\n    assert cstats.alive() == 3\n    del ex12, ex12p, ex12p2\n    assert cstats.alive() == 0\n    assert cstats.values() == [\"10\", \"11\", \"17\"]\n    assert cstats.copy_constructions == 0\n    assert cstats.move_constructions >= 0\n\n\ndef test_alias_delay_initialization1(capture):\n    \"\"\"`A` only initializes its trampoline class when we inherit from it\n\n    If we just create and use an A instance directly, the trampoline initialization is\n    bypassed and we only initialize an A() instead (for performance reasons).\n    \"\"\"\n\n    class B(m.A):\n        def __init__(self):\n            super(B, self).__init__()\n\n        def f(self):\n            print(\"In python f()\")\n\n    # C++ version\n    with capture:\n        a = m.A()\n        m.call_f(a)\n        del a\n        pytest.gc_collect()\n    assert capture == \"A.f()\"\n\n    # Python version\n    with capture:\n        b = B()\n        m.call_f(b)\n        del b\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA.PyA()\n        PyA.f()\n        In python f()\n        PyA.~PyA()\n    \"\"\"\n    )\n\n\ndef test_alias_delay_initialization2(capture):\n    \"\"\"`A2`, unlike the above, is configured to always initialize the alias\n\n    While the extra initialization and extra class layer has small virtual dispatch\n    performance penalty, it also allows us to do more things with the trampoline\n    class such as defining local variables and performing construction/destruction.\n    \"\"\"\n\n    class B2(m.A2):\n        def __init__(self):\n            super(B2, self).__init__()\n\n        def f(self):\n            print(\"In python B2.f()\")\n\n    # No python subclass version\n    with capture:\n        a2 = m.A2()\n        m.call_f(a2)\n        del a2\n        pytest.gc_collect()\n        a3 = m.A2(1)\n        m.call_f(a3)\n        del a3\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA2.PyA2()\n        PyA2.f()\n        A2.f()\n        PyA2.~PyA2()\n        PyA2.PyA2()\n        PyA2.f()\n        A2.f()\n        PyA2.~PyA2()\n    \"\"\"\n    )\n\n    # Python subclass version\n    with capture:\n        b2 = B2()\n        m.call_f(b2)\n        del b2\n        pytest.gc_collect()\n    assert (\n        capture\n        == \"\"\"\n        PyA2.PyA2()\n        PyA2.f()\n        In python B2.f()\n        PyA2.~PyA2()\n    \"\"\"\n    )\n\n\n# PyPy: Reference count > 1 causes call with noncopyable instance\n# to fail in ncv1.print_nc()\n@pytest.mark.xfail(\"env.PYPY\")\n@pytest.mark.skipif(\n    not hasattr(m, \"NCVirt\"), reason=\"NCVirt does not work on Intel/PGI/NVCC compilers\"\n)\ndef test_move_support():\n    class NCVirtExt(m.NCVirt):\n        def get_noncopyable(self, a, b):\n            # Constructs and returns a new instance:\n            nc = m.NonCopyable(a * a, b * b)\n            return nc\n\n        def get_movable(self, a, b):\n            # Return a referenced copy\n            self.movable = m.Movable(a, b)\n            return self.movable\n\n    class NCVirtExt2(m.NCVirt):\n        def get_noncopyable(self, a, b):\n            # Keep a reference: this is going to throw an exception\n            self.nc = m.NonCopyable(a, b)\n            return self.nc\n\n        def get_movable(self, a, b):\n            # Return a new instance without storing it\n            return m.Movable(a, b)\n\n    ncv1 = NCVirtExt()\n    assert ncv1.print_nc(2, 3) == \"36\"\n    assert ncv1.print_movable(4, 5) == \"9\"\n    ncv2 = NCVirtExt2()\n    assert ncv2.print_movable(7, 7) == \"14\"\n    # Don't check the exception message here because it differs under debug/non-debug mode\n    with pytest.raises(RuntimeError):\n        ncv2.print_nc(9, 9)\n\n    nc_stats = ConstructorStats.get(m.NonCopyable)\n    mv_stats = ConstructorStats.get(m.Movable)\n    assert nc_stats.alive() == 1\n    assert mv_stats.alive() == 1\n    del ncv1, ncv2\n    assert nc_stats.alive() == 0\n    assert mv_stats.alive() == 0\n    assert nc_stats.values() == [\"4\", \"9\", \"9\", \"9\"]\n    assert mv_stats.values() == [\"4\", \"5\", \"7\", \"7\"]\n    assert nc_stats.copy_constructions == 0\n    assert mv_stats.copy_constructions == 1\n    assert nc_stats.move_constructions >= 0\n    assert mv_stats.move_constructions >= 0\n\n\ndef test_dispatch_issue(msg):\n    \"\"\"#159: virtual function dispatch has problems with similar-named functions\"\"\"\n\n    class PyClass1(m.DispatchIssue):\n        def dispatch(self):\n            return \"Yay..\"\n\n    class PyClass2(m.DispatchIssue):\n        def dispatch(self):\n            with pytest.raises(RuntimeError) as excinfo:\n                super(PyClass2, self).dispatch()\n            assert (\n                msg(excinfo.value)\n                == 'Tried to call pure virtual function \"Base::dispatch\"'\n            )\n\n            return m.dispatch_issue_go(PyClass1())\n\n    b = PyClass2()\n    assert m.dispatch_issue_go(b) == \"Yay..\"\n\n\ndef test_recursive_dispatch_issue(msg):\n    \"\"\"#3357: Recursive dispatch fails to find python function override\"\"\"\n\n    class Data(m.Data):\n        def __init__(self, value):\n            super(Data, self).__init__()\n            self.value = value\n\n    class Adder(m.Adder):\n        def __call__(self, first, second, visitor):\n            # lambda is a workaround, which adds extra frame to the\n            # current CPython thread. Removing lambda reveals the bug\n            # [https://github.com/pybind/pybind11/issues/3357]\n            (lambda: visitor(Data(first.value + second.value)))()\n\n    class StoreResultVisitor:\n        def __init__(self):\n            self.result = None\n\n        def __call__(self, data):\n            self.result = data.value\n\n    store = StoreResultVisitor()\n\n    m.add2(Data(1), Data(2), Adder(), store)\n    assert store.result == 3\n\n    # without lambda in Adder class, this function fails with\n    # RuntimeError: Tried to call pure virtual function \"AdderBase::__call__\"\n    m.add3(Data(1), Data(2), Data(3), Adder(), store)\n    assert store.result == 6\n\n\ndef test_override_ref():\n    \"\"\"#392/397: overriding reference-returning functions\"\"\"\n    o = m.OverrideTest(\"asdf\")\n\n    # Not allowed (see associated .cpp comment)\n    # i = o.str_ref()\n    # assert o.str_ref() == \"asdf\"\n    assert o.str_value() == \"asdf\"\n\n    assert o.A_value().value == \"hi\"\n    a = o.A_ref()\n    assert a.value == \"hi\"\n    a.value = \"bye\"\n    assert a.value == \"bye\"\n\n\ndef test_inherited_virtuals():\n    class AR(m.A_Repeat):\n        def unlucky_number(self):\n            return 99\n\n    class AT(m.A_Tpl):\n        def unlucky_number(self):\n            return 999\n\n    obj = AR()\n    assert obj.say_something(3) == \"hihihi\"\n    assert obj.unlucky_number() == 99\n    assert obj.say_everything() == \"hi 99\"\n\n    obj = AT()\n    assert obj.say_something(3) == \"hihihi\"\n    assert obj.unlucky_number() == 999\n    assert obj.say_everything() == \"hi 999\"\n\n    for obj in [m.B_Repeat(), m.B_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 13\n        assert obj.lucky_number() == 7.0\n        assert obj.say_everything() == \"B says hi 1 times 13\"\n\n    for obj in [m.C_Repeat(), m.C_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 4444\n        assert obj.lucky_number() == 888.0\n        assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CR(m.C_Repeat):\n        def lucky_number(self):\n            return m.C_Repeat.lucky_number(self) + 1.25\n\n    obj = CR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 889.25\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CT(m.C_Tpl):\n        pass\n\n    obj = CT()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 888.0\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CCR(CR):\n        def lucky_number(self):\n            return CR.lucky_number(self) * 10\n\n    obj = CCR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 8892.5\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class CCT(CT):\n        def lucky_number(self):\n            return CT.lucky_number(self) * 1000\n\n    obj = CCT()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 4444\n    assert obj.lucky_number() == 888000.0\n    assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    class DR(m.D_Repeat):\n        def unlucky_number(self):\n            return 123\n\n        def lucky_number(self):\n            return 42.0\n\n    for obj in [m.D_Repeat(), m.D_Tpl()]:\n        assert obj.say_something(3) == \"B says hi 3 times\"\n        assert obj.unlucky_number() == 4444\n        assert obj.lucky_number() == 888.0\n        assert obj.say_everything() == \"B says hi 1 times 4444\"\n\n    obj = DR()\n    assert obj.say_something(3) == \"B says hi 3 times\"\n    assert obj.unlucky_number() == 123\n    assert obj.lucky_number() == 42.0\n    assert obj.say_everything() == \"B says hi 1 times 123\"\n\n    class DT(m.D_Tpl):\n        def say_something(self, times):\n            return \"DT says:\" + (\" quack\" * times)\n\n        def unlucky_number(self):\n            return 1234\n\n        def lucky_number(self):\n            return -4.25\n\n    obj = DT()\n    assert obj.say_something(3) == \"DT says: quack quack quack\"\n    assert obj.unlucky_number() == 1234\n    assert obj.lucky_number() == -4.25\n    assert obj.say_everything() == \"DT says: quack 1234\"\n\n    class DT2(DT):\n        def say_something(self, times):\n            return \"DT2: \" + (\"QUACK\" * times)\n\n        def unlucky_number(self):\n            return -3\n\n    class BT(m.B_Tpl):\n        def say_something(self, times):\n            return \"BT\" * times\n\n        def unlucky_number(self):\n            return -7\n\n        def lucky_number(self):\n            return -1.375\n\n    obj = BT()\n    assert obj.say_something(3) == \"BTBTBT\"\n    assert obj.unlucky_number() == -7\n    assert obj.lucky_number() == -1.375\n    assert obj.say_everything() == \"BT -7\"\n\n\ndef test_issue_1454():\n    # Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)\n    m.test_gil()\n    m.test_gil_from_thread()\n\n\ndef test_python_override():\n    def func():\n        class Test(m.test_override_cache_helper):\n            def func(self):\n                return 42\n\n        return Test()\n\n    def func2():\n        class Test(m.test_override_cache_helper):\n            pass\n\n        return Test()\n\n    for _ in range(1500):\n        assert m.test_override_cache(func()) == 42\n        assert m.test_override_cache(func2()) == 0\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/valgrind-numpy-scipy.supp",
    "content": "# Valgrind suppression file for NumPy & SciPy errors and leaks in pybind11 tests\n#\n# On updating a dependency, to get a list of \"default\" leaks in e.g. NumPy, run\n# `PYTHONMALLOC=malloc valgrind --leak-check=full --show-leak-kinds=definite,indirect python3.9-dbg -c \"import numpy\"`\n# To use these suppression files, add e.g. `--suppressions=valgrind-numpy-scipy.supp`\n\n{\n   Leaks when importing NumPy\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_Pack\n   ...\n   fun:__pyx_pymod_exec_*\n}\n\n{\n   Leaks when importing NumPy (bis)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_New\n   fun:PyCode_NewWithPosOnlyArgs\n   fun:PyCode_New\n   ...\n   fun:__pyx_pymod_exec_*\n}\n\n{\n   Leaks when importing NumPy (ter)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:_PyTuple_FromArray\n   fun:_PyObject_MakeTpCall\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n   fun:_PyFunction_Vectorcall\n}\n\n{\n   Leaks when importing NumPy (quater)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:_PyTuple_FromArray\n   fun:_PyObject_MakeTpCall\n   fun:_PyObject_VectorcallTstate\n   fun:_PyObject_CallFunctionVa\n   fun:PyObject_CallFunction\n   fun:PyImport_Import\n}\n\n{\n   Leaks when importing NumPy (quinquies)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_New\n   fun:r_object\n   fun:r_object\n   fun:r_object\n   fun:r_object\n}\n\n{\n   Leaks when importing NumPy (sexies)\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyObject_Malloc\n   fun:_PyObject_GC_Alloc\n   fun:_PyObject_GC_Malloc\n   fun:_PyObject_GC_NewVar\n   fun:tuple_alloc\n   fun:PyTuple_New\n   fun:dictiter_iternextitem\n   fun:list_extend\n   fun:_PyList_Extend\n   fun:PySequence_List\n}\n\n{\n   Leak when importing scipy.fft\n   Memcheck:Leak\n   fun:_Znwm\n   fun:PyInit_pypocketfft\n   fun:_PyImport_LoadDynamicModuleWithSpec\n   fun:_imp_create_dynamic_impl*\n   fun:_imp_create_dynamic\n   fun:cfunction_vectorcall_FASTCALL\n   fun:PyVectorcall_Call\n   fun:_PyObject_Call\n   fun:PyObject_Call\n   fun:do_call_core\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:_PyEval_EvalCode\n}\n\n{\n   NumPy leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   ...\n   fun:_buffer_get_info\n   fun:array_getbuffer\n   fun:PyObject_GetBuffer\n   fun:__Pyx__GetBufferAndValidate*\n   fun:__pyx_f_5numpy_6random_13bit_generator_12SeedSequence_mix_entropy\n   fun:__pyx_pw_5numpy_6random_13bit_generator_12SeedSequence_1__init__\n   fun:type_call\n   fun:__Pyx__PyObject_CallOneArg\n   fun:__pyx_pw_5numpy_6random_13bit_generator_12BitGenerator_1__init__\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tests/valgrind-python.supp",
    "content": "# Valgrind suppression file for CPython errors and leaks in pybind11 tests\n\n# Taken verbatim from https://github.com/python/cpython/blob/3.9/Misc/valgrind-python.supp#L266-L272\n{\n   Uninitialised byte(s) false alarm, see bpo-35561\n   Memcheck:Param\n   epoll_ctl(event)\n   fun:epoll_ctl\n   fun:pyepoll_internal_ctl\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyEval_InitState\n   fun:PyInterpreterState_New\n   ...\n   fun:pyinit_core*\n   fun:Py_InitializeFromConfig\n   fun:pymain_init\n   fun:pymain_main\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:_PyMem_DebugRawAlloc\n   fun:_PyMem_DebugRawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyRuntimeState_Init_impl\n   fun:_PyRuntimeState_Init\n   fun:_PyRuntime_Initialize\n   fun:pymain_init\n   fun:pymain_main\n   fun:Py_BytesMain\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:_PyImport_AcquireLock\n   fun:_imp_acquire_lock_impl*\n   fun:_imp_acquire_lock\n   fun:cfunction_vectorcall_NOARGS\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:newlockobject\n   ...\n   fun:cfunction_vectorcall_NOARGS\n   fun:_PyObject_VectorcallTstate\n   fun:PyObject_Vectorcall\n   fun:call_function\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:function_code_fastcall\n   fun:_PyFunction_Vectorcall\n}\n\n{\n   Python leaks when spawning a subprocess\n   Memcheck:Leak\n   fun:malloc\n   fun:_PyMem_RawMalloc\n   fun:PyMem_RawMalloc\n   fun:PyThread_allocate_lock\n   fun:rlock_new\n   fun:type_call\n   fun:_PyObject_Call\n   fun:PyObject_Call\n   fun:do_call_core\n   fun:_PyEval_EvalFrameDefault\n   fun:_PyEval_EvalFrame\n   fun:_PyEval_EvalCode\n   fun:_PyFunction_Vectorcall\n}\n\n# Not really CPython-specific, see link\n{\n   dlopen leak (https://stackoverflow.com/questions/1542457/memory-leak-reported-by-valgrind-in-dlopen)\n   Memcheck:Leak\n   fun:malloc\n   ...\n   fun:dl_open_worker\n   fun:_dl_catch_exception\n   fun:_dl_open\n   fun:dlopen_doit\n   fun:_dl_catch_exception\n   fun:_dl_catch_error\n   fun:_dlerror_run\n   fun:dlopen@@GLIBC_2.2.5\n   fun:_PyImport_FindSharedFuncptr\n   fun:_PyImport_LoadDynamicModuleWithSpec\n}\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/FindCatch.cmake",
    "content": "# - Find the Catch test framework or download it (single header)\n#\n# This is a quick module for internal use. It assumes that Catch is\n# REQUIRED and that a minimum version is provided (not EXACT). If\n# a suitable version isn't found locally, the single header file\n# will be downloaded and placed in the build dir: PROJECT_BINARY_DIR.\n#\n# This code sets the following variables:\n#  CATCH_INCLUDE_DIR      - path to catch.hpp\n#  CATCH_VERSION          - version number\n\noption(DOWNLOAD_CATCH \"Download catch2 if not found\")\n\nif(NOT Catch_FIND_VERSION)\n  message(FATAL_ERROR \"A version number must be specified.\")\nelseif(Catch_FIND_REQUIRED)\n  message(FATAL_ERROR \"This module assumes Catch is not required.\")\nelseif(Catch_FIND_VERSION_EXACT)\n  message(FATAL_ERROR \"Exact version numbers are not supported, only minimum.\")\nendif()\n\n# Extract the version number from catch.hpp\nfunction(_get_catch_version)\n  file(\n    STRINGS \"${CATCH_INCLUDE_DIR}/catch.hpp\" version_line\n    REGEX \"Catch v.*\"\n    LIMIT_COUNT 1)\n  if(version_line MATCHES \"Catch v([0-9]+)\\\\.([0-9]+)\\\\.([0-9]+)\")\n    set(CATCH_VERSION\n        \"${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}\"\n        PARENT_SCOPE)\n  endif()\nendfunction()\n\n# Download the single-header version of Catch\nfunction(_download_catch version destination_dir)\n  message(STATUS \"Downloading catch v${version}...\")\n  set(url https://github.com/philsquared/Catch/releases/download/v${version}/catch.hpp)\n  file(DOWNLOAD ${url} \"${destination_dir}/catch.hpp\" STATUS status)\n  list(GET status 0 error)\n  if(error)\n    message(FATAL_ERROR \"Could not download ${url}\")\n  endif()\n  set(CATCH_INCLUDE_DIR\n      \"${destination_dir}\"\n      CACHE INTERNAL \"\")\nendfunction()\n\n# Look for catch locally\nfind_path(\n  CATCH_INCLUDE_DIR\n  NAMES catch.hpp\n  PATH_SUFFIXES catch2)\nif(CATCH_INCLUDE_DIR)\n  _get_catch_version()\nendif()\n\n# Download the header if it wasn't found or if it's outdated\nif(NOT CATCH_VERSION OR CATCH_VERSION VERSION_LESS ${Catch_FIND_VERSION})\n  if(DOWNLOAD_CATCH)\n    _download_catch(${Catch_FIND_VERSION} \"${PROJECT_BINARY_DIR}/catch/\")\n    _get_catch_version()\n  else()\n    set(CATCH_FOUND FALSE)\n    return()\n  endif()\nendif()\n\nadd_library(Catch2::Catch2 IMPORTED INTERFACE)\nset_property(TARGET Catch2::Catch2 PROPERTY INTERFACE_INCLUDE_DIRECTORIES \"${CATCH_INCLUDE_DIR}\")\n\nset(CATCH_FOUND TRUE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/FindEigen3.cmake",
    "content": "# - Try to find Eigen3 lib\n#\n# This module supports requiring a minimum version, e.g. you can do\n#   find_package(Eigen3 3.1.2)\n# to require version 3.1.2 or newer of Eigen3.\n#\n# Once done this will define\n#\n#  EIGEN3_FOUND - system has eigen lib with correct version\n#  EIGEN3_INCLUDE_DIR - the eigen include directory\n#  EIGEN3_VERSION - eigen version\n\n# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>\n# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>\n# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>\n# Redistribution and use is allowed according to the terms of the 2-clause BSD license.\n\nif(NOT Eigen3_FIND_VERSION)\n  if(NOT Eigen3_FIND_VERSION_MAJOR)\n    set(Eigen3_FIND_VERSION_MAJOR 2)\n  endif(NOT Eigen3_FIND_VERSION_MAJOR)\n  if(NOT Eigen3_FIND_VERSION_MINOR)\n    set(Eigen3_FIND_VERSION_MINOR 91)\n  endif(NOT Eigen3_FIND_VERSION_MINOR)\n  if(NOT Eigen3_FIND_VERSION_PATCH)\n    set(Eigen3_FIND_VERSION_PATCH 0)\n  endif(NOT Eigen3_FIND_VERSION_PATCH)\n\n  set(Eigen3_FIND_VERSION\n      \"${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}\")\nendif(NOT Eigen3_FIND_VERSION)\n\nmacro(_eigen3_check_version)\n  file(READ \"${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h\" _eigen3_version_header)\n\n  string(REGEX MATCH \"define[ \\t]+EIGEN_WORLD_VERSION[ \\t]+([0-9]+)\" _eigen3_world_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_WORLD_VERSION \"${CMAKE_MATCH_1}\")\n  string(REGEX MATCH \"define[ \\t]+EIGEN_MAJOR_VERSION[ \\t]+([0-9]+)\" _eigen3_major_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_MAJOR_VERSION \"${CMAKE_MATCH_1}\")\n  string(REGEX MATCH \"define[ \\t]+EIGEN_MINOR_VERSION[ \\t]+([0-9]+)\" _eigen3_minor_version_match\n               \"${_eigen3_version_header}\")\n  set(EIGEN3_MINOR_VERSION \"${CMAKE_MATCH_1}\")\n\n  set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})\n  if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n    set(EIGEN3_VERSION_OK FALSE)\n  else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n    set(EIGEN3_VERSION_OK TRUE)\n  endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})\n\n  if(NOT EIGEN3_VERSION_OK)\n\n    message(STATUS \"Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, \"\n                   \"but at least version ${Eigen3_FIND_VERSION} is required\")\n  endif(NOT EIGEN3_VERSION_OK)\nendmacro(_eigen3_check_version)\n\nif(EIGEN3_INCLUDE_DIR)\n\n  # in cache already\n  _eigen3_check_version()\n  set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})\n\nelse(EIGEN3_INCLUDE_DIR)\n  if(NOT DEFINED KDE4_INCLUDE_DIR)\n    set(KDE4_INCLUDE_DIR \"\")\n  endif()\n\n  find_path(\n    EIGEN3_INCLUDE_DIR\n    NAMES signature_of_eigen3_matrix_library\n    PATHS ${CMAKE_INSTALL_PREFIX}/include ${KDE4_INCLUDE_DIR}\n    PATH_SUFFIXES eigen3 eigen)\n\n  if(EIGEN3_INCLUDE_DIR)\n    _eigen3_check_version()\n  endif(EIGEN3_INCLUDE_DIR)\n\n  include(FindPackageHandleStandardArgs)\n  find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)\n\n  mark_as_advanced(EIGEN3_INCLUDE_DIR)\n\nendif(EIGEN3_INCLUDE_DIR)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/FindPythonLibsNew.cmake",
    "content": "# - Find python libraries\n# This module finds the libraries corresponding to the Python interpreter\n# FindPythonInterp provides.\n# This code sets the following variables:\n#\n#  PYTHONLIBS_FOUND           - have the Python libs been found\n#  PYTHON_PREFIX              - path to the Python installation\n#  PYTHON_LIBRARIES           - path to the python library\n#  PYTHON_INCLUDE_DIRS        - path to where Python.h is found\n#  PYTHON_MODULE_EXTENSION    - lib extension, e.g. '.so' or '.pyd'\n#  PYTHON_MODULE_PREFIX       - lib name prefix: usually an empty string\n#  PYTHON_SITE_PACKAGES       - path to installation site-packages\n#  PYTHON_IS_DEBUG            - whether the Python interpreter is a debug build\n#\n# Thanks to talljimbo for the patch adding the 'LDVERSION' config\n# variable usage.\n\n#=============================================================================\n# Copyright 2001-2009 Kitware, Inc.\n# Copyright 2012 Continuum Analytics, Inc.\n#\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n# * Redistributions of source code must retain the above copyright\n# notice, this list of conditions and the following disclaimer.\n#\n# * Redistributions in binary form must reproduce the above copyright\n# notice, this list of conditions and the following disclaimer in the\n# documentation and/or other materials provided with the distribution.\n#\n# * Neither the names of Kitware, Inc., the Insight Software Consortium,\n# nor the names of their contributors may be used to endorse or promote\n# products derived from this software without specific prior written\n# permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n# # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n#=============================================================================\n\n# Checking for the extension makes sure that `LibsNew` was found and not just `Libs`.\nif(PYTHONLIBS_FOUND AND PYTHON_MODULE_EXTENSION)\n  return()\nendif()\n\nif(PythonLibsNew_FIND_QUIETLY)\n  set(_pythonlibs_quiet QUIET)\nelse()\n  set(_pythonlibs_quiet \"\")\nendif()\n\nif(PythonLibsNew_FIND_REQUIRED)\n  set(_pythonlibs_required REQUIRED)\nendif()\n\n# Check to see if the `python` command is present and from a virtual\n# environment, conda, or GHA activation - if it is, try to use that.\n\nif(NOT DEFINED PYTHON_EXECUTABLE)\n  if(DEFINED ENV{VIRTUAL_ENV})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{VIRTUAL_ENV}\" \"$ENV{VIRTUAL_ENV}/bin\"\n      NO_DEFAULT_PATH)\n  elseif(DEFINED ENV{CONDA_PREFIX})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{CONDA_PREFIX}\" \"$ENV{CONDA_PREFIX}/bin\"\n      NO_DEFAULT_PATH)\n  elseif(DEFINED ENV{pythonLocation})\n    find_program(\n      PYTHON_EXECUTABLE python\n      PATHS \"$ENV{pythonLocation}\" \"$ENV{pythonLocation}/bin\"\n      NO_DEFAULT_PATH)\n  endif()\n  if(NOT PYTHON_EXECUTABLE)\n    unset(PYTHON_EXECUTABLE)\n  endif()\nendif()\n\n# Use the Python interpreter to find the libs.\nif(NOT PythonLibsNew_FIND_VERSION)\n  set(PythonLibsNew_FIND_VERSION \"\")\nendif()\n\nfind_package(PythonInterp ${PythonLibsNew_FIND_VERSION} ${_pythonlibs_required}\n             ${_pythonlibs_quiet})\n\nif(NOT PYTHONINTERP_FOUND)\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\n# According to https://stackoverflow.com/questions/646518/python-how-to-detect-debug-interpreter\n# testing whether sys has the gettotalrefcount function is a reliable, cross-platform\n# way to detect a CPython debug interpreter.\n#\n# The library suffix is from the config var LDVERSION sometimes, otherwise\n# VERSION. VERSION will typically be like \"2.7\" on unix, and \"27\" on windows.\nexecute_process(\n  COMMAND\n    \"${PYTHON_EXECUTABLE}\" \"-c\" \"\nimport sys;import struct;\nimport sysconfig as s\nUSE_SYSCONFIG = sys.version_info >= (3, 10)\nif not USE_SYSCONFIG:\n    from distutils import sysconfig as ds\nprint('.'.join(str(v) for v in sys.version_info));\nprint(sys.prefix);\nif USE_SYSCONFIG:\n    scheme = s.get_default_scheme()\n    if scheme == 'posix_local':\n        # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/\n        scheme = 'posix_prefix'\n    print(s.get_path('platinclude', scheme))\n    print(s.get_path('platlib'))\nelse:\n    print(ds.get_python_inc(plat_specific=True));\n    print(ds.get_python_lib(plat_specific=True));\nprint(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'));\nprint(hasattr(sys, 'gettotalrefcount')+0);\nprint(struct.calcsize('@P'));\nprint(s.get_config_var('LDVERSION') or s.get_config_var('VERSION'));\nprint(s.get_config_var('LIBDIR') or '');\nprint(s.get_config_var('MULTIARCH') or '');\n\"\n  RESULT_VARIABLE _PYTHON_SUCCESS\n  OUTPUT_VARIABLE _PYTHON_VALUES\n  ERROR_VARIABLE _PYTHON_ERROR_VALUE)\n\nif(NOT _PYTHON_SUCCESS MATCHES 0)\n  if(PythonLibsNew_FIND_REQUIRED)\n    message(FATAL_ERROR \"Python config failure:\\n${_PYTHON_ERROR_VALUE}\")\n  endif()\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\n# Convert the process output into a list\nif(WIN32)\n  string(REGEX REPLACE \"\\\\\\\\\" \"/\" _PYTHON_VALUES ${_PYTHON_VALUES})\nendif()\nstring(REGEX REPLACE \";\" \"\\\\\\\\;\" _PYTHON_VALUES ${_PYTHON_VALUES})\nstring(REGEX REPLACE \"\\n\" \";\" _PYTHON_VALUES ${_PYTHON_VALUES})\nlist(GET _PYTHON_VALUES 0 _PYTHON_VERSION_LIST)\nlist(GET _PYTHON_VALUES 1 PYTHON_PREFIX)\nlist(GET _PYTHON_VALUES 2 PYTHON_INCLUDE_DIR)\nlist(GET _PYTHON_VALUES 3 PYTHON_SITE_PACKAGES)\nlist(GET _PYTHON_VALUES 4 PYTHON_MODULE_EXTENSION)\nlist(GET _PYTHON_VALUES 5 PYTHON_IS_DEBUG)\nlist(GET _PYTHON_VALUES 6 PYTHON_SIZEOF_VOID_P)\nlist(GET _PYTHON_VALUES 7 PYTHON_LIBRARY_SUFFIX)\nlist(GET _PYTHON_VALUES 8 PYTHON_LIBDIR)\nlist(GET _PYTHON_VALUES 9 PYTHON_MULTIARCH)\n\n# Make sure the Python has the same pointer-size as the chosen compiler\n# Skip if CMAKE_SIZEOF_VOID_P is not defined\nif(CMAKE_SIZEOF_VOID_P AND (NOT \"${PYTHON_SIZEOF_VOID_P}\" STREQUAL \"${CMAKE_SIZEOF_VOID_P}\"))\n  if(PythonLibsNew_FIND_REQUIRED)\n    math(EXPR _PYTHON_BITS \"${PYTHON_SIZEOF_VOID_P} * 8\")\n    math(EXPR _CMAKE_BITS \"${CMAKE_SIZEOF_VOID_P} * 8\")\n    message(FATAL_ERROR \"Python config failure: Python is ${_PYTHON_BITS}-bit, \"\n                        \"chosen compiler is  ${_CMAKE_BITS}-bit\")\n  endif()\n  set(PYTHONLIBS_FOUND FALSE)\n  set(PythonLibsNew_FOUND FALSE)\n  return()\nendif()\n\n# The built-in FindPython didn't always give the version numbers\nstring(REGEX REPLACE \"\\\\.\" \";\" _PYTHON_VERSION_LIST ${_PYTHON_VERSION_LIST})\nlist(GET _PYTHON_VERSION_LIST 0 PYTHON_VERSION_MAJOR)\nlist(GET _PYTHON_VERSION_LIST 1 PYTHON_VERSION_MINOR)\nlist(GET _PYTHON_VERSION_LIST 2 PYTHON_VERSION_PATCH)\nset(PYTHON_VERSION \"${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}.${PYTHON_VERSION_PATCH}\")\n\n# Make sure all directory separators are '/'\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_PREFIX \"${PYTHON_PREFIX}\")\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_INCLUDE_DIR \"${PYTHON_INCLUDE_DIR}\")\nstring(REGEX REPLACE \"\\\\\\\\\" \"/\" PYTHON_SITE_PACKAGES \"${PYTHON_SITE_PACKAGES}\")\n\nif(CMAKE_HOST_WIN32)\n  set(PYTHON_LIBRARY \"${PYTHON_PREFIX}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib\")\n\n  # when run in a venv, PYTHON_PREFIX points to it. But the libraries remain in the\n  # original python installation. They may be found relative to PYTHON_INCLUDE_DIR.\n  if(NOT EXISTS \"${PYTHON_LIBRARY}\")\n    get_filename_component(_PYTHON_ROOT ${PYTHON_INCLUDE_DIR} DIRECTORY)\n    set(PYTHON_LIBRARY \"${_PYTHON_ROOT}/libs/python${PYTHON_LIBRARY_SUFFIX}.lib\")\n  endif()\n\n  # if we are in MSYS & MINGW, and we didn't find windows python lib, look for system python lib\n  if(DEFINED ENV{MSYSTEM}\n     AND MINGW\n     AND NOT EXISTS \"${PYTHON_LIBRARY}\")\n    if(PYTHON_MULTIARCH)\n      set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}\" \"${PYTHON_LIBDIR}\")\n    else()\n      set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}\")\n    endif()\n    unset(PYTHON_LIBRARY)\n    find_library(\n      PYTHON_LIBRARY\n      NAMES \"python${PYTHON_LIBRARY_SUFFIX}\"\n      PATHS ${_PYTHON_LIBS_SEARCH}\n      NO_DEFAULT_PATH)\n  endif()\n\n  # raise an error if the python libs are still not found.\n  if(NOT EXISTS \"${PYTHON_LIBRARY}\")\n    message(FATAL_ERROR \"Python libraries not found\")\n  endif()\n\nelse()\n  if(PYTHON_MULTIARCH)\n    set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}/${PYTHON_MULTIARCH}\" \"${PYTHON_LIBDIR}\")\n  else()\n    set(_PYTHON_LIBS_SEARCH \"${PYTHON_LIBDIR}\")\n  endif()\n  #message(STATUS \"Searching for Python libs in ${_PYTHON_LIBS_SEARCH}\")\n  # Probably this needs to be more involved. It would be nice if the config\n  # information the python interpreter itself gave us were more complete.\n  find_library(\n    PYTHON_LIBRARY\n    NAMES \"python${PYTHON_LIBRARY_SUFFIX}\"\n    PATHS ${_PYTHON_LIBS_SEARCH}\n    NO_DEFAULT_PATH)\n\n  # If all else fails, just set the name/version and let the linker figure out the path.\n  if(NOT PYTHON_LIBRARY)\n    set(PYTHON_LIBRARY python${PYTHON_LIBRARY_SUFFIX})\n  endif()\nendif()\n\nmark_as_advanced(PYTHON_LIBRARY PYTHON_INCLUDE_DIR)\n\n# We use PYTHON_INCLUDE_DIR, PYTHON_LIBRARY and PYTHON_DEBUG_LIBRARY for the\n# cache entries because they are meant to specify the location of a single\n# library. We now set the variables listed by the documentation for this\n# module.\nset(PYTHON_INCLUDE_DIRS \"${PYTHON_INCLUDE_DIR}\")\nset(PYTHON_LIBRARIES \"${PYTHON_LIBRARY}\")\nif(NOT PYTHON_DEBUG_LIBRARY)\n  set(PYTHON_DEBUG_LIBRARY \"\")\nendif()\nset(PYTHON_DEBUG_LIBRARIES \"${PYTHON_DEBUG_LIBRARY}\")\n\nfind_package_message(PYTHON \"Found PythonLibs: ${PYTHON_LIBRARY}\"\n                     \"${PYTHON_EXECUTABLE}${PYTHON_VERSION_STRING}\")\n\nset(PYTHONLIBS_FOUND TRUE)\nset(PythonLibsNew_FOUND TRUE)\n\nif(NOT PYTHON_MODULE_PREFIX)\n  set(PYTHON_MODULE_PREFIX \"\")\nendif()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/check-style.sh",
    "content": "#!/bin/bash\n#\n# Script to check include/test code for common pybind11 code style errors.\n#\n# This script currently checks for\n#\n# 1. missing space between keyword and parenthesis, e.g.: for(, if(, while(\n# 2. Missing space between right parenthesis and brace, e.g. 'for (...){'\n# 3. opening brace on its own line. It should always be on the same line as the\n#    if/while/for/do statement.\n#\n# Invoke as: tools/check-style.sh <filenames>\n#\n\ncheck_style_errors=0\nIFS=$'\\n'\n\n\nfound=\"$(grep '\\<\\(if\\|for\\|while\\|catch\\)(\\|){' \"$@\" -rn --color=always)\"\nif [ -n \"$found\" ]; then\n    echo -e '\\033[31;01mError: found the following coding style problems:\\033[0m'\n    check_style_errors=1\n    echo \"${found//^/    /}\"\nfi\n\nfound=\"$(awk '\nfunction prefix(filename, lineno) {\n    return \"    \\033[35m\" filename \"\\033[36m:\\033[32m\" lineno \"\\033[36m:\\033[0m\"\n}\nfunction mark(pattern, string) { sub(pattern, \"\\033[01;31m&\\033[0m\", string); return string }\nlast && /^\\s*{/ {\n    print prefix(FILENAME, FNR-1) mark(\"\\\\)\\\\s*$\", last)\n    print prefix(FILENAME, FNR)   mark(\"^\\\\s*{\", $0)\n    last=\"\"\n}\n{ last = /(if|for|while|catch|switch)\\s*\\(.*\\)\\s*$/ ? $0 : \"\" }\n' \"$(find include -type f)\" \"$@\")\"\nif [ -n \"$found\" ]; then\n    check_style_errors=1\n    echo -e '\\033[31;01mError: braces should occur on the same line as the if/while/.. statement. Found issues in the following files:\\033[0m'\n    echo \"$found\"\nfi\n\nexit $check_style_errors\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/cmake_uninstall.cmake.in",
    "content": "# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake\n\nif(NOT EXISTS \"@CMAKE_BINARY_DIR@/install_manifest.txt\")\n  message(FATAL_ERROR \"Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt\")\nendif()\n\nfile(READ \"@CMAKE_BINARY_DIR@/install_manifest.txt\" files)\nstring(REGEX REPLACE \"\\n\" \";\" files \"${files}\")\nforeach(file ${files})\n  message(STATUS \"Uninstalling $ENV{DESTDIR}${file}\")\n  if(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    exec_program(\n      \"@CMAKE_COMMAND@\" ARGS\n      \"-E remove \\\"$ENV{DESTDIR}${file}\\\"\"\n      OUTPUT_VARIABLE rm_out\n      RETURN_VALUE rm_retval)\n    if(NOT \"${rm_retval}\" STREQUAL 0)\n      message(FATAL_ERROR \"Problem when removing $ENV{DESTDIR}${file}\")\n    endif()\n  else(IS_SYMLINK \"$ENV{DESTDIR}${file}\" OR EXISTS \"$ENV{DESTDIR}${file}\")\n    message(STATUS \"File $ENV{DESTDIR}${file} does not exist.\")\n  endif()\nendforeach()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/libsize.py",
    "content": "# -*- coding: utf-8 -*-\nfrom __future__ import division, print_function\n\nimport os\nimport sys\n\n# Internal build script for generating debugging test .so size.\n# Usage:\n#     python libsize.py file.so save.txt -- displays the size of file.so and, if save.txt exists, compares it to the\n#                                           size in it, then overwrites save.txt with the new size for future runs.\n\nif len(sys.argv) != 3:\n    sys.exit(\"Invalid arguments: usage: python libsize.py file.so save.txt\")\n\nlib = sys.argv[1]\nsave = sys.argv[2]\n\nif not os.path.exists(lib):\n    sys.exit(\"Error: requested file ({}) does not exist\".format(lib))\n\nlibsize = os.path.getsize(lib)\n\nprint(\"------\", os.path.basename(lib), \"file size:\", libsize, end=\"\")\n\nif os.path.exists(save):\n    with open(save) as sf:\n        oldsize = int(sf.readline())\n\n    if oldsize > 0:\n        change = libsize - oldsize\n        if change == 0:\n            print(\" (no change)\")\n        else:\n            print(\" (change of {:+} bytes = {:+.2%})\".format(change, change / oldsize))\nelse:\n    print()\n\nwith open(save, \"w\") as sf:\n    sf.write(str(libsize))\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/make_changelog.py",
    "content": "#!/usr/bin/env python3\n# -*- coding: utf-8 -*-\n\nimport re\n\nimport ghapi.all\nfrom rich import print\nfrom rich.syntax import Syntax\n\nENTRY = re.compile(\n    r\"\"\"\n    Suggested \\s changelog \\s entry:\n    .*\n    ```rst\n    \\s*\n    (.*?)\n    \\s*\n    ```\n\"\"\",\n    re.DOTALL | re.VERBOSE,\n)\n\nprint()\n\n\napi = ghapi.all.GhApi(owner=\"pybind\", repo=\"pybind11\")\n\nissues_pages = ghapi.page.paged(\n    api.issues.list_for_repo, labels=\"needs changelog\", state=\"closed\"\n)\nissues = (issue for page in issues_pages for issue in page)\nmissing = []\n\nfor issue in issues:\n    changelog = ENTRY.findall(issue.body)\n    if changelog:\n        (msg,) = changelog\n        if not msg.startswith(\"* \"):\n            msg = \"* \" + msg\n        if not msg.endswith(\".\"):\n            msg += \".\"\n\n        msg += f\"\\n  `#{issue.number} <{issue.html_url}>`_\"\n\n        print(Syntax(msg, \"rst\", theme=\"ansi_light\", word_wrap=True))\n        print()\n\n    else:\n        missing.append(issue)\n\nif missing:\n    print()\n    print(\"[blue]\" + \"-\" * 30)\n    print()\n\n    for issue in missing:\n        print(f\"[red bold]Missing:[/red bold][red] {issue.title}\")\n        print(f\"[red]  {issue.html_url}\\n\")\n\n    print(\"[bold]Template:\\n\")\n    msg = \"## Suggested changelog entry:\\n\\n```rst\\n\\n```\"\n    print(Syntax(msg, \"md\", theme=\"ansi_light\"))\n\nprint()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/pybind11Common.cmake",
    "content": "#[======================================================[.rst\n\nAdds the following targets::\n\n    pybind11::pybind11 - link to headers and pybind11\n    pybind11::module - Adds module links\n    pybind11::embed - Adds embed links\n    pybind11::lto - Link time optimizations (manual selection)\n    pybind11::thin_lto - Link time optimizations (manual selection)\n    pybind11::python_link_helper - Adds link to Python libraries\n    pybind11::python2_no_register - Avoid warning/error with Python 2 + C++14/7\n    pybind11::windows_extras - MSVC bigobj and mp for building multithreaded\n    pybind11::opt_size - avoid optimizations that increase code size\n\nAdds the following functions::\n\n    pybind11_strip(target) - strip target after building on linux/macOS\n    pybind11_find_import(module) - See if a module is installed.\n\n#]======================================================]\n\n# CMake 3.10 has an include_guard command, but we can't use that yet\n# include_guard(global) (pre-CMake 3.10)\nif(TARGET pybind11::lto)\n  return()\nendif()\n\n# If we are in subdirectory mode, all IMPORTED targets must be GLOBAL. If we\n# are in CONFIG mode, they should be \"normal\" targets instead.\n# In CMake 3.11+ you can promote a target to global after you create it,\n# which might be simpler than this check.\nget_property(\n  is_config\n  TARGET pybind11::headers\n  PROPERTY IMPORTED)\nif(NOT is_config)\n  set(optional_global GLOBAL)\nendif()\n\n# If not run in Python mode, we still would like this to at least\n# include pybind11's include directory:\nset(pybind11_INCLUDE_DIRS\n    \"${pybind11_INCLUDE_DIR}\"\n    CACHE INTERNAL \"Include directory for pybind11 (Python not requested)\")\n\n# --------------------- Shared targets ----------------------------\n\n# Build an interface library target:\nadd_library(pybind11::pybind11 IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::pybind11\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::headers)\n\n# Build a module target:\nadd_library(pybind11::module IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::module\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)\n\n# Build an embed library target:\nadd_library(pybind11::embed IMPORTED INTERFACE ${optional_global})\nset_property(\n  TARGET pybind11::embed\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11)\n\n# ----------------------- no register ----------------------\n\n# Workaround for Python 2.7 and C++17 (C++14 as a warning) incompatibility\n# This adds the flags -Wno-register and -Wno-deprecated-register if the compiler\n# is Clang 3.9+ or AppleClang and the compile language is CXX, or /wd5033 for MSVC (all languages,\n# since MSVC didn't recognize COMPILE_LANGUAGE until CMake 3.11+).\n\nadd_library(pybind11::python2_no_register INTERFACE IMPORTED ${optional_global})\nset(clang_4plus\n    \"$<AND:$<CXX_COMPILER_ID:Clang>,$<NOT:$<VERSION_LESS:$<CXX_COMPILER_VERSION>,3.9>>>\")\nset(no_register \"$<OR:${clang_4plus},$<CXX_COMPILER_ID:AppleClang>>\")\n\nif(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)\n  set(cxx_no_register \"${no_register}\")\nelse()\n  set(cxx_no_register \"$<AND:$<COMPILE_LANGUAGE:CXX>,${no_register}>\")\nendif()\n\nset(msvc \"$<CXX_COMPILER_ID:MSVC>\")\n\nset_property(\n  TARGET pybind11::python2_no_register\n  PROPERTY INTERFACE_COMPILE_OPTIONS\n           \"$<${cxx_no_register}:-Wno-register;-Wno-deprecated-register>\" \"$<${msvc}:/wd5033>\")\n\n# --------------------------- link helper ---------------------------\n\nadd_library(pybind11::python_link_helper IMPORTED INTERFACE ${optional_global})\n\nif(CMAKE_VERSION VERSION_LESS 3.13)\n  # In CMake 3.11+, you can set INTERFACE properties via the normal methods, and\n  # this would be simpler.\n  set_property(\n    TARGET pybind11::python_link_helper\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES \"$<$<PLATFORM_ID:Darwin>:-undefined dynamic_lookup>\")\nelse()\n  # link_options was added in 3.13+\n  # This is safer, because you are ensured the deduplication pass in CMake will not consider\n  # these separate and remove one but not the other.\n  set_property(\n    TARGET pybind11::python_link_helper\n    APPEND\n    PROPERTY INTERFACE_LINK_OPTIONS \"$<$<PLATFORM_ID:Darwin>:LINKER:-undefined,dynamic_lookup>\")\nendif()\n\n# ------------------------ Windows extras -------------------------\n\nadd_library(pybind11::windows_extras IMPORTED INTERFACE ${optional_global})\n\nif(MSVC) # That's also clang-cl\n  # /bigobj is needed for bigger binding projects due to the limit to 64k\n  # addressable sections\n  set_property(\n    TARGET pybind11::windows_extras\n    APPEND\n    PROPERTY INTERFACE_COMPILE_OPTIONS /bigobj)\n\n  # /MP enables multithreaded builds (relevant when there are many files) for MSVC\n  if(\"${CMAKE_CXX_COMPILER_ID}\" STREQUAL \"MSVC\") # no Clang no Intel\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      set_property(\n        TARGET pybind11::windows_extras\n        APPEND\n        PROPERTY INTERFACE_COMPILE_OPTIONS $<$<NOT:$<CONFIG:Debug>>:/MP>)\n    else()\n      # Only set these options for C++ files.  This is important so that, for\n      # instance, projects that include other types of source files like CUDA\n      # .cu files don't get these options propagated to nvcc since that would\n      # cause the build to fail.\n      set_property(\n        TARGET pybind11::windows_extras\n        APPEND\n        PROPERTY INTERFACE_COMPILE_OPTIONS\n                 $<$<NOT:$<CONFIG:Debug>>:$<$<COMPILE_LANGUAGE:CXX>:/MP>>)\n    endif()\n  endif()\nendif()\n\n# ----------------------- Optimize binary size --------------------------\n\nadd_library(pybind11::opt_size IMPORTED INTERFACE ${optional_global})\n\nif(MSVC)\n  set(PYBIND11_OPT_SIZE /Os)\nelse()\n  set(PYBIND11_OPT_SIZE -Os)\nendif()\n\nset_property(\n  TARGET pybind11::opt_size\n  APPEND\n  PROPERTY INTERFACE_COMPILE_OPTIONS $<$<CONFIG:Release>:${PYBIND11_OPT_SIZE}>\n           $<$<CONFIG:MinSizeRel>:${PYBIND11_OPT_SIZE}>\n           $<$<CONFIG:RelWithDebInfo>:${PYBIND11_OPT_SIZE}>)\n\n# ----------------------- Legacy option --------------------------\n\n# Warn or error if old variable name used\nif(PYBIND11_CPP_STANDARD)\n  string(REGEX MATCH [[..$]] VAL \"${PYBIND11_CPP_STANDARD}\")\n  if(CMAKE_CXX_STANDARD)\n    if(NOT CMAKE_CXX_STANDARD STREQUAL VAL)\n      message(WARNING \"CMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} does not match \"\n                      \"PYBIND11_CPP_STANDARD=${PYBIND11_CPP_STANDARD}, \"\n                      \"please remove PYBIND11_CPP_STANDARD from your cache\")\n    endif()\n  else()\n    set(supported_standards 11 14 17 20)\n    if(\"${VAL}\" IN_LIST supported_standards)\n      message(WARNING \"USE -DCMAKE_CXX_STANDARD=${VAL} instead of PYBIND11_CPP_STANDARD\")\n      set(CMAKE_CXX_STANDARD\n          ${VAL}\n          CACHE STRING \"From PYBIND11_CPP_STANDARD\")\n    else()\n      message(FATAL_ERROR \"PYBIND11_CPP_STANDARD should be replaced with CMAKE_CXX_STANDARD \"\n                          \"(last two chars: ${VAL} not understood as a valid CXX std)\")\n    endif()\n  endif()\nendif()\n\n# --------------------- Python specifics -------------------------\n\n# Check to see which Python mode we are in, new, old, or no python\nif(PYBIND11_NOPYTHON)\n  set(_pybind11_nopython ON)\nelseif(\n  PYBIND11_FINDPYTHON\n  OR Python_FOUND\n  OR Python2_FOUND\n  OR Python3_FOUND)\n  # New mode\n  include(\"${CMAKE_CURRENT_LIST_DIR}/pybind11NewTools.cmake\")\n\nelse()\n\n  # Classic mode\n  include(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Tools.cmake\")\n\nendif()\n\n# --------------------- pybind11_find_import -------------------------------\n\nif(NOT _pybind11_nopython)\n  # Check to see if modules are importable. Use REQUIRED to force an error if\n  # one of the modules is not found. <package_name>_FOUND will be set if the\n  # package was found (underscores replace dashes if present). QUIET will hide\n  # the found message, and VERSION will require a minimum version. A successful\n  # find will cache the result.\n  function(pybind11_find_import PYPI_NAME)\n    # CMake variables need underscores (PyPI doesn't care)\n    string(REPLACE \"-\" \"_\" NORM_PYPI_NAME \"${PYPI_NAME}\")\n\n    # Return if found previously\n    if(${NORM_PYPI_NAME}_FOUND)\n      return()\n    endif()\n\n    set(options \"REQUIRED;QUIET\")\n    set(oneValueArgs \"VERSION\")\n    cmake_parse_arguments(ARG \"${options}\" \"${oneValueArgs}\" \"\" ${ARGN})\n\n    if(ARG_REQUIRED)\n      set(status_level FATAL_ERROR)\n    else()\n      set(status_level WARNING)\n    endif()\n\n    execute_process(\n      COMMAND\n        ${${_Python}_EXECUTABLE} -c\n        \"from pkg_resources import get_distribution; print(get_distribution('${PYPI_NAME}').version)\"\n      RESULT_VARIABLE RESULT_PRESENT\n      OUTPUT_VARIABLE PKG_VERSION\n      ERROR_QUIET)\n\n    string(STRIP \"${PKG_VERSION}\" PKG_VERSION)\n\n    # If a result is present, this failed\n    if(RESULT_PRESENT)\n      set(${NORM_PYPI_NAME}_FOUND\n          ${NORM_PYPI_NAME}-NOTFOUND\n          CACHE INTERNAL \"\")\n      # Always warn or error\n      message(\n        ${status_level}\n        \"Missing: ${PYPI_NAME} ${ARG_VERSION}\\nTry: ${${_Python}_EXECUTABLE} -m pip install ${PYPI_NAME}\"\n      )\n    else()\n      if(ARG_VERSION AND PKG_VERSION VERSION_LESS ARG_VERSION)\n        message(\n          ${status_level}\n          \"Version incorrect: ${PYPI_NAME} ${PKG_VERSION} found, ${ARG_VERSION} required - try upgrading\"\n        )\n      else()\n        set(${NORM_PYPI_NAME}_FOUND\n            YES\n            CACHE INTERNAL \"\")\n        set(${NORM_PYPI_NAME}_VERSION\n            ${PKG_VERSION}\n            CACHE INTERNAL \"\")\n      endif()\n      if(NOT ARG_QUIET)\n        message(STATUS \"Found ${PYPI_NAME} ${PKG_VERSION}\")\n      endif()\n    endif()\n    if(NOT ARG_VERSION OR (NOT PKG_VERSION VERSION_LESS ARG_VERSION))\n      # We have successfully found a good version, cache to avoid calling again.\n    endif()\n  endfunction()\nendif()\n\n# --------------------- LTO -------------------------------\n\ninclude(CheckCXXCompilerFlag)\n\n# Checks whether the given CXX/linker flags can compile and link a cxx file.\n# cxxflags and linkerflags are lists of flags to use.  The result variable is a\n# unique variable name for each set of flags: the compilation result will be\n# cached base on the result variable.  If the flags work, sets them in\n# cxxflags_out/linkerflags_out internal cache variables (in addition to\n# ${result}).\nfunction(_pybind11_return_if_cxx_and_linker_flags_work result cxxflags linkerflags cxxflags_out\n         linkerflags_out)\n  set(CMAKE_REQUIRED_LIBRARIES ${linkerflags})\n  check_cxx_compiler_flag(\"${cxxflags}\" ${result})\n  if(${result})\n    set(${cxxflags_out}\n        \"${cxxflags}\"\n        PARENT_SCOPE)\n    set(${linkerflags_out}\n        \"${linkerflags}\"\n        PARENT_SCOPE)\n  endif()\nendfunction()\n\nfunction(_pybind11_generate_lto target prefer_thin_lto)\n  if(MINGW)\n    message(STATUS \"${target} disabled (problems with undefined symbols for MinGW for now)\")\n    return()\n  endif()\n\n  if(CMAKE_CXX_COMPILER_ID MATCHES \"GNU|Clang\")\n    set(cxx_append \"\")\n    set(linker_append \"\")\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\" AND NOT APPLE)\n      # Clang Gold plugin does not support -Os; append -O3 to MinSizeRel builds to override it\n      set(linker_append \";$<$<CONFIG:MinSizeRel>:-O3>\")\n    elseif(CMAKE_CXX_COMPILER_ID MATCHES \"GNU\" AND NOT MINGW)\n      set(cxx_append \";-fno-fat-lto-objects\")\n    endif()\n\n    if(CMAKE_SYSTEM_PROCESSOR MATCHES \"ppc64le\" OR CMAKE_SYSTEM_PROCESSOR MATCHES \"mips64\")\n      set(NO_FLTO_ARCH TRUE)\n    else()\n      set(NO_FLTO_ARCH FALSE)\n    endif()\n\n    if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\"\n       AND prefer_thin_lto\n       AND NOT NO_FLTO_ARCH)\n      _pybind11_return_if_cxx_and_linker_flags_work(\n        HAS_FLTO_THIN \"-flto=thin${cxx_append}\" \"-flto=thin${linker_append}\"\n        PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n    endif()\n\n    if(NOT HAS_FLTO_THIN AND NOT NO_FLTO_ARCH)\n      _pybind11_return_if_cxx_and_linker_flags_work(\n        HAS_FLTO \"-flto${cxx_append}\" \"-flto${linker_append}\" PYBIND11_LTO_CXX_FLAGS\n        PYBIND11_LTO_LINKER_FLAGS)\n    endif()\n  elseif(CMAKE_CXX_COMPILER_ID MATCHES \"Intel\")\n    # Intel equivalent to LTO is called IPO\n    _pybind11_return_if_cxx_and_linker_flags_work(HAS_INTEL_IPO \"-ipo\" \"-ipo\"\n                                                  PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n  elseif(MSVC)\n    # cmake only interprets libraries as linker flags when they start with a - (otherwise it\n    # converts /LTCG to \\LTCG as if it was a Windows path).  Luckily MSVC supports passing flags\n    # with - instead of /, even if it is a bit non-standard:\n    _pybind11_return_if_cxx_and_linker_flags_work(HAS_MSVC_GL_LTCG \"/GL\" \"-LTCG\"\n                                                  PYBIND11_LTO_CXX_FLAGS PYBIND11_LTO_LINKER_FLAGS)\n  endif()\n\n  # Enable LTO flags if found, except for Debug builds\n  if(PYBIND11_LTO_CXX_FLAGS)\n    # CONFIG takes multiple values in CMake 3.19+, until then we have to use OR\n    set(is_debug \"$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>\")\n    set(not_debug \"$<NOT:${is_debug}>\")\n    set(cxx_lang \"$<COMPILE_LANGUAGE:CXX>\")\n    if(MSVC AND CMAKE_VERSION VERSION_LESS 3.11)\n      set(genex \"${not_debug}\")\n    else()\n      set(genex \"$<AND:${not_debug},${cxx_lang}>\")\n    endif()\n    set_property(\n      TARGET ${target}\n      APPEND\n      PROPERTY INTERFACE_COMPILE_OPTIONS \"$<${genex}:${PYBIND11_LTO_CXX_FLAGS}>\")\n    if(CMAKE_PROJECT_NAME STREQUAL \"pybind11\")\n      message(STATUS \"${target} enabled\")\n    endif()\n  else()\n    if(CMAKE_PROJECT_NAME STREQUAL \"pybind11\")\n      message(STATUS \"${target} disabled (not supported by the compiler and/or linker)\")\n    endif()\n  endif()\n\n  if(PYBIND11_LTO_LINKER_FLAGS)\n    if(CMAKE_VERSION VERSION_LESS 3.11)\n      set_property(\n        TARGET ${target}\n        APPEND\n        PROPERTY INTERFACE_LINK_LIBRARIES \"$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>\")\n    else()\n      set_property(\n        TARGET ${target}\n        APPEND\n        PROPERTY INTERFACE_LINK_OPTIONS \"$<${not_debug}:${PYBIND11_LTO_LINKER_FLAGS}>\")\n    endif()\n  endif()\nendfunction()\n\nadd_library(pybind11::lto IMPORTED INTERFACE ${optional_global})\n_pybind11_generate_lto(pybind11::lto FALSE)\n\nadd_library(pybind11::thin_lto IMPORTED INTERFACE ${optional_global})\n_pybind11_generate_lto(pybind11::thin_lto TRUE)\n\n# ---------------------- pybind11_strip -----------------------------\n\nfunction(pybind11_strip target_name)\n  # Strip unnecessary sections of the binary on Linux/macOS\n  if(CMAKE_STRIP)\n    if(APPLE)\n      set(x_opt -x)\n    endif()\n\n    add_custom_command(\n      TARGET ${target_name}\n      POST_BUILD\n      COMMAND ${CMAKE_STRIP} ${x_opt} $<TARGET_FILE:${target_name}>)\n  endif()\nendfunction()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/pybind11Config.cmake.in",
    "content": "#[=============================================================================[.rst:\n\npybind11Config.cmake\n####################\n\nExported variables\n==================\n\nThis module sets the following variables in your project:\n\n``pybind11_FOUND``\n  true if pybind11 and all required components found on the system\n``pybind11_VERSION``\n  pybind11 version in format Major.Minor.Release\n``pybind11_VERSION_TYPE``\n  pybind11 version type (``dev*`` or empty for a release)\n``pybind11_INCLUDE_DIRS``\n  Directories where pybind11 and python headers are located.\n``pybind11_INCLUDE_DIR``\n  Directory where pybind11 headers are located.\n``pybind11_DEFINITIONS``\n  Definitions necessary to use pybind11, namely USING_pybind11.\n``pybind11_LIBRARIES``\n  Compile flags and python libraries (as needed) to link against.\n``pybind11_LIBRARY``\n  Empty.\n\nAvailable components: None\n\n\nExported targets\n================\n\nIf pybind11 is found, this module defines the following ``IMPORTED``\ninterface library targets:\n\n``pybind11::module``\n  for extension modules.\n``pybind11::embed``\n  for embedding the Python interpreter.\n\nPython headers, libraries (as needed by platform), and the C++ standard\nare attached to the target.\n\nAdvanced targets are also supplied - these are primary for users building\ncomplex applications, and they are available in all modes:\n\n``pybind11::headers``\n  Just the pybind11 headers and minimum compile requirements.\n``pybind11::pybind11``\n  Python headers too.\n``pybind11::python_link_helper``\n  Just the \"linking\" part of ``pybind11:module``, for CMake < 3.15.\n``pybind11::python2_no_register``\n  Quiets the warning/error when mixing C++14+ and Python 2, also included in ``pybind11::module``.\n``pybind11::thin_lto``\n  An alternative to ``INTERPROCEDURAL_OPTIMIZATION``.\n``pybind11::lto``\n  An alternative to ``INTERPROCEDURAL_OPTIMIZATION`` (also avoids thin LTO on clang).\n``pybind11::windows_extras``\n  Adds bigobj and mp for MSVC.\n\nModes\n=====\n\nThere are two modes provided; classic, which is built on the old Python\ndiscovery packages in CMake, or the new FindPython mode, which uses FindPython\nfrom 3.12+ forward (3.15+ _highly_ recommended).\n\nNew FindPython mode\n^^^^^^^^^^^^^^^^^^^\n\nTo activate this mode, either call ``find_package(Python COMPONENTS Interpreter Development)``\nbefore finding this package, or set the ``PYBIND11_FINDPYTHON`` variable to ON. In this mode,\nyou can either use the basic targets, or use the FindPython tools:\n\n.. code-block:: cmake\n\n  find_package(Python COMPONENTS Interpreter Development)\n  find_package(pybind11 CONFIG)\n\n  # pybind11 method:\n  pybind11_add_module(MyModule1 src1.cpp)\n\n  # Python method:\n  Python_add_library(MyModule2 src2.cpp)\n  target_link_libraries(MyModule2 pybind11::headers)\n  set_target_properties(MyModule2 PROPERTIES\n                                  INTERPROCEDURAL_OPTIMIZATION ON\n                                  CXX_VISIBILITY_PRESET ON\n                                  VISIBILITY_INLINES_HIDDEN ON)\n\nIf you build targets yourself, you may be interested in stripping the output\nfor reduced size; this is the one other feature that the helper function gives you.\n\nClassic mode\n^^^^^^^^^^^^\n\nSet PythonLibsNew variables to influence python detection and\nCMAKE_CXX_STANDARD to influence standard setting.\n\n.. code-block:: cmake\n\n  find_package(pybind11 CONFIG REQUIRED)\n\n  # Create an extension module\n  add_library(mylib MODULE main.cpp)\n  target_link_libraries(mylib PUBLIC pybind11::module)\n\n  # Or embed the Python interpreter into an executable\n  add_executable(myexe main.cpp)\n  target_link_libraries(myexe PUBLIC pybind11::embed)\n\n\nHints\n=====\n\nThe following variables can be set to guide the search for this package:\n\n``pybind11_DIR``\n  CMake variable, set to directory containing this Config file.\n``CMAKE_PREFIX_PATH``\n  CMake variable, set to root directory of this package.\n``PATH``\n  Environment variable, set to bin directory of this package.\n``CMAKE_DISABLE_FIND_PACKAGE_pybind11``\n  CMake variable, disables ``find_package(pybind11)`` when not ``REQUIRED``,\n  perhaps to force internal build.\n\nCommands\n========\n\npybind11_add_module\n^^^^^^^^^^^^^^^^^^^\n\nThis module defines the following commands to assist with creating Python modules:\n\n.. code-block:: cmake\n\n  pybind11_add_module(<target>\n    [STATIC|SHARED|MODULE]\n    [THIN_LTO] [OPT_SIZE] [NO_EXTRAS] [WITHOUT_SOABI]\n    <files>...\n    )\n\nAdd a module and setup all helpers. You can select the type of the library; the\ndefault is ``MODULE``. There are several options:\n\n``OPT_SIZE``\n  Optimize for size, even if the ``CMAKE_BUILD_TYPE`` is not ``MinSizeRel``.\n``THIN_LTO``\n  Use thin TLO instead of regular if there's a choice (pybind11's selection\n  is disabled if ``CMAKE_INTERPROCEDURAL_OPTIMIZATIONS`` is set).\n``WITHOUT_SOABI``\n  Disable the SOABI component (``PYBIND11_NEWPYTHON`` mode only).\n``NO_EXTRAS``\n  Disable all extras, exit immediately after making the module.\n\npybind11_strip\n^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n  pybind11_strip(<target>)\n\nStrip a target after building it (linux/macOS), called by ``pybind11_add_module``.\n\npybind11_extension\n^^^^^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n    pybind11_extension(<target>)\n\nSets the Python extension name correctly for Python on your platform, called by\n``pybind11_add_module``.\n\npybind11_find_import(module)\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n.. code-block:: cmake\n\n    pybind11_find_import(<module> [VERSION <number>] [REQUIRED] [QUIET])\n\nSee if a module is installed. Use the registered name (the one on PyPI). You\ncan specify a ``VERSION``, and you can specify ``REQUIRED`` or ``QUIET``. Only available if\n``NOPYTHON`` mode is not active.  Sets ``module_VERSION`` and ``module_FOUND``. Caches the\nresult once a valid install is found.\n\nSuggested usage\n===============\n\nUsing ``find_package`` with version info is not recommended except for release versions.\n\n.. code-block:: cmake\n\n  find_package(pybind11 CONFIG)\n  find_package(pybind11 2.0 EXACT CONFIG REQUIRED)\n\n#]=============================================================================]\n@PACKAGE_INIT@\n\n# Location of pybind11/pybind11.h\n# This will be relative unless explicitly set as absolute\nset(pybind11_INCLUDE_DIR \"@pybind11_INCLUDEDIR@\")\n\nset(pybind11_LIBRARY \"\")\nset(pybind11_DEFINITIONS USING_pybind11)\nset(pybind11_VERSION_TYPE \"@pybind11_VERSION_TYPE@\")\n\ncheck_required_components(pybind11)\n\nif(TARGET pybind11::python_link_helper)\n  # This has already been setup elsewhere, such as with a previous call or\n  # add_subdirectory\n  return()\nendif()\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Targets.cmake\")\n\n# Easier to use / remember\nadd_library(pybind11::headers IMPORTED INTERFACE)\nset_target_properties(pybind11::headers PROPERTIES INTERFACE_LINK_LIBRARIES\n                                                   pybind11::pybind11_headers)\n\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/pybind11Common.cmake\")\n\nif(NOT pybind11_FIND_QUIETLY)\n  message(\n    STATUS\n      \"Found pybind11: ${pybind11_INCLUDE_DIR} (found version \\\"${pybind11_VERSION}${pybind11_VERSION_TYPE}\\\")\"\n  )\nendif()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/pybind11NewTools.cmake",
    "content": "# tools/pybind11NewTools.cmake -- Build system for the pybind11 modules\n#\n# Copyright (c) 2020 Wenzel Jakob <wenzel@inf.ethz.ch> and Henry Schreiner\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\nif(CMAKE_VERSION VERSION_LESS 3.12)\n  message(FATAL_ERROR \"You cannot use the new FindPython module with CMake < 3.12\")\nendif()\n\ninclude_guard(GLOBAL)\n\nget_property(\n  is_config\n  TARGET pybind11::headers\n  PROPERTY IMPORTED)\n\nif(pybind11_FIND_QUIETLY)\n  set(_pybind11_quiet QUIET)\nelse()\n  set(_pybind11_quiet \"\")\nendif()\n\nif(NOT Python_FOUND\n   AND NOT Python3_FOUND\n   AND NOT Python2_FOUND)\n  if(NOT DEFINED Python_FIND_IMPLEMENTATIONS)\n    set(Python_FIND_IMPLEMENTATIONS CPython PyPy)\n  endif()\n\n  # GitHub Actions like activation\n  if(NOT DEFINED Python_ROOT_DIR AND DEFINED ENV{pythonLocation})\n    set(Python_ROOT_DIR \"$ENV{pythonLocation}\")\n  endif()\n\n  find_package(Python REQUIRED COMPONENTS Interpreter Development ${_pybind11_quiet})\n\n  # If we are in submodule mode, export the Python targets to global targets.\n  # If this behavior is not desired, FindPython _before_ pybind11.\n  if(NOT is_config)\n    set_property(TARGET Python::Python PROPERTY IMPORTED_GLOBAL TRUE)\n    set_property(TARGET Python::Interpreter PROPERTY IMPORTED_GLOBAL TRUE)\n    if(TARGET Python::Module)\n      set_property(TARGET Python::Module PROPERTY IMPORTED_GLOBAL TRUE)\n    endif()\n  endif()\nendif()\n\nif(Python_FOUND)\n  set(_Python\n      Python\n      CACHE INTERNAL \"\" FORCE)\nelseif(Python3_FOUND AND NOT Python2_FOUND)\n  set(_Python\n      Python3\n      CACHE INTERNAL \"\" FORCE)\nelseif(Python2_FOUND AND NOT Python3_FOUND)\n  set(_Python\n      Python2\n      CACHE INTERNAL \"\" FORCE)\nelse()\n  message(AUTHOR_WARNING \"Python2 and Python3 both present, pybind11 in \"\n                         \"PYBIND11_NOPYTHON mode (manually activate to silence warning)\")\n  set(_pybind11_nopython ON)\n  return()\nendif()\n\nif(PYBIND11_MASTER_PROJECT)\n  if(${_Python}_INTERPRETER_ID MATCHES \"PyPy\")\n    message(STATUS \"PyPy ${${_Python}_PyPy_VERSION} (Py ${${_Python}_VERSION})\")\n  else()\n    message(STATUS \"${_Python} ${${_Python}_VERSION}\")\n  endif()\nendif()\n\n# If a user finds Python, they may forget to include the Interpreter component\n# and the following two steps require it. It is highly recommended by CMake\n# when finding development libraries anyway, so we will require it.\nif(NOT DEFINED ${_Python}_EXECUTABLE)\n  message(\n    FATAL_ERROR\n      \"${_Python} was found without the Interpreter component. Pybind11 requires this component.\")\n\nendif()\n\nif(NOT ${_Python}_EXECUTABLE STREQUAL PYBIND11_PYTHON_EXECUTABLE_LAST)\n  # Detect changes to the Python version/binary in subsequent CMake runs, and refresh config if needed\n  unset(PYTHON_IS_DEBUG CACHE)\n  unset(PYTHON_MODULE_EXTENSION CACHE)\n  set(PYBIND11_PYTHON_EXECUTABLE_LAST\n      \"${${_Python}_EXECUTABLE}\"\n      CACHE INTERNAL \"Python executable during the last CMake run\")\nendif()\n\nif(NOT DEFINED PYTHON_IS_DEBUG)\n  # Debug check - see https://stackoverflow.com/questions/646518/python-how-to-detect-debug-Interpreter\n  execute_process(\n    COMMAND \"${${_Python}_EXECUTABLE}\" \"-c\"\n            \"import sys; sys.exit(hasattr(sys, 'gettotalrefcount'))\"\n    RESULT_VARIABLE _PYTHON_IS_DEBUG)\n  set(PYTHON_IS_DEBUG\n      \"${_PYTHON_IS_DEBUG}\"\n      CACHE INTERNAL \"Python debug status\")\nendif()\n\n# Get the suffix - SO is deprecated, should use EXT_SUFFIX, but this is\n# required for PyPy3 (as of 7.3.1)\nif(NOT DEFINED PYTHON_MODULE_EXTENSION)\n  execute_process(\n    COMMAND\n      \"${${_Python}_EXECUTABLE}\" \"-c\"\n      \"import sys, importlib; s = importlib.import_module('distutils.sysconfig' if sys.version_info < (3, 10) else 'sysconfig'); print(s.get_config_var('EXT_SUFFIX') or s.get_config_var('SO'))\"\n    OUTPUT_VARIABLE _PYTHON_MODULE_EXTENSION\n    ERROR_VARIABLE _PYTHON_MODULE_EXTENSION_ERR\n    OUTPUT_STRIP_TRAILING_WHITESPACE)\n\n  if(_PYTHON_MODULE_EXTENSION STREQUAL \"\")\n    message(\n      FATAL_ERROR \"pybind11 could not query the module file extension, likely the 'distutils'\"\n                  \"package is not installed. Full error message:\\n${_PYTHON_MODULE_EXTENSION_ERR}\")\n  endif()\n\n  # This needs to be available for the pybind11_extension function\n  set(PYTHON_MODULE_EXTENSION\n      \"${_PYTHON_MODULE_EXTENSION}\"\n      CACHE INTERNAL \"\")\nendif()\n\n# Python debug libraries expose slightly different objects before 3.8\n# https://docs.python.org/3.6/c-api/intro.html#debugging-builds\n# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib\nif(PYTHON_IS_DEBUG)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)\nendif()\n\n# Check on every access - since Python2 and Python3 could have been used - do nothing in that case.\n\nif(DEFINED ${_Python}_INCLUDE_DIRS)\n  # Only add Python for build - must be added during the import for config\n  # since it has to be re-discovered.\n  #\n  # This needs to be a target to be included after the local pybind11\n  # directory, just in case there there is an installed pybind11 sitting\n  # next to Python's includes. It also ensures Python is a SYSTEM library.\n  add_library(pybind11::python_headers INTERFACE IMPORTED)\n  set_property(\n    TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                             \"$<BUILD_INTERFACE:${${_Python}_INCLUDE_DIRS}>\")\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)\n  set(pybind11_INCLUDE_DIRS\n      \"${pybind11_INCLUDE_DIR}\" \"${${_Python}_INCLUDE_DIRS}\"\n      CACHE INTERNAL \"Directories where pybind11 and possibly Python headers are located\")\nendif()\n\nif(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)\nendif()\n\n# In CMake 3.18+, you can find these separately, so include an if\nif(TARGET ${_Python}::Python)\n  set_property(\n    TARGET pybind11::embed\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Python)\nendif()\n\n# CMake 3.15+ has this\nif(TARGET ${_Python}::Module)\n  set_property(\n    TARGET pybind11::module\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES ${_Python}::Module)\nelse()\n  set_property(\n    TARGET pybind11::module\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_link_helper)\nendif()\n\n# WITHOUT_SOABI and WITH_SOABI will disable the custom extension handling used by pybind11.\n# WITH_SOABI is passed on to python_add_library.\nfunction(pybind11_add_module target_name)\n  cmake_parse_arguments(PARSE_ARGV 1 ARG\n                        \"STATIC;SHARED;MODULE;THIN_LTO;OPT_SIZE;NO_EXTRAS;WITHOUT_SOABI\" \"\" \"\")\n\n  if(ARG_STATIC)\n    set(lib_type STATIC)\n  elseif(ARG_SHARED)\n    set(lib_type SHARED)\n  else()\n    set(lib_type MODULE)\n  endif()\n\n  if(\"${_Python}\" STREQUAL \"Python\")\n    python_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})\n  elseif(\"${_Python}\" STREQUAL \"Python3\")\n    python3_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})\n  elseif(\"${_Python}\" STREQUAL \"Python2\")\n    python2_add_library(${target_name} ${lib_type} ${ARG_UNPARSED_ARGUMENTS})\n  else()\n    message(FATAL_ERROR \"Cannot detect FindPython version: ${_Python}\")\n  endif()\n\n  target_link_libraries(${target_name} PRIVATE pybind11::headers)\n\n  if(lib_type STREQUAL \"MODULE\")\n    target_link_libraries(${target_name} PRIVATE pybind11::module)\n  else()\n    target_link_libraries(${target_name} PRIVATE pybind11::embed)\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  if(DEFINED ${_Python}_VERSION AND ${_Python}_VERSION VERSION_LESS 3)\n    target_link_libraries(${target_name} PRIVATE pybind11::python2_no_register)\n  endif()\n\n  # -fvisibility=hidden is required to allow multiple modules compiled against\n  # different pybind versions to work properly, and for some features (e.g.\n  # py::module_local).  We force it on everything inside the `pybind11`\n  # namespace; also turning it on for a pybind module compilation here avoids\n  # potential warnings or issues from having mixed hidden/non-hidden types.\n  if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  # If we don't pass a WITH_SOABI or WITHOUT_SOABI, use our own default handling of extensions\n  if(NOT ARG_WITHOUT_SOABI AND NOT \"WITH_SOABI\" IN_LIST ARG_UNPARSED_ARGUMENTS)\n    pybind11_extension(${target_name})\n  endif()\n\n  if(ARG_NO_EXTRAS)\n    return()\n  endif()\n\n  if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)\n    if(ARG_THIN_LTO)\n      target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)\n    else()\n      target_link_libraries(${target_name} PRIVATE pybind11::lto)\n    endif()\n  endif()\n\n  if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)\n    # Strip unnecessary sections of the binary on Linux/macOS\n    pybind11_strip(${target_name})\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  if(ARG_OPT_SIZE)\n    target_link_libraries(${target_name} PRIVATE pybind11::opt_size)\n  endif()\nendfunction()\n\nfunction(pybind11_extension name)\n  # The extension is precomputed\n  set_target_properties(${name} PROPERTIES PREFIX \"\" SUFFIX \"${PYTHON_MODULE_EXTENSION}\")\n\nendfunction()\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/pybind11Tools.cmake",
    "content": "# tools/pybind11Tools.cmake -- Build system for the pybind11 modules\n#\n# Copyright (c) 2020 Wenzel Jakob <wenzel.jakob@epfl.ch>\n#\n# All rights reserved. Use of this source code is governed by a\n# BSD-style license that can be found in the LICENSE file.\n\n# include_guard(global) (pre-CMake 3.10)\nif(TARGET pybind11::python_headers)\n  return()\nendif()\n\n# Built-in in CMake 3.5+\ninclude(CMakeParseArguments)\n\nif(pybind11_FIND_QUIETLY)\n  set(_pybind11_quiet QUIET)\nelse()\n  set(_pybind11_quiet \"\")\nendif()\n\n# If this is the first run, PYTHON_VERSION can stand in for PYBIND11_PYTHON_VERSION\nif(NOT DEFINED PYBIND11_PYTHON_VERSION AND DEFINED PYTHON_VERSION)\n  message(WARNING \"Set PYBIND11_PYTHON_VERSION to search for a specific version, not \"\n                  \"PYTHON_VERSION (which is an output). Assuming that is what you \"\n                  \"meant to do and continuing anyway.\")\n  set(PYBIND11_PYTHON_VERSION\n      \"${PYTHON_VERSION}\"\n      CACHE STRING \"Python version to use for compiling modules\")\n  unset(PYTHON_VERSION)\n  unset(PYTHON_VERSION CACHE)\nelseif(DEFINED PYBIND11_PYTHON_VERSION)\n  # If this is set as a normal variable, promote it\n  set(PYBIND11_PYTHON_VERSION\n      \"${PYBIND11_PYTHON_VERSION}\"\n      CACHE STRING \"Python version to use for compiling modules\")\nelse()\n  # Make an empty cache variable.\n  set(PYBIND11_PYTHON_VERSION\n      \"\"\n      CACHE STRING \"Python version to use for compiling modules\")\nendif()\n\n# A user can set versions manually too\nset(Python_ADDITIONAL_VERSIONS\n    \"3.11;3.10;3.9;3.8;3.7;3.6;3.5;3.4\"\n    CACHE INTERNAL \"\")\n\nlist(APPEND CMAKE_MODULE_PATH \"${CMAKE_CURRENT_LIST_DIR}\")\nfind_package(PythonLibsNew ${PYBIND11_PYTHON_VERSION} MODULE REQUIRED ${_pybind11_quiet})\nlist(REMOVE_AT CMAKE_MODULE_PATH -1)\n\n# Makes a normal variable a cached variable\nmacro(_PYBIND11_PROMOTE_TO_CACHE NAME)\n  set(_tmp_ptc \"${${NAME}}\")\n  # CMake 3.21 complains if a cached variable is shadowed by a normal one\n  unset(${NAME})\n  set(${NAME}\n      \"${_tmp_ptc}\"\n      CACHE INTERNAL \"\")\nendmacro()\n\n# Cache variables so pybind11_add_module can be used in parent projects\n_pybind11_promote_to_cache(PYTHON_INCLUDE_DIRS)\n_pybind11_promote_to_cache(PYTHON_LIBRARIES)\n_pybind11_promote_to_cache(PYTHON_MODULE_PREFIX)\n_pybind11_promote_to_cache(PYTHON_MODULE_EXTENSION)\n_pybind11_promote_to_cache(PYTHON_VERSION_MAJOR)\n_pybind11_promote_to_cache(PYTHON_VERSION_MINOR)\n_pybind11_promote_to_cache(PYTHON_VERSION)\n_pybind11_promote_to_cache(PYTHON_IS_DEBUG)\n\nif(PYBIND11_MASTER_PROJECT)\n  if(PYTHON_MODULE_EXTENSION MATCHES \"pypy\")\n    if(NOT DEFINED PYPY_VERSION)\n      execute_process(\n        COMMAND ${PYTHON_EXECUTABLE} -c\n                [=[import sys; sys.stdout.write(\".\".join(map(str, sys.pypy_version_info[:3])))]=]\n        OUTPUT_VARIABLE pypy_version)\n      set(PYPY_VERSION\n          ${pypy_version}\n          CACHE INTERNAL \"\")\n    endif()\n    message(STATUS \"PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})\")\n  else()\n    message(STATUS \"PYTHON ${PYTHON_VERSION}\")\n  endif()\nendif()\n\n# Only add Python for build - must be added during the import for config since\n# it has to be re-discovered.\n#\n# This needs to be an target to it is included after the local pybind11\n# directory, just in case there are multiple versions of pybind11, we want the\n# one we expect.\nadd_library(pybind11::python_headers INTERFACE IMPORTED)\nset_property(TARGET pybind11::python_headers PROPERTY INTERFACE_INCLUDE_DIRECTORIES\n                                                      \"$<BUILD_INTERFACE:${PYTHON_INCLUDE_DIRS}>\")\nset_property(\n  TARGET pybind11::pybind11\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python_headers)\n\nset(pybind11_INCLUDE_DIRS\n    \"${pybind11_INCLUDE_DIR}\" \"${PYTHON_INCLUDE_DIRS}\"\n    CACHE INTERNAL \"Directories where pybind11 and possibly Python headers are located\")\n\n# Python debug libraries expose slightly different objects before 3.8\n# https://docs.python.org/3.6/c-api/intro.html#debugging-builds\n# https://stackoverflow.com/questions/39161202/how-to-work-around-missing-pymodule-create2-in-amd64-win-python35-d-lib\nif(PYTHON_IS_DEBUG)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_COMPILE_DEFINITIONS Py_DEBUG)\nendif()\n\nset_property(\n  TARGET pybind11::module\n  APPEND\n  PROPERTY\n    INTERFACE_LINK_LIBRARIES pybind11::python_link_helper\n    \"$<$<OR:$<PLATFORM_ID:Windows>,$<PLATFORM_ID:Cygwin>>:$<BUILD_INTERFACE:${PYTHON_LIBRARIES}>>\")\n\nif(PYTHON_VERSION VERSION_LESS 3)\n  set_property(\n    TARGET pybind11::pybind11\n    APPEND\n    PROPERTY INTERFACE_LINK_LIBRARIES pybind11::python2_no_register)\nendif()\n\nset_property(\n  TARGET pybind11::embed\n  APPEND\n  PROPERTY INTERFACE_LINK_LIBRARIES pybind11::pybind11 $<BUILD_INTERFACE:${PYTHON_LIBRARIES}>)\n\nfunction(pybind11_extension name)\n  # The prefix and extension are provided by FindPythonLibsNew.cmake\n  set_target_properties(${name} PROPERTIES PREFIX \"${PYTHON_MODULE_PREFIX}\"\n                                           SUFFIX \"${PYTHON_MODULE_EXTENSION}\")\nendfunction()\n\n# Build a Python extension module:\n# pybind11_add_module(<name> [MODULE | SHARED] [EXCLUDE_FROM_ALL]\n#                     [NO_EXTRAS] [THIN_LTO] [OPT_SIZE] source1 [source2 ...])\n#\nfunction(pybind11_add_module target_name)\n  set(options \"MODULE;SHARED;EXCLUDE_FROM_ALL;NO_EXTRAS;SYSTEM;THIN_LTO;OPT_SIZE\")\n  cmake_parse_arguments(ARG \"${options}\" \"\" \"\" ${ARGN})\n\n  if(ARG_MODULE AND ARG_SHARED)\n    message(FATAL_ERROR \"Can't be both MODULE and SHARED\")\n  elseif(ARG_SHARED)\n    set(lib_type SHARED)\n  else()\n    set(lib_type MODULE)\n  endif()\n\n  if(ARG_EXCLUDE_FROM_ALL)\n    set(exclude_from_all EXCLUDE_FROM_ALL)\n  else()\n    set(exclude_from_all \"\")\n  endif()\n\n  add_library(${target_name} ${lib_type} ${exclude_from_all} ${ARG_UNPARSED_ARGUMENTS})\n\n  target_link_libraries(${target_name} PRIVATE pybind11::module)\n\n  if(ARG_SYSTEM)\n    message(\n      STATUS\n        \"Warning: this does not have an effect - use NO_SYSTEM_FROM_IMPORTED if using imported targets\"\n    )\n  endif()\n\n  pybind11_extension(${target_name})\n\n  # -fvisibility=hidden is required to allow multiple modules compiled against\n  # different pybind versions to work properly, and for some features (e.g.\n  # py::module_local).  We force it on everything inside the `pybind11`\n  # namespace; also turning it on for a pybind module compilation here avoids\n  # potential warnings or issues from having mixed hidden/non-hidden types.\n  if(NOT DEFINED CMAKE_CXX_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CXX_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(NOT DEFINED CMAKE_CUDA_VISIBILITY_PRESET)\n    set_target_properties(${target_name} PROPERTIES CUDA_VISIBILITY_PRESET \"hidden\")\n  endif()\n\n  if(ARG_NO_EXTRAS)\n    return()\n  endif()\n\n  if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION)\n    if(ARG_THIN_LTO)\n      target_link_libraries(${target_name} PRIVATE pybind11::thin_lto)\n    else()\n      target_link_libraries(${target_name} PRIVATE pybind11::lto)\n    endif()\n  endif()\n\n  if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo)\n    pybind11_strip(${target_name})\n  endif()\n\n  if(MSVC)\n    target_link_libraries(${target_name} PRIVATE pybind11::windows_extras)\n  endif()\n\n  if(ARG_OPT_SIZE)\n    target_link_libraries(${target_name} PRIVATE pybind11::opt_size)\n  endif()\nendfunction()\n\n# Provide general way to call common Python commands in \"common\" file.\nset(_Python\n    PYTHON\n    CACHE INTERNAL \"\" FORCE)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/pyproject.toml",
    "content": "[build-system]\nrequires = [\"setuptools>=42\", \"wheel\"]\nbuild-backend = \"setuptools.build_meta\"\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/setup_global.py.in",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n# Setup script for pybind11-global (in the sdist or in tools/setup_global.py in the repository)\n# This package is targeted for easy use from CMake.\n\nimport contextlib\nimport glob\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\n\n# Setuptools has to be before distutils\nfrom setuptools import setup\n\nfrom distutils.command.install_headers import install_headers\n\nclass InstallHeadersNested(install_headers):\n    def run(self):\n        headers = self.distribution.headers or []\n        for header in headers:\n            # Remove pybind11/include/\n            short_header = header.split(\"/\", 2)[-1]\n\n            dst = os.path.join(self.install_dir, os.path.dirname(short_header))\n            self.mkpath(dst)\n            (out, _) = self.copy_file(header, dst)\n            self.outfiles.append(out)\n\n\nmain_headers = glob.glob(\"pybind11/include/pybind11/*.h\")\ndetail_headers = glob.glob(\"pybind11/include/pybind11/detail/*.h\")\nstl_headers = glob.glob(\"pybind11/include/pybind11/stl/*.h\")\ncmake_files = glob.glob(\"pybind11/share/cmake/pybind11/*.cmake\")\nheaders = main_headers + detail_headers + stl_headers\n\ncmdclass = {\"install_headers\": InstallHeadersNested}\n$extra_cmd\n\n# This will _not_ affect installing from wheels,\n# only building wheels or installing from SDist.\n# Primarily intended on Windows, where this is sometimes\n# customized (for example, conda-forge uses Library/)\nbase = os.environ.get(\"PYBIND11_GLOBAL_PREFIX\", \"\")\n\n# Must have a separator\nif base and not base.endswith(\"/\"):\n    base += \"/\"\n\nsetup(\n    name=\"pybind11_global\",\n    version=\"$version\",\n    packages=[],\n    headers=headers,\n    data_files=[\n        (base + \"share/cmake/pybind11\", cmake_files),\n        (base + \"include/pybind11\", main_headers),\n        (base + \"include/pybind11/detail\", detail_headers),\n        (base + \"include/pybind11/stl\", stl_headers),\n    ],\n    cmdclass=cmdclass,\n)\n"
  },
  {
    "path": "external/pybind11_2.9.2/tools/setup_main.py.in",
    "content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n# Setup script (in the sdist or in tools/setup_main.py in the repository)\n\nfrom setuptools import setup\n\ncmdclass = {}\n$extra_cmd\n\nsetup(\n    name=\"pybind11\",\n    version=\"$version\",\n    download_url='https://github.com/pybind/pybind11/tarball/v$version',\n    packages=[\n        \"pybind11\",\n        \"pybind11.include.pybind11\",\n        \"pybind11.include.pybind11.detail\",\n        \"pybind11.include.pybind11.stl\",\n        \"pybind11.share.cmake.pybind11\",\n    ],\n    package_data={\n        \"pybind11\": [\"py.typed\", \"*.pyi\"],\n        \"pybind11.include.pybind11\": [\"*.h\"],\n        \"pybind11.include.pybind11.detail\": [\"*.h\"],\n        \"pybind11.include.pybind11.stl\": [\"*.h\"],\n        \"pybind11.share.cmake.pybind11\": [\"*.cmake\"],\n    },\n    extras_require={\n        \"global\": [\"pybind11_global==$version\"]\n        },\n    entry_points={\n        \"console_scripts\": [\n             \"pybind11-config = pybind11.__main__:main\",\n        ],\n        \"pipx.run\": [\n             \"pybind11 = pybind11.__main__:main\",\n        ]\n    },\n    cmdclass=cmdclass\n)\n"
  },
  {
    "path": "fonts/LICENSE",
    "content": "\nFonts are (c) Bitstream (see below). DejaVu changes are in public domain.\nGlyphs imported from Arev fonts are (c) Tavmjong Bah (see below)\n\n\nBitstream Vera Fonts Copyright\n------------------------------\n\nCopyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is\na trademark of Bitstream, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof the fonts accompanying this license (\"Fonts\") and associated\ndocumentation files (the \"Font Software\"), to reproduce and distribute the\nFont Software, including without limitation the rights to use, copy, merge,\npublish, distribute, and/or sell copies of the Font Software, and to permit\npersons to whom the Font Software is furnished to do so, subject to the\nfollowing conditions:\n\nThe above copyright and trademark notices and this permission notice shall\nbe included in all copies of one or more of the Font Software typefaces.\n\nThe Font Software may be modified, altered, or added to, and in particular\nthe designs of glyphs or characters in the Fonts may be modified and\nadditional glyphs or characters may be added to the Fonts, only if the fonts\nare renamed to names not containing either the words \"Bitstream\" or the word\n\"Vera\".\n\nThis License becomes null and void to the extent applicable to Fonts or Font\nSoftware that has been modified and is distributed under the \"Bitstream\nVera\" names.\n\nThe Font Software may be sold as part of a larger software package but no\ncopy of one or more of the Font Software typefaces may be sold by itself.\n\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\nOR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,\nTRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME\nFOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING\nANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF\nTHE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE\nFONT SOFTWARE.\n\nExcept as contained in this notice, the names of Gnome, the Gnome\nFoundation, and Bitstream Inc., shall not be used in advertising or\notherwise to promote the sale, use or other dealings in this Font Software\nwithout prior written authorization from the Gnome Foundation or Bitstream\nInc., respectively. For further information, contact: fonts at gnome dot\norg.\n\nArev Fonts Copyright\n------------------------------\n\nCopyright (c) 2006 by Tavmjong Bah. All Rights Reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the fonts accompanying this license (\"Fonts\") and\nassociated documentation files (the \"Font Software\"), to reproduce\nand distribute the modifications to the Bitstream Vera Font Software,\nincluding without limitation the rights to use, copy, merge, publish,\ndistribute, and/or sell copies of the Font Software, and to permit\npersons to whom the Font Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright and trademark notices and this permission notice\nshall be included in all copies of one or more of the Font Software\ntypefaces.\n\nThe Font Software may be modified, altered, or added to, and in\nparticular the designs of glyphs or characters in the Fonts may be\nmodified and additional glyphs or characters may be added to the\nFonts, only if the fonts are renamed to names not containing either\nthe words \"Tavmjong Bah\" or the word \"Arev\".\n\nThis License becomes null and void to the extent applicable to Fonts\nor Font Software that has been modified and is distributed under the\n\"Tavmjong Bah Arev\" names.\n\nThe Font Software may be sold as part of a larger software package but\nno copy of one or more of the Font Software typefaces may be sold by\nitself.\n\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL\nTAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n\nExcept as contained in this notice, the name of Tavmjong Bah shall not\nbe used in advertising or otherwise to promote the sale, use or other\ndealings in this Font Software without prior written authorization\nfrom Tavmjong Bah. For further information, contact: tavmjong @ free\n. fr.\n"
  },
  {
    "path": "main.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <getopt.h>\n#include <memory>\n#include <unistd.h>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDateTime>\n#include <QDebug>\n#include <QSettings>\n\n#include \"config.h\"\n#include \"src/application.hpp\"\n#include \"src/devicemanager.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/ui/tabs/smuscripttab.hpp\"\n\n#ifdef ENABLE_SIGNALS\n#include \"signalhandler.hpp\"\n#endif\n\n#ifdef _WIN32\n#include <QtPlugin>\nQ_IMPORT_PLUGIN(QWindowsIntegrationPlugin)\nQ_IMPORT_PLUGIN(QSvgPlugin)\n#endif\n\nusing std::exception;\nusing std::make_shared;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nvoid usage()\n{\n\tfprintf(stdout,\n\t\t\"Usage:\\n\"\n\t\t\"  %s [OPTIONS] [FILE]\\n\"\n\t\t\"\\n\"\n\t\t\"Help Options:\\n\"\n\t\t\"  -h, -?, --help             Show help option\\n\"\n\t\t\"\\n\"\n\t\t\"Application Options:\\n\"\n\t\t\"  -V, --version              Show release version\\n\"\n\t\t\"  -l, --loglevel             Set libsigrok loglevel (0-5, default: 2)\\n\"\n\t\t\"  -d, --driver               Specify the device driver(s) to use\\n\"\n\t\t\"  -D, --dont-scan            Don't auto-scan for devices, use -d spec only\\n\"\n\t\t\"  -s, --script               Specify the SmuScript to load and execute\\n\"\n\t\t\"  -c, --clean                Don't restore previous settings on startup\\n\"\n\t\t/* Disable cmd line options i and I\n\t\t\"  -i, --input-file           Load input from file\\n\"\n\t\t\"  -I, --input-format         Input format\\n\"\n\t\t*/\n\t\t\"\\n\"\n\t\t\"Examples:\\n\"\n\t\t\"  %s --driver tecpel-dmm-8061-ser:conn=/dev/ttyUSB0\\n\"\n\t\t\"\\n\"\n\t\t\"  %s --driver uni-t-ut61e:conn=1a86.e008\\n\"\n\t\t\"\\n\"\n\t\t\"  %s --driver voltcraft-k204:conn=/dev/ttyUSB0 \\\\\\n\"\n\t\t\"     --driver uni-t-ut61d:conn=1a86.e008 \\\\\\n\"\n\t\t\"     --driver uni-t-ut61e-ser:conn=/dev/ttyUSB1\\n\",\n\t\tSV_BIN_NAME, SV_BIN_NAME, SV_BIN_NAME, SV_BIN_NAME);\n}\n\nint main(int argc, char *argv[])\n{\n\tint ret = 0;\n\tshared_ptr<sigrok::Context> context;\n\tint loglevel = -1;\n\tvector<string> drivers;\n\t//string open_file;\n\t//string open_file_format;\n\tbool do_scan = true;\n\tstring script_file;\n\tbool restore_settings = true;\n\n\tApplication app(argc, argv);\n\n\t// Parse arguments\n\twhile (true) {\n\t\tstatic const struct option long_options[] = {\n\t\t\t{ \"help\", no_argument, nullptr, 'h' },\n\t\t\t{ \"version\", no_argument, nullptr, 'V' },\n\t\t\t{ \"loglevel\", required_argument, nullptr, 'l' },\n\t\t\t{ \"driver\", required_argument, nullptr, 'd' },\n\t\t\t{ \"dont-scan\", no_argument, nullptr, 'D' },\n\t\t\t{ \"script\", required_argument, nullptr, 's' },\n\t\t\t{ \"clean\", no_argument, nullptr, 'c' },\n\t\t\t/* Disable cmd line options i and I\n\t\t\t{ \"input-file\", required_argument, nullptr, 'i' },\n\t\t\t{ \"input-format\", required_argument, nullptr, 'I' },\n\t\t\t*/\n\t\t\t{ nullptr, 0, nullptr, 0 }\n\t\t};\n\n\t\t/* Disable cmd line options i and I\n\t\tconst int arg_char = getopt_long(argc, argv,\n\t\t\t\"l:Vhc?d:i:I:\", long_options, nullptr);\n\t\t*/\n\t\tconst int arg_char = getopt_long(argc, argv,\n\t\t\t\"h?VDl:d:s:c\", long_options, nullptr);\n\n\t\tif (arg_char == -1)\n\t\t\tbreak;\n\n\t\tswitch (arg_char) {\n\t\tcase 'h':\n\t\tcase '?':\n\t\t\tusage();\n\t\t\treturn 0;\n\n\t\tcase 'V':\n\t\t\t// Print version info\n\t\t\tfprintf(stdout, \"%s %s\\n\", SV_TITLE, SV_VERSION_STRING);\n\t\t\treturn 0;\n\n\t\tcase 'l':\n\t\t{\n\t\t\tloglevel = atoi(optarg);\n\t\t\tif (loglevel >= 5) {\n\t\t\t\tconst QSettings settings;\n\t\t\t\tqDebug() << \"Settings:\" << settings.fileName()\n\t\t\t\t\t<< \"format\" << settings.format();\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'd':\n\t\t\tdrivers.push_back(optarg);\n\t\t\tbreak;\n\n\t\tcase 'D':\n\t\t\tdo_scan = false;\n\t\t\tbreak;\n\n\t\tcase 's':\n\t\t\tscript_file = optarg;\n\t\t\tbreak;\n\n\t\tcase 'c':\n\t\t\trestore_settings = false;\n\t\t\tbreak;\n\n\t\t/* Disable cmd line options i and I\n\t\tcase 'i':\n\t\t\topen_file = optarg;\n\t\t\tbreak;\n\n\t\tcase 'I':\n\t\t\topen_file_format = optarg;\n\t\t\tbreak;\n\t\t*/\n\t\t}\n\t}\n\n\t/* Disable cmd line options i and I\n\tif (argc - optind > 1) {\n\t\tfprintf(stderr, \"Only one file can be opened.\\n\");\n\t\treturn 1;\n\t}\n\n\tif (argc - optind == 1)\n\t\topen_file = argv[argc - 1];\n\t*/\n\n\t// Initialise libsigrok\n\tcontext = sigrok::Context::create();\n\tsv::Session::sr_context = context;\n\n\tdo {\n\t\ttry {\n\t\t\tif (loglevel >= 0)\n\t\t\t\tcontext->set_log_level(sigrok::LogLevel::get(loglevel));\n\n\t\t\tsv::SettingsManager::set_restore_settings(restore_settings);\n\n\t\t\t// Initialize global start timestamp\n\t\t\t// TODO: use std::chrono / std::time\n\t\t\tsv::Session::session_start_timestamp =\n\t\t\t\t(double)QDateTime::currentMSecsSinceEpoch() / (double)1000;\n\n\t\t\t// Create the device manager, initialise the drivers\n\t\t\tsv::DeviceManager device_manager(context, drivers, do_scan);\n\n\t\t\t// Initialise the session.\n\t\t\tauto session = make_shared<sv::Session>(device_manager);\n\n\t\t\t// Initialise the main window.\n\t\t\tsv::MainWindow main_window(device_manager, session);\n\t\t\tmain_window.show();\n\n\t\t\tif (!script_file.empty())\n\t\t\t\tmain_window.add_smuscript_tab(script_file)->run_script();\n\n#ifdef ENABLE_SIGNALS\n\t\t\tif (SignalHandler::prepare_signals()) {\n\t\t\t\tSignalHandler *const handler = new SignalHandler(&main_window);\n\t\t\t\tQObject::connect(handler, &SignalHandler::int_received,\n\t\t\t\t\t&main_window, &sv::MainWindow::close);\n\t\t\t\tQObject::connect(handler, &SignalHandler::term_received,\n\t\t\t\t\t&main_window, &sv::MainWindow::close);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tqWarning() << \"Could not prepare signal handler.\";\n\t\t\t}\n#endif\n\n\t\t\t// Run the application\n\t\t\tret = Application::exec();\n\t\t}\n\t\tcatch (exception &e) {\n\t\t\tqCritical() << \"main() failed: \" << e.what();\n\t\t}\n\n\t}\n\twhile (false);\n\n\treturn ret;\n}\n"
  },
  {
    "path": "manual/CMakeLists.txt",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2018 Gerhard Sittig <gerhard.sittig@gmx.net>\n## Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 3 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\ncmake_minimum_required(VERSION 2.8.12)\n\n# External dependencies, required and optional tools.\nfind_program(ASCIIDOCTOR_EXECUTABLE NAMES asciidoctor)\nfind_program(ASCIIDOCTOR_PDF_EXECUTABLE NAMES asciidoctor-pdf)\n\n# Tunables.\nset(STYLES_DIR \"asciidoctor-stylesheet-factory/stylesheets\")\nset(STYLE_SHEET \"readthedocs.css\")\n\n# Input files.\nset(MANUAL_SRC \"${CMAKE_CURRENT_SOURCE_DIR}/manual.adoc\")\n\n# Output files, conversion results.\nset(MANUAL_OUT_HTML \"${CMAKE_CURRENT_BINARY_DIR}/manual.html\")\nset(MANUAL_OUT_PDF \"${CMAKE_CURRENT_BINARY_DIR}/manual.pdf\")\n\n# Manual related make(1) targets.\nadd_custom_target(manual-html\n\tCOMMAND ${ASCIIDOCTOR_EXECUTABLE}\n\t\t-a stylesheet=${STYLE_SHEET}\n\t\t-a stylesdir=${CMAKE_CURRENT_SOURCE_DIR}/${STYLES_DIR}\n\t\t-a toc=left\n\t\t-a sv_version=${SV_VERSION_STRING}\n\t\t-a sv_manual_version=${SV_MANUAL_VERSION}\n\t\t--destination-dir=${CMAKE_CURRENT_BINARY_DIR}\n\t\t${MANUAL_SRC}\n\tBYPRODUCTS ${MANUAL_OUT_HTML}\n\tDEPENDS ${MANUAL_SRC}\n\tWORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n\tCOMMENT \"Generating manual, HTML output\"\n)\nif (ASCIIDOCTOR_PDF_EXECUTABLE)\n\tadd_custom_target(manual-pdf\n\t\tCOMMAND ${ASCIIDOCTOR_PDF_EXECUTABLE}\n\t\t\t-a stylesheet=${STYLE_SHEET}\n\t\t\t-a stylesdir=${CMAKE_CURRENT_SOURCE_DIR}/${STYLES_DIR}\n\t\t\t-a sv_version=${SV_VERSION_STRING}\n\t\t\t-a sv_manual_version=${SV_MANUAL_VERSION}\n\t\t\t--destination-dir=${CMAKE_CURRENT_BINARY_DIR}\n\t\t\t${MANUAL_SRC}\n\t\tBYPRODUCTS ${MANUAL_OUT_PDF}\n\t\tDEPENDS ${MANUAL_SRC}\n\t\tWORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n\t\tCOMMENT \"Generating manual, PDF output\"\n\t)\nelse ()\n\tadd_custom_target(manual-pdf\n\t\tCOMMAND ${CMAKE_COMMAND} -E echo\n\t\t\t\"asciidoctor-pdf executable is missing, NOT generating PDF output\"\n\t\tDEPENDS ${MANUAL_SRC}\n\t\tWORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}\n\t)\nendif ()\nadd_custom_target(manual)\nadd_dependencies(manual manual-html manual-pdf)\n\n\n#===============================================================================\n#= Installation\n#-------------------------------------------------------------------------------\n\nset(MANUAL_INST_SUBDIR \"share/doc/smuview\")\ninstall(\n\tFILES ${MANUAL_OUT_HTML} ${MANUAL_OUT_PDF}\n\tDESTINATION ${MANUAL_INST_SUBDIR}\n\tPERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ\n\tOPTIONAL\n)\nif (ASCIIDOCTOR_EXECUTABLE)\n\tinstall(\n\t\tDIRECTORY images\n\t\tDESTINATION ${MANUAL_INST_SUBDIR}\n\t\tFILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ\n\t\tPATTERN \"*.xcf\" EXCLUDE\n\t)\nendif ()\n\n\n#===============================================================================\n#= Publish\n#-------------------------------------------------------------------------------\n\nset(MANUAL_PUP_DIR \"${CMAKE_BINARY_DIR}/manual_publish/${SV_MANUAL_VERSION}\")\nadd_custom_target(manual-publish)\nadd_custom_command(TARGET manual-publish PRE_BUILD\n\tCOMMAND ${CMAKE_COMMAND} -E make_directory ${MANUAL_PUP_DIR}\n\tCOMMAND ${CMAKE_COMMAND} -E copy ${MANUAL_OUT_HTML} ${MANUAL_PUP_DIR}\n\tCOMMAND ${CMAKE_COMMAND} -E copy ${MANUAL_OUT_PDF} ${MANUAL_PUP_DIR}\n\tCOMMAND ${CMAKE_COMMAND} -E make_directory ${MANUAL_PUP_DIR}/images\n\tCOMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/images/*.png ${MANUAL_PUP_DIR}/images\n\tCOMMAND ${CMAKE_COMMAND} -E make_directory ${MANUAL_PUP_DIR}/images/icons\n\tCOMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/images/icons/*.png ${MANUAL_PUP_DIR}/images/icons\n\tCOMMAND ${CMAKE_COMMAND} -E make_directory ${MANUAL_PUP_DIR}/images/numbers\n\tCOMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/images/numbers/*.png ${MANUAL_PUP_DIR}/images/numbers)\n"
  },
  {
    "path": "manual/asciidoctor-stylesheet-factory/LICENSE",
    "content": "Asciidoctor styles\n------------------\n\nCopyright (c) 2013 Dan Allen\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\nOther licensed work\n-------------------\n\n- Foundation 4 by Zurb, on which the themes are built, is licensed under the\n  Apache License, v2.0:\n\n  http://apache.org/licenses/LICENSE-2.0\n  http://foundation.zurb.com\n\n- The riak theme is derived from the Riak documentation theme by Basho,\n  licensed under the Creative Commons Attribution 3.0 Unported License:\n\n  http://creativecommons.org/licenses/by/3.0/us\n  http://docs.basho.org\n\n- The iconic theme is inspired by O'Reilly typography and Atlas manual.\n\n  http://oreilly.com\n"
  },
  {
    "path": "manual/asciidoctor-stylesheet-factory/stylesheets/readthedocs.css",
    "content": "/*! normalize.css v2.1.2 | MIT License | git.io/normalize */\n/* ========================================================================== HTML5 display definitions ========================================================================== */\n/** Correct `block` display not defined in IE 8/9. */\narticle, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary { display: block; }\n\n/** Correct `inline-block` display not defined in IE 8/9. */\naudio, canvas, video { display: inline-block; }\n\n/** Prevent modern browsers from displaying `audio` without controls. Remove excess height in iOS 5 devices. */\naudio:not([controls]) { display: none; height: 0; }\n\n/** Address `[hidden]` styling not present in IE 8/9. Hide the `template` element in IE, Safari, and Firefox < 22. */\n[hidden], template { display: none; }\n\nscript { display: none !important; }\n\n/* ========================================================================== Base ========================================================================== */\n/** 1. Set default font family to sans-serif. 2. Prevent iOS text size adjust after orientation change, without disabling user zoom. */\nhtml { font-family: sans-serif; /* 1 */ -ms-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */ }\n\n/** Remove default margin. */\nbody { margin: 0; }\n\n/* ========================================================================== Links ========================================================================== */\n/** Remove the gray background color from active links in IE 10. */\na { background: transparent; }\n\n/** Address `outline` inconsistency between Chrome and other browsers. */\na:focus { outline: thin dotted; }\n\n/** Improve readability when focused and also mouse hovered in all browsers. */\na:active, a:hover { outline: 0; }\n\n/* ========================================================================== Typography ========================================================================== */\n/** Address variable `h1` font-size and margin within `section` and `article` contexts in Firefox 4+, Safari 5, and Chrome. */\nh1 { font-size: 2em; margin: 0.67em 0; }\n\n/** Address styling not present in IE 8/9, Safari 5, and Chrome. */\nabbr[title] { border-bottom: 1px dotted; }\n\n/** Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. */\nb, strong { font-weight: bold; }\n\n/** Address styling not present in Safari 5 and Chrome. */\ndfn { font-style: italic; }\n\n/** Address differences between Firefox and other browsers. */\nhr { -moz-box-sizing: content-box; box-sizing: content-box; height: 0; }\n\n/** Address styling not present in IE 8/9. */\nmark { background: #ff0; color: #000; }\n\n/** Correct font family set oddly in Safari 5 and Chrome. */\ncode, kbd, pre, samp { font-family: monospace, serif; font-size: 1em; }\n\n/** Improve readability of pre-formatted text in all browsers. */\npre { white-space: pre-wrap; }\n\n/** Set consistent quote types. */\nq { quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"; }\n\n/** Address inconsistent and variable font size in all browsers. */\nsmall { font-size: 80%; }\n\n/** Prevent `sub` and `sup` affecting `line-height` in all browsers. */\nsub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }\n\nsup { top: -0.5em; }\n\nsub { bottom: -0.25em; }\n\n/* ========================================================================== Embedded content ========================================================================== */\n/** Remove border when inside `a` element in IE 8/9. */\nimg { border: 0; }\n\n/** Correct overflow displayed oddly in IE 9. */\nsvg:not(:root) { overflow: hidden; }\n\n/* ========================================================================== Figures ========================================================================== */\n/** Address margin not present in IE 8/9 and Safari 5. */\nfigure { margin: 0; }\n\n/* ========================================================================== Forms ========================================================================== */\n/** Define consistent border, margin, and padding. */\nfieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; }\n\n/** 1. Correct `color` not being inherited in IE 8/9. 2. Remove padding so people aren't caught out if they zero out fieldsets. */\nlegend { border: 0; /* 1 */ padding: 0; /* 2 */ }\n\n/** 1. Correct font family not being inherited in all browsers. 2. Correct font size not being inherited in all browsers. 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. */\nbutton, input, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 2 */ margin: 0; /* 3 */ }\n\n/** Address Firefox 4+ setting `line-height` on `input` using `!important` in the UA stylesheet. */\nbutton, input { line-height: normal; }\n\n/** Address inconsistent `text-transform` inheritance for `button` and `select`. All other form control elements do not inherit `text-transform` values. Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. Correct `select` style inheritance in Firefox 4+ and Opera. */\nbutton, select { text-transform: none; }\n\n/** 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` and `video` controls. 2. Correct inability to style clickable `input` types in iOS. 3. Improve usability and consistency of cursor style between image-type `input` and others. */\nbutton, html input[type=\"button\"], input[type=\"reset\"], input[type=\"submit\"] { -webkit-appearance: button; /* 2 */ cursor: pointer; /* 3 */ }\n\n/** Re-set default cursor for disabled elements. */\nbutton[disabled], html input[disabled] { cursor: default; }\n\n/** 1. Address box sizing set to `content-box` in IE 8/9. 2. Remove excess padding in IE 8/9. */\ninput[type=\"checkbox\"], input[type=\"radio\"] { box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ }\n\n/** 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome (include `-moz` to future-proof). */\ninput[type=\"search\"] { -webkit-appearance: textfield; /* 1 */ -moz-box-sizing: content-box; -webkit-box-sizing: content-box; /* 2 */ box-sizing: content-box; }\n\n/** Remove inner padding and search cancel button in Safari 5 and Chrome on OS X. */\ninput[type=\"search\"]::-webkit-search-cancel-button, input[type=\"search\"]::-webkit-search-decoration { -webkit-appearance: none; }\n\n/** Remove inner padding and border in Firefox 4+. */\nbutton::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }\n\n/** 1. Remove default vertical scrollbar in IE 8/9. 2. Improve readability and alignment in all browsers. */\ntextarea { overflow: auto; /* 1 */ vertical-align: top; /* 2 */ }\n\n/* ========================================================================== Tables ========================================================================== */\n/** Remove most spacing between table cells. */\ntable { border-collapse: collapse; border-spacing: 0; }\n\nmeta.foundation-mq-small { font-family: \"only screen and (min-width: 768px)\"; width: 768px; }\n\nmeta.foundation-mq-medium { font-family: \"only screen and (min-width:1280px)\"; width: 1280px; }\n\nmeta.foundation-mq-large { font-family: \"only screen and (min-width:1440px)\"; width: 1440px; }\n\n*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; }\n\nhtml, body { font-size: 100%; }\n\nbody { background: #fff; color: #222; padding: 0; margin: 0; font-family: \"Helvetica Neue\", \"Helvetica\", Helvetica, Arial, sans-serif; font-weight: normal; font-style: normal; line-height: 1; position: relative; cursor: auto; }\n\na:hover { cursor: pointer; }\n\nimg, object, embed { max-width: 100%; height: auto; }\n\nobject, embed { height: 100%; }\n\nimg { -ms-interpolation-mode: bicubic; }\n\n#map_canvas img, #map_canvas embed, #map_canvas object, .map_canvas img, .map_canvas embed, .map_canvas object { max-width: none !important; }\n\n.left { float: left !important; }\n\n.right { float: right !important; }\n\n.text-left { text-align: left !important; }\n\n.text-right { text-align: right !important; }\n\n.text-center { text-align: center !important; }\n\n.text-justify { text-align: justify !important; }\n\n.hide { display: none; }\n\n.antialiased { -webkit-font-smoothing: antialiased; }\n\nimg { display: inline-block; vertical-align: middle; }\n\ntextarea { height: auto; min-height: 50px; }\n\nselect { width: 100%; }\n\nobject, svg { display: inline-block; vertical-align: middle; }\n\n.center { margin-left: auto; margin-right: auto; }\n\n.stretch { width: 100%; }\n\np.lead { font-size: 1.21875em; line-height: 1.6; }\n\n.subheader, .admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { line-height: 1.4; color: #6c818f; font-weight: 300; margin-top: 0.2em; margin-bottom: 0.5em; }\n\n/* Typography resets */\ndiv, dl, dt, dd, ul, ol, li, h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6, pre, form, p, blockquote, th, td { margin: 0; padding: 0; direction: ltr; }\n\n/* Default Link Styles */\na { color: #444; text-decoration: underline; line-height: inherit; }\na:hover, a:focus { color: #111; }\na img { border: none; }\n\n/* Default paragraph styles */\np { font-family: inherit; font-weight: normal; font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; text-rendering: optimizeLegibility; }\np aside { font-size: 0.875em; line-height: 1.35; font-style: italic; }\n\n/* Default header styles */\nh1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { font-family: ff-meta-web-pro-1, ff-meta-web-pro-2, Arial, \"Helvetica Neue\", sans-serif; font-weight: bold; font-style: normal; color: #465158; text-rendering: optimizeLegibility; margin-top: 1em; margin-bottom: 0.5em; line-height: 1.2125em; }\nh1 small, h2 small, h3 small, #toctitle small, .sidebarblock > .content > .title small, h4 small, h5 small, h6 small { font-size: 60%; color: #909ea7; line-height: 0; }\n\nh1 { font-size: 2.125em; }\n\nh2 { font-size: 1.6875em; }\n\nh3, #toctitle, .sidebarblock > .content > .title { font-size: 1.375em; }\n\nh4 { font-size: 1.125em; }\n\nh5 { font-size: 1.125em; }\n\nh6 { font-size: 1em; }\n\nhr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 1.25em 0 1.1875em; height: 0; }\n\n/* Helpful Typography Defaults */\nem, i { font-style: italic; line-height: inherit; }\n\nstrong, b { font-weight: bold; line-height: inherit; }\n\nsmall { font-size: 60%; line-height: inherit; }\n\ncode { font-family: \"Consolas\", \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", monospace; font-weight: normal; color: #444; }\n\n/* Lists */\nul, ol, dl { font-size: 1em; line-height: 1.5; margin-bottom: 1.25em; list-style-position: outside; font-family: inherit; }\n\nul, ol { margin-left: 1.50em; }\nul.no-bullet, ol.no-bullet { margin-left: 0; }\n\n/* Unordered Lists */\nul li ul, ul li ol { margin-left: 1.25em; margin-bottom: 0; font-size: 1em; /* Override nested font-size change */ }\nul.square li ul, ul.circle li ul, ul.disc li ul { list-style: inherit; }\nul.square { list-style-type: square; }\nul.circle { list-style-type: circle; }\nul.disc { list-style-type: disc; }\nul.no-bullet { list-style: none; }\n\n/* Ordered Lists */\nol li ul, ol li ol { margin-left: 1.25em; margin-bottom: 0; }\n\n/* Definition Lists */\ndl dt { margin-bottom: 0.3em; font-weight: bold; }\ndl dd { margin-bottom: 0.75em; }\n\n/* Abbreviations */\nabbr, acronym { text-transform: uppercase; font-size: 90%; color: #000; border-bottom: 1px dotted #ddd; cursor: help; }\n\nabbr { text-transform: none; }\n\n/* Blockquotes */\nblockquote { margin: 0 0 1.25em; padding: 0.5625em 1.25em 0 1.1875em; border-left: 1px solid #ddd; }\nblockquote cite { display: block; font-size: 0.8125em; color: #748590; }\nblockquote cite:before { content: \"\\2014 \\0020\"; }\nblockquote cite a, blockquote cite a:visited { color: #748590; }\n\nblockquote, blockquote p { line-height: 1.5; color: #909ea7; }\n\n/* Microformats */\n.vcard { display: inline-block; margin: 0 0 1.25em 0; border: 1px solid #ddd; padding: 0.625em 0.75em; }\n.vcard li { margin: 0; display: block; }\n.vcard .fn { font-weight: bold; font-size: 0.9375em; }\n\n.vevent .summary { font-weight: bold; }\n.vevent abbr { cursor: auto; text-decoration: none; font-weight: bold; border: none; padding: 0 0.0625em; }\n\n@media only screen and (min-width: 768px) { h1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }\n  h1 { font-size: 2.75em; }\n  h2 { font-size: 2.3125em; }\n  h3, #toctitle, .sidebarblock > .content > .title { font-size: 1.6875em; }\n  h4 { font-size: 1.4375em; } }\n/* Tables */\ntable { background: #fff; margin-bottom: 1.25em; border: solid 0 #ddd; }\ntable thead, table tfoot { background: none; font-weight: bold; }\ntable thead tr th, table thead tr td, table tfoot tr th, table tfoot tr td { padding: 1px 8px 1px 5px; font-size: 1em; color: #222; text-align: left; }\ntable tr th, table tr td { padding: 1px 8px 1px 5px; font-size: 1em; color: #222; }\ntable tr.even, table tr.alt, table tr:nth-of-type(even) { background: none; }\ntable thead tr th, table tfoot tr th, table tbody tr td, table tr td, table tfoot tr td { display: table-cell; line-height: 1.5; }\n\nbody { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; tab-size: 4; }\n\nh1, h2, h3, #toctitle, .sidebarblock > .content > .title, h4, h5, h6 { line-height: 1.4; }\n\n.clearfix:before, .clearfix:after, .float-group:before, .float-group:after { content: \" \"; display: table; }\n.clearfix:after, .float-group:after { clear: both; }\n\n*:not(pre) > code { font-size: 0.95em; font-style: normal !important; letter-spacing: 0; padding: 0; background-color: #f2f2f2; -webkit-border-radius: 6px; border-radius: 6px; line-height: inherit; word-wrap: break-word; }\n*:not(pre) > code.nobreak { word-wrap: normal; }\n*:not(pre) > code.nowrap { white-space: nowrap; }\n\npre, pre > code { line-height: 1.2; color: inherit; font-family: \"Consolas\", \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", monospace; font-weight: normal; }\n\nem em { font-style: normal; }\n\nstrong strong { font-weight: normal; }\n\n.keyseq { color: #333333; }\n\nkbd { font-family: \"Consolas\", \"Deja Vu Sans Mono\", \"Bitstream Vera Sans Mono\", monospace; display: inline-block; color: #000; font-size: 0.65em; line-height: 1.45; background-color: #f7f7f7; border: 1px solid #ccc; -webkit-border-radius: 3px; border-radius: 3px; -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 0 0.1em white inset; margin: 0 0.15em; padding: 0.2em 0.5em; vertical-align: middle; position: relative; top: -0.1em; white-space: nowrap; }\n\n.keyseq kbd:first-child { margin-left: 0; }\n\n.keyseq kbd:last-child { margin-right: 0; }\n\n.menuseq, .menuref { color: #000; }\n\n.menuseq b:not(.caret), .menuref { font-weight: inherit; }\n\n.menuseq { word-spacing: -0.02em; }\n.menuseq b.caret { font-size: 1.25em; line-height: 0.8; }\n.menuseq i.caret { font-weight: bold; text-align: center; width: 0.45em; }\n\nb.button:before, b.button:after { position: relative; top: -1px; font-weight: normal; }\n\nb.button:before { content: \"[\"; padding: 0 3px 0 2px; }\n\nb.button:after { content: \"]\"; padding: 0 2px 0 3px; }\n\np a > code:hover { color: #373737; }\n\n#header, #content, #footnotes, #footer { width: 100%; margin-left: auto; margin-right: auto; margin-top: 0; margin-bottom: 0; max-width: 62.5em; *zoom: 1; position: relative; padding-left: 0.9375em; padding-right: 0.9375em; }\n#header:before, #header:after, #content:before, #content:after, #footnotes:before, #footnotes:after, #footer:before, #footer:after { content: \" \"; display: table; }\n#header:after, #content:after, #footnotes:after, #footer:after { clear: both; }\n\n#content { margin-top: 1.25em; }\n\n#content:before { content: none; }\n\n#header > h1:first-child { color: #111; margin-top: 2.25rem; margin-bottom: 0; }\n#header > h1:first-child + #toc { margin-top: 8px; border-top: 1px solid #ddd; }\n#header > h1:only-child, body.toc2 #header > h1:nth-last-child(2) { border-bottom: 1px solid #ddd; padding-bottom: 8px; }\n#header .details { border-bottom: 1px solid #ddd; line-height: 1.45; padding-top: 0.25em; padding-bottom: 0.25em; padding-left: 0.25em; color: #748590; display: -ms-flexbox; display: -webkit-flex; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; }\n#header .details span:first-child { margin-left: -0.125em; }\n#header .details span.email a { color: #909ea7; }\n#header .details br { display: none; }\n#header .details br + span:before { content: \"\\00a0\\2013\\00a0\"; }\n#header .details br + span.author:before { content: \"\\00a0\\22c5\\00a0\"; color: #909ea7; }\n#header .details br + span#revremark:before { content: \"\\00a0|\\00a0\"; }\n#header #revnumber { text-transform: capitalize; }\n#header #revnumber:after { content: \"\\00a0\"; }\n\n#content > h1:first-child:not([class]) { color: #111; border-bottom: 1px solid #ddd; padding-bottom: 8px; margin-top: 0; padding-top: 1rem; margin-bottom: 1.25rem; }\n\n#toc { border-bottom: 1px solid #ddd; padding-bottom: 0.5em; }\n#toc > ul { margin-left: 0.125em; }\n#toc ul.sectlevel0 > li > a { font-style: italic; }\n#toc ul.sectlevel0 ul.sectlevel1 { margin: 0.5em 0; }\n#toc ul { font-family: ff-meta-web-pro-1, ff-meta-web-pro-2, Arial, \"Helvetica Neue\", sans-serif; list-style-type: none; }\n#toc li { line-height: 1.3334; margin-top: 0.3334em; }\n#toc a { text-decoration: none; }\n#toc a:active { text-decoration: underline; }\n\n#toctitle { color: #6c818f; font-size: 1.2em; }\n\n@media only screen and (min-width: 768px) { #toctitle { font-size: 1.375em; }\n  body.toc2 { padding-left: 15em; padding-right: 0; }\n  #toc.toc2 { margin-top: 0 !important; background-color: #f2f2f2; position: fixed; width: 15em; left: 0; top: 0; border-right: 1px solid #ddd; border-top-width: 0 !important; border-bottom-width: 0 !important; z-index: 1000; padding: 1.25em 1em; height: 100%; overflow: auto; }\n  #toc.toc2 #toctitle { margin-top: 0; margin-bottom: 0.8rem; font-size: 1.2em; }\n  #toc.toc2 > ul { font-size: 0.9em; margin-bottom: 0; }\n  #toc.toc2 ul ul { margin-left: 0; padding-left: 1em; }\n  #toc.toc2 ul.sectlevel0 ul.sectlevel1 { padding-left: 0; margin-top: 0.5em; margin-bottom: 0.5em; }\n  body.toc2.toc-right { padding-left: 0; padding-right: 15em; }\n  body.toc2.toc-right #toc.toc2 { border-right-width: 0; border-left: 1px solid #ddd; left: auto; right: 0; } }\n@media only screen and (min-width: 1280px) { body.toc2 { padding-left: 20em; padding-right: 0; }\n  #toc.toc2 { width: 20em; }\n  #toc.toc2 #toctitle { font-size: 1.375em; }\n  #toc.toc2 > ul { font-size: 0.95em; }\n  #toc.toc2 ul ul { padding-left: 1.25em; }\n  body.toc2.toc-right { padding-left: 0; padding-right: 20em; } }\n#content #toc { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 6px; border-radius: 6px; }\n#content #toc > :first-child { margin-top: 0; }\n#content #toc > :last-child { margin-bottom: 0; }\n\n#footer { max-width: 100%; background-color: #000; padding: 1.25em; }\n\n#footer-text { color: white; line-height: 1.35; }\n\n#content { margin-bottom: 0.625em; }\n\n.sect1 { padding-bottom: 0.625em; }\n\n@media only screen and (min-width: 768px) { #content { margin-bottom: 1.25em; }\n  .sect1 { padding-bottom: 1.25em; } }\n.sect1:last-child { padding-bottom: 0; }\n\n.sect1 + .sect1 { border-top: 1px solid #ddd; }\n\n#content h1 > a.anchor, h2 > a.anchor, h3 > a.anchor, #toctitle > a.anchor, .sidebarblock > .content > .title > a.anchor, h4 > a.anchor, h5 > a.anchor, h6 > a.anchor { position: absolute; z-index: 1001; width: 1.5ex; margin-left: -1.5ex; display: block; text-decoration: none !important; visibility: hidden; text-align: center; font-weight: normal; }\n#content h1 > a.anchor:before, h2 > a.anchor:before, h3 > a.anchor:before, #toctitle > a.anchor:before, .sidebarblock > .content > .title > a.anchor:before, h4 > a.anchor:before, h5 > a.anchor:before, h6 > a.anchor:before { content: \"\\00A7\"; font-size: 0.85em; display: block; padding-top: 0.1em; }\n#content h1:hover > a.anchor, #content h1 > a.anchor:hover, h2:hover > a.anchor, h2 > a.anchor:hover, h3:hover > a.anchor, #toctitle:hover > a.anchor, .sidebarblock > .content > .title:hover > a.anchor, h3 > a.anchor:hover, #toctitle > a.anchor:hover, .sidebarblock > .content > .title > a.anchor:hover, h4:hover > a.anchor, h4 > a.anchor:hover, h5:hover > a.anchor, h5 > a.anchor:hover, h6:hover > a.anchor, h6 > a.anchor:hover { visibility: visible; }\n#content h1 > a.link, h2 > a.link, h3 > a.link, #toctitle > a.link, .sidebarblock > .content > .title > a.link, h4 > a.link, h5 > a.link, h6 > a.link { color: #465158; text-decoration: none; }\n#content h1 > a.link:hover, h2 > a.link:hover, h3 > a.link:hover, #toctitle > a.link:hover, .sidebarblock > .content > .title > a.link:hover, h4 > a.link:hover, h5 > a.link:hover, h6 > a.link:hover { color: #3b444a; }\n\n.audioblock, .imageblock, .literalblock, .listingblock, .stemblock, .videoblock { margin-bottom: 1.25em; }\n\n.admonitionblock td.content > .title, .audioblock > .title, .exampleblock > .title, .imageblock > .title, .listingblock > .title, .literalblock > .title, .stemblock > .title, .openblock > .title, .paragraph > .title, .quoteblock > .title, table.tableblock > .title, .verseblock > .title, .videoblock > .title, .dlist > .title, .olist > .title, .ulist > .title, .qlist > .title, .hdlist > .title { text-rendering: optimizeLegibility; text-align: left; }\n\ntable.tableblock.fit-content > caption.title { white-space: nowrap; width: 0; }\n\n.paragraph.lead > p, #preamble > .sectionbody > [class=\"paragraph\"]:first-of-type p { font-size: 1.21875em; line-height: 1.6; color: #111; }\n\ntable.tableblock #preamble > .sectionbody > [class=\"paragraph\"]:first-of-type p { font-size: inherit; }\n\n.admonitionblock > table { border-collapse: separate; border: 0; background: none; width: 100%; }\n.admonitionblock > table td.icon { text-align: center; width: 80px; }\n.admonitionblock > table td.icon img { max-width: none; }\n.admonitionblock > table td.icon .title { font-weight: bold; font-family: ff-meta-web-pro-1, ff-meta-web-pro-2, Arial, \"Helvetica Neue\", sans-serif; text-transform: uppercase; }\n.admonitionblock > table td.content { padding-left: 1.125em; padding-right: 1.25em; border-left: 1px solid #ddd; color: #748590; }\n.admonitionblock > table td.content > :last-child > :last-child { margin-bottom: 0; }\n\n.exampleblock > .content { border-style: solid; border-width: 1px; border-color: #e6e6e6; margin-bottom: 1.25em; padding: 1.25em; background: #fff; -webkit-border-radius: 6px; border-radius: 6px; }\n.exampleblock > .content > :first-child { margin-top: 0; }\n.exampleblock > .content > :last-child { margin-bottom: 0; }\n\n.sidebarblock { border-style: solid; border-width: 1px; border-color: #d9d9d9; margin-bottom: 1.25em; padding: 1.25em; background: #f2f2f2; -webkit-border-radius: 6px; border-radius: 6px; }\n.sidebarblock > :first-child { margin-top: 0; }\n.sidebarblock > :last-child { margin-bottom: 0; }\n.sidebarblock > .content > .title { color: #6c818f; margin-top: 0; }\n\n.exampleblock > .content > :last-child > :last-child, .exampleblock > .content .olist > ol > li:last-child > :last-child, .exampleblock > .content .ulist > ul > li:last-child > :last-child, .exampleblock > .content .qlist > ol > li:last-child > :last-child, .sidebarblock > .content > :last-child > :last-child, .sidebarblock > .content .olist > ol > li:last-child > :last-child, .sidebarblock > .content .ulist > ul > li:last-child > :last-child, .sidebarblock > .content .qlist > ol > li:last-child > :last-child { margin-bottom: 0; }\n\n.literalblock pre, .listingblock pre:not(.highlight), .listingblock pre[class=\"highlight\"], .listingblock pre[class^=\"highlight \"], .listingblock pre.CodeRay, .listingblock pre.prettyprint { background: #eee; }\n.sidebarblock .literalblock pre, .sidebarblock .listingblock pre:not(.highlight), .sidebarblock .listingblock pre[class=\"highlight\"], .sidebarblock .listingblock pre[class^=\"highlight \"], .sidebarblock .listingblock pre.CodeRay, .sidebarblock .listingblock pre.prettyprint { background: #f2f1f1; }\n\n.literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { border: 1px solid #ccc; -webkit-border-radius: 6px; border-radius: 6px; word-wrap: break-word; padding: 0.5em; font-size: 0.8125em; }\n.literalblock pre.nowrap, .literalblock pre[class].nowrap, .listingblock pre.nowrap, .listingblock pre[class].nowrap { overflow-x: auto; white-space: pre; word-wrap: normal; }\n@media only screen and (min-width: 768px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 0.90625em; } }\n@media only screen and (min-width: 1280px) { .literalblock pre, .literalblock pre[class], .listingblock pre, .listingblock pre[class] { font-size: 1em; } }\n\n.literalblock.output pre { color: #eee; background-color: inherit; }\n\n.listingblock pre.highlightjs { padding: 0; }\n.listingblock pre.highlightjs > code { padding: 0.5em; -webkit-border-radius: 6px; border-radius: 6px; }\n\n.listingblock > .content { position: relative; }\n\n.listingblock code[data-lang]:before { display: none; content: attr(data-lang); position: absolute; font-size: 0.75em; top: 0.425rem; right: 0.5rem; line-height: 1; text-transform: uppercase; color: #999; }\n\n.listingblock:hover code[data-lang]:before { display: block; }\n\n.listingblock.terminal pre .command:before { content: attr(data-prompt); padding-right: 0.5em; color: #999; }\n\n.listingblock.terminal pre .command:not([data-prompt]):before { content: \"$\"; }\n\ntable.pyhltable { border-collapse: separate; border: 0; margin-bottom: 0; background: none; }\n\ntable.pyhltable td { vertical-align: top; padding-top: 0; padding-bottom: 0; line-height: 1.2; }\n\ntable.pyhltable td.code { padding-left: .75em; padding-right: 0; }\n\npre.pygments .lineno, table.pyhltable td:not(.code) { color: #999; padding-left: 0; padding-right: .5em; border-right: 1px solid #ddd; }\n\npre.pygments .lineno { display: inline-block; margin-right: .25em; }\n\ntable.pyhltable .linenodiv { background: none !important; padding-right: 0 !important; }\n\n.quoteblock { margin: 0 1em 1.25em 1.5em; display: table; }\n.quoteblock > .title { margin-left: -1.5em; margin-bottom: 0.75em; }\n.quoteblock blockquote, .quoteblock blockquote p { color: #909ea7; font-size: 1.15rem; line-height: 1.75; word-spacing: 0.1em; letter-spacing: 0; font-style: italic; text-align: justify; }\n.quoteblock blockquote { margin: 0; padding: 0; border: 0; }\n.quoteblock blockquote:before { content: \"\\201c\"; float: left; font-size: 2.75em; font-weight: bold; line-height: 0.6em; margin-left: -0.6em; color: #6c818f; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); }\n.quoteblock blockquote > .paragraph:last-child p { margin-bottom: 0; }\n.quoteblock .attribution { margin-top: 0.5em; margin-right: 0.5ex; text-align: right; }\n.quoteblock .quoteblock { margin-left: 0; margin-right: 0; padding: 0.5em 0; border-left: 3px solid #748590; }\n.quoteblock .quoteblock blockquote { padding: 0 0 0 0.75em; }\n.quoteblock .quoteblock blockquote:before { display: none; }\n\n.verseblock { margin: 0 1em 1.25em 1em; }\n.verseblock pre { font-family: \"Open Sans\", \"DejaVu Sans\", sans; font-size: 1.15rem; color: #909ea7; font-weight: 300; text-rendering: optimizeLegibility; }\n.verseblock pre strong { font-weight: 400; }\n.verseblock .attribution { margin-top: 1.25rem; margin-left: 0.5ex; }\n\n.quoteblock .attribution, .verseblock .attribution { font-size: 0.8125em; line-height: 1.45; font-style: italic; }\n.quoteblock .attribution br, .verseblock .attribution br { display: none; }\n.quoteblock .attribution cite, .verseblock .attribution cite { display: block; letter-spacing: -0.025em; color: #748590; }\n\n.quoteblock.abstract { margin: 0 1em 1.25em 1em; display: block; }\n.quoteblock.abstract > .title { margin: 0 0 0.375em 0; font-size: 1.15em; text-align: center; }\n.quoteblock.abstract blockquote, .quoteblock.abstract blockquote p { word-spacing: 0; line-height: 1.6; }\n.quoteblock.abstract blockquote:before, .quoteblock.abstract p:before { display: none; }\n\ntable.tableblock { max-width: 100%; border-collapse: separate; }\n\np.tableblock:last-child { margin-bottom: 0; }\n\ntd.tableblock > .content { margin-bottom: -1.25em; }\n\ntable.tableblock, th.tableblock, td.tableblock { border: 0 solid #ddd; }\n\ntable.grid-all > thead > tr > .tableblock, table.grid-all > tbody > tr > .tableblock { border-width: 0 0 0 0; }\n\ntable.grid-all > tfoot > tr > .tableblock { border-width: 0 0 0 0; }\n\ntable.grid-cols > * > tr > .tableblock { border-width: 0 0 0 0; }\n\ntable.grid-rows > thead > tr > .tableblock, table.grid-rows > tbody > tr > .tableblock { border-width: 0 0 0 0; }\n\ntable.grid-rows > tfoot > tr > .tableblock { border-width: 0 0 0 0; }\n\ntable.grid-all > * > tr > .tableblock:last-child, table.grid-cols > * > tr > .tableblock:last-child { border-right-width: 0; }\n\ntable.grid-all > tbody > tr:last-child > .tableblock, table.grid-all > thead:last-child > tr > .tableblock, table.grid-rows > tbody > tr:last-child > .tableblock, table.grid-rows > thead:last-child > tr > .tableblock { border-bottom-width: 0; }\n\ntable.frame-all { border-width: 0; }\n\ntable.frame-sides { border-width: 0 0; }\n\ntable.frame-topbot, table.frame-ends { border-width: 0 0; }\n\ntable.stripes-all tr, table.stripes-odd tr:nth-of-type(odd) { background: none; }\n\ntable.stripes-none tr, table.stripes-odd tr:nth-of-type(even) { background: none; }\n\nth.halign-left, td.halign-left { text-align: left; }\n\nth.halign-right, td.halign-right { text-align: right; }\n\nth.halign-center, td.halign-center { text-align: center; }\n\nth.valign-top, td.valign-top { vertical-align: top; }\n\nth.valign-bottom, td.valign-bottom { vertical-align: bottom; }\n\nth.valign-middle, td.valign-middle { vertical-align: middle; }\n\ntable thead th, table tfoot th { font-weight: bold; }\n\ntbody tr th { display: table-cell; line-height: 1.5; background: none; }\n\ntbody tr th, tbody tr th p, tfoot tr th, tfoot tr th p { color: #222; font-weight: bold; }\n\np.tableblock > code:only-child { background: none; padding: 0; }\n\np.tableblock { font-size: 1em; }\n\ntd > div.verse { white-space: pre; }\n\nol { margin-left: 1.50em; }\n\nul li ol { margin-left: 0; }\n\ndl dd { margin-left: 1.125em; }\n\ndl dd:last-child, dl dd:last-child > :last-child { margin-bottom: 0; }\n\nol > li p, ul > li p, ul dd, ol dd, .olist .olist, .ulist .ulist, .ulist .olist, .olist .ulist { margin-bottom: 0.625em; }\n\nul.checklist, ul.none, ol.none, ul.no-bullet, ol.no-bullet, ol.unnumbered, ul.unstyled, ol.unstyled { list-style-type: none; }\n\nul.no-bullet, ol.no-bullet, ol.unnumbered { margin-left: 0.625em; }\n\nul.unstyled, ol.unstyled { margin-left: 0; }\n\nul.checklist { margin-left: 0.625em; }\n\nul.checklist li > p:first-child > .fa-square-o:first-child, ul.checklist li > p:first-child > .fa-check-square-o:first-child { width: 1.25em; font-size: 0.8em; position: relative; bottom: 0.125em; }\n\nul.checklist li > p:first-child > input[type=\"checkbox\"]:first-child { margin-right: 0.25em; }\n\nul.inline { display: -ms-flexbox; display: -webkit-box; display: flex; -ms-flex-flow: row wrap; -webkit-flex-flow: row wrap; flex-flow: row wrap; list-style: none; margin: 0 0 0.625em -1.25em; }\n\nul.inline > li { margin-left: 1.25em; }\n\n.unstyled dl dt { font-weight: normal; font-style: normal; }\n\nol.arabic { list-style-type: decimal; }\n\nol.decimal { list-style-type: decimal-leading-zero; }\n\nol.loweralpha { list-style-type: lower-alpha; }\n\nol.upperalpha { list-style-type: upper-alpha; }\n\nol.lowerroman { list-style-type: lower-roman; }\n\nol.upperroman { list-style-type: upper-roman; }\n\nol.lowergreek { list-style-type: lower-greek; }\n\n.hdlist > table, .colist > table { border: 0; background: none; }\n.hdlist > table > tbody > tr, .colist > table > tbody > tr { background: none; }\n\ntd.hdlist1, td.hdlist2 { vertical-align: top; padding: 0 0.625em; }\n\ntd.hdlist1 { font-weight: bold; padding-bottom: 1.25em; }\n\n.literalblock + .colist, .listingblock + .colist { margin-top: -0.5em; }\n\n.colist td:not([class]):first-child { padding: 0.4em 0.75em 0 0.75em; line-height: 1; vertical-align: top; }\n.colist td:not([class]):first-child img { max-width: none; }\n.colist td:not([class]):last-child { padding: 0.25em 0; }\n\n.thumb, .th { line-height: 0; display: inline-block; border: solid 4px #fff; -webkit-box-shadow: 0 0 0 1px #ddd; box-shadow: 0 0 0 1px #ddd; }\n\n.imageblock.left { margin: 0.25em 0.625em 1.25em 0; }\n.imageblock.right { margin: 0.25em 0 1.25em 0.625em; }\n.imageblock > .title { margin-bottom: 0; }\n.imageblock.thumb, .imageblock.th { border-width: 6px; }\n.imageblock.thumb > .title, .imageblock.th > .title { padding: 0 0.125em; }\n\n.image.left, .image.right { margin-top: 0.25em; margin-bottom: 0.25em; display: inline-block; line-height: 0; }\n.image.left { margin-right: 0.625em; }\n.image.right { margin-left: 0.625em; }\n\na.image { text-decoration: none; display: inline-block; }\na.image object { pointer-events: none; }\n\nsup.footnote, sup.footnoteref { font-size: 0.875em; position: static; vertical-align: super; }\nsup.footnote a, sup.footnoteref a { text-decoration: none; }\nsup.footnote a:active, sup.footnoteref a:active { text-decoration: underline; }\n\n#footnotes { padding-top: 0.75em; padding-bottom: 0.75em; margin-bottom: 0.625em; }\n#footnotes hr { width: 20%; min-width: 6.25em; margin: -0.25em 0 0.75em 0; border-width: 1px 0 0 0; }\n#footnotes .footnote { padding: 0 0.375em 0 0.225em; line-height: 1.3334; font-size: 0.875em; margin-left: 1.2em; margin-bottom: 0.2em; }\n#footnotes .footnote a:first-of-type { font-weight: bold; text-decoration: none; margin-left: -1.05em; }\n#footnotes .footnote:last-of-type { margin-bottom: 0; }\n#content #footnotes { margin-top: -0.625em; margin-bottom: 0; padding: 0.75em 0; }\n\n.gist .file-data > table { border: 0; background: #fff; width: 100%; margin-bottom: 0; }\n.gist .file-data > table td.line-data { width: 99%; }\n\ndiv.unbreakable { page-break-inside: avoid; }\n\n.big { font-size: larger; }\n\n.small { font-size: smaller; }\n\n.underline { text-decoration: underline; }\n\n.overline { text-decoration: overline; }\n\n.line-through { text-decoration: line-through; }\n\n.aqua { color: #00bfbf; }\n\n.aqua-background { background-color: #00fafa; }\n\n.black { color: black; }\n\n.black-background { background-color: black; }\n\n.blue { color: #0000bf; }\n\n.blue-background { background-color: #0000fa; }\n\n.fuchsia { color: #bf00bf; }\n\n.fuchsia-background { background-color: #fa00fa; }\n\n.gray { color: #606060; }\n\n.gray-background { background-color: #7d7d7d; }\n\n.green { color: #006000; }\n\n.green-background { background-color: #007d00; }\n\n.lime { color: #00bf00; }\n\n.lime-background { background-color: #00fa00; }\n\n.maroon { color: #600000; }\n\n.maroon-background { background-color: #7d0000; }\n\n.navy { color: #000060; }\n\n.navy-background { background-color: #00007d; }\n\n.olive { color: #606000; }\n\n.olive-background { background-color: #7d7d00; }\n\n.purple { color: #600060; }\n\n.purple-background { background-color: #7d007d; }\n\n.red { color: #bf0000; }\n\n.red-background { background-color: #fa0000; }\n\n.silver { color: #909090; }\n\n.silver-background { background-color: #bcbcbc; }\n\n.teal { color: #006060; }\n\n.teal-background { background-color: #007d7d; }\n\n.white { color: #bfbfbf; }\n\n.white-background { background-color: #fafafa; }\n\n.yellow { color: #bfbf00; }\n\n.yellow-background { background-color: #fafa00; }\n\nspan.icon > .fa { cursor: default; }\na span.icon > .fa { cursor: inherit; }\n\n.admonitionblock td.icon [class^=\"fa icon-\"] { font-size: 2.5em; text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); cursor: default; }\n.admonitionblock td.icon .icon-note:before { content: \"\\f05a\"; color: #333333; }\n.admonitionblock td.icon .icon-tip:before { content: \"\\f0eb\"; text-shadow: 1px 1px 2px rgba(155, 155, 0, 0.8); color: #111; }\n.admonitionblock td.icon .icon-warning:before { content: \"\\f071\"; color: #bf6900; }\n.admonitionblock td.icon .icon-caution:before { content: \"\\f06d\"; color: #bf3400; }\n.admonitionblock td.icon .icon-important:before { content: \"\\f06a\"; color: #bf0000; }\n\n.conum[data-value] { display: inline-block; color: #fff !important; background-color: #000; -webkit-border-radius: 100px; border-radius: 100px; text-align: center; font-size: 0.75em; width: 1.67em; height: 1.67em; line-height: 1.67em; font-family: \"Open Sans\", \"DejaVu Sans\", sans-serif; font-style: normal; font-weight: bold; }\n.conum[data-value] * { color: #fff !important; }\n.conum[data-value] + b { display: none; }\n.conum[data-value]:after { content: attr(data-value); }\npre .conum[data-value] { position: relative; top: -0.125em; }\n\nb.conum * { color: inherit !important; }\n\n.conum:not([data-value]):empty { display: none; }\n\nh4 { color: #6c818f; }\n\n.literalblock > .content > pre, .listingblock > .content > pre { -webkit-border-radius: 6px; border-radius: 6px; margin-left: 2em; margin-right: 2em; }\n\n.admonitionblock { margin-left: 2em; margin-right: 2em; }\n.admonitionblock > table { border: 1px solid #607f90; border-top-width: 1.5em; background-color: #f0f9ff; border-collapse: separate; -webkit-border-radius: 0; border-radius: 0; }\n.admonitionblock > table td.icon { padding-top: .5em; padding-bottom: .5em; }\n.admonitionblock > table td.content { padding: .5em 1em; color: #000; font-size: .9em; border-left: none; }\n\n.sidebarblock { background-color: #e8ecef; border-color: #ccc; }\n.sidebarblock > .content > .title { color: #444; }\n\ntable.tableblock.grid-all { border-collapse: collapse; -webkit-border-radius: 0; border-radius: 0; }\ntable.tableblock.grid-all th.tableblock, table.tableblock.grid-all td.tableblock { border-bottom: 1px solid #aaa; }\n\n#footer { background-color: #465158; padding: 2em; }\n\n#footer-text { color: #eee; font-size: 0.8em; text-align: center; }\n"
  },
  {
    "path": "manual/cli.adoc",
    "content": "[[cli,Command line interface]]\n== Command Line Interface\n\nEven though SmuView has a graphical user interface, there is also a command line\ninterface that you can make use of. It is meant to provide functions for\nconvenience and debug purposes, not to replace the user interface itself.\n\nWindows only shows output on the command line when the debug build is used.\n\nRunning\n[listing, subs=\"normal\"]\nsmuview -h\n\ngives you a list of all available options.\n\nSince SmuView can't automatically scan for devices connected to a COM port\n(`ttySx` on Linux) or Ethernet, you can tell it to look for a specific device\nusing the `-d` or `--driver` parameter. Its usage is the same as for\n`sigrok-cli`. All possible connection parameters are documented in the\nhttps://sigrok.org/wiki/Connection_parameters[sigrok wiki]. For example:\n[listing, subs=\"normal\"]\nsmuview -d arachnid-labs-re-load-pro:conn=/dev/ttyUSB0\n\nYou also can start smuscripts from the command line with the `-s` or `--script`\nparameter:\n[listing, subs=\"normal\"]\nsmuview -s /path/to/example_script.py\n\nThe remaining parameters are mostly for debug purposes:\n[listing, subs=\"normal\"]\n-V / --version\t\tShows the release version\n-l / --loglevel\t\tSets the libsigrok log level (0-5, default: 2)\n-D / --dont-scan\tDo not auto-scan for devices and use -d spec only\n-c / --clean\t\tDo not restore previous settings on startup\n\nOf these, `-D` / `--dont-scan` can be useful when SmuView gets stuck during\nthe startup device scan. No such scan will be performed then, allowing the\nprogram to start up but you'll have to scan for your acquisition device(s)\nmanually before you can use them.\n\nAnother potentially useful option is `-c` / `--clean`, which can be used when\nSmuView doesn’t start up and you don’t know what could cause this.\n\nThus, the combination of both parameters can be seen as some kind of \"safe mode\"\nfor SmuView:\n[listing, subs=\"normal\"]\nsmuview -c -D\n\nThe `-D` option can be used in combination with `-d`. This eliminates the\nautomatic scan for devices, but will connect to those devices specified by\nthe `-d` option. Which can speedup the program start, and can be useful\nfor scripts or shortcuts on desktops when a specific device or set of\ndevices is often used in combination.\n\n"
  },
  {
    "path": "manual/data_processing.adoc",
    "content": "[[data_processing,Data Processing]]\n== Data Processing\n\nSmuView can process and combine channels via math channels.\n\nimage::AddMathChannelDialog.png[Add math channel dialog,558,743]\n\nimage:numbers/1.png[1,22,22] Name of the new math channel. +\nimage:numbers/2.png[2,22,22] Selection for the quantity, the quantity flags and\nthe unit of the new math channel. +\nimage:numbers/3.png[3,22,22] Selection to which device and channel group the new\nmath channel should be added to. +\nimage:numbers/4.png[4,22,22] Various types of math channels.\n\nOne example this could be used is, when you measure a current via the voltage\ndrop over a shunt resistor with a DMM. With the multiplication of a constant\nfactor and the voltage signal of the DMM you can generate a current channel with\nthe correct values in the correct unit (Ampere).\n\nThese types of math channels are currently implemented:\n\n. Multiplication of two signals.\n. Multiplication of a signal and a constant factor.\n. Division of two signals.\n. Addition of a signal and a constant value.\n. Integration of a signal over time.\n. Moving average of a signal.\n\nAs an alternative to math channels, you can use <<smuscript,SmuScript>> to do\nfar more complex signal processing.\n"
  },
  {
    "path": "manual/data_tables/combine.csv",
    "content": "Time,Demo device,Demo device,Demo device\nTime,Analog,Analog,Analog\nTime,A1,A2,A3\nTime,A1 [V DC],A2 [V DC],A3 [V DC]\n0.3400,0,,0\n0.3600,,0,\n0.5400,3.09017,2,1\n0.7300,,,2\n0.7400,5.87785,4,\n0.9410,8.09017,6,3\n"
  },
  {
    "path": "manual/data_tables/combine_30ms.csv",
    "content": "Time,Demo device,Demo device,Demo device\nTime,Analog,Analog,Analog\nTime,A1,A2,A3\nTime,A1 [V DC],A2 [V DC],A3 [V DC]\n0.3400,0,0,0\n0.5400,3.09017,2,1\n0.7300,5.87785,4,2\n0.9410,8.09017,6,3\n"
  },
  {
    "path": "manual/data_tables/combine_absolute.csv",
    "content": "Time,Demo device,Demo device,Demo device\nTime,Analog,Analog,Analog\nTime,A1,A2,A3\nTime,A1 [V DC],A2 [V DC],A3 [V DC]\n2021.01.04 19:05:38.917,0,,0\n2021.01.04 19:05:38.937,,0,\n2021.01.04 19:05:39.117,3.09017,2,1\n2021.01.04 19:05:39.307,,,2\n2021.01.04 19:05:39.317,5.87785,4,\n2021.01.04 19:05:39.518,8.09017,6,3\n"
  },
  {
    "path": "manual/data_tables/simple.csv",
    "content": "Demo device,Demo device,Demo device,Demo device,Demo device,Demo device\nAnalog,Analog,Analog,Analog,Analog,Analog\nA1,A1,A2,A2,A3,A3\nTime A1 [V DC],A1 [V DC],Time A2 [V DC],A2 [V DC],Time A3 [V DC],A3 [V DC]\n0.3400,0,0.3600,0,0.3400,0\n0.5400,3.09017,0.5400,2,0.5400,1\n0.7400,5.87785,0.7400,4,0.7300,2\n0.9410,8.09017,0.9410,6,0.9410,3\n"
  },
  {
    "path": "manual/data_visualisation.adoc",
    "content": "[[data_visualisation,Data Visualisation]]\n== Data Visualisation\n\nSmuView can visualize the captured data in various views. When a devices is\nconnected, some common views are automatically displayed, depending on the\ndevice type and the available features of the connected device.\n\nYou can close views and create new ones via the tool bar of the device tab.\n\n[[value_panel_view]]\n=== Value Panel View\n\nimage::ValuePanelView.png[Value panel,402,185]\n\nThe value panel view displays the current value (image:numbers/1.png[1,22,22])\nof a signal or channel. Also the minimum (image:numbers/2.png[2,22,22]) and\nmaximum (image:numbers/3.png[3,22,22]) values since the last reset are shown.\n\nEach value can have a unit (image:numbers/4.png[4,22,22]) and optional flags\n(image:numbers/5.png[5,22,22])\n\nThe minimum and maximum value can be reset with the tool bar button\nimage:numbers/6.png[6,22,22].\n\n[[power_panel_view]]\n=== Power Panel View\n\nimage::PowerPanelView.png[Power panel]\n\nThe power panel view is shown for power supplies and electronic loads. This view\nis using the voltage and current channel for calculating resistance, power, Wh\nand Ah. Also the minimum and maximum values since the last reset are shown.\n\nThe minimum, maximum, Wh and Ah values can be reset with the tool bar buttion\nimage:numbers/1.png[1,22,22].\n\nThere is no tool bar button in the device tab to show a power panel view, but it\nis accessible via the _Add View_ dialog in the device tab.\n\n[[data_table_view]]\n=== Data Table View\n\nimage::DataTableView.png[Data table,270,266]\n\nThe data table view shows all available sample points for one or more signals.\n\nYou can control if the table scrolls to the bottom or stays at a given position\nwith the tool bar button image:numbers/1.png[1,22,22] and you can add new\nsignals to the table via the tool bar button image:numbers/2.png[2,22,22].\n\n[[time_plot_view]]\n=== Time Plot View\n\nimage::TimePlotView_2.png[Time plot,645,369]\n\nThe time plot view shows one or more channels or signals in a plot over time.\n\nYou can move the plot by dragging the plot canvas or by dragging the axis and\nyou can zoom the whole plot by scrolling inside the plot canvas or zooming a\nspecific axis by using the mouse wheel over the axis.\n\nWhen double clicking an axis, you can manually set the axis boundaries, lock the\nboundaries and set an axis scale (linear or logarithmic). With the lock symbols\n(image:numbers/1.png[1,22,22] and image:numbers/2.png[2,22,22]) at the axis, you\ncan also lock an axis boundary. When clicking on a signal label\n(image:numbers/3.png[3,22,22]), you can change the curve name, the visibility,\ncolor, line type and symbol type of the corresponding signal.\n\nYou can add plot markers (image:numbers/4.png[4,22,22]), differential markers\n(image:numbers/5.png[5,22,22]), resize to best fit (image:numbers/6.png[6,22,22]),\nand add new signals (image:numbers/7.png[7,22,22]) to the plot via the tool bar.\n\nThe plot can be saved (tool bar button image:numbers/8.png[8,22,22]) to various image formats like SVG, PDF, PNG, etc. At the moment, the image size is fixed.\n\nYou can also configure the plot with the tool bar button\nimage:numbers/9.png[9,22,22]: Change the plot mode (additive, rolling,\noscilloscope) and change the display position of the markers info box.\n\n[[xy_plot_view]]\n=== X/Y-Plot View\n\nThe X/Y-plot view shows two signals in X/Y-mode. It has the same functionality\nas the time plot view.\n"
  },
  {
    "path": "manual/device_control.adoc",
    "content": "[[device_control,Device Control]]\n== Device Control\n\nSmuView can control devices, depending on the device type and the available\nfeatures of the connected device. When a device is connected and it is\ncontrollable, control views  are automatically displayed.\n\nYou can close control views and create new ones via the tool bar of the device\ntab.\n\n[[control_view]]\n=== Control View\n\nimage::SourceControlView.png[Control view,344,414]\n\nDepending on the device type the control view looks different and functions may\nbe disabled.\n\nPower supplies and electronic loads have a very similar control view, which\ngives access to all possible functions supported by the sigrok library.\n\nOther controllable devices like sound level meters will have a generic control\nview.\n\n[[sequence_output_view]]\n=== Sequence Output View\n\nimage::SequenceOutputView.png[Sequence output view,282,303]\n\nSome <<config_key,config keys>> of a device (for example the output voltage of a\npower supply) can be set to a sequence of values. The sequence can be played one\nor more times. You can generate sine, triangle, sawtooth and square wave\nsequences, load a sequence from a CSV file or enter the sequence manually.\n\nThere is no tool bar button in the device tab to show a sequence output view\nyet, but it is accesible via the _Add View_ dialog in the device tab.\n"
  },
  {
    "path": "manual/devices.adoc",
    "content": "[[devices,Devices]]\n== Devices\n\nSmuView supports a wide variety of analog devices. Because of that, some of the\nfollowing terms may have a slightly different meaning for different device\ntypes.\n\nA device can contain the following objects:\n\nChannel Group image:icons/document-open-folder.png[width=18,Height=18]::\nA device can have no, one or more channel groups. Channel groups normally\ncorresponds to a physical channel on the device itself.\n+\nA three output channel power supply for example will have three channel\ngroups, probably named `1`, `2` and `3`.\n+\nA multimeter normally doesn't have a channel group.\n\nChannel image:icons/office-chart-area.png[width=18,Height=18]::\nA device can have multiple channels. Channels can be in a channel group or\nbelong to the device itself.\n+\nA power supply normally has a voltage and a current channel per channel group.\n+\nA multimeter probably has one channel for the main display and maybe one for a\nsecondary display.\n\n[[signal]]\nSignal image:icons/office-chart-line.png[width=18,Height=18]::\nA channel can contain one or more signals. A signal represents the samples\ngenerated by the device.\n+\nChannels of power supplies, electronic loads and math channels always contain\nonly one signal with a fixed quantity and unit.\n+\nChannels of multimeters may contain multiple signals, each one with a unique\nquantity, quantity flags and unit.\n\nControllable image:icons/mixer-front.png[width=18,Height=18]::\nA device can have no, one or more controllables. Up to one controllable can\nbelong to a channel group or to the device itself.\n+\nA power supplies channel group controllable can probably control the output\nvoltage and current, enable OVP and OCP and enable the output.\n\n[[config_key]]\nConfig Key image:icons/configure.png[width=18,Height=18]::\nA controllable contains one or more config keys. A config key controls a single\nproperty of the device like the sink current of an electronic load or enables\nthe output of a power supply channel group. It may be read- and writeable.\n\nThis is the start screen, when you start SmuView without any\n<<cli,command line parameters>>:\n\nimage::Welcome.png[width=610,height=294]\n\nimage:numbers/1.png[1,22,22] Connect a new hardware device. +\nimage:numbers/2.png[2,22,22] Create a new <<user_device,user device>>. +\nimage:numbers/3.png[3,22,22] Disconnect and close the selected device. All\nacquired data will be lost!\n\n[[connect_device, Connect a Device]]\n=== Connect a Device\n\nYou can connect a hardware device with a dialog or with a\n<<cli,command line parameter>>.\n\nWhen using the dialog, first you’ll need to pick a driver that you want to use\n(Step 1, image:numbers/1.png[1,22,22]). In order to do this, you’ll need to\nknow which driver is used to talk to the device. If you’re unsure, you can\neither try the driver which you think may fit best or you can check the\nhttps://sigrok.org/wiki/Supported_hardware[sigrok wiki]. For every supported\ndevice there’s a wiki page, showing you which driver is used.\n\nOnce the driver has been chosen, you need to select the interface (Step 2,\nimage:numbers/2.png[2,22,22]). Please be aware that USB is only usable for\ndevices that directly communicate over USB. Devices that use USB to emulate a\nserial port (like many multimeters) will have their serial port listed in the\nserial port drop-down. The GPIB interface option is only available, if you have\nbuilt `libsigrok` with `linux-gbip` support under Linux.\n\nIn case your device connects via Ethernet, you must supply the IP address and\nport. You are also given the option to choose between raw TCP access and using\nthe VXI protocol. VXI is an industry standard which is mainly used in\nprofessional equipment and the device will most likely let you know that it\nsupports VXI. If your device however is more of a hobbyist grade device, it’s\nmore likely that using raw TCP will be the correct choice.\n\nAfter you selected the appropriate options, clicking the btn:[Scan] button\n(Step 3, image:numbers/3.png[3,22,22]) will make SmuView try to connect to the\ndevice with the given settings. If successful, any device(s) found will be shown\nin the list box (Step 4, image:numbers/4.png[4,22,22]).\n\nimage::ConnectDeviceDialog.png[width=536,height=660]\n\nTo avoid having to manually enter the device configuration for a serial port or\nEthernet device every time you want to use it and then having to scan for it,\nyou can also use the <<cli,command line parameter>> `-d` or `--driver` to have\nSmuView scan for it on startup:\n\n[listing, subs=\"normal\"]\nsmuview -d arachnid-labs-re-load-pro:conn=/dev/ttyUSB0\n\n[listing, subs=\"normal\"]\nsmuview -d korad-kaxxxxp:conn=/dev/ttyUSB1:force_detect=KORADKA3005PV2.0\n\nTIP: All possible connection parameters are documented in the\nhttps://sigrok.org/wiki/Connection_parameters[sigrok wiki].\n\nConnecting a device for the first time, some default views are shown, like\n<<control_view,control views>> and <<data_visualisation,visualisation views>>,\ndepending on the device type and the features that device supports. You are free\nto customize which views are displayed and the position and size of these views.\n\nWhen reconnecting that device (identified by its name and serial id or\nconnection string) again, your previous view settings will be restored. To\nconnect an already known device without its stored settings but with its default\nsettings, you have to start SmuView with the command line parameter `-c`.\n\n=== Default Functions\n\nWhen you connect a device, you will get the following default functions:\n\nimage::UserDevice.png[width=641,height=221]\n\nimage:numbers/1.png[1,22,22] Start/Stop data acquisition for this device. +\nimage:numbers/2.png[2,22,22] <<export_data,Save acquired data>> to a CSV file. +\nimage:numbers/3.png[3,22,22] Add a new <<control_view,control view>>. +\nimage:numbers/4.png[4,22,22] Add a new <<value_panel_view,value panel view>>. +\nimage:numbers/5.png[5,22,22] Add a new <<time_plot_view,time plot view>>. +\nimage:numbers/6.png[6,22,22] Add a new <<data_table_view,data table view>>. +\nimage:numbers/7.png[7,22,22] Create a new <<data_processing,math channel>>. +\nimage:numbers/8.png[8,22,22] Open the about dialog.\n\n[[export_data,Export Data]]\n==== Export Data\n\nAll acquired data (<<signal,signals>>) can be saved to a CSV file by clicking\nthe save button (image:icons/document-save.png[save,22,22]) in the device tab.\n\nThere are several options to affect the resulting CSV file. Of course you are able\nto choose which signals should be saved. The signals from the current device are\nselected by default (image:numbers/1.png[1,22,22]).\n\nNext you can determine how the data of the signals should be arranged. When the\n_Combine all timestamps_ option (image:numbers/2.png[2,22,22]) is disabled, four\nheader rows are generated. The first row indicates the device, the second\nindicates the channel group, the third the channel and the fourth identifies the\nsignal itself. Each signal has two columns: One for the timestamp (in seconds)\nand one for the value of the signal at that given time (see\n<<csv_simple,table 1>>).\n\n.Formated CSV without any option selected\n[[csv_simple]]\n[%autowidth,format=csv]\n|===\ninclude::data_tables/simple.csv[]\n|===\n\nThe CSV file produced with the _Combine all timestamps_ option\n(image:numbers/2.png[2,22,22]) enabled has also four header rows, similar to the\nexample above, except that only one timestamp column (1st column) will be\ngenerated for all signals followed by one column for each signal (see\n<<csv_combine,table 2>>).\n\n.Formated CSV with the combine option selected\n[[csv_combine]]\n[%autowidth,format=csv]\n|===\ninclude::data_tables/combine.csv[]\n|===\n\nWhen the _Combine all timestamps_ option (image:numbers/2.png[2,22,22]) is\nenabled you can also define a _Combination time frame_\n(image:numbers/3.png[3,22,22]) which will combine values into one timestamp,\nwhen they fall into the defined time span (see <<csv_combine_30ms,table 3>>).\n\n.Formated CSV with the combined option selected and a time frame of 30 ms\n[[csv_combine_30ms]]\n[%autowidth,format=csv]\n|===\ninclude::data_tables/combine_30ms.csv[]\n|===\n\nBy enabling the option _Absolute time_ (image:numbers/4.png[4,22,22]), the time\ncolumn(s) will contain an absolute timestamp in the format\n`yyyy.MM.dd hh:mm:ss.zzz`, otherwise the timestamp will be relative to the start\nof the SmuView application in seconds (see <<csv_absolut,table 4>>).\n\n.Formated CSV with the combined and the absolute option selected\n[[csv_absolut]]\n[%autowidth,format=csv]\n|===\ninclude::data_tables/combine_absolute.csv[]\n|===\n\nYou can also define a custom _CSV separator_ (image:numbers/5.png[5,22,22]) used\nas the separation character in the CSV file.\n\nimage::SaveSignalsDialog.png[width=450,height=429]\n\n=== Device types\n\n==== Measurement Device\n\nA measurement device can be everything from a multimeter to a thermometer to\na scale.\n\nMost of the measurement devices are not controllable and have no channel groups.\n\n==== Power Supply\n\nMost of the supported  power supplies are controllable and have one or more\nchannel group with a voltage channel and a current channel. Some power supplies\nmay have additional channels like for power or frequency. The channels contain\nonly one signal with a fixed quantity and unit.\n\nMath channels for power, resistance, Wh and Ah are automatically generated if\nnot provided by the device.\n\n==== Electronic Load\n\nAll of the supported loads are controllable and have one channel group with a\nvoltage channel and a current channel. Some loads may have additional channels\nlike for power or Ah. The channels contain only one signal with a fixed quantity\nand unit.\n\nMath channels for power, resistance, Wh and Ah are automatically generated if\nnot provided by the device.\n\n==== Oscilloscope\n\nOscilloscopes aren't supported yet, but will be in the future!\n\nOscilloscopes have a channel group for each scope channel and one channel per\nchannel group with a signal for each captured frame. The controllable for a\nchannel group is responsible for the vertical settings of the correspondig scope\nchannel. The controllable for the device itself controls the timebase, the\ntrigger settings and so on.\n\n[[user_device]]\n==== User Device\n\nA user device has no hardware device attached to it and is basically a virtual\ndevice. It may contain math channels or visualisation and control views from\nother devices to build a custom GUI.\n"
  },
  {
    "path": "manual/installation.adoc",
    "content": "[[installation,Installation]]\n== Installation\n\nSmuView can be run on Linux, Windows and macOS. For Windows we provide\ninstallers, for Linux we provide AppImage containers and for macOS DMGs. Both\nthe AppImage and the DMG can be run without the need to install anything.\n\nYou can choose between stable releases (by the time of writing, the last stable\nversion is 0.0.5) and continuous builds. We strongly recommend the use of the\ncontinuous builds as they include bugfixes, new features and also an up-to-date\nversion of libsigrok with the latest available device drivers. Stable versions\nare released infrequently in rather big intervals.\n\nCheck the https://github.com/knarfS/smuview/releases[SmuView download page] to\nsee which option is available for your platform.\n\n=== Linux\n\nYou have two options to install SmuView, eiher you can use a pre-build AppImage\nor you can build SmuView from source yourself.\n\n[WARNING]\n--\nWhether you install SmuView using the AppImage or building from source, SmuView will\nnot be able to access USB and serial port devices unless it's run as `root`.\nSince programs shouldn't be run as `root` unless absolutely necessary, we\nprovide udev configuration files that allows SmuView access to those devices\nwithout being `root`.\n\nHere's how you install them:\n[listing, subs=\"normal\"]\nsudo bash\ncd /etc/udev/rules.d/\nwget -O 60-libsigrok.rules \"'https://sigrok.org/gitweb/?p=libsigrok.git;a=blob_plain;f=contrib/60-libsigrok.rules'\"\nwget -O 61-libsigrok-plugdev.rules \"'https://sigrok.org/gitweb/?p=libsigrok.git;a=blob_plain;f=contrib/61-libsigrok-plugdev.rules'\"\nwget -O 61-libsigrok-uaccess.rules \"'https://sigrok.org/gitweb/?p=libsigrok.git;a=blob_plain;f=contrib/61-libsigrok-uaccess.rules'\"\nsudo udevadm control --reload-rules\n--\n\n==== AppImage\n\nhttps://github.com/knarfS/smuview/releases[Download] and use the AppImage\nwhich contains all required files and needs no installation:\n\n[listing, subs=\"normal\"]\nchmod u+x SmuView-{sv_version}-x86_64.AppImage\n./SmuView{sv_version}-x86_64.AppImage\n\nPlease be aware, however, that the AppImages are development releases at the\nmoment, so they always contain the latest development changes. While we do try\nto keep the code base in a working state, it is sometimes unavoidable to\nintroduce bugs that show up in the AppImage builds. If you encounter something\nthat is odd to you, please download and install the latest release and check if\nthe issue still exists. If it does, feel free to\nhttps://github.com/knarfS/smuview/issues[file a bug].\n\nNo system files are changed, so if you decide that you no longer want to use\nSmuView, simply delete the AppImage. If you also want to remove the stored\nsettings, delete `~/.config/sigrok/SmuView.conf` as well.\n\n==== Build from source\n\nUninstall any sigrok packages from your package manager and install all\nnecessary dependencies for\nhttps://sigrok.org/wiki/Linux#Installing_the_requirements[libserialport],\nhttps://sigrok.org/wiki/Linux#Installing_the_requirements_2[libsigrok] and\nhttps://sigrok.org/wiki/Linux#Installing_the_requirements_6[SmuView].\n\n[WARNING]\nThe linked build requirements are distro-specific and may or may not be out of\ndate, depending on which distro you use. Please check the official\nhttps://sigrok.org/wiki/Building#Build_requirements[build requirements list] in\nthe sigrok wiki for the full list of requirements.\n\n[WARNING]\n--\nPlease make sure, that Python 3.x is your default Python interpreter. For Ubuntu\nand Debian you can do so by installing the package `python-is-python3`:\n[listing, subs=\"normal\"]\nsudo apt install python-is-python3\n--\n\nNow you can build SmuView from source with the help of a build script:\n\n[listing, subs=\"normal\"]\nmkdir ~/sr\ncd ~/sr\ngit clone --branch smuview --single-branch \"'https://github.com/knarfS/sigrok-util.git'\"\ncd sigrok-util/cross-compile/linux\n./sigrok-cross-linux-smuview\nexport LD_LIBRARY_PATH=~/sr/lib\n~/sr/bin/smuview\n\nNo system files are changed, so if you decide that you no longer want to use\nSmuView, simply delete the `~/sr` directory. If you also want to remove the\nstored settings, delete `~/.config/sigrok/SmuView.conf` as well.\n\n=== Windows\n\nWe offer installers for SmuView that contain everything you need to get started.\nSimply download them from the\nhttps://github.com/knarfS/smuview/releases[SmuView download page] and run them\nas any other Windows installer.\n\nPlease be aware, however, that the Windows installers are development builds, so\nthey always contain the latest development changes. While we do try to keep the\ncode base in a working state, it is sometimes unavoidable to introduce bugs that\nshow up in the development builds. If you encounter something that is odd to\nyou, please download and install the latest release and check if the issue still\nexists. If it does, feel free to\nhttps://github.com/knarfS/smuview/issues/[file a bug].\n\nAfter installation, you will find a program called Zadig in the start menu. By\ndefault, certain devices recognized by Windows will have drivers installed for\nthem that SmuView cannot use. The purpose of Zadig is to let you change the\ndriver Windows uses for a particular device - for most devices you'll need to\nchoose WinUSB to use them with SmuView or the original proprietary Windows\ndriver to use it with whatever other software you access the device with. More\ndetails are available https://sigrok.org/wiki/Windows[in the wiki].\n\nIn case your device doesn't show up in SmuView and you can't find it with a scan\neither (see next chapter), check with Zadig whether the correct driver is\nassigned for the device.\n\n=== macOS\n\nWe offer a Apple Disk Image (DMG) for SmuvView that contains everything you need\nto get started. Simply download them from the\nhttps://github.com/knarfS/smuview/releases[SmuView download page] and run them.\n\nPlease be aware, however, that the DMG installers are development builds, so\nthey always contain the latest development changes. While we do try to keep the\ncode base in a working state, it is sometimes unavoidable to introduce bugs that\nshow up in the DMG builds. If you encounter something that is odd to you, please\ndownload and install the latest release and check if the issue still exists. If\nit does, feel free to https://github.com/knarfS/smuview/issues[file a bug].\n\nNo system files are changed, so if you decide that you no longer want to use\nSmuView, simply delete the DMG file. If you also want the stored settings gone,\ndelete `~/Library/Preferences/SmuView.plist` as well.\n"
  },
  {
    "path": "manual/license.adoc",
    "content": "== License\n\nSmuView is licensed under the terms of the GNU General Public License (GPL), version 3 or later. To view a copy of this license, visit https://www.gnu.org/licenses/gpl-3.0.html.\n\nThis manual is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.\n"
  },
  {
    "path": "manual/manual.adoc",
    "content": "SmuView User Manual\n===================\nVersion {sv_version}, dated {localdate}\n:doctype: book\n:imagesdir: ./images\n:sectnums:\n:toc:\n:toclevels: 2\n:icons: font\n:figure-caption: Image\n:source-highlighter: coderay\n:experimental:\n:sv_version:\n:sv_manual_version:\n\nifdef::ebook-format[:leveloffset: -1]\n\ninclude::overview.adoc[]\n\ninclude::installation.adoc[]\n\ninclude::devices.adoc[]\n\ninclude::data_visualisation.adoc[]\n\ninclude::data_processing.adoc[]\n\ninclude::device_control.adoc[]\n\ninclude::smuscript.adoc[]\n\ninclude::cli.adoc[]\n\ninclude::license.adoc[]\n"
  },
  {
    "path": "manual/overview.adoc",
    "content": "[[overview,Overview]]\n== Overview\n\nSmuView is a graphical frontend for the libsigrok library, permitting access to\na wide range of devices to let you record, analyze, process and export analog\ndata. It is part of the sigrok suite, just like the libraries that it makes use\nof.\n\nThe sigrok suite needs some kind of hardware to interface to the signals you\nwant to examine or control. SmuView currently supports a wide variarity of\nanalog devices like\nhttps://sigrok.org/wiki/Supported_hardware#Power_supplies[power supplies]\nor https://sigrok.org/wiki/Supported_hardware#Digital_loads[electronic loads].\nBoth of these device types are most of the time controllable. There is also a\nlarge number of measurement devices that are supported by SmuView like\nhttps://sigrok.org/wiki/Supported_hardware#Multimeters[multimeters],\nhttps://sigrok.org/wiki/Supported_hardware#LCR_meters[LCR meters],\nhttps://sigrok.org/wiki/Supported_hardware#Sound_level_meters[sound level meters],\nhttps://sigrok.org/wiki/Supported_hardware#Thermometers[thermometers],\nhttps://sigrok.org/wiki/Supported_hardware#Hygrometers[hygrometers],\nhttps://sigrok.org/wiki/Supported_hardware#Anemometers[anemometers],\nhttps://sigrok.org/wiki/Supported_hardware#Light_meters[light meters],\nhttps://sigrok.org/wiki/Supported_hardware#Energy_meters[energy meters],\nhttps://sigrok.org/wiki/Supported_hardware#Tachometers[tachometers] and\nhttps://sigrok.org/wiki/Supported_hardware#Scales[scales].\n\nPlease be aware that SmuView does not support devices that either work as\nhttps://sigrok.org/wiki/Supported_hardware#Oscilloscopes[oscilloscopes],\nhttps://sigrok.org/wiki/Supported_hardware#Logic_analyzers[logic analyzers] or\nhttps://sigrok.org/wiki/Supported_hardware#Mixed-signal_devices[mixed-signal devices].\nThese device types are currently only usable with either\nhttps://sigrok.org/wiki/Sigrok-cli[sigrok-cli] or\nhttps://sigrok.org/wiki/PulseView[PulseView].\n\nHowever, oscilloscopes will be supported in the future to perform high frequency\nmeasurements (like voltage ripple on switch mode power supplies) or measurements\nin the frequency domain (e.g. for filter characterization).\n\nimage::sv_with_psu.png[SmuView with a power supply.]\n\nThe SmuView user interface is geared towards controlling devices and analysis of\ncaptured data. From here, you can access all features.\n\nBefore we dive deeper into how to accomplish things, let's make SmuView\navailable on your system first.\n"
  },
  {
    "path": "manual/smuscript.adoc",
    "content": "[[smuscript,SmuScript]]\n== SmuScript\n\nSmuView has a Python scripting extension to automate, setup and control complex\nor repetitive measurements, to process the incoming data and to create a\nstandardized user interface for those measurements.\n\nThe `smuview` Python module offers two default object instances: `Session` and\n`UiProxy`.\nThe `Session` object gives access to already connected devices or connects new\ndevices. The returned device object can then be used to read data from the\ndevice or control the device.\nThe `UiProxy` object instance is used to modify the user interface, for example\nadding tabs or views.\n\n[WARNING]\nOnly one script can be executed at a time!\n\nYou can find an API documentation https://knarfs.github.io/doc/smuview/{sv_manual_version}/python_bindings_api.html[here]\nand example scripts in the `smuscript` folder.\n\nSmuView provides a basic editor to edit and run scripts. Here you can use the\nkeyboard shortcuts kbd:[Ctrl+S] to save the current file and kbd:[Ctrl+F] to open\nthe search and replace dialog.\n\nimage::SmuScript.png[]\n\nimage:numbers/1.png[1,22,22] Directory tree. +\nimage:numbers/2.png[2,22,22] Script editor. +\nimage:numbers/3.png[3,22,22] Script output. +\nimage:numbers/4.png[4,22,22] Create a new script. +\nimage:numbers/5.png[5,22,22] Open the selected script file. +\nimage:numbers/6.png[6,22,22] Execute the selected script file. +\nimage:numbers/7.png[7,22,22] Open new script file. +\nimage:numbers/8.png[8,22,22] Save script file. +\nimage:numbers/9.png[9,22,22] Save script file with a new name. +\nimage:numbers/10.png[10,22,22] Execute script file. +\nimage:numbers/11.png[11,22,22] Open Search & Replace dialog. +\nimage:numbers/12.png[11,22,22] Scroll to bottom. +\nimage:numbers/13.png[11,22,22] Clear output window.\n\nSmuScripts can also be started on startup, using the command line parameter\n`-s`:\n[listing, subs=\"normal\"]\nsmuview -s /path/to/script.py\n\n=== Examples\n\nThe following short example connects the HP 3478A DMM via GPIB, reads a sample\nand creates the default tab for the device:\n\n[source,python]\n----\nimport smuview\nimport time\n\n# Connect device.\ndmm_dev = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\n# Sleep 1s to give the devices the chance to create signals\ntime.sleep(1)\n# Get last sample from channel P1\nsample = dmm_dev.channels()[\"P1\"].actual_signal().get_last_sample(True)\nprint(sample)\n\n# Add default tab for the DMM device.\nUiProxy.add_device_tab(dmm_dev)\n----\n\nThe following more complex example script from the `smuscript` folder\ncharacterizes a battery and plots the resulting graph:\n\n.example_characterize_battery.py\n[source,python]\n----\nimport smuview\nimport time\n\n# Connect devices\nload_device = Session.connect_device(\"arachnid-labs-re-load-pro:conn=/dev/ttyUSB1\")[0]\nload_conf = load_device.configurables()[\"1\"]\ndmm_device = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\ndmm_conf = dmm_device.configurables()[\"\"]\n\n# Init device settings\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\ndmm_conf.set_config(smuview.ConfigKey.MeasuredQuantity, smuview.Quantity.Voltage)\n\n# Give the devices the chance to create signals\ntime.sleep(1)\n\n# Add user device\nuser_device = Session.add_user_device()\n# Add channel for measurement values\nuser_device.add_user_channel(\"Results\", \"User\")\nresult_ch = user_device.channels()[\"Results\"]\n\n# Show device tabs and add plot to user device\nUiProxy.add_device_tab(load_device)\nUiProxy.add_device_tab(dmm_device)\nUiProxy.add_device_tab(user_device)\nUiProxy.add_plot_view(user_device.id(), smuview.DockArea.BottomDockArea, result_ch)\n\n# Start test\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .150)\n\n# Drain the battery until it is below 0.5 Volt\nvalue = 100\nwhile value > 0.5:\n    # Take a reading every 2s and write it to the user channel\n    time_stamp = time.time()\n    value = dmm_device.channels()[\"P1\"].actual_signal().get_last_sample(True)[1]\n    result_ch.push_sample(value, time_stamp, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 6, 5)\n    time.sleep(2)\n\n# Set device settings to a save state\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\n----\n"
  },
  {
    "path": "signalhandler.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Adam Reichold\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <csignal>\n#include <cstdlib>\n\n#include <sys/socket.h>\n#include <unistd.h>\n\n#include <QDebug>\n#include <QSocketNotifier>\n\n#include \"signalhandler.hpp\"\n\nint SignalHandler::sockets_[2];\n\nbool SignalHandler::prepare_signals()\n{\n\tif (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets_) != 0)\n\t\treturn false;\n\n\tstruct sigaction sig_action;\n\n\tsig_action.sa_handler = SignalHandler::handle_signals;\n\tsigemptyset(&sig_action.sa_mask);\n\tsig_action.sa_flags = SA_RESTART;\n\n\tif (sigaction(SIGINT, &sig_action, nullptr) != 0 ||\n\t\tsigaction(SIGTERM, &sig_action, nullptr) != 0) {\n\t\tclose(sockets_[0]);\n\t\tclose(sockets_[1]);\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nSignalHandler::SignalHandler(QObject* parent) : QObject(parent),\n\tsocket_notifier_(nullptr)\n{\n\tsocket_notifier_ = new QSocketNotifier(sockets_[1],\n\t\tQSocketNotifier::Read, this);\n\tconnect(socket_notifier_, &QSocketNotifier::activated,\n\t\tthis, &SignalHandler::on_socket_notifier_activated);\n}\n\nvoid SignalHandler::on_socket_notifier_activated()\n{\n\tsocket_notifier_->setEnabled(false);\n\n\tint sig_number;\n\tif (read(sockets_[1], &sig_number, sizeof(int)) != sizeof(int)) {\n\t\tqDebug() << \"Failed to catch signal\";\n\t\tabort();\n\t}\n\n\tswitch (sig_number) {\n\tcase SIGINT:\n\t\tQ_EMIT int_received();\n\t\tbreak;\n\tcase SIGTERM:\n\t\tQ_EMIT term_received();\n\t\tbreak;\n\t}\n\n\tsocket_notifier_->setEnabled(true);\n}\n\nvoid SignalHandler::handle_signals(int sig_number)\n{\n\tif (write(sockets_[0], &sig_number, sizeof(int)) != sizeof(int)) {\n\t\t// Failed to handle signal\n\t\tabort();\n\t}\n}\n"
  },
  {
    "path": "signalhandler.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Adam Reichold\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SIGNALHANDLER_H\n#define SIGNALHANDLER_H\n\n#include <QObject>\n\nclass QSocketNotifier;\n\nclass SignalHandler : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tstatic bool prepare_signals();\n\npublic:\n\texplicit SignalHandler(QObject* parent = nullptr);\n\nQ_SIGNALS:\n\tvoid int_received();\n\tvoid term_received();\n\nprivate Q_SLOTS:\n\tvoid on_socket_notifier_activated();\n\nprivate:\n\tstatic void handle_signals(int sig_number);\n\nprivate:\n\tQSocketNotifier* socket_notifier_;\n\nprivate:\n\tstatic int sockets_[2];\n};\n\n#endif // SIGNALHANDLER_H\n"
  },
  {
    "path": "smuscript/example_characterize_battery.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Connect devices\nload_device = Session.connect_device(\"arachnid-labs-re-load-pro:conn=/dev/ttyUSB1\")[0]\nload_conf = load_device.configurables()[\"1\"]\ndmm_device = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\ndmm_conf = dmm_device.configurables()[\"\"]\n\n# Init device settings\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\ndmm_conf.set_config(smuview.ConfigKey.MeasuredQuantity, (smuview.Quantity.Voltage, {smuview.QuantityFlag.DC}))\n\n# Give the devices the chance to create signals\ntime.sleep(1)\n\n# Add user device\nuser_device = Session.add_user_device()\n# Add channel for measurement values\nuser_device.add_user_channel(\"Results\", \"User\")\nresult_ch = user_device.channels()[\"Results\"]\n\n# Show device tabs and add plot to user device\nUiProxy.add_device_tab(load_device)\nUiProxy.add_device_tab(dmm_device)\nuser_device_tab = UiProxy.add_device_tab(user_device)\nplot = UiProxy.add_time_plot_view(user_device_tab, smuview.DockArea.BottomDockArea)\nUiProxy.set_channel_to_time_plot_view(user_device_tab, plot, result_ch)\n\n# Start test\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .150)\n\n# Drain the battery until it is below 0.5 Volt\nvalue = 100\nwhile value > 0.5:\n    # Take a reading every 2s and write it to the user channel\n    time_stamp = time.time()\n    value = dmm_device.channels()[\"P1\"].actual_signal().get_last_sample(True)[1]\n    result_ch.push_sample(value, time_stamp, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 6, 5)\n    time.sleep(2)\n\n# Set device settings to a save state\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\n"
  },
  {
    "path": "smuscript/example_characterize_psu.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Connect all devices\nload_dev = Session.connect_device(\"arachnid-labs-re-load-pro:conn=/dev/ttyUSB2\")[0]\nload_conf = load_dev.configurables()[\"1\"]\npsu_dev = Session.connect_device(\"scpi-pps:conn=libgpib/hp6632b\")[0]\npsu_conf = psu_dev.configurables()[\"1\"]\ndmm_dev = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\ndmm_conf = dmm_dev.configurables()[\"\"]\n\n# Init device settings\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\npsu_conf.set_config(smuview.ConfigKey.VoltageTarget, 10.0)\npsu_conf.set_config(smuview.ConfigKey.CurrentLimit, 2.000)\npsu_conf.set_config(smuview.ConfigKey.Enabled, True)\ndmm_conf.set_config(smuview.ConfigKey.MeasuredQuantity, (smuview.Quantity.Current, {smuview.QuantityFlag.DC}))\n\n# Sleep 1s to give the devices the chance to create signals\ntime.sleep(1)\n\n# Add user device and result channels/signals\nuser_dev = Session.add_user_device()\np_in_ch = user_dev.add_user_channel(\"P_in\", \"User\")\np_in_sig = p_in_ch.add_signal(smuview.Quantity.Power, set(), smuview.Unit.Watt)\np_out_ch = user_dev.add_user_channel(\"P_out\", \"User\")\np_out_sig = p_out_ch.add_signal(smuview.Quantity.Power, set(), smuview.Unit.Watt)\neff_ch = user_dev.add_user_channel(\"eff\", \"User\")\neff_sig = eff_ch.add_signal(smuview.Quantity.PowerFactor, set(), smuview.Unit.Percentage)\n\n# Show device tabs and plots\nUiProxy.add_device_tab(load_dev)\nUiProxy.add_device_tab(psu_dev)\nUiProxy.add_device_tab(dmm_dev)\nuser_dev_tab = UiProxy.add_device_tab(user_dev)\np_plot = UiProxy.add_plot_view(user_dev_tab, smuview.DockArea.TopDockArea)\nUiProxy.add_curve_to_time_plot(user_dev_tab, p_plot, p_in_sig)\nUiProxy.add_curve_to_time_plot(user_dev_tab, p_plot, p_out_sig)\nxy_plot = UiProxy.add_xy_plot_view(user_dev_tab, smuview.DockArea.TopDockArea)\nUiProxy.add_curve_to_xy_plot_view(user_dev_tab, xy_plot, p_out_sig, eff_sig)\n\nd = .0\nwhile d <= 2.0:\n    load_conf.set_config(smuview.ConfigKey.CurrentLimit, d)\n    time.sleep(0.5)\n    u_in = psu_dev.channels()[\"V1\"].actual_signal().get_last_sample(True)[1]\n    i_in = dmm_dev.channels()[\"P1\"].actual_signal().get_last_sample(True)[1]\n    power_in = u_in * i_in\n    u_out = load_dev.channels()[\"V\"].actual_signal().get_last_sample(True)[1]\n    i_out = load_dev.channels()[\"I\"].actual_signal().get_last_sample(True)[1]\n    # MathChannels are not in the python bindings yet, so we have to calculate by our own.\n    power_out = u_out * i_out\n    eff = (power_out / power_in) * 100\n    ts = time.time()\n    p_in_ch.push_sample(power_in, ts, smuview.Quantity.Power, set(), smuview.Unit.Watt, 6, 3)\n    p_out_ch.push_sample(power_out, ts, smuview.Quantity.Power, set(), smuview.Unit.Watt, 6, 3)\n    eff_ch.push_sample(eff, ts, smuview.Quantity.PowerFactor, set(), smuview.Unit.Percentage, 6, 3)\n    d += 0.005\n\n# Set values to a save state\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\npsu_conf.set_config(smuview.ConfigKey.Enabled, False)\n"
  },
  {
    "path": "smuscript/example_characterize_psu_2.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Test settings:\ninput_voltages = [8.0, 14.0, 20.0]\ninput_colors = [(255, 0, 0), (255, 128, 0), (255, 255, 0)]\nmax_current = 2.0\nstart_current = 0.01\ncurrent_steps = 0.005\n\n\n# Connect all devices\nload_dev = Session.connect_device(\"arachnid-labs-re-load-pro:conn=/dev/ttyUSB2\")[0]\nload_conf = load_dev.configurables()[\"1\"]\npsu_dev = Session.connect_device(\"scpi-pps:conn=libgpib/hp6632b\")[0]\npsu_conf = psu_dev.configurables()[\"1\"]\ndmm_dev = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\ndmm_conf = dmm_dev.configurables()[\"\"]\n\n# Init device settings\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\npsu_conf.set_config(smuview.ConfigKey.VoltageTarget, .0)\npsu_conf.set_config(smuview.ConfigKey.CurrentLimit, max_current)\npsu_conf.set_config(smuview.ConfigKey.Enabled, True)\ndmm_conf.set_config(smuview.ConfigKey.MeasuredQuantity, (smuview.Quantity.Current, {smuview.QuantityFlag.DC}))\n\n# Sleep 1s to give the devices the chance to create signals\ntime.sleep(1)\n\n# Add user device and result channels/signals\nuser_dev = Session.add_user_device()\np_in_ch = user_dev.add_user_channel(\"P_in\", \"User\")\np_in_sig = p_in_ch.add_signal(smuview.Quantity.Power, set(), smuview.Unit.Watt)\np_out_ch = user_dev.add_user_channel(\"P_out\", \"User\")\np_out_sig = p_out_ch.add_signal(smuview.Quantity.Power, set(), smuview.Unit.Watt)\neff_ch = user_dev.add_user_channel(\"eff\", \"User\")\n\n# Show device tabs and plots\nUiProxy.add_device_tab(load_dev)\nUiProxy.add_device_tab(psu_dev)\nUiProxy.add_device_tab(dmm_dev)\nuser_dev_tab = UiProxy.add_device_tab(user_dev)\np_plot = UiProxy.add_time_plot_view(user_dev_tab, smuview.DockArea.TopDockArea)\nUiProxy.add_curve_to_time_plot_view(user_dev_tab, p_plot, p_in_sig)\nUiProxy.add_curve_to_time_plot_view(user_dev_tab, p_plot, p_out_sig)\nxy_plot = UiProxy.add_xy_plot_view(user_dev_tab, smuview.DockArea.TopDockArea)\n\nfor n in range(len(input_voltages)):\n    u_in_set = input_voltages[n]\n    eff_sig = eff_ch.add_signal(smuview.Quantity.PowerFactor, set(), smuview.Unit.Percentage, \"eff@{}V\".format(str(u_in_set)))\n    curve = UiProxy.add_curve_to_xy_plot_view(user_dev_tab, xy_plot, p_out_sig, eff_sig)\n    UiProxy.set_curve_name(user_dev_tab, xy_plot, curve, \"V_in = {}V\".format(str(u_in_set)))\n    UiProxy.set_curve_color(user_dev_tab, xy_plot, curve, input_colors[n])\n    load_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\n    psu_conf.set_config(smuview.ConfigKey.VoltageTarget, u_in_set)\n    # Wait for 10 s to let the DUT cool down\n    time.sleep(10)\n    current = start_current\n    while current <= max_current:\n        load_conf.set_config(smuview.ConfigKey.CurrentLimit, current)\n        time.sleep(0.5)\n        u_in = psu_dev.channels()[\"V1\"].actual_signal().get_last_sample(True)[1]\n        i_in = dmm_dev.channels()[\"P1\"].actual_signal().get_last_sample(True)[1]\n        power_in = u_in * i_in\n        u_out = load_dev.channels()[\"V\"].actual_signal().get_last_sample(True)[1]\n        i_out = load_dev.channels()[\"I\"].actual_signal().get_last_sample(True)[1]\n        # MathChannels are not in the python bindings yet, so we have to calculate by our own.\n        power_out = u_out * i_out\n        eff = (power_out / power_in) * 100\n        ts = time.time()\n        p_in_ch.push_sample(power_in, ts, smuview.Quantity.Power, set(), smuview.Unit.Watt, 6, 3)\n        p_out_ch.push_sample(power_out, ts, smuview.Quantity.Power, set(), smuview.Unit.Watt, 6, 3)\n        eff_ch.push_sample(eff, ts, smuview.Quantity.PowerFactor, set(), smuview.Unit.Percentage, 6, 3)\n        current += current_steps\n\n# Set values to a save state\nload_conf.set_config(smuview.ConfigKey.CurrentLimit, .0)\npsu_conf.set_config(smuview.ConfigKey.VoltageTarget, .0)\npsu_conf.set_config(smuview.ConfigKey.Enabled, False)\n"
  },
  {
    "path": "smuscript/example_device_properties.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\n\n# Get all connected devices from the session\ndevices = Session.devices()\n\n# Iterate over all devices and print all properties\nfor deviceId in devices:\n    device = devices[deviceId]\n    print(\"\")\n    print(\"device   = \" + device.name())\n    print(\"deviceId = \" + deviceId)\n\n    configurables = device.configurables()\n    for configruableId in configurables:\n        configurable = configurables[configruableId]\n        print(\"\")\n        print(\"  configurable   = \" + configurable.name())\n        print(\"  configurableId = \" + configruableId)\n\n        print(\"\")\n        print(\"    Getable ConfigKeys:\")\n        config_keys = configurable.getable_configs()\n        for config_key in config_keys:\n            data_type = smuview.ConfigKey.get_data_type(config_key)\n            if data_type == smuview.DataType.Double:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_double_config(config_key), data_type.name))\n            elif data_type == smuview.DataType.Int32:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_int_config(config_key), data_type.name))\n            elif data_type == smuview.DataType.UInt64:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_uint_config(config_key), data_type.name))\n            elif data_type == smuview.DataType.String:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_string_config(config_key), data_type.name))\n            elif data_type == smuview.DataType.Bool:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_bool_config(config_key), data_type.name))\n            elif data_type == smuview.DataType.MQ:\n                print(\"      {} = {} ({})\".format(config_key.name, configurable.get_measured_quantity_config(config_key), data_type.name))\n            else:\n                print(\"      {} = ?? ({})\".format(config_key.name, data_type.name))\n\n        print(\"\")\n        print(\"    Setable ConfigKeys:\")\n        config_keys = configurable.setable_configs()\n        for config_key in config_keys:\n            data_type = smuview.ConfigKey.get_data_type(config_key)\n            print(\"      {} ({})\".format(config_key.name, data_type.name))\n\n        print(\"\")\n        print(\"    Listable ConfigKeys:\")\n        config_keys = configurable.listable_configs()\n        for config_key in config_keys:\n            data_type = smuview.ConfigKey.get_data_type(config_key)\n            print(\"      {} ({})\".format(config_key.name, data_type.name))\n\n    channels = device.channels()\n    for channelId in channels:\n        channel = channels[channelId]\n        print(\"\")\n        print(\"  channel   = \" + channel.name())\n        print(\"  channelId = \" + channelId)\n\n        actual_signal = channel.actual_signal()\n        if actual_signal != None:\n            print(\"\")\n            print(\"    actual_signal   = \" + actual_signal.name())\n            print(\"      sample_count  = {}\".format(actual_signal.sample_count()))\n            print(\"      get_sample(1) = {}\".format(actual_signal.get_sample(1, True)))\n            print(\"      last_sample   = {}\".format(actual_signal.get_last_sample(True)))\n\n        signals = channel.signals()\n        for signal in signals:\n            print(\"\")\n            print(\"    signal          = \" + signal.name())\n            print(\"      sample_count  = {}\".format(signal.sample_count()))\n            print(\"      get_sample(1) = {}\".format(signal.get_sample(1, True)))\n            print(\"      last_sample   = {}\".format(signal.get_last_sample(True)))\n"
  },
  {
    "path": "smuscript/example_multiplexer.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Connect device\nmux_device = Session.connect_device(\"hp-59306a:conn=libgpib/hp59306a\")[0]\n\n# Show device tabs and add plot to user device\nUiProxy.add_device_tab(mux_device)\n\n# Start test\nenabled = True\nfor i in range(6):\n    for ch_idx in range(6):\n        channel_group = \"CH{}\".format(ch_idx+1)\n        mux_device.configurables()[channel_group].set_config(smuview.ConfigKey.Enabled, enabled)\n        time.sleep(1)\n    enabled = not enabled\n"
  },
  {
    "path": "smuscript/example_ui.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\nprint(\"TEST UI\")\nprint(\"=======\")\nprint(\"\")\n\n# Connect the demo device (it's just one!)\ndemo_dev = Session.connect_device(\"demo\")[0]\nprint(\"New demo device = \" + demo_dev.id())\n\n# Add a user device\nuser_dev = Session.add_user_device()\n\n# Show tab for demo device\ndemo_dev_tab = UiProxy.add_device_tab(demo_dev)\nprint(\"New device tab (1) = \" + demo_dev_tab)\n\n# Show 2nd tab for demo device\ndemo_dev_tab_2 = UiProxy.add_device_tab(demo_dev)\nprint(\"New device tab (2) = \" + demo_dev_tab_2)\n\n# Show tab for user device\nuser_dev_tab = UiProxy.add_device_tab(user_dev)\nprint(\"New user tab = \" + user_dev_tab)\n\n# Sleep 1 second to give the newly connected demo device the chance to create data and the corresponding signals. TODO\ntime.sleep(1)\n\n# Add a data view to the device tab\ndata_view = UiProxy.add_data_view(user_dev_tab, smuview.DockArea.TopDockArea, demo_dev.channels()[\"A1\"].actual_signal())\nprint(\"New data view = \" + data_view)\n# Add a signal to the existing data view\nUiProxy.add_signal_to_data_view(user_dev_tab, data_view, demo_dev.channels()[\"A3\"].actual_signal())\n\n# Add the (generic) control view to the device tab\ncontrol_views_1 = UiProxy.add_control_views(user_dev_tab, smuview.DockArea.TopDockArea, demo_dev.configurables()[\"\"])\nprint(\"New control views (1) = {}\".format(control_views_1))\n\n# Add the demo control view to the device tab\ncontrol_views_2 = UiProxy.add_control_views(user_dev_tab, smuview.DockArea.TopDockArea, demo_dev.configurables()[\"A1\"])\nprint(\"New control views (2) = {}\".format(control_views_2))\n\n# Add a time plot view (1) to the device tab\ntime_plot_view_1 = UiProxy.add_time_plot_view(user_dev_tab, smuview.DockArea.BottomDockArea)\nprint(\"New time plot view (1) = \" + time_plot_view_1)\n# Set a channel to time plot view (1)\nUiProxy.set_channel_to_time_plot_view(user_dev_tab, time_plot_view_1, demo_dev.channels()[\"A1\"])\n\n# Add a time plot view (2) to the device tab\ntime_plot_view_2 = UiProxy.add_time_plot_view(user_dev_tab, smuview.DockArea.BottomDockArea)\nprint(\"New time plot view (2) = \" + time_plot_view_2)\n# Add a curve (1) to the time plot view (2)\ncurve_1 = UiProxy.add_curve_to_time_plot_view(user_dev_tab, time_plot_view_2, demo_dev.channels()[\"A2\"].actual_signal())\nprint(\"New curve (1) = \" + curve_1)\nUiProxy.set_curve_color(user_dev_tab, time_plot_view_2, curve_1, (255, 0, 255))\n# Add a curve (2) to the time plot view (2)\ncurve_2 = UiProxy.add_curve_to_time_plot_view(user_dev_tab, time_plot_view_2, demo_dev.channels()[\"A3\"].actual_signal())\nprint(\"New curve (2) = \" + curve_2)\nUiProxy.set_curve_color(user_dev_tab, time_plot_view_2, curve_2, (0, 255, 0))\n\n# Add a x/y plot view to the device tab\nxy_plot_view = UiProxy.add_xy_plot_view(user_dev_tab, smuview.DockArea.BottomDockArea)\nprint(\"New x/y plot view = \" + xy_plot_view)\n# Add a curve (3) to the existing x/y plot view\ncurve_3 = UiProxy.add_curve_to_xy_plot_view(user_dev_tab, xy_plot_view, demo_dev.channels()[\"A1\"].actual_signal(), demo_dev.channels()[\"A2\"].actual_signal())\nprint(\"New curve (3) = \" + curve_3)\nUiProxy.set_curve_color(user_dev_tab, xy_plot_view, curve_3, (255, 255, 0))\n# Add a curve (4) to the existing x/y plot view\ncurve_4 = UiProxy.add_curve_to_xy_plot_view(user_dev_tab, xy_plot_view, demo_dev.channels()[\"A0\"].actual_signal(), demo_dev.channels()[\"A3\"].actual_signal())\nprint(\"New curve (4) = \" + curve_4)\nUiProxy.set_curve_color(user_dev_tab, xy_plot_view, curve_4, (0, 255, 255))\n\n# Add a power panel view to the device tab\npower_panel_view = UiProxy.add_power_panel_view(user_dev_tab, smuview.DockArea.BottomDockArea, demo_dev.channels()[\"A1\"].actual_signal(), demo_dev.channels()[\"A2\"].actual_signal())\nprint(\"New powerpanel view = \" + power_panel_view)\n\n# Add a value panel view to the device tab\nvalue_panel_view_1 = UiProxy.add_value_panel_view(user_dev_tab, smuview.DockArea.TopDockArea, demo_dev.channels()[\"A1\"])\nprint(\"New valuepanel view (1) = \" + value_panel_view_1)\n\n# Add a value panel view to the device tab\nvalue_panel_view_2 = UiProxy.add_value_panel_view(user_dev_tab, smuview.DockArea.TopDockArea, demo_dev.channels()[\"A1\"].actual_signal())\nprint(\"New valuepanel view (2) = \" + value_panel_view_2)\n\n# Message box\nmsg_ret = UiProxy.show_message_box(\"Message Box\", \"This is a message box. The script will wait, until you press OK.\")\nif msg_ret:\n    print(\"MessageBox: Was closed!\")\nelse:\n    print(\"MessageBox: Was canceled!\")\n\n# String input\ns_input = UiProxy.show_string_input_dialog(\"Text Input\", \"Please enter a text:\")\nif s_input != None:\n    print(\"StringInputDlg: \" + s_input)\nelse:\n    print(\"StringInputDlg: Was canceled!\")\n\n# Double input\nd_input = UiProxy.show_double_input_dialog(\"Double Input\", \"Please enter a double number:\")\nif d_input != None:\n    print(\"DoubleInputDlg: {}\".format(d_input))\nelse:\n    print(\"DoubleInputDlg: Was canceled!\")\n\n# Int input\ni_input = UiProxy.show_int_input_dialog(\"Integer Input\", \"Please enter an integer number:\")\nif i_input != None:\n    print(\"IntInputDlg: {}\".format(i_input))\nelse:\n    print(\"IntInputDlg: Was canceled!\")\n\nprint(\"\")\n"
  },
  {
    "path": "smuscript/example_user_channel.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\nfrom math import sin\n\n# Add user device\nuser_device = Session.add_user_device()\n# Add a user channel for measurement values to user device\nuser_device.add_user_channel(\"Results\", \"User\")\nresult_ch = user_device.channels()[\"Results\"]\n\n# Show tab for the user device\nuser_device_tab = UiProxy.add_device_tab(user_device)\n# Add a time plot view.\nplot = UiProxy.add_time_plot_view(user_device_tab, smuview.DockArea.TopDockArea)\n# We don't have to wait for the signal to be created, because we are using the channel here.\nUiProxy.set_channel_to_time_plot_view(user_device_tab, plot, user_device.channels()[\"Results\"])\n\n# Fill the user channel with some data\nprint(\"Starting loop...\")\ni = 0\nwhile i<10000:\n    ts = time.time()\n    result_ch.push_sample(sin(i), ts, smuview.Quantity.Power, set(), smuview.Unit.Watt, 6, 3)\n    print(\"  new value = {}\".format(result_ch.actual_signal().get_last_sample(True)[1]))\n    time.sleep(0.25)\n    i = i + 0.1\n"
  },
  {
    "path": "smuscript/generate_documentation.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport sys\nimport pydoc\nimport pdoc\nimport re\n\n#\n# pydoc\n#\n# pydoc is Pythons build in documentation generator and online help system\n#\n\n# Write to text file\n#file_name = './smuview_python_bindings_pydoc.txt'\n#with open(file_name, mode='w') as f:\n#    sys.stdout = f\n#    pydoc.help(smuview)\n#sys.stdout = sys.__stdout__\n\n# Write html file to current directory\n#pydoc.writedoc(smuview)\n\n\n#\n# pdoc3\n#\n# Install:\n#   $ pip3 install pdoc3\n#\n\nhtml_str = pdoc.html(\"smuview\", show_type_annotations=True)\nfile_name = './smuview_python_bindings_pdoc3.html'\nwith open(file_name, mode='w') as f:\n    print(html_str, file=f)\n\n\n#\n# pdoc\n#\n# Install:\n#   $ pip3 install pdoc\n#\n\n#html_str = pdoc.pdoc(\"smuview\")\n#file_name = './smuview_python_bindings_pdoc.html'\n#with open(file_name, mode='w') as f:\n#    print(html_str, file=f)\n\n# Test for setting a custom doxstring to enum values\n#doc = pdoc.doc.Module(smuview)\n#doc.get(\"ConfigKey.Samplerate\").docstring = \"I'm a docstring for ConfigKey.Samplerate\"\n#with open(\"docs.html\", \"w\") as f:\n#    f.write(pdoc.render.html_module(module=doc, all_modules=[\"smuview\"]))\n"
  },
  {
    "path": "smuscript/python_version.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport sys\n\nprint(sys.version)\n"
  },
  {
    "path": "smuscript/test_combine_signals.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\n#\n# Script to test AnalogTimeSignal::combine_signals()\n# TODO: Implement as unit test!\n#\n\nimport time\nimport smuview\n\n# Add user device and tab\nuser_device = Session.add_user_device()\ntab = UiProxy.add_device_tab(user_device)\n\n\n# Test to reproduce the bug fixed in PR #30\ndef test_pr30():\n    start_ts = time.time()\n\n    #  Add 2 channels\n    ch1 = user_device.add_user_channel(\"CH1\", \"Test_PR30\")\n    ch2 = user_device.add_user_channel(\"CH2\", \"Test_PR30\")\n\n    # Push initial sample data\n    ch1.push_sample(1, start_ts+1, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(2, start_ts+3, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(10, start_ts+4, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n    # Add a xy-plot to get AnalogTimeSignal::combine_signals() called and force the error.\n    # Without the fix from PR #30 SmuView will get stuck in an infinite loop!\n    plot = UiProxy.add_xy_plot_view(tab, smuview.DockArea.TopDockArea)\n    curve = UiProxy.add_curve_to_xy_plot_view(tab, plot, ch1.actual_signal(), ch2.actual_signal())\n\n    # Push more data\n    ch1.push_sample(3, start_ts+5, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(9, start_ts+6, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n\n# Test with an empty signal\ndef test_empty():\n    start_ts = time.time()\n\n    #  Add and prime 2 channels\n    ch1 = user_device.add_user_channel(\"CH1\", \"Test_Empty\")\n    ch1.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n    ch2 = user_device.add_user_channel(\"CH2\", \"Test_Empty\")\n    ch2.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n\n    # Push initial sample data\n    ch1.push_sample(1, start_ts+1, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(2, start_ts+3, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n    # Add a xy-plot to call AnalogTimeSignal::combine_signals()\n    plot = UiProxy.add_xy_plot_view(tab, smuview.DockArea.TopDockArea)\n    curve = UiProxy.add_curve_to_xy_plot_view(tab, plot, ch1.actual_signal(), ch2.actual_signal())\n\n    # Push more data\n    ch1.push_sample(3, start_ts+5, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(10, start_ts+6, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n\n# Test for improved AnalogTimeSignal::combine_signals()\ndef test_improved1():\n    start_ts = time.time()\n\n    #  Add 2 channels\n    ch1 = user_device.add_user_channel(\"CH1\", \"Test_Improve\")\n    ch1.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n    ch2 = user_device.add_user_channel(\"CH2\", \"Test_Improve\")\n    ch2.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n\n    # Push initial sample data\n    ch1.push_sample(1, start_ts+1, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(2, start_ts+3, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(3, start_ts+5, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n    # Add a xy-plot to call AnalogTimeSignal::combine_signals()\n    plot = UiProxy.add_xy_plot_view(tab, smuview.DockArea.TopDockArea)\n    curve = UiProxy.add_curve_to_xy_plot_view(tab, plot, ch1.actual_signal(), ch2.actual_signal())\n\n    # Push more data\n    ch1.push_sample(4, start_ts+7, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(10, start_ts+8, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch1.push_sample(5, start_ts+9, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(9, start_ts+10, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch1.push_sample(6, start_ts+11, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(8, start_ts+12, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch1.push_sample(7, start_ts+13, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(7, start_ts+14, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch1.push_sample(8, start_ts+15, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(6, start_ts+16, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(5, start_ts+18, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch2.push_sample(4, start_ts+20, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    time.sleep(1)\n    ch1.push_sample(9, start_ts+17, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n\n# Another test for improved AnalogTimeSignal::combine_signals()\n#\n# Time | S1 | S2 | combined S1 | combined S1 |\n# --------------------------------------------\n#    1 |  1 |    |             |             |\n#    3 |  2 |    |             |             |\n#    5 |  3 |    |             |             |\n#    6 |    | 10 |         3.5 |          10 |\n#    7 |  4 |    |           4 |         9.5 |\n#    8 |    |  9 |         4.5 |           9 |\n#    9 |  5 |    |           5 |         8.5 |\n#   10 |    |  8 |             |             |\n#   12 |    |  7 |             |             |\n#\ndef test_improved2():\n    start_ts = time.time()\n\n    #  Add 2 channels\n    ch1 = user_device.add_user_channel(\"CH1\", \"Test_Improve\")\n    ch1.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n    ch2 = user_device.add_user_channel(\"CH2\", \"Test_Improve\")\n    ch2.add_signal(smuview.Quantity.Voltage, set(), smuview.Unit.Volt)\n\n    # Push initial sample data\n    ch1.push_sample(1, start_ts+1, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(2, start_ts+3, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(3, start_ts+5, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(10, start_ts+6, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(4, start_ts+7, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(9, start_ts+8, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch1.push_sample(5, start_ts+9, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(8, start_ts+10, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n    ch2.push_sample(7, start_ts+12, smuview.Quantity.Voltage, set(), smuview.Unit.Volt, 4, 2)\n\n    # Add a xy-plot to call AnalogTimeSignal::combine_signals()\n    plot = UiProxy.add_xy_plot_view(tab, smuview.DockArea.TopDockArea)\n    curve = UiProxy.add_curve_to_xy_plot_view(tab, plot, ch1.actual_signal(), ch2.actual_signal())\n\n# Call tests\ntest_pr30()\ntest_empty()\ntest_improved1()\ntest_improved2()\n"
  },
  {
    "path": "smuscript/test_fixed_channel.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Connect a device with a fixed channel\ndevice = Session.connect_device(\"arachnid-labs-re-load-pro:conn=/dev/ttyUSB2\")[0]\nchannel_name = \"V\"\n# Connect a device with no fixed channels\n#device = Session.connect_device(\"hp-3478a:conn=libgpib/hp3478a\")[0]\n#channel_name = \"P1\"\n\n# Don't give the devices a chance to create a (non fixed) signal by receiving samples\nsignal = device.channels()[channel_name].actual_signal()\n\n# Read signals from a fixed channel. This will only work for fixed channels!\nprint(\"signal.sample_count() = {0}\".format(signal.sample_count()))\nprint(\"signal.get_last_sample() = {0}\".format(signal.get_last_sample(True)))\n\n# Sleep 1s to give the devices a chance to receive some samples\ntime.sleep(1)\n\n# Read signals from channel\nprint(\"signal.sample_count() = {0}\".format(signal.sample_count()))\nprint(\"signal.get_last_sample() = {0}\".format(signal.get_last_sample(True)))\n\nSession.remove_device(device)\n"
  },
  {
    "path": "smuscript/test_rnd_crashes.py",
    "content": "# This file is part of the SmuView project.\n#\n# Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nimport smuview\nimport time\n\n# Connect the demo device (it's just one!)\ndemo_dev = devices = Session.connect_device(\"demo\")[0]\n\n# Show tab for demo device\nUiProxy.add_device_tab(demo_dev)\n\n# Sleep 1 second to give the newly connected demo device the chance to create data and the corresponding signals. TODO\ntime.sleep(1)\n\n# Get device id of the demo device\ndemo_dev_id = demo_dev.id()\n\n# Get BaseTab for the demo device\n#demo_dev_tab = UiProxy.get_base_tab_from_device_id(demo_dev_id);\n\n# Add a data view to the device tab\nUiProxy.add_data_view(demo_dev_id, smuview.DockArea.TopDockArea, demo_dev.channels()[\"A1\"].actual_signal())\n\n# Sleep 3 sec to finish the adding of the view in the MainThread, otherwise SmuView will crash... TODO\n#time.sleep(3)\n"
  },
  {
    "path": "smuview.kdev4",
    "content": "[Project]\nName=smuview\nManager=KDevCMakeManager\n"
  },
  {
    "path": "smuview.qrc",
    "content": "<RCC>\n\t<qresource prefix=\"/\">\n\t\t<file>icons/smuview.ico</file>\n\t\t<file>icons/smuview.png</file>\n\t\t<file>icons/smuview.svg</file>\n\n\t\t<file>icons/status-green.svg</file>\n\t\t<file>icons/status-grey.svg</file>\n\t\t<file>icons/status-red.svg</file>\n\n\t\t<file>icons/chronometer.png</file>\n\t\t<file>icons/configure.png</file>\n\t\t<file>icons/document-new.png</file>\n\t\t<file>icons/document-open-folder.png</file>\n\t\t<file>icons/document-open.png</file>\n\t\t<file>icons/document-save-as.png</file>\n\t\t<file>icons/document-save.png</file>\n\t\t<file>icons/edit-delete.png</file>\n\t\t<file>icons/edit-find.png</file>\n\t\t<file>icons/edit-table-delete-row.png</file>\n\t\t<file>icons/edit-table-insert-row-under.png</file>\n\t\t<file>icons/go-bottom.png</file>\n\t\t<file>icons/help-about.png</file>\n\t\t<file>icons/list-add.png</file>\n\t\t<file>icons/list-remove.png</file>\n\t\t<file>icons/media-playback-pause.png</file>\n\t\t<file>icons/media-playback-start.png</file>\n\t\t<file>icons/media-playback-stop.png</file>\n\t\t<file>icons/mixer-front.png</file>\n\t\t<file>icons/object-locked.png</file>\n\t\t<file>icons/object-unlocked.png</file>\n\t\t<file>icons/office-chart-area.png</file>\n\t\t<file>icons/office-chart-line-percentage.png</file>\n\t\t<file>icons/office-chart-line.png</file>\n\t\t<file>icons/preferences-system.png</file>\n\t\t<file>icons/snap-guideline.png</file>\n\t\t<file>icons/snap-orthogonal.png</file>\n\t\t<file>icons/tab-new-background.png</file>\n\t\t<file>icons/view-form-table.png</file>\n\t\t<file>icons/view-refresh.png</file>\n\t\t<file>icons/window-new.png</file>\n\t\t<file>icons/zoom-fit-best.png</file>\n\t\t<file>icons/zoom-in.png</file>\n\t\t<file>icons/zoom-original.png</file>\n\t\t<file>icons/zoom-out.png</file>\n\n\t\t<file>icons/channels.svg</file>\n\t\t<file>icons/information.svg</file>\n\t\t<file>icons/menu.svg</file>\n\t\t<file>icons/settings-views.svg</file>\n\n\t\t<!-- Fonts -->\n\t\t<file>fonts/DejaVuSansMono.ttf</file>\n\n\t</qresource>\n</RCC>\n"
  },
  {
    "path": "smuviewico.rc",
    "content": "IDI_ICON1\tICON\tDISCARDABLE\t\"icons/smuview.ico\"\n"
  },
  {
    "path": "src/application.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2014 Martin Ling <martin-sigrok@earth.li>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <iostream>\n\n#include \"application.hpp\"\n#include \"config.h\"\n\nusing std::cerr;\nusing std::endl;\nusing std::exception;\n\nApplication::Application(int &argc, char *argv[]) :\n\tQApplication(argc, argv)\n{\n\tQApplication::setApplicationVersion(SV_VERSION_STRING);\n\tQApplication::setApplicationName(\"SmuView\");\n\tQApplication::setOrganizationName(\"sigrok\");\n\tQApplication::setOrganizationDomain(\"sigrok.org\");\n}\n\nbool Application::notify(QObject *receiver, QEvent *event)\n{\n\ttry {\n\t\treturn QApplication::notify(receiver, event);\n\t}\n\tcatch (exception &e) {\n\t\tcerr << \"Caught exception: \" << e.what() << endl;\n\t\texit(1);\n\t\treturn false;\n\t}\n}\n"
  },
  {
    "path": "src/application.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2014 Martin Ling <martin-sigrok@earth.li>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SV_APPLICATION_HPP\n#define SV_APPLICATION_HPP\n\n#include <QApplication>\n\nclass Application : public QApplication\n{\n\tQ_OBJECT\n\npublic:\n\tApplication(int &argc, char *argv[]);\n\nprivate:\n\tbool notify(QObject *receiver, QEvent *event);\n\n};\n\n#endif // SV_APPLICATION_HPP\n"
  },
  {
    "path": "src/channels/addscchannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"addscchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nAddSCChannel::AddSCChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tdouble constant,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tsignal_(signal),\n\tconstant_(constant),\n\tnext_signal_pos_(0)\n{\n\tassert(signal_);\n\n\ttotal_digits_ = signal_->total_digits();\n\tsr_digits_ = signal_->sr_digits();\n\n\tconnect(signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &AddSCChannel::on_sample_appended);\n}\n\nvoid AddSCChannel::on_sample_appended()\n{\n\tsize_t signal_sample_count = signal_->sample_count();\n\twhile (next_signal_pos_ < signal_sample_count) {\n\t\tauto sample = signal_->get_sample(next_signal_pos_, false);\n\t\tdouble time = sample.first;\n\t\tdouble value = sample.second + constant_;\n\t\tpush_sample(value, time);\n\t\t++next_signal_pos_;\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/addscchannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_ADDSCCHANNEL_HPP\n#define CHANNELS_ADDSCCHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass AddSCChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tAddSCChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tdouble constant,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> signal_;\n\tdouble constant_;\n\tsize_t next_signal_pos_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_ADDSCCHANNEL_HPP\n"
  },
  {
    "path": "src/channels/basechannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"basechannel.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::make_pair;\nusing std::make_shared;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\nusing sv::data::measured_quantity_t;\n\nQ_DECLARE_METATYPE(std::shared_ptr<sv::data::BaseSignal>)\n\nnamespace sv {\nnamespace channels {\n\nBaseChannel::BaseChannel(\n\t\tshared_ptr<sigrok::Channel> sr_channel,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tdouble channel_start_timestamp) :\n\tsr_channel_(sr_channel),\n\tchannel_start_timestamp_(channel_start_timestamp),\n\tparent_device_(parent_device),\n\tchannel_group_names_(channel_group_names),\n\tfixed_signal_(false),\n\tactual_signal_(nullptr)\n{\n\tname_ = (sr_channel_) ? sr_channel_->name() : \"\";\n\n\tqWarning() << \"Init channel \" << QString::fromStdString(name_)\n\t\t<< \", channel_start_timestamp = \"\n\t\t<< util::format_time_date(channel_start_timestamp);\n}\n\nBaseChannel::~BaseChannel()\n{\n\tqWarning() << \"BaseChannel::~BaseChannel(): \" <<\n\t\tQString::fromStdString(name());\n}\n\nshared_ptr<sigrok::Channel> BaseChannel::sr_channel() const\n{\n\treturn sr_channel_;\n}\n\nstring BaseChannel::name() const\n{\n\treturn (sr_channel_) ? sr_channel_->name() : name_;\n}\n\nvoid BaseChannel::set_name(const string &name)\n{\n\tif (sr_channel_)\n\t\tsr_channel_->set_name(name);\n\n\tname_ = name;\n\tQ_EMIT name_changed(name);\n}\n\nQString BaseChannel::display_name() const\n{\n\treturn QString::fromStdString(name_);\n}\n\nunsigned int BaseChannel::index() const\n{\n\treturn (sr_channel_) ? sr_channel_->index() : index_;\n}\n\nChannelType BaseChannel::type() const\n{\n\treturn type_;\n}\n\nbool BaseChannel::enabled() const\n{\n\treturn (sr_channel_) ? sr_channel_->enabled() : true;\n}\n\nvoid BaseChannel::set_enabled(bool enabled)\n{\n\tif (sr_channel_) {\n\t\tsr_channel_->set_enabled(enabled);\n\t\tQ_EMIT enabled_changed(enabled);\n\t}\n}\n\nbool BaseChannel::fixed_signal() const\n{\n\treturn fixed_signal_;\n}\n\nvoid BaseChannel::set_fixed_signal(bool fixed_signal)\n{\n\tfixed_signal_ = fixed_signal;\n}\n\nshared_ptr<devices::BaseDevice> BaseChannel::parent_device()\n{\n\treturn parent_device_;\n}\n\nset<string> BaseChannel::channel_group_names() const\n{\n\treturn channel_group_names_;\n}\n\nvoid BaseChannel::add_channel_group_name(const string &channel_group_name)\n{\n\tchannel_group_names_.insert(channel_group_name);\n}\n\nvoid BaseChannel::add_signal(shared_ptr<data::AnalogTimeSignal> signal)\n{\n\tif (!signal_map_.empty() && fixed_signal_) {\n\t\t/*\n\t\t * NOTE: Previous versions didn't create a new signal but just exited\n\t\t *       here, which led to a subsequent segfault.\n\t\t *       Just print a message and create the new signals anyways.\n\t\t */\n\t\tqCritical() << \"WARNING: Adding the unexpected signal \"\n\t\t\t<< signal->display_name() << \" to the fixed channel \"\n\t\t\t<< display_name() << \" with an already existing signal \"\n\t\t\t<< actual_signal_->display_name();\n\t\tqCritical() << \"WARNING: The sigrok device driver is propably sending \"\n\t\t\t<< \"a wrong measured qunatity or wrong mq_flags.\";\n\t\tqCritical() << \"WARNING: Please fix this in the libsigrok driver!\";\n\t}\n\n\tconnect(this, &BaseChannel::channel_start_timestamp_changed,\n\t\tsignal.get(), &data::AnalogTimeSignal::on_channel_start_timestamp_changed);\n\n\tmeasured_quantity_t mq = make_pair(\n\t\tsignal->quantity(), signal->quantity_flags());\n\tif (signal_map_.count(mq) > 0) {\n\t\tsignal_map_[mq].push_back(signal);\n\t}\n\telse {\n\t\tsignal_map_.insert(\n\t\t\tmake_pair(mq, vector<shared_ptr<data::BaseSignal>> { signal }));\n\t}\n\n\tactual_signal_ = signal;\n\tQ_EMIT signal_added(signal);\n}\n\nshared_ptr<data::BaseSignal> BaseChannel::add_signal(\n\tdata::Quantity quantity,\n\tset<data::QuantityFlag> quantity_flags,\n\tdata::Unit unit,\n\tstring custom_name)\n{\n\t/*\n\t * TODO: Remove shared_from_this() / (channel pointer in signal), so that\n\t *       \"add_signal()\" can be called from MathChannel ctor.\n\t */\n\tauto signal = make_shared<data::AnalogTimeSignal>(\n\t\tquantity, quantity_flags, unit,\n\t\tshared_from_this(), channel_start_timestamp_, custom_name);\n\n\tthis->add_signal(signal);\n\n\treturn signal;\n}\n\nshared_ptr<data::BaseSignal> BaseChannel::actual_signal()\n{\n\treturn actual_signal_;\n}\n\nmap<measured_quantity_t, vector<shared_ptr<data::BaseSignal>>>\n\tBaseChannel::signal_map()\n{\n\treturn signal_map_;\n}\n\nvector<shared_ptr<data::BaseSignal>> BaseChannel::signals()\n{\n\tvector<shared_ptr<data::BaseSignal>> signals;\n\tfor (const auto &signal_pair : signal_map_) {\n\t\tsignals.insert(signals.end(),\n\t\t\tsignal_pair.second.begin(), signal_pair.second.end());\n\t}\n\treturn signals;\n}\n\nvoid BaseChannel::clear_signals()\n{\n\t/* TODO\n\tfor (const auto &signal_pair : signal_map_) {\n\t\tsignal_pair.second->\n\t}\n\t*/\n}\n\nvoid BaseChannel::save_settings(QSettings &settings) const\n{\n\tsettings.setValue(\"name\", QString::fromStdString(name()));\n\tsettings.setValue(\"enabled\", enabled());\n}\n\nvoid BaseChannel::restore_settings(QSettings &settings)\n{\n\tset_name(settings.value(\"name\").toString().toStdString());\n\tset_enabled(settings.value(\"enabled\").toBool());\n}\n\nvoid BaseChannel::on_aquisition_start_timestamp_changed(double timestamp)\n{\n\tqWarning()\n\t\t<< \"BaseChannel::on_aquisition_start_timestamp_changed() timestamp = \"\n\t\t<< util::format_time_date(timestamp);\n\tchannel_start_timestamp_ = timestamp;\n\tQ_EMIT channel_start_timestamp_changed(timestamp);\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/basechannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2016-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_BASECHANNEL_HPP\n#define CHANNELS_BASECHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <vector>\n\n#include <QObject>\n#include <QSettings>\n#include <QString>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::map;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\nusing sv::data::measured_quantity_t;\n\nnamespace sigrok {\nclass Channel;\n}\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\nclass BaseSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nenum class ChannelType {\n\t/**\n\t * Channels with analog data (Power supplies, loads, DMMs)\n\t */\n\tAnalogChannel,\n\t/**\n\t * Virtual channel for calculated data\n\t */\n\tMathChannel,\n\t/**\n\t * Virtual channel for user generated data (e.g. scripts)\n\t */\n\tUserChannel\n};\n\nclass BaseChannel :\n\tpublic QObject,\n\tpublic std::enable_shared_from_this<BaseChannel>\n{\n\tQ_OBJECT\n\npublic:\n\tBaseChannel(\n\t\tshared_ptr<sigrok::Channel> sr_channel,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tdouble channel_start_timestamp);\n\tvirtual ~BaseChannel();\n\npublic:\n\t/**\n\t * Return the underlying sigrok channel.\n\t *\n\t * HardwareChannels always have a sigrok channel, UserChannels only have a\n\t * sigrok channel when created in a UserDevice!\n\t */\n\tshared_ptr<sigrok::Channel> sr_channel() const;\n\n\t/**\n\t * Get the name of this channel, i.e. how the device calls it.\n\t */\n\tstring name() const;\n\n\t/**\n\t * Set the name of the signal.\n\t */\n\tvoid set_name(const string &name);\n\n\t/**\n\t * Get the display name of this channel.\n\t */\n\tQString display_name() const;\n\n\t/**\n\t * Get the index number of this channel, i.e. a unique ID assigned by\n\t * the device driver.\n\t */\n\tunsigned int index() const;\n\n\t/**\n\t * Get the type of this channel.\n\t */\n\tChannelType type() const;\n\n\t/**\n\t * Return enabled status of this channel.\n\t */\n\tbool enabled() const;\n\n\t/**\n\t * Set the enabled status of this channel.\n\t */\n\tvoid set_enabled(bool enabled);\n\n\t/**\n\t * Does this channel have just one signal, thats quantity doesn't change?\n\t */\n\tbool fixed_signal() const;\n\n\t/**\n\t * Set if this channel has just one signal, thats quantity doesn't change\n\t */\n\tvoid set_fixed_signal(bool fixed_signal);\n\n\t/**\n\t * Return the device, this channel belongs to.\n\t */\n\tshared_ptr<devices::BaseDevice> parent_device();\n\n\t/**\n\t * Get the channel group name, the channel is in. Returns \"\" if the channel\n\t * is not in a channel group.\n\t */\n\tset<string> channel_group_names() const;\n\n\t/**\n\t * Add a channel group name\n\t */\n\tvoid add_channel_group_name(const string &channel_group_name);\n\n\t/**\n\t * Add a signal to the channel. For now only AnalogTimeSignals\n\t * are supported.\n\t */\n\tvoid add_signal(shared_ptr<data::AnalogTimeSignal> signal);\n\n\t/**\n\t * Add a signal by its quantity, quantity_flags and unit.\n\t */\n\tshared_ptr<data::BaseSignal> add_signal(\n\t\tdata::Quantity quantity,\n\t\tset<data::QuantityFlag> quantity_flags,\n\t\tdata::Unit unit,\n\t\tstring custom_name = \"\");\n\n\t/**\n\t * Get the actual signal\n\t */\n\tshared_ptr<data::BaseSignal> actual_signal();\n\n\t/**\n\t * Get all signals for this channel. Normaly a measurement quantity only\n\t * has one corresponding signal, but for user channels this can be\n\t * different.\n\t */\n\tmap<measured_quantity_t, vector<shared_ptr<data::BaseSignal>>> signal_map();\n\n\t/**\n\t * Get all signals for this channel.\n\t * This function is especially for the Python bindings.\n\t */\n\tvector<shared_ptr<data::BaseSignal>> signals();\n\n\t/**\n\t * Delete all signals from this channel\n\t */\n\tvoid clear_signals();\n\n\tvirtual void save_settings(QSettings &settings) const;\n\tvirtual void restore_settings(QSettings &settings);\n\nprotected:\n\tstatic const size_t size_of_double_ = sizeof(double);\n\n\t/** The corresponding sigrok channel object. */\n\tshared_ptr<sigrok::Channel> sr_channel_;\n\t/** Name of this channel. */\n\tstring name_;\n\t/** Index of this channel. */\n\tunsigned int index_;\n\t/** Type of this channel. */\n\tChannelType type_;\n\t/** Timestamp when this channel was created/started. */\n\tdouble channel_start_timestamp_;\n\n\t/** The device this channel belongs to. */\n\tshared_ptr<devices::BaseDevice> parent_device_;\n\t/** The channel group names this channel belongs to. */\n\tset<string> channel_group_names_;\n\n\tbool fixed_signal_;\n\tshared_ptr<data::BaseSignal> actual_signal_;\n\tmap<measured_quantity_t, vector<shared_ptr<data::BaseSignal>>> signal_map_;\n\npublic Q_SLOTS:\n\tvoid on_aquisition_start_timestamp_changed(double timestamp);\n\nQ_SIGNALS:\n\tvoid channel_start_timestamp_changed(double timestamp);\n\tvoid enabled_changed(const bool enabled);\n\tvoid name_changed(const std::string &name);\n\tvoid signal_added(shared_ptr<sv::data::BaseSignal> signal);\n\tvoid signal_changed(shared_ptr<sv::data::BaseSignal> signal);\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_BASECHANNEL_HPP\n"
  },
  {
    "path": "src/channels/dividechannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"dividechannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::lock_guard;\nusing std::make_shared;\nusing std::mutex;\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nDivideChannel::DivideChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> dividend_signal,\n\t\tshared_ptr<data::AnalogTimeSignal> divisor_signal,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tdividend_signal_(dividend_signal),\n\tdivisor_signal_(divisor_signal),\n\tdividend_signal_pos_(0),\n\tdivisor_signal_pos_(0)\n{\n\tassert(dividend_signal_);\n\tassert(divisor_signal_);\n\n\tif (dividend_signal->total_digits() >= divisor_signal->total_digits())\n\t\ttotal_digits_ = dividend_signal->total_digits();\n\telse\n\t\ttotal_digits_ = divisor_signal->total_digits();\n\n\t// Use the lower sr_digits value to get a greater resoulution\n\tif (dividend_signal->sr_digits() < divisor_signal->sr_digits())\n\t\tsr_digits_ = dividend_signal->sr_digits();\n\telse\n\t\tsr_digits_ = divisor_signal->sr_digits();\n\n\tconnect(dividend_signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &DivideChannel::on_sample_appended);\n\tconnect(divisor_signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &DivideChannel::on_sample_appended);\n}\n\nvoid DivideChannel::on_sample_appended()\n{\n\tlock_guard<mutex> lock(sample_append_mutex_);\n\n\tshared_ptr<vector<double>> time = make_shared<vector<double>>();\n\tshared_ptr<vector<double>> dividend_data = make_shared<vector<double>>();\n\tshared_ptr<vector<double>> divisor_data = make_shared<vector<double>>();\n\n\tsv::data::AnalogTimeSignal::combine_signals(\n\t\tdividend_signal_, dividend_signal_pos_,\n\t\tdivisor_signal_, divisor_signal_pos_,\n\t\ttime, dividend_data, divisor_data);\n\n\tfor (size_t i=0; i<time->size(); i++) {\n\t\t// Division\n\t\tdouble value;\n\t\tif (divisor_data->at(i) == 0) {\n\t\t\tif (dividend_data->at(i) > 0)\n\t\t\t\tvalue = std::numeric_limits<double>::max();\n\t\t\telse\n\t\t\t\tvalue = std::numeric_limits<double>::lowest();\n\t\t}\n\t\telse {\n\t\t\tvalue = dividend_data->at(i) / divisor_data->at(i);\n\t\t}\n\t\tpush_sample(value, time->at(i));\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/dividechannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_DIVIDECHANNEL_HPP\n#define CHANNELS_DIVIDECHANNEL_HPP\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::mutex;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass DivideChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tDivideChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> dividend_signal,\n\t\tshared_ptr<data::AnalogTimeSignal> divisor_signal,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> dividend_signal_;\n\tshared_ptr<data::AnalogTimeSignal> divisor_signal_;\n\tsize_t dividend_signal_pos_;\n\tsize_t divisor_signal_pos_;\n\tmutex sample_append_mutex_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_DIVIDECHANNEL_HPP\n"
  },
  {
    "path": "src/channels/hardwarechannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n\n#include <QDebug>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"hardwarechannel.hpp\"\n#include \"src/session.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::make_pair;\nusing std::set;\nusing std::static_pointer_cast;\nusing std::string;\nusing std::unique_ptr;\nusing sv::data::measured_quantity_t;\n\nnamespace sv {\nnamespace channels {\n\nHardwareChannel::HardwareChannel(\n\t\tshared_ptr<sigrok::Channel> sr_channel,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tdouble channel_start_timestamp) :\n\tBaseChannel(sr_channel, parent_device, channel_group_names,\n\t\tchannel_start_timestamp)\n{\n\tassert(sr_channel);\n\n\ttype_ = ChannelType::AnalogChannel;\n\tname_ = sr_channel_->name();\n}\n\nvoid HardwareChannel::push_interleaved_samples(const float *data,\n\tsize_t sample_count, size_t stride, double timestamp, uint64_t samplerate,\n\tshared_ptr<sigrok::Analog> sr_analog)\n{\n\t//lock_guard<recursive_mutex> lock(mutex_);\n\n\t/*\n\t * NOTE: Sometimes the mq is not set (e.g. for the demo driver in\n\t *       sigrok 6.0.0) and mq() just throws an exception, without a\n\t *       possibility to check if mq is set or not.\n\t */\n\tdata::Quantity quantity;\n\ttry {\n\t\tquantity = data::datautil::get_quantity(sr_analog->mq());\n\t}\n\tcatch (const sigrok::Error &e) {\n\t\tquantity = data::Quantity::Unknown;\n\t}\n\tset<data::QuantityFlag> quantity_flags =\n\t\tdata::datautil::get_quantity_flags(sr_analog->mq_flags());\n\n\tif (!actual_signal_ || actual_signal_->quantity() != quantity ||\n\t\tactual_signal_->quantity_flags() != quantity_flags) {\n\n\t\t/* actual_signal_ not set or doesn't match the mq/mqf */\n\t\tmeasured_quantity_t mq = make_pair(quantity, quantity_flags);\n\t\tsize_t signals_count = signal_map_.count(mq);\n\t\tif (signals_count == 0) {\n\t\t\tdata::Unit unit = data::datautil::get_unit(sr_analog->unit());\n\t\t\tadd_signal(quantity, quantity_flags, unit);\n\t\t\tqWarning() << \"HardwareChannel::push_sample_sr_analog(): \"\n\t\t\t\t<< display_name()\n\t\t\t\t<< \" - Signal was not found and was therefore created: \"\n\t\t\t\t<< actual_signal_->display_name();\n\t\t}\n\t\telse if (signals_count > 1) {\n\t\t\tthrow (\"More than one signal found for \" + name());\n\t\t}\n\n\t\tactual_signal_ = signal_map_[mq][0];\n\t\tQ_EMIT signal_changed(actual_signal_);\n\t}\n\n\t// Deinterleave the samples and add them\n\tunique_ptr<float[]> deint_data(new float[sample_count]);\n\tfloat *deint_data_ptr = deint_data.get();\n\tfor (size_t i = 0; i < sample_count; i++) {\n\t\t*deint_data_ptr = (float)(*data);\n\t\tdeint_data_ptr++;\n\t\tdata += stride;\n\t}\n\n\t// NOTE: Not implementet in sigrok yet, so using the default for now.\n\tconst int total_digits = data::DefaultTotalDigits;\n\n\tstatic_pointer_cast<data::AnalogTimeSignal>(actual_signal_)->push_samples(\n\t\tdeint_data.get(), sample_count, timestamp, samplerate,\n\t\tsr_analog->unitsize(), total_digits, sr_analog->digits());\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/hardwarechannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_HARDWARECHANNEL_HPP\n#define CHANNELS_HARDWARECHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sigrok {\nclass Analog;\nclass Channel;\n}\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass HardwareChannel : public BaseChannel\n{\n\tQ_OBJECT\n\npublic:\n\t/**\n\t * A HardwareChannel does handle interleaved samples from a\n\t * (hardware) device.\n\t */\n\tHardwareChannel(\n\t\tshared_ptr<sigrok::Channel> sr_channel,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tdouble channel_start_timestamp);\n\npublic:\n\t/**\n\t * Add one or more interleaved samples with timestamps to the channel\n\t */\n\tvoid push_interleaved_samples(const float *data, size_t sample_count,\n\t\tsize_t stride, double timestamp, uint64_t samplerate,\n\t\tshared_ptr<sigrok::Analog> sr_analog);\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_HARDWARECHANNEL_HPP\n"
  },
  {
    "path": "src/channels/integratechannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"integratechannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nIntegrateChannel::IntegrateChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> int_signal,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tint_signal_(int_signal),\n\tnext_int_signal_pos_(0),\n\tlast_timestamp_(channel_start_timestamp),\n\tlast_value_(0.)\n{\n\tassert(int_signal_);\n\n\ttotal_digits_ = int_signal_->total_digits();\n\tsr_digits_ = int_signal_->sr_digits();\n\n\tconnect(this, &IntegrateChannel::channel_start_timestamp_changed,\n\t\tthis, &IntegrateChannel::on_channel_start_timestamp_changed);\n\tconnect(int_signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &IntegrateChannel::on_sample_appended);\n}\n\nvoid IntegrateChannel::on_channel_start_timestamp_changed(double timestamp)\n{\n\t// TODO: check if already started?\n\tif (last_timestamp_ < 0)\n\t\tlast_timestamp_ = timestamp;\n}\n\nvoid IntegrateChannel::on_sample_appended()\n{\n\t// Integrate\n\tsize_t int_signal_sample_count = int_signal_->sample_count();\n\twhile (next_int_signal_pos_ < int_signal_sample_count) {\n\t\tauto sample = int_signal_->get_sample(next_int_signal_pos_, false);\n\t\tdouble time = sample.first;\n\t\tdouble elapsed_time_hours = (time - last_timestamp_) / (double)3600;\n\t\tdouble value = last_value_ + (sample.second * elapsed_time_hours);\n\n\t\tpush_sample(value, time);\n\n\t\tlast_timestamp_ = time;\n\t\tlast_value_ = value;\n\t\t++next_int_signal_pos_;\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/integratechannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_INTEGRATECHANNEL_HPP\n#define CHANNELS_INTEGRATECHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass IntegrateChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tIntegrateChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> int_signal,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> int_signal_;\n\tsize_t next_int_signal_pos_;\n\tdouble last_timestamp_;\n\tdouble last_value_;\n\nprivate Q_SLOTS:\n\tvoid on_channel_start_timestamp_changed(double timestamp);\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_INTEGRATECHANNEL_HPP\n"
  },
  {
    "path": "src/channels/mathchannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"mathchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::set;\nusing std::static_pointer_cast;\nusing std::string;\nusing sv::data::measured_quantity_t;\n\nnamespace sv {\nnamespace channels {\n\nMathChannel::MathChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tBaseChannel(nullptr, parent_device, channel_group_names,\n\t\t\tchannel_start_timestamp),\n\ttotal_digits_(data::DefaultTotalDigits),\n\tsr_digits_(data::DefaultSRDigits),\n\tquantity_(quantity),\n\tquantity_flags_(quantity_flags),\n\tunit_(unit)\n{\n\tname_ = channel_name;\n\ttype_ = ChannelType::MathChannel;\n\tindex_ = parent_device->next_channel_index();\n\tfixed_signal_ = true;\n\n\tif (parent_device_->type() == devices::DeviceType::UserDevice) {\n\t\tauto sr_udev = static_pointer_cast<sigrok::UserDevice>(\n\t\t\tparent_device_->sr_device());\n\t\tsr_channel_ = sr_udev->add_channel(\n\t\t\tindex_, sigrok::ChannelType::ANALOG, name_);\n\t}\n\n\t/*\n\t * TODO: Remove shared_from_this() / (channel pointer in signal), so that\n\t *       \"add_signal()\" can be called from MathChannel ctor.\n\t *       But are the signals channel_added() and signal_added() in\n\t *       the correct order then?\n\tadd_signal(quantity_, quantity_flags_, unit_);\n\t */\n}\n\ndata::Quantity MathChannel::quantity()\n{\n\treturn quantity_;\n}\n\nset<data::QuantityFlag> MathChannel::quantity_flags()\n{\n\treturn quantity_flags_;\n}\n\ndata::Unit MathChannel::unit()\n{\n\treturn unit_;\n}\n\nvoid MathChannel::push_sample(double sample, double timestamp)\n{\n\tauto signal = static_pointer_cast<data::AnalogTimeSignal>(actual_signal_);\n\tsignal->push_sample(&sample, timestamp, size_of_double_,\n\t\ttotal_digits_, sr_digits_);\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/mathchannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_MATHCHANNEL_HPP\n#define CHANNELS_MATHCHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <vector>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nnamespace data {\nclass BaseSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass MathChannel : public BaseChannel\n{\n\tQ_OBJECT\n\npublic:\n\tMathChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\n\t/**\n\t * Get the quantity of the math channel.\n\t * TODO: remove when add_signal() is calles in the MathChannel ctor\n\t */\n\tdata::Quantity quantity();\n\n\t/**\n\t * Get the quantity flags of the math channel.\n\t * TODO: remove when add_signal() is calles in the MathChannel ctor\n\t */\n\tset<data::QuantityFlag> quantity_flags();\n\n\t/**\n\t * Get the unit of the math channel\n\t * TODO: remove when add_signal() is calles in the MathChannel ctor\n\t */\n\tdata::Unit unit();\n\nprotected:\n\t/**\n\t * Add a single sample with timestamp to the channel/signal\n\t */\n\tvoid push_sample(double sample, double timestamp);\n\n\tint total_digits_;\n\tint sr_digits_;\n\tdata::Quantity quantity_;\n\tset<data::QuantityFlag> quantity_flags_;\n\tdata::Unit unit_;\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_MATHCHANNEL_HPP\n"
  },
  {
    "path": "src/channels/movingavgchannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"movingavgchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nMovingAvgChannel::MovingAvgChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tuint avg_sample_count,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tsignal_(signal),\n\tavg_sample_count_(avg_sample_count),\n\tnext_signal_pos_(0)\n{\n\tassert(signal_);\n\n\ttotal_digits_ = signal_->total_digits();\n\tsr_digits_ = signal_->sr_digits();\n\n\t// Init (ring) buffer\n\tavg_samples_.reserve(avg_sample_count_);\n\tfor (size_t i=0; i<avg_sample_count_; ++i)\n\t\tavg_samples_[i] = 0;\n\n\tconnect(signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &MovingAvgChannel::on_sample_appended);\n}\n\nvoid MovingAvgChannel::on_sample_appended()\n{\n\tsize_t signal_sample_count = signal_->sample_count();\n\twhile (next_signal_pos_ < signal_sample_count) {\n\t\tauto sample = signal_->get_sample(next_signal_pos_, false);\n\t\tavg_samples_[next_signal_pos_%avg_sample_count_] = sample.second;\n\t\tdouble value = 0.;\n\t\tfor (size_t i=0; i<avg_sample_count_; ++i) {\n\t\t\tvalue += avg_samples_[i];\n\t\t}\n\t\tvalue /= avg_sample_count_;\n\t\tpush_sample(value, sample.first);\n\t\t++next_signal_pos_;\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/movingavgchannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_MOVINGACGCHANNEL_HPP\n#define CHANNELS_MOVINGACGCHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass MovingAvgChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tMovingAvgChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tuint avg_sample_count,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> signal_;\n\tuint avg_sample_count_;\n\tvector<double> avg_samples_;\n\tsize_t next_signal_pos_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_MOVINGACGCHANNEL_HPP\n"
  },
  {
    "path": "src/channels/multiplysfchannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"multiplysfchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nMultiplySFChannel::MultiplySFChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tdouble factor,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tsignal_(signal),\n\tfactor_(factor),\n\tnext_signal_pos_(0)\n{\n\tassert(signal_);\n\n\ttotal_digits_ = signal_->total_digits();\n\tsr_digits_ = signal_->sr_digits();\n\n\tconnect(signal_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &MultiplySFChannel::on_sample_appended);\n}\n\nvoid MultiplySFChannel::on_sample_appended()\n{\n\tsize_t signal_sample_count = signal_->sample_count();\n\twhile (next_signal_pos_ < signal_sample_count) {\n\t\tauto sample = signal_->get_sample(next_signal_pos_, false);\n\t\tdouble time = sample.first;\n\t\tdouble value = sample.second * factor_;\n\t\tpush_sample(value, time);\n\t\t++next_signal_pos_;\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/multiplysfchannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_MULTIPLYSFCHANNEL_HPP\n#define CHANNELS_MULTIPLYSFCHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass MultiplySFChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tMultiplySFChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal,\n\t\tdouble factor,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> signal_;\n\tdouble factor_;\n\tsize_t next_signal_pos_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_MULTIPLYSFCHANNEL_HPP\n"
  },
  {
    "path": "src/channels/multiplysschannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"multiplysschannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::lock_guard;\nusing std::make_shared;\nusing std::mutex;\nusing std::set;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nMultiplySSChannel::MultiplySSChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal1,\n\t\tshared_ptr<data::AnalogTimeSignal> signal2,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp) :\n\tMathChannel(quantity, quantity_flags, unit,\n\t\tparent_device, channel_group_names, channel_name,\n\t\tchannel_start_timestamp),\n\tsignal1_(signal1),\n\tsignal2_(signal2),\n\tsignal1_pos_(0),\n\tsignal2_pos_(0)\n{\n\tassert(signal1_);\n\tassert(signal2_);\n\n\tif (signal1_->total_digits() >= signal2_->total_digits())\n\t\ttotal_digits_ = signal1_->total_digits();\n\telse\n\t\ttotal_digits_ = signal2_->total_digits();\n\n\t// Use the lower sr_digits value to get a greater resolution\n\tif (signal1_->sr_digits() < signal2_->sr_digits())\n\t\tsr_digits_ = signal1_->sr_digits();\n\telse\n\t\tsr_digits_ = signal2_->sr_digits();\n\n\tconnect(signal1_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &MultiplySSChannel::on_sample_appended);\n\tconnect(signal2_.get(), &data::AnalogTimeSignal::sample_appended,\n\t\tthis, &MultiplySSChannel::on_sample_appended);\n}\n\nvoid MultiplySSChannel::on_sample_appended()\n{\n\tlock_guard<mutex> lock(sample_append_mutex_);\n\n\tshared_ptr<vector<double>> time = make_shared<vector<double>>();\n\tshared_ptr<vector<double>> signal1_data = make_shared<vector<double>>();\n\tshared_ptr<vector<double>> signal2_data = make_shared<vector<double>>();\n\n\tsv::data::AnalogTimeSignal::combine_signals(\n\t\tsignal1_, signal1_pos_,\n\t\tsignal2_, signal2_pos_,\n\t\ttime, signal1_data, signal2_data);\n\n\tfor (size_t i=0; i<time->size(); i++) {\n\t\tpush_sample(signal1_data->at(i) * signal2_data->at(i), time->at(i));\n\t}\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/multiplysschannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_MULTIPLYSSCHANNEL_HPP\n#define CHANNELS_MULTIPLYSSCHANNEL_HPP\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::mutex;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace data {\nclass AnalogTimeSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass MultiplySSChannel : public MathChannel\n{\n\tQ_OBJECT\n\npublic:\n\tMultiplySSChannel(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<data::AnalogTimeSignal> signal1,\n\t\tshared_ptr<data::AnalogTimeSignal> signal2,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tconst set<string> &channel_group_names,\n\t\tconst string &channel_name,\n\t\tdouble channel_start_timestamp);\n\nprivate:\n\tshared_ptr<data::AnalogTimeSignal> signal1_;\n\tshared_ptr<data::AnalogTimeSignal> signal2_;\n\tsize_t signal1_pos_;\n\tsize_t signal2_pos_;\n\tmutex sample_append_mutex_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_MULTIPLYSSCHANNEL_HPP\n"
  },
  {
    "path": "src/channels/userchannel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n\n#include \"userchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::make_pair;\nusing std::set;\nusing std::static_pointer_cast;\nusing std::string;\n\nnamespace sv {\nnamespace channels {\n\nUserChannel::UserChannel(\n\t\tconst string &channel_name,\n\t\tconst set<string> &channel_group_names,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tdouble channel_start_timestamp) :\n\tBaseChannel(nullptr, parent_device, channel_group_names,\n\t\tchannel_start_timestamp)\n{\n\tname_ = channel_name;\n\ttype_ = ChannelType::UserChannel;\n\tindex_ = parent_device->next_channel_index();\n\tfixed_signal_ = false;\n\n\tif (parent_device_->type() == devices::DeviceType::UserDevice) {\n\t\tauto sr_udev = static_pointer_cast<sigrok::UserDevice>(\n\t\t\tparent_device_->sr_device());\n\t\tsr_channel_ = sr_udev->add_channel(\n\t\t\tindex_, sigrok::ChannelType::ANALOG, name_);\n\t}\n}\n\nvoid UserChannel::push_sample(double sample, double timestamp,\n\tdata::Quantity quantity, set<data::QuantityFlag> quantity_flags,\n\tdata::Unit unit, int total_digits, int sr_digits)\n{\n\tif (!actual_signal_ || actual_signal_->quantity() != quantity ||\n\t\tactual_signal_->quantity_flags() != quantity_flags) {\n\n\t\tmeasured_quantity_t mq = make_pair(quantity, quantity_flags);\n\t\tsize_t signals_count = signal_map_.count(mq);\n\t\tif (signals_count == 0) {\n\t\t\tactual_signal_ = add_signal(quantity, quantity_flags, unit);\n\t\t\tqWarning() << \"UserChannel::push_sample(): \" << display_name() <<\n\t\t\t\t\" - No signal found: \" << actual_signal_->display_name();\n\t\t}\n\t\telse if (signals_count > 1) {\n\t\t\tactual_signal_ = signal_map_[mq][0];\n\t\t\tqWarning() << \"UserChannel::push_sample(): \" << display_name() <<\n\t\t\t\t\" - More than one signal found, using first found signal: \" <<\n\t\t\t\tactual_signal_->display_name();\n\t\t}\n\t\tQ_EMIT signal_changed(actual_signal_);\n\t}\n\n\tstatic_pointer_cast<data::AnalogTimeSignal>(actual_signal_)->push_sample(\n\t\t&sample, timestamp, size_of_double_, total_digits, sr_digits);\n}\n\n} // namespace channels\n} // namespace sv\n"
  },
  {
    "path": "src/channels/userchannel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef CHANNELS_USERCHANNEL_HPP\n#define CHANNELS_USERCHANNEL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <vector>\n\n#include <QObject>\n\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nnamespace data {\nclass BaseSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace channels {\n\nclass UserChannel : public BaseChannel\n{\n\tQ_OBJECT\n\npublic:\n\tUserChannel(\n\t\tconst string &channel_name,\n\t\tconst set<string> &channel_group_names,\n\t\tshared_ptr<devices::BaseDevice> parent_device,\n\t\tdouble channel_start_timestamp);\n\n\t/**\n\t * Add a single sample with timestamp to the channel/signal\n\t * TODO: Move to base?\n\t */\n\tvoid push_sample(double sample, double timestamp,\n\t\tdata::Quantity quantity, set<data::QuantityFlag> quantity_flags,\n\t\tdata::Unit unit, int total_digits, int sr_digits);\n\n};\n\n} // namespace channels\n} // namespace sv\n\n#endif // CHANNELS_USERCHANNEL_HPP\n"
  },
  {
    "path": "src/data/analogbasesignal.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n#include <QString>\n\n#include \"analogbasesignal.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::make_shared;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\nAnalogBaseSignal::AnalogBaseSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name) :\n\tBaseSignal(quantity, quantity_flags, unit, parent_channel, custom_name),\n\tsample_count_(0),\n\ttotal_digits_(data::DefaultTotalDigits),\n\tsr_digits_(data::DefaultSRDigits),\n\tlast_value_(0.),\n\tmin_value_(std::numeric_limits<double>::max()),\n\tmax_value_(std::numeric_limits<double>::lowest())\n{\n\tqWarning() << \"Init analog base signal \" << display_name();\n\tdata_ = make_shared<vector<double>>();\n}\n\nsize_t AnalogBaseSignal::sample_count() const\n{\n\tsize_t sample_count = sample_count_;\n\t//qWarning() << \"AnalogBaseSignal::sample_count(): sample_count_ = \"\n\t//\t<< sample_count;\n\treturn sample_count;\n}\n\n/*\nanalog_time_sample_t AnalogSignal::get_sample(\n\tsize_t pos, bool relative_time) const\n{\n\t// TODO: retrun reference (&double)? See get_value_at_timestamp()\n\n\t//qWarning() << \"AnalogSignal::get_sample(\" << pos\n\t//\t<< \"): sample_count_ = \" << sample_count_;\n\n\tif (pos < sample_count_) {\n\t\tdouble timestamp = time_->at(pos);\n\t\tif (relative_time)\n\t\t\ttimestamp -= signal_start_timestamp_;\n\t\t//qWarning() << \"AnalogSignal::get_sample(\" << pos\n\t\t//\t<< \"): sample = \" << timestamp << \", \" << data_->at(pos);\n\t\treturn make_pair(timestamp, data_->at(pos));\n\t}\n\n\treturn make_pair(0., 0.);\n}\n*/\n\n/*\nbool AnalogSignal::get_value_at_timestamp(\n\tdouble timestamp, double &value, bool relative_time) const\n{\n\tif (time_->size() == 0)\n\t\treturn false;\n\tif (timestamp < time_->at(0))\n\t\treturn false;\n\tif (timestamp > time_->back())\n\t\treturn false;\n\n\tif (relative_time)\n\t\ttimestamp += signal_start_timestamp_;\n\n\tauto lower = std::lower_bound(time_->begin(), time_->end(), timestamp);\n\n\t// Check if timestamp and found timestamp match\n\tif (timestamp == *lower) {\n\t\tvalue = *lower;\n\t\treturn true;\n\t}\n\n\tsize_t lower_pos = lower - time_->begin();\n\n\t// Get the previous timestamp for linear interpolation\n\tif (lower_pos > 0)\n\t\t--lower_pos;\n\n\tdouble lower_ts = time_->at(lower_pos);\n\tdouble lower_data = data_->at(lower_pos);\n\tsize_t upper_pos = lower_pos + 1;\n\tdouble upper_ts = time_->at(upper_pos);\n\n\t// Use linear interpolation to get the value beetween time stamps\n\tdouble ts_factor = (timestamp - lower_ts) / (upper_ts - lower_ts);\n\tdouble data_diff = data_->at(upper_pos) - lower_data;\n\tdouble lininter_data = lower_data + (data_diff * ts_factor);\n\n\tvalue = lininter_data;\n\treturn true;\n}\n*/\n\n/*\nvoid AnalogSignal::push_sample(void *sample, double timestamp,\n\tsize_t unit_size, int digits, int decimal_places)\n{\n\tdouble dsample = 0.;\n\tif (unit_size == size_of_float_)\n\t\tdsample = (double) *(float *)sample;\n\telse if (unit_size == size_of_double_)\n\t\tdsample = *(double *)sample;\n\n\t/ *\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \": sample = \" << dsample << \" @ \" <<  timestamp;\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \": sample_count_ = \" << sample_count_+1;\n\t* /\n\n\t// TODO: Mutex?\n\tlast_timestamp_ = timestamp;\n\tlast_value_ = dsample;\n\tif (min_value_ > dsample)\n\t\tmin_value_ = dsample;\n\tif (max_value_ < dsample)\n\t\tmax_value_ = dsample;\n\n\t/ *\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \":last_timestamp_ = \" << last_timestamp_;\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \":last_value_ = \" << last_value_;\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \":min_value_ = \" << min_value_;\n\tqWarning() << \"AnalogSignal::push_sample(): \" << name_\n\t\t<< \":max_value_ = \" << max_value_;\n\t* /\n\n\t// TODO: Mutex?\n\ttime_->push_back(timestamp);\n\tdata_->push_back(dsample);\n\tsample_count_++;\n\tQ_EMIT sample_appended();\n\n\tbool digits_chngd = false;\n\tif (digits != digits_) {\n\t\tdigits_ = digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (decimal_places != decimal_places_) {\n\t\tdecimal_places_ = decimal_places;\n\t\tdigits_chngd = true;\n\t}\n\tif (digits_chngd)\n\t\tQ_EMIT digits_changed(digits_, decimal_places_);\n}\n*/\n\nint AnalogBaseSignal::total_digits() const\n{\n\treturn total_digits_;\n}\n\nint AnalogBaseSignal::sr_digits() const\n{\n\treturn sr_digits_;\n}\n\ndouble AnalogBaseSignal::last_value() const\n{\n\treturn last_value_;\n}\n\ndouble AnalogBaseSignal::min_value() const\n{\n\treturn min_value_;\n}\n\ndouble AnalogBaseSignal::max_value() const\n{\n\treturn max_value_;\n}\n\n/*\nvoid AnalogSignal::combine_signals(\n\tshared_ptr<AnalogSignal> signal1, size_t &signal1_pos,\n\tshared_ptr<AnalogSignal> signal2, size_t &signal2_pos,\n\tshared_ptr<vector<double>> time_vector,\n\tshared_ptr<vector<double>> data1_vector,\n\tshared_ptr<vector<double>> data2_vector)\n{\n\t// Ignore the first sample(s)\n\t// TODO: Use last of the ignored samples?\n\tif (signal1_pos == 0 && signal2_pos == 0) {\n\t\tif (signal1->get_sample_count() <= signal1_pos ||\n\t\t\tsignal2->get_sample_count() <= signal2_pos)\n\t\t\treturn;\n\n\t\tdouble signal1_ts = signal1->get_sample(signal1_pos, false).first;\n\t\tdouble signal2_ts = signal2->get_sample(signal2_pos, false).first;\n\t\tif (signal1_ts < signal2_ts) {\n\t\t\twhile (signal1_ts < signal2_ts)\n\t\t\t\tsignal1_ts = signal1->get_sample(++signal1_pos, false).first;\n\t\t}\n\t\telse if (signal1_ts > signal2_ts) {\n\t\t\twhile (signal1_ts > signal2_ts)\n\t\t\t\tsignal2_ts = signal2->get_sample(++signal2_pos, false).first;\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tif (signal1->get_sample_count() <= signal1_pos ||\n\t\t\tsignal2->get_sample_count() <= signal2_pos)\n\t\t\tbreak;\n\n\t\t/ *\n\t\tqWarning() << \"AnalogSignal::merge_signals(): signal1_size = \"\n\t\t\t\t<< signal1->get_sample_count() << \", signal1_pos = \"\n\t\t\t\t<< signal1_pos;\n\t\tqWarning() << \"AnalogSignal::merge_signals(): signal2_size = \"\n\t\t\t\t<< signal2->get_sample_count() << \", signal2_pos = \"\n\t\t\t\t<< signal2_pos;\n\t\t* /\n\n\t\tdouble time;\n\t\tdouble value1;\n\t\tdouble value2;\n\n\t\tauto signal1_sample = signal1->get_sample(signal1_pos, false);\n\t\tauto signal2_sample = signal2->get_sample(signal2_pos, false);\n\t\tif (signal1_sample.first == signal2_sample.first) {\n\t\t\ttime = signal1_sample.first;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal1_pos;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse if (signal1_sample.first < signal2_sample.first &&\n\t\t\tsignal2->get_sample_count() > signal2_pos+1) {\n\n\t\t\ttime = signal1_sample.first;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\tif (!signal2->get_value_at_timestamp(time, value2, false))\n\t\t\t\treturn;\n\t\t\t++signal1_pos;\n\t\t}\n\t\telse if (signal1_sample.first > signal2_sample.first &&\n\t\t\tsignal1->get_sample_count() > signal1_pos+1) {\n\n\t\t\ttime = signal2_sample.first;\n\t\t\tif (!signal1->get_value_at_timestamp(time, value1, false))\n\t\t\t\treturn;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse {\n\t\t\treturn;\n\t\t}\n\n\t\ttime_vector->push_back(time);\n\t\tdata1_vector->push_back(value1);\n\t\tdata2_vector->push_back(value2);\n\t}\n}\n*/\n\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/analogbasesignal.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_ANALOGBASESIGNAL_HPP\n#define DATA_ANALOGBASESIGNAL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QObject>\n\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\nclass AnalogBaseSignal : public BaseSignal\n{\n\tQ_OBJECT\n\npublic:\n\tAnalogBaseSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name);\n\n\t/**\n\t * Return the number of samples in this signal.\n\t */\n\tsize_t sample_count() const override;\n\n\t/**\n\t * Return the sample at the given position.\n\tanalog_time_sample_t get_sample(size_t pos, bool relative_time) const;\n\t */\n\n\t/**\n\t * Return the value at the given timestamp in &value. If there is no\n\t * exactty matching timestamp, the value is linearly interpolated. No\n\t * value can be found/interpolated, if the timestamp is smaller than the\n\t * first timestamp in the signal or bigger than the last timestamp in the\n\t * signal.\n\t *\n\t * @param timestamp The timestamp for the value to return.\n\t * @param value The found/interpolated value at the given timestamp.\n\t * @param relative_time Use time relative to the session start time.\n\t *\n\t * @return true if a value was found/interpolated, false if not.\n\tbool get_value_at_timestamp(\n\t\tdouble timestamp, double &value, bool relative_time) const;\n\t */\n\n\t/**\n\t * Push a single sample to the signal.\n\t *\n\t * TODO: Can this be removed?\n\tvoid push_sample(void *sample, double timestamp,\n\t\tsize_t unit_size, int digits, int decimal_places);\n\t */\n\n\t/**\n\t * Number of total digits (count) of the measured value.\n\t * NOTE: Not implemented in sigrok yet. There is no good way to get the\n\t *       total number of digits for the analog payload. Therefore\n\t *       `total_digits` is initialized with some reasonable value.\n\t */\n\tint total_digits() const;\n\t/** digits from ....digits */\n\tint sr_digits() const;\n\tdouble last_value() const;\n\tdouble min_value() const;\n\tdouble max_value() const;\n\n\t/*\n\tstatic void combine_signals(\n\t\tshared_ptr<AnalogSignal> signal1, size_t &signal1_pos,\n\t\tshared_ptr<AnalogSignal> signal2, size_t &signal2_pos,\n\t\tshared_ptr<vector<double>> time_vector,\n\t\tshared_ptr<vector<double>> data1_vector,\n\t\tshared_ptr<vector<double>> data2_vector);\n\t*/\n\nprotected:\n\tshared_ptr<vector<double>> data_;\n\tsize_t sample_count_;\n\tint total_digits_;\n\tint sr_digits_;\n\tdouble last_value_;\n\tdouble min_value_;\n\tdouble max_value_;\n\n\tstatic const size_t size_of_float_ = sizeof(float);\n\tstatic const size_t size_of_double_ = sizeof(double);\n\nQ_SIGNALS:\n\tvoid samples_cleared();\n\tvoid sample_appended();\n\tvoid digits_changed(const int total_digits, const int sr_digits);\n\n};\n\n} // namespace data\n} // namespace sv\n\n#endif // DATA_ANALOGBASESIGNAL_HPP\n"
  },
  {
    "path": "src/data/analogsamplesignal.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n#include <QString>\n\n#include \"analogsamplesignal.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::make_pair;\nusing std::make_shared;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\nAnalogSampleSignal::AnalogSampleSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name) :\n\tAnalogBaseSignal(quantity, quantity_flags, unit, parent_channel, custom_name),\n\tlast_pos_(0)\n{\n\tqWarning() << \"Init analog sample signal \" << display_name();\n\tpos_ = make_shared<vector<uint32_t>>();\n}\n\nvoid AnalogSampleSignal::clear()\n{\n\t// TODO: mutex\n\tpos_->clear();\n\tdata_->clear();\n\tsample_count_ = 0;\n\n\tQ_EMIT samples_cleared();\n}\n\nanalog_pos_sample_t AnalogSampleSignal::get_sample(uint32_t pos) const\n{\n\t// TODO: retrun reference (&double)? See get_value_at_timestamp()\n\n\t//qWarning() << \"AnalogSampleSignal::get_sample(\" << pos\n\t//\t<< \"): sample_count_ = \" << sample_count_;\n\n\tif (pos < sample_count_) {\n\t\t//qWarning() << \"AnalogSampleSignal::get_sample(\" << pos\n\t\t//\t<< \"): value = \" << data_->at(pos);\n\t\treturn make_pair(pos, data_->at(pos));\n\t}\n\n\treturn make_pair(0, 0.);\n}\n\nvoid AnalogSampleSignal::push_sample(void *sample, uint32_t pos,\n\t\tsize_t unit_size, int total_digits, int sr_digits)\n{\n\tdouble dsample = 0.;\n\tif (unit_size == size_of_float_)\n\t\tdsample = static_cast<double>(*static_cast<float *>(sample));\n\telse if (unit_size == size_of_double_)\n\t\tdsample = *static_cast<double *>(sample);\n\n\t/*\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \": sample = \" << dsample << \" @ \" <<  pos;\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \": sample_count_ = \" << sample_count_+1;\n\t*/\n\n\t// TODO: Mutex?\n\tlast_pos_ = pos;\n\tlast_value_ = dsample;\n\tif (min_value_ > dsample)\n\t\tmin_value_ = dsample;\n\t// Ignore infinitiy (overflow) as max value.\n\tif (max_value_ < dsample &&\n\t\tdsample != std::numeric_limits<double>::infinity()) {\n\n\t\tmax_value_ = dsample;\n\t}\n\n\t/*\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \":last_pos_ = \" << last_pos_;\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \":last_value_ = \" << last_value_;\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \":min_value_ = \" << min_value_;\n\tqWarning() << \"AnalogSampleSignal::push_sample(): \" << name_\n\t\t<< \":max_value_ = \" << max_value_;\n\t*/\n\n\t// TODO: Mutex?\n\tpos_->push_back(pos);\n\tdata_->push_back(dsample);\n\tsample_count_++;\n\tQ_EMIT sample_appended();\n\n\tbool digits_chngd = false;\n\tif (total_digits != total_digits_) {\n\t\ttotal_digits_ = total_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (sr_digits != sr_digits_) {\n\t\tsr_digits_ = sr_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (digits_chngd)\n\t\tQ_EMIT digits_changed(total_digits_, sr_digits_);\n}\n\nuint32_t AnalogSampleSignal::first_pos() const\n{\n\tif (pos_->empty())\n\t\treturn 0;\n\n\treturn pos_->front();\n}\n\nuint32_t AnalogSampleSignal::last_pos() const\n{\n\tif (pos_->empty())\n\t\treturn 0;\n\n\treturn last_pos_;\n}\n\n/*\nvoid AnalogSampleSignal::combine_signals(\n\tshared_ptr<AnalogSampleSignal> signal1, size_t &signal1_pos,\n\tshared_ptr<AnalogSampleSignal> signal2, size_t &signal2_pos,\n\tshared_ptr<vector<uint32_t>> pos_vector,\n\tshared_ptr<vector<double>> data1_vector,\n\tshared_ptr<vector<double>> data2_vector)\n{\n\t// Ignore the first sample(s)\n\t// TODO: Use last of the ignored samples?\n\tif (signal1_pos == 0 && signal2_pos == 0) {\n\t\tif (signal1->get_sample_count() <= signal1_pos ||\n\t\t\tsignal2->get_sample_count() <= signal2_pos)\n\t\t\treturn;\n\n\t\tdouble signal1_ts = signal1->get_sample(signal1_pos, false).first;\n\t\tdouble signal2_ts = signal2->get_sample(signal2_pos, false).first;\n\t\tif (signal1_ts < signal2_ts) {\n\t\t\twhile (signal1_ts < signal2_ts)\n\t\t\t\tsignal1_ts = signal1->get_sample(++signal1_pos, false).first;\n\t\t}\n\t\telse if (signal1_ts > signal2_ts) {\n\t\t\twhile (signal1_ts > signal2_ts)\n\t\t\t\tsignal2_ts = signal2->get_sample(++signal2_pos, false).first;\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tif (signal1->get_sample_count() <= signal1_pos ||\n\t\t\tsignal2->get_sample_count() <= signal2_pos)\n\t\t\tbreak;\n\n\t\t/ *\n\t\tqWarning() << \"AnalogSampleSignal::merge_signals(): signal1_size = \"\n\t\t\t\t<< signal1->get_sample_count() << \", signal1_pos = \"\n\t\t\t\t<< signal1_pos;\n\t\tqWarning() << \"AnalogSampleSignal::merge_signals(): signal2_size = \"\n\t\t\t\t<< signal2->get_sample_count() << \", signal2_pos = \"\n\t\t\t\t<< signal2_pos;\n\t\t* /\n\n\t\tdouble time;\n\t\tdouble value1;\n\t\tdouble value2;\n\n\t\tsample_t signal1_sample = signal1->get_sample(signal1_pos, false);\n\t\tsample_t signal2_sample = signal2->get_sample(signal2_pos, false);\n\t\tif (signal1_sample.first == signal2_sample.first) {\n\t\t\ttime = signal1_sample.first;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal1_pos;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse if (signal1_sample.first < signal2_sample.first &&\n\t\t\tsignal2->get_sample_count() > signal2_pos+1) {\n\n\t\t\ttime = signal1_sample.first;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\tif (!signal2->get_value_at_timestamp(time, value2, false))\n\t\t\t\treturn;\n\t\t\t++signal1_pos;\n\t\t}\n\t\telse if (signal1_sample.first > signal2_sample.first &&\n\t\t\tsignal1->get_sample_count() > signal1_pos+1) {\n\n\t\t\ttime = signal2_sample.first;\n\t\t\tif (!signal1->get_value_at_timestamp(time, value1, false))\n\t\t\t\treturn;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse {\n\t\t\treturn;\n\t\t}\n\n\t\ttime_vector->push_back(time);\n\t\tdata1_vector->push_back(value1);\n\t\tdata2_vector->push_back(value2);\n\t}\n}\n*/\n\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/analogsamplesignal.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_ANALOGSAMPLESIGNAL_HPP\n#define DATA_ANALOGSAMPLESIGNAL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QObject>\n\n#include \"src/data/analogbasesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::pair;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\ntypedef pair<uint32_t, double> analog_pos_sample_t;\n\nclass AnalogSampleSignal : public AnalogBaseSignal\n{\n\tQ_OBJECT\n\npublic:\n\tAnalogSampleSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name = \"\");\n\n\t/**\n\t * Clear all samples from this signal.\n\t */\n\tvoid clear() override;\n\n\t/**\n\t * Return the sample at the given position.\n\t */\n\tanalog_pos_sample_t get_sample(uint32_t pos) const;\n\n\t/**\n\t * Push a single sample to the signal.\n\t */\n\tvoid push_sample(void *sample, uint32_t pos,\n\t\tsize_t unit_size, int total_digits, int sr_digits);\n\n\tuint32_t first_pos() const;\n\tuint32_t last_pos() const;\n\n\t/*\n\tstatic void combine_signals(\n\t\tshared_ptr<AnalogSampleSignal> signal1, size_t &signal1_pos,\n\t\tshared_ptr<AnalogSampleSignal> signal2, size_t &signal2_pos,\n\t\tshared_ptr<vector<uint32_t>> pos_vector,\n\t\tshared_ptr<vector<double>> data1_vector,\n\t\tshared_ptr<vector<double>> data2_vector);\n\t*/\n\nprivate:\n\tshared_ptr<vector<uint32_t>> pos_;\n\tuint32_t last_pos_;\n\n};\n\n} // namespace data\n} // namespace sv\n\n#endif // DATA_ANALOGSAMPLESIGNAL_HPP\n"
  },
  {
    "path": "src/data/analogtimesignal.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QDebug>\n#include <QString>\n\n#include \"analogtimesignal.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::make_pair;\nusing std::make_shared;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\nAnalogTimeSignal::AnalogTimeSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tdouble signal_start_timestamp,\n\t\tconst string &custom_name) :\n\tAnalogBaseSignal(quantity, quantity_flags, unit, parent_channel, custom_name),\n\tsignal_start_timestamp_(signal_start_timestamp),\n\tlast_timestamp_(0.)\n{\n\tqWarning() << \"Init analog time signal \" << display_name()\n\t\t<< \", signal_start_timestamp_ = \"\n\t\t<< util::format_time_date(signal_start_timestamp_);\n\n\ttime_ = make_shared<vector<double>>();\n}\n\nvoid AnalogTimeSignal::clear()\n{\n\t// TODO: mutex\n\ttime_->clear();\n\tdata_->clear();\n\tsample_count_ = 0;\n\n\tQ_EMIT samples_cleared();\n}\n\nanalog_time_sample_t AnalogTimeSignal::get_sample(\n\tsize_t pos, bool relative_time) const\n{\n\t// TODO: retrun reference (&double)? See get_value_at_timestamp()\n\n\t//qWarning() << \"AnalogSignal::get_sample(\" << pos\n\t//\t<< \"): sample_count_ = \" << sample_count_;\n\n\tif (pos < sample_count_) {\n\t\tdouble timestamp = time_->at(pos);\n\t\tif (relative_time)\n\t\t\ttimestamp -= signal_start_timestamp_;\n\t\t//qWarning() << \"AnalogSignal::get_sample(\" << pos\n\t\t//\t<< \"): sample = \" << timestamp << \", \" << data_->at(pos);\n\t\treturn make_pair(timestamp, data_->at(pos));\n\t}\n\n\treturn make_pair(0., 0.);\n}\n\nanalog_time_sample_t AnalogTimeSignal::get_last_sample(bool relative_time) const\n{\n\t// TODO: retrun reference (&double)? See get_value_at_timestamp()\n\tif (sample_count_ == 0)\n\t\treturn make_pair(0., 0.);\n\n\tsize_t pos = sample_count_ - 1;\n\tdouble timestamp = time_->at(pos);\n\tif (relative_time)\n\t\ttimestamp -= signal_start_timestamp_;\n\treturn make_pair(timestamp, data_->at(pos));\n}\n\nbool AnalogTimeSignal::get_value_at_timestamp(\n\tdouble timestamp, double &value, bool relative_time) const\n{\n\tif (time_->empty())\n\t\treturn false;\n\tif (timestamp < time_->at(0))\n\t\treturn false;\n\tif (timestamp > time_->back())\n\t\treturn false;\n\n\tif (relative_time)\n\t\ttimestamp += signal_start_timestamp_;\n\n\tauto lower = std::lower_bound(time_->begin(), time_->end(), timestamp);\n\n\t// Check if timestamp and found timestamp match\n\tif (timestamp == *lower) {\n\t\tvalue = *lower;\n\t\treturn true;\n\t}\n\n\tsize_t lower_pos = lower - time_->begin();\n\n\t// Get the previous timestamp for linear interpolation\n\tif (lower_pos > 0)\n\t\t--lower_pos;\n\n\tdouble lower_ts = time_->at(lower_pos);\n\tdouble lower_data = data_->at(lower_pos);\n\tsize_t upper_pos = lower_pos + 1;\n\tdouble upper_ts = time_->at(upper_pos);\n\n\t// Use linear interpolation to get the value beetween time stamps\n\tdouble ts_factor = (timestamp - lower_ts) / (upper_ts - lower_ts);\n\tdouble data_diff = data_->at(upper_pos) - lower_data;\n\tdouble lininter_data = lower_data + (data_diff * ts_factor);\n\n\tvalue = lininter_data;\n\treturn true;\n}\n\nvoid AnalogTimeSignal::push_sample(void *sample, double timestamp,\n\tsize_t unit_size, int total_digits, int sr_digits)\n{\n\tdouble dsample = 0.;\n\tif (unit_size == size_of_float_)\n\t\tdsample = static_cast<double>(*static_cast<float *>(sample));\n\telse if (unit_size == size_of_double_)\n\t\tdsample = *static_cast<double *>(sample);\n\n\t/*\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": sample = \" << dsample << \" @ \" <<  timestamp;\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": sample_count_ = \" << sample_count_+1;\n\t*/\n\n\t// TODO: Mutex?\n\tlast_timestamp_ = timestamp;\n\tlast_value_ = dsample;\n\tif (min_value_ > dsample)\n\t\tmin_value_ = dsample;\n\t// Ignore infinitiy (overflow) as max value.\n\tif (max_value_ < dsample &&\n\t\tdsample != std::numeric_limits<double>::infinity()) {\n\n\t\tmax_value_ = dsample;\n\t}\n\n\t/*\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": last_timestamp_ = \" << last_timestamp_;\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": last_value_ = \" << last_value_;\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": min_value_ = \" << min_value_;\n\tqWarning() << \"AnalogTimeSignal::push_sample(): \" << display_name()\n\t\t<< \": max_value_ = \" << max_value_;\n\t*/\n\n\t// TODO: Mutex?\n\ttime_->push_back(timestamp);\n\tdata_->push_back(dsample);\n\tsample_count_++;\n\tQ_EMIT sample_appended();\n\n\tbool digits_chngd = false;\n\tif (total_digits != total_digits_) {\n\t\ttotal_digits_ = total_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (sr_digits != sr_digits_) {\n\t\tsr_digits_ = sr_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (digits_chngd)\n\t\tQ_EMIT digits_changed(total_digits_, sr_digits_);\n}\n\nvoid AnalogTimeSignal::push_samples(void *data,\n\tuint64_t samples, double timestamp, uint64_t samplerate, size_t unit_size,\n\tint total_digits, int sr_digits)\n{\n\t//lock_guard<recursive_mutex> lock(mutex_);\n\n\tdouble dsample = 0.0;\n\tuint64_t pos = 0;\n\tdouble time_stride = 0.0;\n\tif (samplerate > 0)\n\t\ttime_stride = 1 / (double)samplerate;\n\n\t/*\n\tif (timestamp < last_timestamp_) {\n\t\tqWarning() << \"AnalogSignal::push_samples(): samples = \" << samples\n\t\t\t<<  \", timestamp < last_timestamp = \"\n\t\t\t<< timestamp-signal_start_timestamp_ << \" < \"\n\t\t\t<< last_timestamp_-signal_start_timestamp_;\n\t}\n\t*/\n\n\twhile (pos < samples) {\n\t\tif (unit_size == size_of_float_)\n\t\t\tdsample = static_cast<double>(static_cast<float *>(data)[pos]);\n\t\telse if (unit_size == size_of_double_)\n\t\t\tdsample = static_cast<double *>(data)[pos];\n\n\t\t/*\n\t\tqWarning() << \"AnalogSignal::push_samples(): \" << name_\n\t\t\t<< \": sample = \" << dsample << \" @ \"\n\t\t\t<<  timestamp - signal_start_timestamp_;\n\t\tqWarning() << \"AnalogSignal::push_samples(): \" << name_\n\t\t\t<< \": remaining_samples = \" << remaining_samples;\n\t\t*/\n\n\t\t// TODO: Mutex?\n\t\tif (min_value_ > dsample)\n\t\t\tmin_value_ = dsample;\n\t\t// Ignore infinitiy (overflow) as max value.\n\t\tif (max_value_ < dsample &&\n\t\t\tdsample != std::numeric_limits<double>::infinity()) {\n\n\t\t\tmax_value_ = dsample;\n\t\t}\n\n\t\t// TODO: Limit memory!\n\t\ttime_->push_back(timestamp);\n\t\tdata_->push_back(dsample);\n\n\t\ttimestamp += time_stride;\n\t\t++pos;\n\t\t++sample_count_;\n\t}\n\n\tlast_timestamp_ = timestamp - time_stride;\n\tlast_value_ = dsample;\n\tQ_EMIT sample_appended();\n\n\tbool digits_chngd = false;\n\tif (total_digits != total_digits_) {\n\t\ttotal_digits_ = total_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (sr_digits != sr_digits_) {\n\t\tsr_digits_ = sr_digits;\n\t\tdigits_chngd = true;\n\t}\n\tif (digits_chngd)\n\t\tQ_EMIT digits_changed(total_digits_, sr_digits_);\n}\n\ndouble AnalogTimeSignal::signal_start_timestamp() const\n{\n\treturn signal_start_timestamp_;\n}\n\ndouble AnalogTimeSignal::first_timestamp(bool relative_time) const\n{\n\tif (time_->empty())\n\t\treturn 0.;\n\n\tif (relative_time)\n\t\treturn time_->front() - signal_start_timestamp_;\n\telse // NOLINT\n\t\treturn time_->front();\n}\n\ndouble AnalogTimeSignal::last_timestamp(bool relative_time) const\n{\n\tif (time_->empty())\n\t\treturn 0.;\n\n\tif (relative_time)\n\t\treturn last_timestamp_ - signal_start_timestamp_;\n\telse // NOLINT\n\t\treturn last_timestamp_;\n}\n\nvoid AnalogTimeSignal::on_channel_start_timestamp_changed(double timestamp)\n{\n\tsignal_start_timestamp_ = timestamp;\n\tQ_EMIT signal_start_timestamp_changed(timestamp);\n}\n\nvoid AnalogTimeSignal::combine_signals(\n\tshared_ptr<AnalogTimeSignal> signal1, size_t &signal1_pos,\n\tshared_ptr<AnalogTimeSignal> signal2, size_t &signal2_pos,\n\tshared_ptr<vector<double>> time_vector,\n\tshared_ptr<vector<double>> data1_vector,\n\tshared_ptr<vector<double>> data2_vector)\n{\n\tif (signal1 == nullptr || signal1->sample_count() == 0)\n\t\treturn;\n\tif (signal2 == nullptr || signal2->sample_count() == 0)\n\t\treturn;\n\n\t// Ignore the first sample(s)\n\tif (signal1_pos == 0 || signal2_pos == 0) {\n\t\tif (signal1->sample_count() <= signal1_pos ||\n\t\t\t\tsignal2->sample_count() <= signal2_pos)\n\t\t\treturn;\n\n\t\tdouble signal1_ts = signal1->get_sample(signal1_pos, false).first;\n\t\tdouble signal2_ts = signal2->get_sample(signal2_pos, false).first;\n\t\tif (signal1_ts < signal2_ts) {\n\t\t\twhile (signal1_ts < signal2_ts &&\n\t\t\t\t\tsignal1->sample_count() > signal1_pos+1)\n\t\t\t\tsignal1_ts = signal1->get_sample(++signal1_pos, false).first;\n\t\t}\n\t\telse if (signal1_ts > signal2_ts) {\n\t\t\twhile (signal1_ts > signal2_ts &&\n\t\t\t\t\tsignal2->sample_count() > signal2_pos+1)\n\t\t\t\tsignal2_ts = signal2->get_sample(++signal2_pos, false).first;\n\t\t}\n\t}\n\n\twhile (true) {\n\t\tif (signal1->sample_count() <= signal1_pos ||\n\t\t\t\tsignal2->sample_count() <= signal2_pos)\n\t\t\tbreak;\n\n\t\tdouble time;\n\t\tdouble value1;\n\t\tdouble value2;\n\n\t\tauto signal1_sample = signal1->get_sample(signal1_pos, false);\n\t\tauto signal1_ts = signal1_sample.first;\n\t\tauto signal2_sample = signal2->get_sample(signal2_pos, false);\n\t\tauto signal2_ts = signal2_sample.first;\n\n\t\tif (signal1_ts == signal2_ts) {\n\t\t\ttime = signal1_ts;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal1_pos;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse if (signal1_ts < signal2_ts &&\n\t\t\tsignal2->sample_count() > signal2_pos) {\n\n\t\t\ttime = signal1_ts;\n\t\t\tif (!signal2->get_value_at_timestamp(time, value2, false))\n\t\t\t\treturn;\n\t\t\tvalue1 = signal1_sample.second;\n\t\t\t++signal1_pos;\n\t\t}\n\t\telse if (signal1_ts > signal2_ts &&\n\t\t\tsignal1->sample_count() > signal1_pos) {\n\n\t\t\ttime = signal2_ts;\n\t\t\tif (!signal1->get_value_at_timestamp(time, value1, false))\n\t\t\t\treturn;\n\t\t\tvalue2 = signal2_sample.second;\n\t\t\t++signal2_pos;\n\t\t}\n\t\telse {\n\t\t\treturn;\n\t\t}\n\n\t\ttime_vector->push_back(time);\n\t\tdata1_vector->push_back(value1);\n\t\tdata2_vector->push_back(value2);\n\t}\n}\n\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/analogtimesignal.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_ANALOGTIMESIGNAL_HPP\n#define DATA_ANALOGTIMESIGNAL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QObject>\n\n#include \"src/data/analogbasesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::pair;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\n\ntypedef pair<double, double> analog_time_sample_t;\n\nclass AnalogTimeSignal : public AnalogBaseSignal\n{\n\tQ_OBJECT\n\npublic:\n\tAnalogTimeSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tdouble signal_start_timestamp,\n\t\tconst string &custom_name = \"\");\n\n\t/**\n\t * Clear all samples from this signal.\n\t */\n\tvoid clear() override;\n\n\t/**\n\t * Return the sample at the given position.\n\t */\n\tanalog_time_sample_t get_sample(size_t pos, bool relative_time) const;\n\n\t/**\n\t * Return the last captured sample.\n\t */\n\tanalog_time_sample_t get_last_sample(bool relative_time) const;\n\n\t/**\n\t * Return the value at the given timestamp in &value. If there is no\n\t * exactty matching timestamp, the value is linearly interpolated. No\n\t * value can be found/interpolated, if the timestamp is smaller than the\n\t * first timestamp in the signal or bigger than the last timestamp in the\n\t * signal.\n\t *\n\t * @param timestamp The timestamp for the value to return.\n\t * @param value The found/interpolated value at the given timestamp.\n\t * @param relative_time Use time relative to the session start time.\n\t *\n\t * @return true if a value was found/interpolated, false if not.\n\t */\n\tbool get_value_at_timestamp(\n\t\tdouble timestamp, double &value, bool relative_time) const;\n\n\t/**\n\t * Push a single sample to the signal.\n\t *\n\t * TODO: Can this be removed?\n\t */\n\tvoid push_sample(void *sample, double timestamp,\n\t\tsize_t unit_size, int total_digits, int sr_digits);\n\n\t/**\n\t * Push multiple samples to the signal.\n\t */\n\tvoid push_samples(void *data, uint64_t samples, double timestamp,\n\t\tuint64_t samplerate, size_t unit_size, int total_digits, int sr_digits);\n\n\tdouble signal_start_timestamp() const;\n\tdouble first_timestamp(bool relative_time) const;\n\tdouble last_timestamp(bool relative_time) const;\n\n\t/**\n\t * Combine two signals with each other.\n\t *\n\t * E.g.:\n\t * | Time | S1 | S2 | combined S1 | combined S2 |\n\t * |------|----|----|-------------|-------------|\n\t * |    1 |  1 |    |             |             |\n\t * |    3 |  2 |    |             |             |\n\t * |    5 |  3 |    |             |             |\n\t * |    6 |    | 10 |         3.5 |          10 |\n\t * |    7 |  4 |    |           4 |         9.5 |\n\t * |    8 |    |  9 |         4.5 |           9 |\n\t * |    9 |  5 |    |           5 |         8.5 |\n\t * |   10 |    |  8 |             |             |\n\t * |   12 |    |  7 |             |             |\n\t *\n\t * TODO: Use std::deque<double>& instead of shared_ptr<vector<double>>?\n\t */\n\tstatic void combine_signals(\n\t\tshared_ptr<AnalogTimeSignal> signal1, size_t &signal1_pos,\n\t\tshared_ptr<AnalogTimeSignal> signal2, size_t &signal2_pos,\n\t\tshared_ptr<vector<double>> time_vector,\n\t\tshared_ptr<vector<double>> data1_vector,\n\t\tshared_ptr<vector<double>> data2_vector);\n\nprivate:\n\tshared_ptr<vector<double>> time_;\n\tdouble signal_start_timestamp_;\n\tdouble last_timestamp_;\n\npublic Q_SLOTS:\n\tvoid on_channel_start_timestamp_changed(double timestamp);\n\nQ_SIGNALS:\n\tvoid signal_start_timestamp_changed(double timestamp);\n\n};\n\n} // namespace data\n} // namespace sv\n\n#endif // DATA_ANALOGTIMESIGNAL_HPP\n"
  },
  {
    "path": "src/data/basesignal.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <string>\n\n#include <QDebug>\n#include <QString>\n\n#include \"basesignal.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace data {\n\nBaseSignal::BaseSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name) :\n\tquantity_(quantity),\n\tquantity_flags_(quantity_flags),\n\tunit_(unit),\n\tparent_channel_(parent_channel)\n{\n\t/* TODO\n\tif (!util::is_valid_sr_quantity(sr_quantity_))\n\t\tassert(\"Invalide quantity for BaseSignal()\");\n\t*/\n\n\tquantity_name_ = data::datautil::format_quantity(quantity_);\n\tquantity_flags_name_ = data::datautil::format_quantity_flags(\n\t\tquantity_flags_, QString(\" \"));\n\tunit_name_ = data::datautil::format_unit(unit_);\n\n\tif (custom_name.empty()) {\n\t\tname_ = parent_channel_->name() + \" [\" + unit_name_.toStdString();\n\t\tif (!quantity_flags_.empty())\n\t\t\tname_ += \" \" + quantity_flags_name_.toStdString();\n\t\tname_ += \"]\";\n\t}\n\telse {\n\t\tname_ = custom_name;\n\t}\n}\n\nBaseSignal::~BaseSignal()\n{\n\tqWarning() << \"BaseSignal::~BaseSignal(): \" << display_name();\n}\n\ndata::Quantity BaseSignal::quantity() const\n{\n\treturn quantity_;\n}\n\nQString BaseSignal::quantity_name() const\n{\n\treturn quantity_name_;\n}\n\nset<data::QuantityFlag> BaseSignal::quantity_flags() const\n{\n\treturn quantity_flags_;\n}\n\nQString BaseSignal::quantity_flags_name() const\n{\n\treturn quantity_flags_name_;\n}\n\ndata::Unit BaseSignal::unit() const\n{\n\treturn unit_;\n}\n\nQString BaseSignal::unit_name() const\n{\n\treturn unit_name_;\n}\n\nshared_ptr<channels::BaseChannel> BaseSignal::parent_channel() const\n{\n\treturn parent_channel_;\n}\n\nvoid BaseSignal::set_name(const string &custom_name)\n{\n\tif (!custom_name.empty()) {\n\t\tname_ = custom_name;\n\t\tQ_EMIT name_changed(name_);\n\t}\n}\n\nstring BaseSignal::name() const\n{\n\treturn name_;\n}\n\nQString BaseSignal::display_name() const\n{\n\treturn QString::fromStdString(name_);\n}\n\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/basesignal.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_BASESIGNAL_HPP\n#define DATA_BASESIGNAL_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QColor>\n#include <QObject>\n#include <QString>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace channels {\nclass BaseChannel;\n}\n\nnamespace data {\n\nclass BaseSignal : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tBaseSignal(\n\t\tdata::Quantity quantity,\n\t\tconst set<data::QuantityFlag> &quantity_flags,\n\t\tdata::Unit unit,\n\t\tshared_ptr<channels::BaseChannel> parent_channel,\n\t\tconst string &custom_name);\n\tvirtual ~BaseSignal();\n\npublic:\n\t/**\n\t * Clear all samples from this signal.\n\t */\n\tvirtual void clear() = 0;\n\n\t/**\n\t * Return the number of samples in this signal.\n\t */\n\tvirtual size_t sample_count() const = 0;\n\n\t/**\n\t * Return the quantity of this signal.\n\t */\n\tdata::Quantity quantity() const;\n\n\t/**\n\t * Return the quantity of this signal as string\n\t */\n\tQString quantity_name() const;\n\n\t/**\n\t * Return the quantity flags of this signal as set\n\t */\n\tset<data::QuantityFlag> quantity_flags() const;\n\n\t/**\n\t * Return the quantity flags of this signal as string\n\t */\n\tQString quantity_flags_name() const;\n\n\t/**\n\t * Return the unit of this signal\n\t */\n\tdata::Unit unit() const;\n\n\t/**\n\t * Return the unit of this signal as string\n\t */\n\tQString unit_name() const;\n\n\t/**\n\t * Return the parent channel, this signal belongs to\n\t */\n\tshared_ptr<channels::BaseChannel> parent_channel() const;\n\n\t/**\n\t * Set a custom name for this signal.\n\t */\n\tvoid set_name(const string &custom_name);\n\n\t/**\n\t * Get the name of this signal.\n\t */\n\tstring name() const;\n\n\t/**\n\t * Get the display name of this signal.\n\t */\n\tQString display_name() const;\n\nprotected:\n\tdata::Quantity quantity_;\n\tQString quantity_name_;\n\tset<data::QuantityFlag> quantity_flags_;\n\tQString quantity_flags_name_;\n\tdata::Unit unit_;\n\tQString unit_name_;\n\tshared_ptr<channels::BaseChannel> parent_channel_;\n\n\tstring name_;\n\nQ_SIGNALS:\n\tvoid name_changed(const std::string &name);\n\n};\n\n} // namespace data\n} // namespace sv\n\n#endif // DATA_BASESIGNAL_HPP\n"
  },
  {
    "path": "src/data/datautil.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <set>\n\n#include \"datautil.hpp\"\n\nusing std::set;\n\nnamespace sv {\nnamespace data {\nnamespace datautil {\n\nquantity_name_map_t get_quantity_name_map()\n{\n\treturn quantity_name_map;\n}\n\nquantity_flag_name_map_t get_quantity_flag_name_map()\n{\n\treturn quantity_flag_name_map;\n}\n\nunit_name_map_t get_unit_name_map()\n{\n\treturn unit_name_map;\n}\n\ndata_type_name_map_t get_data_type_name_map()\n{\n\treturn data_type_name_map;\n}\n\n\nQuantity get_quantity(const sigrok::Quantity *sr_quantity)\n{\n\tif (sr_quantity_quantity_map.count(sr_quantity) > 0)\n\t\treturn sr_quantity_quantity_map[sr_quantity];\n\treturn Quantity::Unknown;\n}\n\nQuantity get_quantity(uint32_t sr_quantity)\n{\n\tconst sigrok::Quantity *sr_q = sigrok::Quantity::get(\n\t\tstatic_cast<int>(sr_quantity));\n\treturn get_quantity(sr_q);\n}\n\nuint32_t get_sr_quantity_id(Quantity quantity)\n{\n\tif (quantity_sr_quantity_map.count(quantity) > 0)\n\t\treturn quantity_sr_quantity_map[quantity]->id();\n\treturn 0;\n}\n\n\nQuantityFlag get_quantity_flag(const sigrok::QuantityFlag *sr_quantity_flag)\n{\n\tif (sr_quantity_flag_quantity_flag_map.count(sr_quantity_flag) > 0)\n\t\treturn sr_quantity_flag_quantity_flag_map[sr_quantity_flag];\n\treturn QuantityFlag::Unknown;\n}\n\nuint64_t get_sr_quantity_flag_id(QuantityFlag quantity_flag)\n{\n\tif (quantity_flag_sr_quantity_flag_map.count(quantity_flag) > 0)\n\t\treturn quantity_flag_sr_quantity_flag_map[quantity_flag]->id();\n\treturn 0;\n}\n\nbool is_valid_sr_quantity(data::Quantity quantity)\n{\n\treturn quantity_sr_quantity_map.count(quantity) > 0;\n}\n\nset<QuantityFlag> get_quantity_flags(\n\tconst vector<const sigrok::QuantityFlag *> &sr_quantity_flags)\n{\n\tset<data::QuantityFlag> quantity_flag_set;\n\tfor (const auto &sr_qf : sr_quantity_flags) {\n\t\tquantity_flag_set.insert(get_quantity_flag(sr_qf));\n\t}\n\treturn quantity_flag_set;\n}\n\nset<QuantityFlag> get_quantity_flags(uint64_t sr_quantity_flags)\n{\n\tset<data::QuantityFlag> quantity_flag_set;\n\tuint64_t mask = 1;\n\tfor (uint i = 0; i < 32; i++, mask <<= 1) {\n\t\tif (!(sr_quantity_flags & mask))\n\t\t\tcontinue;\n\n\t\t// TODO: Fix in libsigrokcxx.hpp, template EnumValue:\n\t\t//       Change datatype of id from int to unsigned int.\n\t\t//       See knarfS/libsigrok#v0.6.0-wip\n\t\tconst sigrok::QuantityFlag *sr_qf =\n\t\t\tsigrok::QuantityFlag::get((int)(sr_quantity_flags & mask));\n\t\tquantity_flag_set.insert(get_quantity_flag(sr_qf));\n\t}\n\treturn quantity_flag_set;\n}\n\nuint64_t get_sr_quantity_flags_id(const set<QuantityFlag> &quantity_flags)\n{\n\tuint64_t sr_qfs_id = 0;\n\tfor (const auto &quantity_flag : quantity_flags) {\n\t\tsr_qfs_id |= get_sr_quantity_flag_id(quantity_flag);\n\t}\n\treturn sr_qfs_id;\n}\n\n\nUnit get_unit(const sigrok::Unit *sr_unit)\n{\n\tif (sr_unit_unit_map.count(sr_unit) > 0)\n\t\treturn sr_unit_unit_map[sr_unit];\n\treturn Unit::Unknown;\n}\n\n\nDataType get_data_type(const sigrok::DataType *sr_data_type)\n{\n\tif (sr_data_type_data_type_map.count(sr_data_type) > 0)\n\t\treturn sr_data_type_data_type_map[sr_data_type];\n\treturn DataType::Unknown;\n}\n\nDataType get_data_type(uint32_t sr_data_type)\n{\n\tconst sigrok::DataType *sr_dt = sigrok::DataType::get(\n\t\tstatic_cast<int>(sr_data_type));\n\treturn get_data_type(sr_dt);\n}\n\nconst sigrok::DataType *get_sr_data_type(DataType data_type)\n{\n\treturn data_type_sr_data_type_map[data_type];\n}\n\nuint32_t get_sr_data_type_id(DataType data_type)\n{\n\tif (data_type_sr_data_type_map.count(data_type) > 0)\n\t\treturn data_type_sr_data_type_map[data_type]->id();\n\treturn 0;\n}\n\nbool is_valid_sr_data_type(DataType data_type)\n{\n\treturn data_type_sr_data_type_map.count(data_type) > 0;\n}\n\n\nQString format_quantity(Quantity quantity)\n{\n\tif (quantity_name_map.count(quantity) > 0)\n\t\treturn quantity_name_map[quantity];\n\treturn quantity_name_map[Quantity::Unknown];\n}\n\nQString format_quantity_flag(QuantityFlag quantity_flag)\n{\n\tif (quantity_flag_name_map.count(quantity_flag) > 0)\n\t\treturn quantity_flag_name_map[quantity_flag];\n\treturn quantity_flag_name_map[QuantityFlag::Unknown];\n}\n\nQString format_quantity_flags(const set<QuantityFlag> &quantity_flags,\n\tconst QString &seperator)\n{\n\tQString qfs_str(\"\");\n\tQString sep(\"\");\n\n\t// Show AC/DC first\n\tif (quantity_flags.count(QuantityFlag::AC) > 0) {\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::AC]);\n\t\tsep = seperator;\n\t}\n\tif (quantity_flags.count(QuantityFlag::DC) > 0) {\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::DC]);\n\t\tsep = seperator;\n\t}\n\t// 2nd is RMS\n\tif (quantity_flags.count(QuantityFlag::RMS) > 0) {\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::RMS]);\n\t\tsep = seperator;\n\t}\n\t// 3rd is min/max/avg\n\tif (quantity_flags.count(QuantityFlag::Min) > 0) {\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::Min]);\n\t\tsep = seperator;\n\t}\n\tif (quantity_flags.count(QuantityFlag::Max) > 0) {\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::Max]);\n\t\tsep = seperator;\n\t}\n\tif (quantity_flags.count(QuantityFlag::Avg) > 0) {\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[QuantityFlag::Avg]);\n\t\tsep = seperator;\n\t}\n\n\t// And now the rest of the flags\n\tfor (const auto &qf : quantity_flags) {\n\t\tif (qf == QuantityFlag::AC || qf == QuantityFlag::DC ||\n\t\t\t\tqf == QuantityFlag::RMS || qf == QuantityFlag::Min ||\n\t\t\t\tqf == QuantityFlag::Max || qf == QuantityFlag::Avg)\n\t\t\tcontinue;\n\n\t\tif (quantity_flag_name_map.count(qf) == 0)\n\t\t\tcontinue;\n\n\t\tqfs_str.append(sep);\n\t\tqfs_str.append(quantity_flag_name_map[qf]);\n\t\tsep = seperator;\n\t}\n\n\treturn qfs_str;\n}\n\nQString format_measured_quantity(const measured_quantity_t &measured_quantity)\n{\n\tQuantity q = measured_quantity.first; // NOLINT(readability-identifier-length)\n\tset<QuantityFlag> qfs = measured_quantity.second;\n\tQString q_qfs_str = format_quantity(q);\n\tif (!qfs.empty())\n\t\tq_qfs_str.append(\" \").append(format_quantity_flags(qfs, \" \"));\n\n\treturn q_qfs_str;\n}\n\nQString format_unit(Unit unit)\n{\n\tif (unit_name_map.count(unit) > 0)\n\t\treturn unit_name_map[unit];\n\treturn unit_name_map[Unit::Unknown];\n}\n\nQString format_unit(Unit unit, const set<QuantityFlag> &quantity_flags)\n{\n\tQString unit_str = format_unit(unit);\n\tif (unit == Unit::Volt || unit == Unit::Ampere) {\n\t\tif (quantity_flags.count(QuantityFlag::AC) > 0) {\n\t\t\tunit_str = unit_str.append(\" \").append(\n\t\t\t\tformat_quantity_flag(QuantityFlag::AC));\n\t\t}\n\t\tif (quantity_flags.count(QuantityFlag::DC) > 0) {\n\t\t\tunit_str = unit_str.append(\" \").append(\n\t\t\t\tformat_quantity_flag(QuantityFlag::DC));\n\t\t}\n\t}\n\treturn unit_str;\n}\n\nQString format_data_type(DataType data_type)\n{\n\tif (data_type_name_map.count(data_type) > 0)\n\t\treturn data_type_name_map[data_type];\n\treturn data_type_name_map[DataType::Unknown];\n}\n\n\nset<data::Unit> get_units_from_quantity(data::Quantity quantity)\n{\n\tset<data::Unit> units;\n\tif (quantity_unit_map.count(quantity) > 0)\n\t\tunits = quantity_unit_map[quantity];\n\treturn units;\n}\n\n} // namespace datautil\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/datautil.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_DATAUTIL_HPP\n#define DATA_DATAUTIL_HPP\n\n#include <map>\n#include <set>\n#include <vector>\n#include <utility>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QObject>\n#include <QString>\n\nusing std::map;\nusing std::pair;\nusing std::set;\nusing std::vector;\n\nnamespace sigrok {\nclass Quantity;\nclass QuantityFlag;\nclass Unit;\n}\n\nnamespace sv {\nnamespace data {\n\n/**\n * The default value for the total digits used for incomming analog data\n * and for formating values in views, etc.\n */\nconst int DefaultTotalDigits = 6;\n\n/**\n * The default value for sr_digits for all cases it is not available, e.g. for\n * the math channels\n */\nconst int DefaultSRDigits = 0;\n\n/**\n * The default value for decimal places for all cases where the decimal places\n * cannot be calculated, e.g. the min/max displays.\n */\nconst int DefaultDecimalPlaces = 2;\n\nenum class Quantity\n{\n\tVoltage,\n\tCurrent,\n\tResistance,\n\tCapacitance,\n\tTemperature,\n\tFrequency,\n\tDutyCyle,\n\tContinuity,\n\tPulseWidth,\n\tConductance,\n\t/** Electrical power, usually in W, or dBm. */\n\tPower,\n\t/** TODO: Implement in libsigrok */\n\tElectricCharge,\n\t/** Gain (a transistor's gain, or hFE, for example). */\n\tGain,\n\t/**\n\t * Logarithmic representation of sound pressure relative to a\n\t * reference value.\n\t */\n\tSoundPressureLevel,\n\tCarbonMonoxide,\n\tRelativeHumidity,\n\tTime,\n\tWindSpeed,\n\tPressure,\n\tParallelInductance,\n\tParallelCapacitance,\n\tParallelResistance,\n\tSeriesInductance,\n\tSeriesCapacitance,\n\tSeriesResistance,\n\tDissipationFactor,\n\tQualityFactor,\n\tPhaseAngle,\n\t/** Difference from reference value. */\n\tDifference,\n\tCount,\n\tPowerFactor,\n\tApparentPower,\n\tMass,\n\tHarmonicRatio,\n\tEnergy,\n\tUnknown,\n};\n\nenum class QuantityFlag\n{\n\tAC,\n\tDC,\n\tRMS,\n\t/** Value is voltage drop across a diode, or NAN. */\n\tDiode,\n\t/** Device is in \"hold\" mode (repeating the last measurement). */\n\tHold,\n\t/** Device is in \"max\" mode, only updating upon a new max value. */\n\tMax,\n\t/** Device is in \"min\" mode, only updating upon a new min value. */\n\tMin,\n\tAutorange,\n\tRelative,\n\t/**\n\t * Sound pressure level is A-weighted in the frequency domain,\n\t * according to IEC 61672:2003.\n\t */\n\tSplFreqWeightA,\n\t/**\n\t * Sound pressure level is C-weighted in the frequency domain,\n\t * according to IEC 61672:2003.\n\t */\n\tSplFreqWeightC,\n\t/** Sound pressure level is Z-weighted */\n\tSplFreqWeightZ,\n\t/**\n\t * Sound pressure level is not weighted in the frequency domain, albeit\n\t * without standards-defined low and high frequency limits.\n\t */\n\tSplFreqWeightFlat,\n\t/**\n\t * Sound pressure level measurement is S-weighted (1s) in the time domain.\n\t */\n\tSplTimeWeightS,\n\t/**\n\t * Sound pressure level measurement is F-weighted (125ms) in the\n\t * time domain.\n\t */\n\tSplTimeWeightF,\n\t/**\n\t * Sound pressure level is time-averaged (LAT), also known as\n\t * Equivalent Continuous A-weighted Sound Level (LEQ).\n\t */\n\tSplLAT,\n\t/**\n\t * Sound pressure level represented as a percentage of measurements that\n\t * were over a preset alarm level.\n\t */\n\tSplPctOverAlarm,\n\t/** Time is duration (as opposed to epoch, ...). */\n\tDuration,\n\t/** Device is in \"avg\" mode, averaging upon each new value. */\n\tAvg,\n\t/** Reference value shown. */\n\tReference,\n\t/** Unstable value (hasn't settled yet). */\n\tUnstable,\n\tFourWire,\n\tUnknown,\n};\n\nenum class Unit\n{\n\tVolt,\n\tAmpere,\n\tOhm,\n\tFarad,\n\tKelvin,\n\tCelsius,\n\tFahrenheit,\n\tHertz,\n\tPercentage,\n\tBoolean,\n\tSecond,\n\tSiemens,\n\tDecibelMW,\n\tDecibelVolt,\n\tUnitless,\n\tDecibelSpl,\n\tConcentration,\n\tRevolutionsPerMinute,\n\tVoltAmpere,\n\tWatt,\n\tWattHour,\n\tJoule,\n\tAmpereHour,\n\tCoulomb,\n\tMeterPerSecond,\n\tHectoPascal,\n\tHumidity293K,\n\tDegree,\n\tHenry,\n\tGram,\n\tCarat,\n\t/** Avoirdupois ounce (oz) */\n\tOunce,\n\t/** Troy ounce (oz t) */\n\tTroyOunce,\n\t/** Avoirdupois pound (lb) */\n\tPound,\n\tPennyweight,\n\tGrain,\n\tTael,\n\tMomme,\n\tTola,\n\tPiece,\n\t// TODO: Implement in libsigrok\n\t//Decibel,\n\tUnknown,\n};\n\nenum class DataType\n{\n\tUInt64,\n\tString,\n\tBool,\n\tDouble,\n\tRationalPeriod,\n\tRationalVolt,\n\tKeyValue,\n\tUInt64Range,\n\tDoubleRange,\n\tInt32,\n\tMQ,\n\tUnknown,\n};\n\ntypedef pair<Quantity, set<QuantityFlag>> measured_quantity_t;\ntypedef pair<double, double> double_range_t;\n/**\n * Normaly <int64_t, uint64_t> should be used, but <uint64_t, uint64_t>\n * is transfered in the config keys\n */\ntypedef pair<uint64_t, uint64_t> rational_t;\ntypedef pair<uint64_t, uint64_t> uint64_range_t;\n\nnamespace datautil {\n\ntypedef map<Quantity, QString> quantity_name_map_t;\ntypedef map<QuantityFlag, QString> quantity_flag_name_map_t;\ntypedef map<Unit, QString> unit_name_map_t;\ntypedef map<DataType, QString> data_type_name_map_t;\n\nnamespace {\n\ntypedef map<Quantity, set<Unit>> quantity_unit_map_t;\n\n// TODO: Use tr(), QCoreApplication::translate(), QT_TR_NOOP() or\n//       QT_TRANSLATE_NOOP() for translation.\n//       See: http://doc.qt.io/qt-5/i18n-source-translation.html\nquantity_name_map_t quantity_name_map = {\n\t{ Quantity::Voltage, QString(\"Voltage\") },\n\t{ Quantity::Current, QString(\"Current\") },\n\t{ Quantity::Resistance, QString(\"Resistance\") },\n\t{ Quantity::Capacitance, QString(\"Capacitance\") },\n\t{ Quantity::Temperature, QString(\"Temperature\") },\n\t{ Quantity::Frequency, QString(\"Frequency\") },\n\t{ Quantity::DutyCyle, QString(\"Duty Cycle\") },\n\t{ Quantity::Continuity, QString(\"Continuity\") },\n\t{ Quantity::PulseWidth, QString(\"Pulse Width\") },\n\t{ Quantity::Conductance, QString(\"Conductance\") },\n\t{ Quantity::Power, QString(\"Power\") },\n\t{ Quantity::ElectricCharge, QString(\"Electric Charge\") },\n\t{ Quantity::Gain, QString(\"Gain\") },\n\t{ Quantity::SoundPressureLevel, QString(\"Sound Pressure Level\") },\n\t{ Quantity::CarbonMonoxide, QString(\"Carbon Monoxide\") },\n\t{ Quantity::RelativeHumidity, QString(\"Relative Humidity\") },\n\t{ Quantity::Time, QString(\"Time\") },\n\t{ Quantity::WindSpeed, QString(\"Wind Speed\") },\n\t{ Quantity::Pressure, QString(\"Pressure\") },\n\t{ Quantity::ParallelInductance, QString(\"Parallel Inductance\") },\n\t{ Quantity::ParallelCapacitance, QString(\"Parallel Capacitance\") },\n\t{ Quantity::ParallelResistance, QString(\"Parallel Resistance\") },\n\t{ Quantity::SeriesInductance, QString(\"Series Inductance\") },\n\t{ Quantity::SeriesCapacitance, QString(\"Series Capacitance\") },\n\t{ Quantity::SeriesResistance, QString(\"Series Resistance\") },\n\t{ Quantity::DissipationFactor, QString(\"Dissipation Factor\") },\n\t{ Quantity::QualityFactor, QString(\"Quality Factor\") },\n\t{ Quantity::PhaseAngle, QString(\"Phase Angle\") },\n\t{ Quantity::Difference, QString(\"Difference\") },\n\t{ Quantity::Count, QString(\"Count\") },\n\t{ Quantity::PowerFactor, QString(\"Power Factor\") },\n\t{ Quantity::ApparentPower, QString(\"Apparent Power\") },\n\t{ Quantity::Mass, QString(\"Mass\") },\n\t{ Quantity::HarmonicRatio, QString(\"Harmonic Ratio\") },\n\t{ Quantity::Energy, QString(\"Energy\") },\n\t{ Quantity::Unknown, QString(\"Unknown\") },\n};\n\nquantity_flag_name_map_t quantity_flag_name_map = {\n\t{ QuantityFlag::AC, QString(\"AC\") },\n\t{ QuantityFlag::DC, QString(\"DC\") },\n\t{ QuantityFlag::RMS, QString(\"RMS\") },\n\t{ QuantityFlag::Diode, QString(\"Diode\") },\n\t{ QuantityFlag::Hold, QString(\"Hold\") },\n\t{ QuantityFlag::Max, QString(\"max\") },\n\t{ QuantityFlag::Min, QString(\"min\") },\n\t{ QuantityFlag::Autorange, QString(\"Autorange\") },\n\t{ QuantityFlag::Relative, QString(\"Relative\") },\n\t{ QuantityFlag::SplFreqWeightA, QString(\"SPL A-weighted F\") },\n\t{ QuantityFlag::SplFreqWeightC, QString(\"SPL C-weighted F\") },\n\t{ QuantityFlag::SplFreqWeightZ, QString(\"SPL Z-weighted F\") },\n\t{ QuantityFlag::SplFreqWeightFlat, QString(\"SPL flat weighted\") },\n\t{ QuantityFlag::SplTimeWeightS, QString(\"SPL S-weighted t\") },\n\t{ QuantityFlag::SplTimeWeightF, QString(\"SPL F-weighted t\") },\n\t{ QuantityFlag::SplLAT, QString(\"SPL LAT\") },\n\t{ QuantityFlag::SplPctOverAlarm, QString(\"SPL Over%\") },\n\t{ QuantityFlag::Duration, QString(\"Duration\") },\n\t{ QuantityFlag::Avg, QString(\"avg\") },\n\t{ QuantityFlag::Reference, QString(\"Reference\") },\n\t{ QuantityFlag::Unstable, QString(\"Unstable\") },\n\t{ QuantityFlag::FourWire, QString(\"4W\") },\n\t{ QuantityFlag::Unknown, QString(\"Unknown\") },\n};\n\nunit_name_map_t unit_name_map = {\n\t{ Unit::Volt, QString(\"V\") },\n\t{ Unit::Ampere, QString(\"A\") },\n\t{ Unit::Ohm, QString::fromUtf8(\"\\u2126\") },\n\t{ Unit::Farad, QString(\"F\") },\n\t{ Unit::Kelvin, QString(\"K\") },\n\t{ Unit::Celsius, QString(\"°C\") },\n\t{ Unit::Fahrenheit, QString(\"°F\") },\n\t{ Unit::Hertz, QString(\"Hz\") },\n\t{ Unit::Percentage, QString(\"%\") },\n\t{ Unit::Boolean, QString(\"bool\") },\n\t{ Unit::Second, QString(\"s\") },\n\t{ Unit::Siemens, QString(\"S\") },\n\t{ Unit::DecibelMW, QString(\"dBm\") },\n\t{ Unit::DecibelVolt, QString(\"dBV\") },\n\t{ Unit::Unitless, QString(\"\") },\n\t{ Unit::DecibelSpl, QString(\"dB\") },\n\t{ Unit::Concentration, QString(\"ppx\") },\n\t{ Unit::RevolutionsPerMinute, QString(\"RPM\") },\n\t{ Unit::VoltAmpere, QString(\"VA\") },\n\t{ Unit::Watt, QString(\"W\") },\n\t{ Unit::WattHour, QString(\"Wh\") },\n\t{ Unit::MeterPerSecond, QString(\"m/s\") },\n\t{ Unit::HectoPascal, QString(\"hPa\") },\n\t{ Unit::Humidity293K, QString(\"%\") },\n\t{ Unit::Degree, QString(\"°\") },\n\t{ Unit::Henry, QString(\"H\") },\n\t{ Unit::Gram, QString(\"g\") },\n\t{ Unit::Carat, QString(\"ct\") },\n\t{ Unit::Ounce, QString(\"oz.\") },\n\t{ Unit::TroyOunce, QString(\"oz.tr.\") },\n\t{ Unit::Pound, QString(\"lb\") },\n\t{ Unit::Pennyweight, QString(\"dwt.\") },\n\t{ Unit::Grain, QString(\"gr.\") },\n\t{ Unit::Tael, QString::fromUtf8(\"\\u4E24\") },\n\t{ Unit::Momme, QString::fromUtf8(\"\\u5301\") },\n\t{ Unit::Tola, QString(\"tola\") },\n\t{ Unit::Piece, QString(\"pc.\") },\n\t{ Unit::Joule, QString(\"J\") },\n\t{ Unit::AmpereHour, QString(\"Ah\") },\n\t{ Unit::Coulomb, QString(\"C\") },\n\t// TODO: Implement in libsigrok\n\t//{ Unit::Decibel, QString(\"dB\") },\n\t{ Unit::Unknown, QString(\"??\") },\n};\n\ndata_type_name_map_t data_type_name_map = {\n\t{ DataType::UInt64, QString(\"UInt64\") },\n\t{ DataType::String, QString(\"String\") },\n\t{ DataType::Bool, QString(\"Boolean\") },\n\t{ DataType::Double, QString(\"Double\") },\n\t{ DataType::RationalPeriod, QString(\"Rational Period\") },\n\t{ DataType::RationalVolt, QString(\"Rational Volt\") },\n\t{ DataType::KeyValue, QString(\"Key Value\") },\n\t{ DataType::UInt64Range, QString(\"UInt64 Range\") },\n\t{ DataType::DoubleRange, QString(\"Double Range\") },\n\t{ DataType::Int32, QString(\"Int32\") },\n\t{ DataType::MQ, QString(\"Measured Quantity\") },\n\t{ DataType::Unknown, QString(\"Unknown\") },\n};\n\nmap<const sigrok::Quantity *, Quantity> sr_quantity_quantity_map = {\n\t{ sigrok::Quantity::VOLTAGE, Quantity::Voltage },\n\t{ sigrok::Quantity::CURRENT, Quantity::Current },\n\t{ sigrok::Quantity::RESISTANCE, Quantity::Resistance },\n\t{ sigrok::Quantity::CAPACITANCE, Quantity::Capacitance },\n\t{ sigrok::Quantity::TEMPERATURE, Quantity::Temperature },\n\t{ sigrok::Quantity::FREQUENCY, Quantity::Frequency },\n\t{ sigrok::Quantity::DUTY_CYCLE, Quantity::DutyCyle },\n\t{ sigrok::Quantity::CONTINUITY, Quantity::Continuity },\n\t{ sigrok::Quantity::PULSE_WIDTH, Quantity::PulseWidth },\n\t{ sigrok::Quantity::CONDUCTANCE, Quantity::Conductance },\n\t{ sigrok::Quantity::POWER, Quantity::Power },\n\t{ sigrok::Quantity::GAIN, Quantity::Gain },\n\t{ sigrok::Quantity::SOUND_PRESSURE_LEVEL, Quantity::SoundPressureLevel },\n\t{ sigrok::Quantity::CARBON_MONOXIDE, Quantity::CarbonMonoxide },\n\t{ sigrok::Quantity::RELATIVE_HUMIDITY, Quantity::RelativeHumidity },\n\t{ sigrok::Quantity::TIME, Quantity::Time },\n\t{ sigrok::Quantity::WIND_SPEED, Quantity::WindSpeed },\n\t{ sigrok::Quantity::PRESSURE, Quantity::Pressure },\n\t{ sigrok::Quantity::PARALLEL_INDUCTANCE, Quantity::ParallelInductance },\n\t{ sigrok::Quantity::PARALLEL_CAPACITANCE, Quantity::ParallelCapacitance },\n\t{ sigrok::Quantity::PARALLEL_RESISTANCE, Quantity::ParallelResistance },\n\t{ sigrok::Quantity::SERIES_INDUCTANCE, Quantity::SeriesInductance },\n\t{ sigrok::Quantity::SERIES_CAPACITANCE, Quantity::SeriesCapacitance },\n\t{ sigrok::Quantity::SERIES_RESISTANCE, Quantity::SeriesResistance },\n\t{ sigrok::Quantity::DISSIPATION_FACTOR, Quantity::DissipationFactor },\n\t{ sigrok::Quantity::QUALITY_FACTOR, Quantity::QualityFactor },\n\t{ sigrok::Quantity::PHASE_ANGLE, Quantity::PhaseAngle },\n\t{ sigrok::Quantity::DIFFERENCE, Quantity::Difference },\n\t{ sigrok::Quantity::COUNT, Quantity::Count },\n\t{ sigrok::Quantity::POWER_FACTOR, Quantity::PowerFactor },\n\t{ sigrok::Quantity::APPARENT_POWER, Quantity::ApparentPower },\n\t{ sigrok::Quantity::MASS, Quantity::Mass },\n\t{ sigrok::Quantity::HARMONIC_RATIO, Quantity::HarmonicRatio },\n\t{ sigrok::Quantity::ENERGY, Quantity::Energy },\n};\n\nmap<Quantity, const sigrok::Quantity *> quantity_sr_quantity_map = {\n\t{ Quantity::Voltage, sigrok::Quantity::VOLTAGE },\n\t{ Quantity::Current, sigrok::Quantity::CURRENT },\n\t{ Quantity::Resistance, sigrok::Quantity::RESISTANCE },\n\t{ Quantity::Capacitance, sigrok::Quantity::CAPACITANCE },\n\t{ Quantity::Temperature, sigrok::Quantity::TEMPERATURE },\n\t{ Quantity::Frequency, sigrok::Quantity::FREQUENCY },\n\t{ Quantity::DutyCyle, sigrok::Quantity::DUTY_CYCLE },\n\t{ Quantity::Continuity, sigrok::Quantity::CONTINUITY },\n\t{ Quantity::PulseWidth, sigrok::Quantity::PULSE_WIDTH },\n\t{ Quantity::Conductance, sigrok::Quantity::CONDUCTANCE },\n\t{ Quantity::Power, sigrok::Quantity::POWER },\n\t{ Quantity::Gain, sigrok::Quantity::GAIN },\n\t{ Quantity::SoundPressureLevel, sigrok::Quantity::SOUND_PRESSURE_LEVEL },\n\t{ Quantity::CarbonMonoxide, sigrok::Quantity::CARBON_MONOXIDE },\n\t{ Quantity::RelativeHumidity, sigrok::Quantity::RELATIVE_HUMIDITY },\n\t{ Quantity::Time, sigrok::Quantity::TIME },\n\t{ Quantity::WindSpeed, sigrok::Quantity::WIND_SPEED },\n\t{ Quantity::Pressure, sigrok::Quantity::PRESSURE },\n\t{ Quantity::ParallelInductance, sigrok::Quantity::PARALLEL_INDUCTANCE },\n\t{ Quantity::ParallelCapacitance, sigrok::Quantity::PARALLEL_CAPACITANCE },\n\t{ Quantity::ParallelResistance, sigrok::Quantity::PARALLEL_RESISTANCE },\n\t{ Quantity::SeriesInductance, sigrok::Quantity::SERIES_INDUCTANCE },\n\t{ Quantity::SeriesCapacitance,  sigrok::Quantity::SERIES_CAPACITANCE },\n\t{ Quantity::SeriesResistance, sigrok::Quantity::SERIES_RESISTANCE },\n\t{ Quantity::DissipationFactor, sigrok::Quantity::DISSIPATION_FACTOR },\n\t{ Quantity::QualityFactor, sigrok::Quantity::QUALITY_FACTOR },\n\t{ Quantity::PhaseAngle, sigrok::Quantity::PHASE_ANGLE },\n\t{ Quantity::Difference, sigrok::Quantity::DIFFERENCE },\n\t{ Quantity::Count, sigrok::Quantity::COUNT },\n\t{ Quantity::PowerFactor, sigrok::Quantity::POWER_FACTOR },\n\t{ Quantity::ApparentPower, sigrok::Quantity::APPARENT_POWER },\n\t{ Quantity::Mass, sigrok::Quantity::MASS },\n\t{ Quantity::HarmonicRatio, sigrok::Quantity::HARMONIC_RATIO },\n\t{ Quantity::Energy, sigrok::Quantity::ENERGY },\n};\n\nmap<const sigrok::QuantityFlag *, QuantityFlag> sr_quantity_flag_quantity_flag_map = {\n\t{ sigrok::QuantityFlag::AC, QuantityFlag::AC },\n\t{ sigrok::QuantityFlag::DC, QuantityFlag::DC },\n\t{ sigrok::QuantityFlag::RMS, QuantityFlag::RMS },\n\t{ sigrok::QuantityFlag::DIODE, QuantityFlag::Diode },\n\t{ sigrok::QuantityFlag::HOLD, QuantityFlag::Hold },\n\t{ sigrok::QuantityFlag::MAX, QuantityFlag::Max },\n\t{ sigrok::QuantityFlag::MIN, QuantityFlag::Min },\n\t{ sigrok::QuantityFlag::AUTORANGE, QuantityFlag::Autorange },\n\t{ sigrok::QuantityFlag::RELATIVE, QuantityFlag::Relative },\n\t{ sigrok::QuantityFlag::SPL_FREQ_WEIGHT_A, QuantityFlag::SplFreqWeightA },\n\t{ sigrok::QuantityFlag::SPL_FREQ_WEIGHT_C, QuantityFlag::SplFreqWeightC },\n\t{ sigrok::QuantityFlag::SPL_FREQ_WEIGHT_Z, QuantityFlag::SplFreqWeightZ },\n\t{ sigrok::QuantityFlag::SPL_FREQ_WEIGHT_FLAT, QuantityFlag::SplFreqWeightFlat },\n\t{ sigrok::QuantityFlag::SPL_TIME_WEIGHT_S, QuantityFlag::SplTimeWeightS },\n\t{ sigrok::QuantityFlag::SPL_TIME_WEIGHT_F, QuantityFlag::SplTimeWeightF },\n\t{ sigrok::QuantityFlag::SPL_LAT, QuantityFlag::SplLAT },\n\t{ sigrok::QuantityFlag::SPL_PCT_OVER_ALARM, QuantityFlag::SplPctOverAlarm },\n\t{ sigrok::QuantityFlag::DURATION, QuantityFlag::Duration },\n\t{ sigrok::QuantityFlag::AVG, QuantityFlag::Avg },\n\t{ sigrok::QuantityFlag::REFERENCE, QuantityFlag::Reference },\n\t{ sigrok::QuantityFlag::UNSTABLE, QuantityFlag::Unstable },\n\t{ sigrok::QuantityFlag::FOUR_WIRE, QuantityFlag::FourWire },\n};\n\nmap<QuantityFlag, const sigrok::QuantityFlag *> quantity_flag_sr_quantity_flag_map = {\n\t{ QuantityFlag::AC, sigrok::QuantityFlag::AC },\n\t{ QuantityFlag::DC, sigrok::QuantityFlag::DC },\n\t{ QuantityFlag::RMS, sigrok::QuantityFlag::RMS },\n\t{ QuantityFlag::Diode, sigrok::QuantityFlag::DIODE },\n\t{ QuantityFlag::Hold, sigrok::QuantityFlag::HOLD },\n\t{ QuantityFlag::Max, sigrok::QuantityFlag::MAX },\n\t{ QuantityFlag::Min, sigrok::QuantityFlag::MIN },\n\t{ QuantityFlag::Autorange, sigrok::QuantityFlag::AUTORANGE },\n\t{ QuantityFlag::Relative, sigrok::QuantityFlag::RELATIVE },\n\t{ QuantityFlag::SplFreqWeightA, sigrok::QuantityFlag::SPL_FREQ_WEIGHT_A },\n\t{ QuantityFlag::SplFreqWeightC, sigrok::QuantityFlag::SPL_FREQ_WEIGHT_C },\n\t{ QuantityFlag::SplFreqWeightZ, sigrok::QuantityFlag::SPL_FREQ_WEIGHT_Z },\n\t{ QuantityFlag::SplFreqWeightFlat, sigrok::QuantityFlag::SPL_FREQ_WEIGHT_FLAT },\n\t{ QuantityFlag::SplTimeWeightS, sigrok::QuantityFlag::SPL_TIME_WEIGHT_S },\n\t{ QuantityFlag::SplTimeWeightF, sigrok::QuantityFlag::SPL_TIME_WEIGHT_F },\n\t{ QuantityFlag::SplLAT, sigrok::QuantityFlag::SPL_LAT },\n\t{ QuantityFlag::SplPctOverAlarm, sigrok::QuantityFlag::SPL_PCT_OVER_ALARM },\n\t{ QuantityFlag::Duration, sigrok::QuantityFlag::DURATION },\n\t{ QuantityFlag::Avg, sigrok::QuantityFlag::AVG },\n\t{ QuantityFlag::Reference, sigrok::QuantityFlag::REFERENCE },\n\t{ QuantityFlag::Unstable, sigrok::QuantityFlag::UNSTABLE },\n\t{ QuantityFlag::FourWire, sigrok::QuantityFlag::FOUR_WIRE },\n};\n\nmap<const sigrok::Unit *, Unit> sr_unit_unit_map = {\n\t{ sigrok::Unit::VOLT, Unit::Volt },\n\t{ sigrok::Unit::AMPERE, Unit::Ampere },\n\t{ sigrok::Unit::OHM, Unit::Ohm },\n\t{ sigrok::Unit::FARAD, Unit::Farad },\n\t{ sigrok::Unit::KELVIN, Unit::Kelvin },\n\t{ sigrok::Unit::CELSIUS, Unit::Celsius },\n\t{ sigrok::Unit::FAHRENHEIT, Unit::Fahrenheit },\n\t{ sigrok::Unit::HERTZ, Unit::Hertz },\n\t{ sigrok::Unit::PERCENTAGE, Unit::Percentage },\n\t{ sigrok::Unit::BOOLEAN, Unit::Boolean },\n\t{ sigrok::Unit::SECOND, Unit::Second },\n\t{ sigrok::Unit::SIEMENS, Unit::Siemens },\n\t{ sigrok::Unit::DECIBEL_MW, Unit::DecibelMW },\n\t{ sigrok::Unit::DECIBEL_VOLT, Unit::DecibelVolt },\n\t{ sigrok::Unit::UNITLESS, Unit::Unitless },\n\t{ sigrok::Unit::DECIBEL_SPL, Unit::DecibelSpl },\n\t{ sigrok::Unit::CONCENTRATION, Unit::Concentration },\n\t{ sigrok::Unit::REVOLUTIONS_PER_MINUTE, Unit::RevolutionsPerMinute },\n\t{ sigrok::Unit::VOLT_AMPERE, Unit::VoltAmpere },\n\t{ sigrok::Unit::WATT, Unit::Watt },\n\t{ sigrok::Unit::WATT_HOUR, Unit::WattHour },\n\t{ sigrok::Unit::METER_SECOND, Unit::MeterPerSecond },\n\t{ sigrok::Unit::HECTOPASCAL, Unit::HectoPascal },\n\t{ sigrok::Unit::HUMIDITY_293K, Unit::Humidity293K },\n\t{ sigrok::Unit::DEGREE, Unit::Degree },\n\t{ sigrok::Unit::HENRY, Unit::Henry },\n\t{ sigrok::Unit::GRAM, Unit::Gram },\n\t{ sigrok::Unit::CARAT, Unit::Carat },\n\t{ sigrok::Unit::OUNCE, Unit::Ounce },\n\t{ sigrok::Unit::TROY_OUNCE, Unit::TroyOunce },\n\t{ sigrok::Unit::POUND, Unit::Pound },\n\t{ sigrok::Unit::PENNYWEIGHT, Unit::Pennyweight },\n\t{ sigrok::Unit::GRAIN, Unit::Grain },\n\t{ sigrok::Unit::TAEL, Unit::Tael },\n\t{ sigrok::Unit::MOMME, Unit::Momme },\n\t{ sigrok::Unit::TOLA, Unit::Tola },\n\t{ sigrok::Unit::PIECE, Unit::Piece },\n\t{ sigrok::Unit::JOULE, Unit::Joule },\n\t{ sigrok::Unit::COULOMB, Unit::Coulomb },\n\t{ sigrok::Unit::AMPERE_HOUR, Unit::AmpereHour },\n};\n\nmap<Unit, const sigrok::Unit *> unit_sr_unit_map = {\n\t{ Unit::Volt, sigrok::Unit::VOLT },\n\t{ Unit::Ampere, sigrok::Unit::AMPERE },\n\t{ Unit::Ohm, sigrok::Unit::OHM },\n\t{ Unit::Farad, sigrok::Unit::FARAD },\n\t{ Unit::Kelvin, sigrok::Unit::KELVIN },\n\t{ Unit::Celsius, sigrok::Unit::CELSIUS },\n\t{ Unit::Fahrenheit, sigrok::Unit::FAHRENHEIT },\n\t{ Unit::Hertz, sigrok::Unit::HERTZ },\n\t{ Unit::Percentage, sigrok::Unit::PERCENTAGE },\n\t{ Unit::Boolean, sigrok::Unit::BOOLEAN },\n\t{ Unit::Second, sigrok::Unit::SECOND },\n\t{ Unit::Siemens, sigrok::Unit::SIEMENS },\n\t{ Unit::DecibelMW, sigrok::Unit::DECIBEL_MW },\n\t{ Unit::DecibelVolt, sigrok::Unit::DECIBEL_VOLT },\n\t{ Unit::Unitless, sigrok::Unit::UNITLESS },\n\t{ Unit::DecibelSpl, sigrok::Unit::DECIBEL_SPL },\n\t{ Unit::Concentration, sigrok::Unit::CONCENTRATION },\n\t{ Unit::RevolutionsPerMinute, sigrok::Unit::REVOLUTIONS_PER_MINUTE },\n\t{ Unit::VoltAmpere, sigrok::Unit::VOLT_AMPERE },\n\t{ Unit::Watt, sigrok::Unit::WATT },\n\t{ Unit::WattHour, sigrok::Unit::WATT_HOUR },\n\t{ Unit::MeterPerSecond, sigrok::Unit::METER_SECOND },\n\t{ Unit::HectoPascal, sigrok::Unit::HECTOPASCAL },\n\t{ Unit::Humidity293K, sigrok::Unit::HUMIDITY_293K },\n\t{ Unit::Degree, sigrok::Unit::DEGREE },\n\t{ Unit::Henry, sigrok::Unit::HENRY },\n\t{ Unit::Gram, sigrok::Unit::GRAM },\n\t{ Unit::Carat, sigrok::Unit::CARAT },\n\t{ Unit::Ounce, sigrok::Unit::OUNCE },\n\t{ Unit::TroyOunce, sigrok::Unit::TROY_OUNCE },\n\t{ Unit::Pound, sigrok::Unit::POUND },\n\t{ Unit::Pennyweight, sigrok::Unit::PENNYWEIGHT },\n\t{ Unit::Grain, sigrok::Unit::GRAIN },\n\t{ Unit::Tael, sigrok::Unit::TAEL },\n\t{ Unit::Momme, sigrok::Unit::MOMME },\n\t{ Unit::Tola, sigrok::Unit::TOLA },\n\t{ Unit::Piece, sigrok::Unit::PIECE },\n\t{ Unit::Joule, sigrok::Unit::JOULE },\n\t{ Unit::Coulomb, sigrok::Unit::COULOMB },\n\t{ Unit::AmpereHour, sigrok::Unit::AMPERE_HOUR },\n};\n\nmap<const sigrok::DataType *, DataType> sr_data_type_data_type_map = {\n\t{ sigrok::DataType::UINT64, DataType::UInt64 },\n\t{ sigrok::DataType::STRING, DataType::String },\n\t{ sigrok::DataType::BOOL, DataType::Bool },\n\t{ sigrok::DataType::FLOAT, DataType::Double },\n\t{ sigrok::DataType::RATIONAL_PERIOD, DataType::RationalPeriod },\n\t{ sigrok::DataType::RATIONAL_VOLT, DataType::RationalVolt },\n\t{ sigrok::DataType::KEYVALUE, DataType::KeyValue },\n\t{ sigrok::DataType::UINT64_RANGE, DataType::UInt64Range },\n\t{ sigrok::DataType::DOUBLE_RANGE, DataType::DoubleRange },\n\t{ sigrok::DataType::INT32, DataType::Int32 },\n\t{ sigrok::DataType::MQ, DataType::MQ },\n};\n\nmap<DataType, const sigrok::DataType *> data_type_sr_data_type_map = {\n\t{ DataType::UInt64, sigrok::DataType::UINT64 },\n\t{ DataType::String, sigrok::DataType::STRING },\n\t{ DataType::Bool, sigrok::DataType::BOOL },\n\t{ DataType::Double, sigrok::DataType::FLOAT },\n\t{ DataType::RationalPeriod, sigrok::DataType::RATIONAL_PERIOD },\n\t{ DataType::RationalVolt, sigrok::DataType::RATIONAL_VOLT },\n\t{ DataType::KeyValue, sigrok::DataType::KEYVALUE },\n\t{ DataType::UInt64Range, sigrok::DataType::UINT64_RANGE },\n\t{ DataType::DoubleRange, sigrok::DataType::DOUBLE_RANGE },\n\t{ DataType::Int32, sigrok::DataType::INT32 },\n\t{ DataType::MQ, sigrok::DataType::MQ },\n};\n\nquantity_unit_map_t quantity_unit_map = {\n\t{ Quantity::Voltage, { Unit::Volt } },\n\t{ Quantity::Current, { Unit::Ampere } },\n\t{ Quantity::Resistance, { Unit::Ohm } },\n\t{ Quantity::Capacitance, { Unit::Farad } },\n\t{ Quantity::Temperature, { Unit::Kelvin, Unit::Celsius, Unit::Fahrenheit} },\n\t{ Quantity::Frequency, { Unit::Hertz } },\n\t{ Quantity::DutyCyle, { Unit::Percentage } },\n\t{ Quantity::Continuity, { Unit::Ohm, Unit::Boolean } },\n\t{ Quantity::PulseWidth, { Unit::Percentage } },\n\t{ Quantity::Conductance, { Unit::Siemens } },\n\t{ Quantity::Power, { Unit::Watt, Unit::VoltAmpere } },\n\t{ Quantity::ElectricCharge, { Unit::AmpereHour, Unit::Coulomb } },\n\t{ Quantity::Gain, { /* TODO Unit::Decibel,*/ Unit::Unitless } },\n\t{ Quantity::SoundPressureLevel, { Unit::DecibelSpl } },\n\t{ Quantity::CarbonMonoxide, { Unit::Concentration } },\n\t{ Quantity::RelativeHumidity, { Unit::Humidity293K } },\n\t{ Quantity::Time, { Unit::Second } },\n\t{ Quantity::WindSpeed, { Unit::MeterPerSecond } },\n\t{ Quantity::Pressure, { Unit::HectoPascal } },\n\t{ Quantity::ParallelInductance, { Unit::Henry } },\n\t{ Quantity::ParallelCapacitance, { Unit::Farad } },\n\t{ Quantity::ParallelResistance, { Unit::Ohm } },\n\t{ Quantity::SeriesInductance, { Unit::Henry } },\n\t{ Quantity::SeriesCapacitance, { Unit::Farad } },\n\t{ Quantity::SeriesResistance, { Unit::Ohm } },\n\t{ Quantity::DissipationFactor, { Unit::Unitless } },\n\t{ Quantity::QualityFactor, { Unit::Unitless } },\n\t{ Quantity::PhaseAngle, { Unit::Degree } },\n\t{ Quantity::Difference, { Unit::Unitless } },\n\t{ Quantity::Count, { Unit::Piece, Unit::Unitless } },\n\t{ Quantity::PowerFactor, { Unit::Unitless } },\n\t{ Quantity::ApparentPower, { Unit::VoltAmpere } },\n\t{ Quantity::Mass, { Unit::Gram, Unit::Carat, Unit::Ounce, Unit::TroyOunce,\n\t\t\t\t\t\tUnit::Pound, Unit::Pennyweight, Unit::Grain, Unit::Tael,\n\t\t\t\t\t\tUnit::Momme, Unit::Tola} },\n\t{ Quantity::HarmonicRatio, { Unit::Unitless } },\n\t{ Quantity::Energy, { Unit::WattHour, Unit::Joule } },\n};\n\n} // namespace\n\n/**\n * Return all known quantities\n *\n * @return The quantity name map\n */\nquantity_name_map_t get_quantity_name_map();\n\n/**\n * Return all known quantity flags\n *\n * @return The quantity flags name map\n */\nquantity_flag_name_map_t get_quantity_flag_name_map();\n\n/**\n * Return all known units\n *\n * @return The unit name map\n */\nunit_name_map_t get_unit_name_map();\n\n/**\n * Return all known data types\n *\n * @return The data type name map\n */\ndata_type_name_map_t get_data_type_name_map();\n\n\n/**\n * Return the corresponding Quantity for a sigrok Quantity\n *\n * @param sr_quantity The sigrok Quantity\n *\n * @return The Quantity.\n */\nQuantity get_quantity(const sigrok::Quantity *sr_quantity);\n\n/**\n * Return the corresponding Quantity for a sigrok Quantity (unit32_t)\n *\n * @param sr_quantity The sigrok Quantity as uint32_t\n *\n * @return The Quantity.\n */\nQuantity get_quantity(uint32_t sr_quantity);\n\n/**\n * Return the corresponding sigrok Quantity ID for a Quantity\n *\n * @param quantity The Quantity\n *\n * @return The sigrok Quantity ID as uint32_t.\n */\nuint32_t get_sr_quantity_id(Quantity quantity);\n\n/**\n * Check if the quantity is a known sigrok quantity\n *\n * @param quantity The quantity\n *\n * @return true if it is a known sigrok quantity\n */\nbool is_valid_sr_quantity(data::Quantity quantity);\n\n\n/**\n * Return the corresponding QuantityFlag for a sigrok QuantityFlag\n *\n * @param sr_quantity_flag The sigrok QuantityFlag\n *\n * @return The QuantityFlag.\n */\nQuantityFlag get_quantity_flag(const sigrok::QuantityFlag *sr_quantity_flag);\n\n/**\n * Return the corresponding sigrok QuantityFlag ID for a QuantityFlag\n *\n * @param quantity_flag The QuantityFlag\n *\n * @return The sigrok QuantityFlag ID as uint64_t.\n */\nuint64_t get_sr_quantity_flag_id(QuantityFlag quantity_flag);\n\n/**\n * Return the corresponding QuantityFlags as a set for the\n * sigrok QuantityFlags vector\n *\n * @param sr_quantity_flags The sigrok QuantityFlags as vector\n *\n * @return The QuantityFlags as set.\n */\nset<QuantityFlag> get_quantity_flags(\n\tconst vector<const sigrok::QuantityFlag *> &sr_quantity_flags);\n\n/**\n * Return the corresponding QuantityFlags as a set for the\n * sigrok QuantityFlags (uint64_t)\n *\n * @param sr_quantity_flags The sigrok QuantityFlags as uint64_t\n *\n * @return The QuantityFlags as set.\n */\nset<QuantityFlag> get_quantity_flags(uint64_t sr_quantity_flags);\n\n/**\n * Return the corresponding QuantityFlags as an uint64_t\n *\n * @param quantity_flags The QuantityFlags as set\n *\n * @return The sigrok QuantityFlags IDs\n */\nuint64_t get_sr_quantity_flags_id(const set<QuantityFlag> &quantity_flags);\n\n\n/**\n * Return the corresponding Unit for a sigrok Unit\n *\n * @param sr_unit The sigrok Unit\n *\n * @return The Unit.\n */\nUnit get_unit(const sigrok::Unit *sr_unit);\n\n\n/**\n * Return the corresponding DataType for a sigrok DataType\n *\n * @param sr_data_type The sigrok DataType\n *\n * @return The DataType.\n */\nDataType get_data_type(const sigrok::DataType *sr_data_type);\n\n/**\n * Return the corresponding DataType for a sigrok DataType (unit32_t)\n *\n * @param sr_data_type The sigrok DataType as uint32_t\n *\n * @return The DataType.\n */\nDataType get_data_type(uint32_t sr_data_type);\n\n/**\n * Return the corresponding sigrok DataType for a DataType\n *\n * @param data_type The DataType.\n *\n * @return The sigrok DataType.\n */\nconst sigrok::DataType *get_sr_data_type(DataType data_type);\n\n/**\n * Return the corresponding sigrok DataType ID for a DataType\n *\n * @param data_type The DataType\n *\n * @return The sigrok DataType ID as uint32_t.\n */\nuint32_t get_sr_data_type_id(DataType data_type);\n\n/**\n * Check if the DataType is a known sigrok DataType\n *\n * @param data_type The DataType\n *\n * @return true if it is a known sigrok DataType\n */\nbool is_valid_sr_data_type(DataType data_type);\n\n\n/**\n * Format a Quantity to a string\n *\n * @param quantity The Quantity to format.\n *\n * @return The formatted quantity.\n */\nQString format_quantity(Quantity quantity);\n\n/**\n * Format a QuantityFlag enum to a string\n *\n * @param quantity_flag The QuantityFlag to format.\n *\n * @return The formatted QuantityFlag.\n */\nQString format_quantity_flag(QuantityFlag quantity_flag);\n\n/**\n * Format a QuantityFlag enum set to a string\n *\n * @param quantity_flags The QuantityFlags to format.\n * @param seperator The seperator between the flags.\n *\n * @return The formatted QuantityFlags.\n */\nQString format_quantity_flags(const set<QuantityFlag> &quantity_flags,\n\tconst QString &seperator);\n\n/**\n * Format a measured_quantity_t (pair<Quantity, set<QuantityFlag>>) to a string\n *\n * @param measured_quantity The measured_quantity.\n *\n * @return The formated measured_quantity.\n */\nQString format_measured_quantity(const measured_quantity_t &measured_quantity);\n\n/**\n * Format a Unit to a string\n *\n * @param unit The quantity to format.\n *\n * @return The formatted unit.\n */\nQString format_unit(Unit unit);\n\n/**\n * Format a Unit to a string and adds AC/DC for voltage and current\n *\n * @param unit The quantity to format.\n * @param quantity_flags The quantity flags.\n *\n * @return The formatted unit.\n */\nQString format_unit(Unit unit, const set<QuantityFlag> &quantity_flags);\n\n/**\n * Format a DataType to a string\n *\n * @param data_type The DataType to format.\n *\n * @return The formatted DataType.\n */\nQString format_data_type(DataType data_type);\n\n\n/**\n * Return the (SI) units for the given quantity\n *\n * @param quantity The quantity\n *\n * @return The units as set\n */\nset<data::Unit> get_units_from_quantity(data::Quantity quantity);\n\n} // namespace datautil\n} // namespace data\n} // namespace sv\n\n#endif // DATA_DATAUTIL_HPP\n"
  },
  {
    "path": "src/data/properties/baseproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string>\n\n#include <QDebug>\n\n#include \"baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::string;\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nBaseProperty::BaseProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tconfigurable_(configurable),\n\tconfig_key_(config_key)\n{\n\tdata_type_ = devices::deviceutil::get_data_type_for_config_key(config_key_);\n\t//quantity_ = data::Quantity::Unknown; // TODO\n\tunit_ = devices::deviceutil::get_unit_for_config_key(config_key_);\n\tis_getable_ = configurable_->has_get_config(config_key_);\n\tis_setable_ = configurable_->has_set_config(config_key_);\n\tis_listable_ = configurable_->has_list_config(config_key_);\n}\n\nshared_ptr<devices::Configurable> BaseProperty::configurable() const\n{\n\treturn configurable_;\n}\n\ndevices::ConfigKey BaseProperty::config_key() const\n{\n\treturn config_key_;\n}\n\ndata::DataType BaseProperty::data_type() const\n{\n\treturn data_type_;\n}\n\n/*\ndata::Quantity BaseProperty::quantity() const\n{\n\treturn quantity_;\n}\n*/\n\ndata::Unit BaseProperty::unit() const\n{\n\treturn unit_;\n}\n\nbool BaseProperty::is_getable() const\n{\n\treturn is_getable_;\n}\n\nbool BaseProperty::is_setable() const\n{\n\treturn is_setable_;\n}\n\nbool BaseProperty::is_listable() const\n{\n\treturn is_listable_;\n}\n\nstring BaseProperty::name() const\n{\n\treturn devices::deviceutil::format_config_key(config_key_).toStdString();\n}\n\nQString BaseProperty::display_name() const\n{\n\treturn devices::deviceutil::format_config_key(config_key_);\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/baseproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_BASEPROPERTY_HPP\n#define DATA_PROPERTIES_BASEPROPERTY_HPP\n\n#include <memory>\n#include <string>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass BaseProperty : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tBaseProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\n\tshared_ptr<devices::Configurable> configurable() const;\n\tdevices::ConfigKey config_key() const;\n\tdata::DataType data_type() const;\n\t//data::Quantity quantity() const;\n\tdata::Unit unit() const;\n\tbool is_getable() const;\n\tbool is_setable() const;\n\tbool is_listable() const;\n\tstring name() const;\n\tQString display_name() const;\n\tvirtual QVariant value() const = 0;\n\tvirtual QString to_string(const QVariant &qvar) const = 0;\n\tvirtual QString to_string() const = 0;\n\nprotected:\n\tshared_ptr<devices::Configurable> configurable_;\n\tdevices::ConfigKey config_key_;\n\tdata::DataType data_type_;\n\t//data::Quantity quantity_;\n\tdata::Unit unit_;\n\tbool is_getable_;\n\tbool is_setable_;\n\tbool is_listable_;\n\npublic Q_SLOTS:\n\t/**\n\t * Load the list of available values for this property.\n\t */\n\tvirtual bool list_config() = 0;\n\t/**\n\t * Value has changed within SmuView and should be send to the device.\n\t */\n\tvirtual void change_value(const QVariant &qvar) = 0;\n\t/**\n\t * Devices has send a changed value via a meta package.\n\t */\n\tvirtual void on_value_changed(Glib::VariantBase gvar) = 0;\n\nQ_SIGNALS:\n\tvoid value_changed(const QVariant &qvar);\n\tvoid list_changed();\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_BASEPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/boolproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"boolproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nBoolProperty::BoolProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n}\n\nQVariant BoolProperty::value() const\n{\n\treturn QVariant(bool_value());\n}\n\nbool BoolProperty::bool_value() const\n{\n\tbool bool_value;\n\tconfigurable_->get_config<bool>(config_key_, bool_value);\n\treturn bool_value;\n}\n\nQString BoolProperty::to_string(bool value) const\n{\n\treturn value ? QString(\"true\") : QString(\"false\");\n}\n\nQString BoolProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.toBool());\n}\n\nQString BoolProperty::to_string() const\n{\n\treturn this->to_string(bool_value());\n}\n\nbool BoolProperty::list_config()\n{\n\t// No list for boolean properties!\n\treturn false;\n}\n\nvoid BoolProperty::change_value(const QVariant &qvar)\n{\n\tconfigurable_->set_config(config_key_, qvar.toBool());\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid BoolProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(g_variant_get_boolean(gvar.gobj())));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/boolproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_BOOLPROPERTY_HPP\n#define DATA_PROPERTIES_BOOLPROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass BoolProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tBoolProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tbool bool_value() const;\n\tQString to_string(bool value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_BOOLPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/doubleproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"doubleproperty.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nDoubleProperty::DoubleProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key),\n\tmin_(std::numeric_limits<double>::lowest()),\n\tmax_(std::numeric_limits<double>::max()),\n\tstep_(0.001), //std::numeric_limits<double>::epsilon()\n\ttotal_digits_(data::DefaultTotalDigits),\n\tdecimal_places_(data::DefaultDecimalPlaces)\n{\n\tif (is_listable_)\n\t\tDoubleProperty::list_config();\n}\n\nQVariant DoubleProperty::value() const\n{\n\treturn QVariant(double_value());\n}\n\ndouble DoubleProperty::double_value() const\n{\n\tdouble double_value;\n\tconfigurable_->get_config<double>(config_key_, double_value);\n\treturn double_value;\n}\n\nQString DoubleProperty::to_string(double value) const\n{\n\tQString str_val(\"\");\n\tQString si_prefix(\"\");\n\tutil::format_value_si_autoscale(value, total_digits_, decimal_places_,\n\t\tstr_val, si_prefix);\n\tQString unit_str = datautil::format_unit(unit_);\n\tif (!si_prefix.isEmpty() || !unit_str.isEmpty())\n\t\tstr_val.append(\" \").append(si_prefix).append(unit_str);\n\n\treturn str_val;\n}\n\nQString DoubleProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.toDouble());\n}\n\nQString DoubleProperty::to_string() const\n{\n\treturn this->to_string(double_value());\n}\n\ndouble DoubleProperty::min() const\n{\n\treturn min_;\n}\n\ndouble DoubleProperty::max() const\n{\n\treturn max_;\n}\n\ndouble DoubleProperty::step() const\n{\n\treturn step_;\n}\n\nint DoubleProperty::total_digits() const\n{\n\treturn total_digits_;\n}\n\nint DoubleProperty::decimal_places() const\n{\n\treturn decimal_places_;\n}\n\nbool DoubleProperty::list_config()\n{\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tmin_ = Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\titer.next_value(gvar);\n\tmax_ = Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\titer.next_value(gvar);\n\tstep_ = Glib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\n\ttotal_digits_ = util::count_double_digits(max_, step_);\n\tdecimal_places_ = util::count_decimal_places(step_);\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\nvoid DoubleProperty::change_value(const QVariant &qvar)\n{\n\tconfigurable_->set_config(config_key_, qvar.toDouble());\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid DoubleProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(g_variant_get_double(gvar.gobj())));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/doubleproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_DOUBLEPROPERTY_HPP\n#define DATA_PROPERTIES_DOUBLEPROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass DoubleProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tdouble double_value() const;\n\tQString to_string(double value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\tdouble min() const;\n\tdouble max() const;\n\tdouble step() const;\n\tint total_digits() const;\n\tint decimal_places() const;\n\nprivate:\n\tdouble min_;\n\tdouble max_;\n\tdouble step_;\n\tint total_digits_;\n\tint decimal_places_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_DOUBLEPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/doublerangeproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <utility>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"doublerangeproperty.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::make_pair;\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nDoubleRangeProperty::DoubleRangeProperty(\n\t\tshared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n\tif (is_listable_)\n\t\tDoubleRangeProperty::list_config();\n}\n\nQVariant DoubleRangeProperty::value() const\n{\n\treturn QVariant::fromValue(double_range_value());\n}\n\ndouble_range_t DoubleRangeProperty::double_range_value() const\n{\n\tGlib::VariantContainerBase gvar;\n\tconfigurable_->get_container_config(config_key_, gvar);\n\n\tsize_t child_cnt = gvar.get_n_children();\n\tif (child_cnt != 2) {\n\t\tthrow std::runtime_error(QString(\n\t\t\t\"DoubleRangeProperty::double_range_value(): \").append(\n\t\t\t\"container should have 2 child, but has %1\").arg(child_cnt).\n\t\t\ttoStdString());\n\t}\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tdouble low =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\titer.next_value(gvar);\n\tdouble high =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\n\treturn make_pair(low, high);\n}\n\nQString DoubleRangeProperty::to_string(data::double_range_t value) const\n{\n\tQString str = QString(\"%1 - %2\").arg(\n\t\tQString::number(value.first, 'f'), QString::number(value.second, 'f'));\n\tif (unit_ != data::Unit::Unknown && unit_ != data::Unit::Unitless)\n\t\tstr.append(\" \").append(datautil::format_unit(unit_));\n\n\treturn str;\n}\n\nQString DoubleRangeProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.value<data::double_range_t>());\n}\n\nQString DoubleRangeProperty::to_string() const\n{\n\treturn this->to_string(double_range_value());\n}\n\nvector<data::double_range_t> DoubleRangeProperty::list_values() const\n{\n\treturn values_list_;\n}\n\nbool DoubleRangeProperty::list_config()\n{\n\tvalues_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\twhile (iter.next_value (gvar)) {\n\t\tdouble low = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<double>>(gvar.get_child(0)).get();\n\t\tdouble high = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<double>>(gvar.get_child(1)).get();\n\n\t\tvalues_list_.push_back(make_pair(low, high));\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\n/**\n * TODO: When glibmm >= 2.52 is more supported and tuple bug is fixed,\n *       use the template function with tuple<double, double>:\n *\n *       set_config(config_key_, std::tuple<double, double>);\n */\nvoid DoubleRangeProperty::change_value(const QVariant &qvar)\n{\n\tdata::double_range_t range = qvar.value<data::double_range_t>();\n\n\tGlib::VariantBase gvar_low = Glib::Variant<double>::create(range.first);\n\tGlib::VariantBase gvar_high = Glib::Variant<double>::create(range.second);\n\n\tvector<Glib::VariantBase> gcontainer;\n\tgcontainer.push_back(gvar_low);\n\tgcontainer.push_back(gvar_high);\n\n\tconfigurable_->set_container_config(config_key_, gcontainer);\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid DoubleRangeProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tdouble low =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\titer.next_value(gvar);\n\tdouble high =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<double>>(gvar).get();\n\n\tQ_EMIT value_changed(QVariant::fromValue(make_pair(low, high)));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/doublerangeproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_DOUBLERANGEPROPERTY_HPP\n#define DATA_PROPERTIES_DOUBLERANGEPROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass DoubleRangeProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleRangeProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tdata::double_range_t double_range_value() const;\n\tQString to_string(data::double_range_t value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\tvector<data::double_range_t> list_values() const;\n\nprivate:\n\tvector<data::double_range_t> values_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_DOUBLERANGEPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/int32property.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"int32property.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nInt32Property::Int32Property(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key),\n\tmin_(std::numeric_limits<int32_t>::lowest()),\n\tmax_(std::numeric_limits<int32_t>::max()),\n\tstep_(1)\n{\n\tif (is_listable_)\n\t\tInt32Property::list_config();\n}\n\nQVariant Int32Property::value() const\n{\n\treturn QVariant(int32_value());\n}\n\nint32_t Int32Property::int32_value() const\n{\n\tint32_t int32_value;\n\tconfigurable_->get_config<int32_t>(config_key_, int32_value);\n\treturn int32_value;\n}\n\nQString Int32Property::to_string(int32_t value) const\n{\n\tQString str = QString::number(value);\n\tif (unit_ != data::Unit::Unknown && unit_ != data::Unit::Unitless)\n\t\tstr.append(\" \").append(datautil::format_unit(unit_));\n\n\treturn str;\n}\n\nQString Int32Property::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.toInt());\n}\n\nQString Int32Property::to_string() const\n{\n\treturn this->to_string(int32_value());\n}\n\nint32_t Int32Property::min() const\n{\n\treturn min_;\n}\n\nint32_t Int32Property::max() const\n{\n\treturn max_;\n}\n\nint32_t Int32Property::step() const\n{\n\treturn step_;\n}\n\nbool Int32Property::list_config()\n{\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tmin_ = Glib::VariantBase::cast_dynamic<Glib::Variant<int32_t>>(gvar).get();\n\titer.next_value(gvar);\n\tmax_ = Glib::VariantBase::cast_dynamic<Glib::Variant<int32_t>>(gvar).get();\n\titer.next_value(gvar);\n\tstep_ = Glib::VariantBase::cast_dynamic<Glib::Variant<int32_t>>(gvar).get();\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\nvoid Int32Property::change_value(const QVariant &qvar)\n{\n\tconfigurable_->set_config(config_key_, qvar.toInt());\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid Int32Property::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(g_variant_get_int32(gvar.gobj())));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/int32property.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_INT32PROPERTY_HPP\n#define DATA_PROPERTIES_INT32PROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass Int32Property : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tInt32Property(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tint32_t int32_value() const;\n\tint32_t min() const;\n\tint32_t max() const;\n\tint32_t step() const;\n\tQString to_string(int32_t value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\nprivate:\n\tint32_t min_;\n\tint32_t max_;\n\tint32_t step_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_INT32PROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/measuredquantityproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <set>\n#include <stdexcept>\n#include <utility>\n#include <vector>\n\n#include <glib.h>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"measuredquantityproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::make_pair;\nusing std::set;\nusing std::vector;\n\nQ_DECLARE_METATYPE(sv::data::measured_quantity_t)\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nMeasuredQuantityProperty::MeasuredQuantityProperty(\n\t\tshared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n\tif (is_listable_)\n\t\tMeasuredQuantityProperty::list_config();\n}\n\nQVariant MeasuredQuantityProperty::value() const\n{\n\treturn QVariant::fromValue(measured_quantity_value());\n}\n\ndata::measured_quantity_t\nMeasuredQuantityProperty::measured_quantity_value() const\n{\n\tdata::measured_quantity_t mq_value;\n\tconfigurable_->get_measured_quantity_config(config_key_, mq_value);\n\treturn mq_value;\n}\n\nQString MeasuredQuantityProperty::to_string(\n\tconst data::measured_quantity_t &value) const\n{\n\treturn data::datautil::format_measured_quantity(value);\n}\n\nQString MeasuredQuantityProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.value<data::measured_quantity_t>());\n}\n\nQString MeasuredQuantityProperty::to_string() const\n{\n\treturn this->to_string(measured_quantity_value());\n}\n\nvector<data::measured_quantity_t> MeasuredQuantityProperty::list_values() const\n{\n\treturn measured_quantity_list_;\n}\n\nbool MeasuredQuantityProperty::list_config()\n{\n\tmeasured_quantity_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\twhile (iter.next_value (gvar)) {\n\t\tuint32_t sr_q = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint32_t>>(gvar.get_child(0)).get();\n\t\tdata::Quantity quantity = data::datautil::get_quantity(sr_q);\n\t\tuint64_t sr_qflags = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(1)).get();\n\t\tset<data::QuantityFlag> quantity_flags =\n\t\t\tdata::datautil::get_quantity_flags(sr_qflags);\n\n\t\tmeasured_quantity_list_.push_back(make_pair(quantity, quantity_flags));\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\nvoid MeasuredQuantityProperty::change_value(const QVariant &qvar)\n{\n\tdata::measured_quantity_t mq = qvar.value<data::measured_quantity_t>();\n\tconfigurable_->set_measured_quantity_config(config_key_, mq);\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid MeasuredQuantityProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(g_variant_get_string(gvar.gobj(), nullptr)));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/measuredquantityproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_MEASUREDQUANTITYPROPERTY_HPP\n#define DATA_PROPERTIES_MEASUREDQUANTITYPROPERTY_HPP\n\n#include <memory>\n#include <vector>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass MeasuredQuantityProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tMeasuredQuantityProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tdata::measured_quantity_t measured_quantity_value() const;\n\tvector<data::measured_quantity_t> list_values() const;\n\tQString to_string(const data::measured_quantity_t &value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\nprivate:\n\tvector<data::measured_quantity_t> measured_quantity_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_MEASUREDQUANTITYPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/rationalproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"rationalproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/util.hpp\"\n\nusing std::make_pair;\nusing std::string;\nusing std::vector;\n\nQ_DECLARE_METATYPE(sv::data::rational_t)\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nRationalProperty::RationalProperty(\n\t\tshared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n\tif (is_listable_)\n\t\tRationalProperty::list_config();\n}\n\nQVariant RationalProperty::value() const\n{\n\treturn QVariant::fromValue(rational_value());\n}\n\n/**\n * TODO: When glibmm >= 2.52 is more supported and tuple bug is fixed,\n *       use the template function and return tuple<uint64_t, uint64_t>:\n *\n *       return get_config<std::tuple<uint32_t, uint64_t>>(sigrok::ConfigKey);\n */\ndata::rational_t RationalProperty::rational_value() const\n{\n\tGlib::VariantContainerBase gvar;\n\tconfigurable_->get_container_config(config_key_, gvar);\n\n\tsize_t child_cnt = gvar.get_n_children();\n\tif (child_cnt != 2) {\n\t\tthrow std::runtime_error(QString(\"RationalProperty::rational_value(): \")\n\t\t\t.append(\"container should have 2 child, but has %1\")\n\t\t\t.arg(child_cnt).toStdString());\n\t}\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tuint64_t p =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\titer.next_value(gvar);\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tuint64_t q =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\n\treturn make_pair(p, q);\n}\n\nQString RationalProperty::to_string(data::rational_t value) const\n{\n\tQString str_val;\n\tQString si_prefix(\"\");\n\tdouble d_val =\n\t\tstatic_cast<double>(value.first) / static_cast<double>(value.second);\n\tutil::format_value_si(d_val, 0, 2, str_val, si_prefix);\n\tQString unit_str = datautil::format_unit(unit_);\n\tif (!si_prefix.isEmpty() || !unit_str.isEmpty())\n\t\tstr_val.append(\" \").append(si_prefix).append(datautil::format_unit(unit_));\n\n\treturn str_val;\n}\n\nQString RationalProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.value<data::rational_t>());\n}\n\nQString RationalProperty::to_string() const\n{\n\treturn this->to_string(rational_value());\n}\n\nvector<data::rational_t> RationalProperty::list_values() const\n{\n\treturn values_list_;\n}\n\nbool RationalProperty::list_config()\n{\n\tvalues_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\twhile (iter.next_value(gvar)) {\n\t\t// NOLINTNEXTLINE(readability-identifier-length)\n\t\tuint64_t p = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(0)).get();\n\t\t// NOLINTNEXTLINE(readability-identifier-length)\n\t\tuint64_t q = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(1)).get();\n\n\t\tvalues_list_.push_back(make_pair(p, q));\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\n/**\n * TODO: When glibmm >= 2.52 is more supported and tuple bug is fixed,\n *       use the template function with tuple<uint32_t, uint64_t>:\n *\n *       set_config(config_key_, std::tuple<uint32_t, uint64_t>);\n */\nvoid RationalProperty::change_value(const QVariant &qvar)\n{\n\tdata::rational_t rational = qvar.value<data::rational_t>();\n\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tGlib::VariantBase p = Glib::Variant<uint64_t>::create(rational.first);\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tGlib::VariantBase q = Glib::Variant<uint64_t>::create(rational.second);\n\n\tvector<Glib::VariantBase> gcontainer;\n\tgcontainer.push_back(p);\n\tgcontainer.push_back(q);\n\n\tconfigurable_->set_container_config(config_key_, gcontainer);\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid RationalProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tuint64_t p =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\titer.next_value(gvar);\n\t// NOLINTNEXTLINE(readability-identifier-length)\n\tuint64_t q =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\n\tQ_EMIT value_changed(QVariant::fromValue(make_pair(p, q)));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/rationalproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_RATIONALPROPERTY_HPP\n#define DATA_PROPERTIES_RATIONALPROPERTY_HPP\n\n#include <memory>\n#include <utility>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass RationalProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tRationalProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tdata::rational_t rational_value() const;\n\tQString to_string(data::rational_t value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\tvector<data::rational_t> list_values() const;\n\nprivate:\n\tvector<data::rational_t> values_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_RATIONALPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/stringproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string>\n\n#include <glibmm.h>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"stringproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::string;\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nStringProperty::StringProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n\tif (is_listable_) {\n\t\tif (!StringProperty::list_config())\n\t\t\tis_listable_ = false;\n\t}\n}\n\nQVariant StringProperty::value() const\n{\n\treturn QVariant(string_value());\n}\n\nQString StringProperty::string_value() const\n{\n\tstring string_value;\n\tconfigurable_->get_config<string>(config_key_, string_value);\n\treturn QString::fromStdString(string_value);\n}\n\nQString StringProperty::to_string(const QVariant &qvar) const\n{\n\treturn qvar.toString();\n}\n\nQString StringProperty::to_string() const\n{\n\treturn string_value();\n}\n\nQStringList StringProperty::list_values() const\n{\n\treturn string_list_;\n}\n\nbool StringProperty::list_config()\n{\n\tstring_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\twhile (iter.next_value (gvar)) {\n\t\tstring_list_.append(QString::fromStdString(\n\t\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<string>>(gvar).get()));\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\nvoid StringProperty::change_value(const QVariant &qvar)\n{\n\t// We have to use Glib::ustring here, to get a variant type of 's'.\n\t// std::string will create a variant type of 'ay'\n\tconfigurable_->set_config<Glib::ustring>(\n\t\tconfig_key_, Glib::ustring(qvar.toString().toStdString()));\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid StringProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(g_variant_get_string(gvar.gobj(), nullptr)));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/stringproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_STRINGPROPERTY_HPP\n#define DATA_PROPERTIES_STRINGPROPERTY_HPP\n\n#include <map>\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QStringList>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::map;\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass StringProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tStringProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tQString string_value() const;\n\tQStringList list_values() const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\nprivate:\n\tQStringList string_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_STRINGPROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/uint64property.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n#include <string>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"uint64property.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nUInt64Property::UInt64Property(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key),\n\tmin_(std::numeric_limits<uint64_t>::lowest()),\n\tmax_(std::numeric_limits<uint64_t>::max()),\n\tstep_(1)\n{\n\tif (is_listable_)\n\t\tUInt64Property::list_config();\n}\n\nQVariant UInt64Property::value() const\n{\n\treturn QVariant((qulonglong)uint64_value());\n}\n\nuint64_t UInt64Property::uint64_value() const\n{\n\tuint64_t uint64_value;\n\tconfigurable_->get_config<uint64_t>(config_key_, uint64_value);\n\treturn uint64_value;\n}\n\nQString UInt64Property::to_string(uint64_t value) const\n{\n\t// TODO: calculate total_digits + decimal_places from min/max/step\n\tQString str_val;\n\tQString si_prefix;\n\tutil::format_value_si(static_cast<double>(value), 0, 0, str_val, si_prefix);\n\tQString unit_str = datautil::format_unit(unit_);\n\tif (!si_prefix.isEmpty() || !unit_str.isEmpty())\n\t\tstr_val.append(\" \").append(si_prefix).append(unit_str);\n\n\treturn str_val;\n}\n\nQString UInt64Property::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.toULongLong());\n}\n\nQString UInt64Property::to_string() const\n{\n\treturn this->to_string(uint64_value());\n}\n\nuint64_t UInt64Property::min() const\n{\n\treturn min_;\n}\n\nuint64_t UInt64Property::max() const\n{\n\treturn max_;\n}\n\nuint64_t UInt64Property::step() const\n{\n\treturn step_;\n}\n\nvector<uint64_t> UInt64Property::list_values() const\n{\n\treturn values_list_;\n}\n\nbool UInt64Property::list_config()\n{\n\tvalues_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tif (config_key_ == devices::ConfigKey::Samplerate) {\n\t\tGVariant *gvar_list;\n\t\tconst uint64_t *elements = nullptr;\n\t\tgsize num_elements;\n\t\tif ((gvar_list = g_variant_lookup_value(gvar.gobj(),\n\t\t\t\t\"samplerate-steps\", G_VARIANT_TYPE(\"at\")))) {\n\t\t\telements = static_cast<const uint64_t *>(g_variant_get_fixed_array(\n\t\t\t\tgvar_list, &num_elements, sizeof(uint64_t)));\n\t\t\tmin_ = elements[0];\n\t\t\tmax_ = elements[1];\n\t\t\tstep_ = elements[2];\n\t\t\tg_variant_unref(gvar_list);\n\t\t}\n\t\telse if ((gvar_list = g_variant_lookup_value(gvar.gobj(),\n\t\t\t\t\"samplerates\", G_VARIANT_TYPE(\"at\")))) {\n\t\t\telements = static_cast<const uint64_t *>(g_variant_get_fixed_array(\n\t\t\t\tgvar_list, &num_elements, sizeof(uint64_t)));\n\t\t\tfor (size_t i=0; i<num_elements; i++) {\n\t\t\t\tvalues_list_.push_back(elements[i]);\n\t\t\t}\n\t\t\tg_variant_unref(gvar_list);\n\t\t}\n\t\telse {\n\t\t\treturn false;\n\t\t}\n\t}\n\telse if (config_key_ == devices::ConfigKey::SampleInterval) {\n\t\t// TODO: *data = std_gvar_tuple_array(ARRAY_AND_SIZE(kecheng_kc_330b_sample_intervals));\n\t\tGlib::VariantIter iter(gvar);\n\t\twhile (iter.next_value (gvar)) {\n\t\t\tuint64_t low = Glib::VariantBase::cast_dynamic\n\t\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(0)).get();\n\t\t\tuint64_t high = Glib::VariantBase::cast_dynamic\n\t\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(1)).get();\n\n\t\t\t(void)low;\n\t\t\t(void)high;\n\t\t\t//values_list_.push_back(make_pair(low, high));\n\t\t}\n\t}\n\telse {\n\t\tGlib::VariantIter iter(gvar);\n\t\twhile (iter.next_value (gvar)) {\n\t\t\tvalues_list_.push_back(\n\t\t\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<guint64>>(gvar).get());\n\t\t}\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\nvoid UInt64Property::change_value(const QVariant &qvar)\n{\n\t/*\n\t * TODO: This is a dirty hack to limit the sample rate of the (demo) device\n\t *       to 20 kSamples/s to prevent memory overflow.\n\t *       To fix this hack, a proper memory management has to be implemented!\n\t */\n\tQVariant new_qvar = qvar;\n\tif (config_key_ == devices::ConfigKey::Samplerate) {\n\t\tuint64_t sample_rate = (uint64_t)new_qvar.toULongLong();\n\t\tif (sample_rate > 20000)\n\t\t\tnew_qvar.setValue((qulonglong)20000);\n\t}\n\n\tconfigurable_->set_config(config_key_, (uint64_t)new_qvar.toULongLong());\n\tQ_EMIT value_changed(new_qvar);\n}\n\nvoid UInt64Property::on_value_changed(Glib::VariantBase gvar)\n{\n\tQ_EMIT value_changed(QVariant(\n\t\t(qulonglong)g_variant_get_uint64(gvar.gobj())));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/uint64property.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_UINT64PROPERTY_HPP\n#define DATA_PROPERTIES_UINT64PROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass UInt64Property : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64Property(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tuint64_t uint64_value() const;\n\tQString to_string(uint64_t value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\tuint64_t min() const;\n\tuint64_t max() const;\n\tuint64_t step() const;\n\tvector<uint64_t> list_values() const;\n\nprivate:\n\tuint64_t min_;\n\tuint64_t max_;\n\tuint64_t step_;\n\tvector<uint64_t> values_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_UINT64PROPERTY_HPP\n"
  },
  {
    "path": "src/data/properties/uint64rangeproperty.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"uint64rangeproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::make_pair;\nusing std::string;\nusing std::vector;\n\nQ_DECLARE_METATYPE(sv::data::uint64_range_t)\n\nnamespace sv {\nnamespace data {\nnamespace properties {\n\nUInt64RangeProperty::UInt64RangeProperty(\n\t\tshared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key) :\n\tBaseProperty(configurable, config_key)\n{\n\tif (is_listable_)\n\t\tUInt64RangeProperty::list_config();\n}\n\nQVariant UInt64RangeProperty::value() const\n{\n\treturn QVariant::fromValue(uint64_range_value());\n}\n\n/**\n * TODO: When glibmm >= 2.52 is more supported and tuple bug is fixed,\n *       use the template function and return tuple<uint64_t, uint64_t>:\n *\n *       return get_config<std::tuple<uint64_t, uint64_t>>(sigrok::ConfigKey);\n */\ndata::uint64_range_t UInt64RangeProperty::uint64_range_value() const\n{\n\tGlib::VariantContainerBase gvar;\n\tconfigurable_->get_container_config(config_key_, gvar);\n\n\tsize_t child_cnt = gvar.get_n_children();\n\tif (child_cnt != 2) {\n\t\tthrow std::runtime_error(QString(\n\t\t\t\"UInt64RangeProperty::uint64_range_value(): \").append(\n\t\t\t\"container should have 2 child, but has %1\").arg(child_cnt).\n\t\t\ttoStdString());\n\t}\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tuint64_t low =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\titer.next_value(gvar);\n\tuint64_t high =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\n\treturn make_pair(low, high);\n}\n\nQString UInt64RangeProperty::to_string(data::uint64_range_t value) const\n{\n\tQString str = QString(\"%1 - %2\").arg(value.first).arg(value.second);\n\tif (unit_ != data::Unit::Unknown && unit_ != data::Unit::Unitless)\n\t\tstr.append(\" \").append(datautil::format_unit(unit_));\n\n\treturn str;\n}\n\nQString UInt64RangeProperty::to_string(const QVariant &qvar) const\n{\n\treturn this->to_string(qvar.value<data::uint64_range_t>());\n}\n\nQString UInt64RangeProperty::to_string() const\n{\n\treturn this->to_string(uint64_range_value());\n}\n\nvector<data::uint64_range_t> UInt64RangeProperty::list_values() const\n{\n\treturn values_list_;\n}\n\nbool UInt64RangeProperty::list_config()\n{\n\tvalues_list_.clear();\n\n\tGlib::VariantContainerBase gvar;\n\tif (!configurable_->list_config(config_key_, gvar))\n\t\treturn false;\n\n\tGlib::VariantIter iter(gvar);\n\twhile (iter.next_value (gvar)) {\n\t\tuint64_t low = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(0)).get();\n\t\tuint64_t high = Glib::VariantBase::cast_dynamic\n\t\t\t<Glib::Variant<uint64_t>>(gvar.get_child(1)).get();\n\n\t\tvalues_list_.push_back(make_pair(low, high));\n\t}\n\n\tQ_EMIT list_changed();\n\n\treturn true;\n}\n\n/**\n * TODO: When glibmm >= 2.52 is more supported and tuple bug is fixed,\n *       use the template function with tuple<uint32_t, uint64_t>:\n *\n *       set_config(config_key_, std::tuple<uint32_t, uint64_t>);\n */\nvoid UInt64RangeProperty::change_value(const QVariant &qvar)\n{\n\tdata::uint64_range_t range = qvar.value<data::uint64_range_t>();\n\n\tGlib::VariantBase gvar_low = Glib::Variant<uint64_t>::create(range.first);\n\tGlib::VariantBase gvar_high = Glib::Variant<uint64_t>::create(range.second);\n\n\tvector<Glib::VariantBase> gcontainer;\n\tgcontainer.push_back(gvar_low);\n\tgcontainer.push_back(gvar_high);\n\n\tconfigurable_->set_container_config(config_key_, gcontainer);\n\tQ_EMIT value_changed(qvar);\n}\n\nvoid UInt64RangeProperty::on_value_changed(Glib::VariantBase gvar)\n{\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tuint64_t low =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\titer.next_value(gvar);\n\tuint64_t high =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\n\tQ_EMIT value_changed(QVariant::fromValue(make_pair(low, high)));\n}\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n"
  },
  {
    "path": "src/data/properties/uint64rangeproperty.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DATA_PROPERTIES_UINT64RANGEPROPERTY_HPP\n#define DATA_PROPERTIES_UINT64RANGEPROPERTY_HPP\n\n#include <memory>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace data {\nnamespace properties {\n\nclass UInt64RangeProperty : public BaseProperty\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64RangeProperty(shared_ptr<devices::Configurable> configurable,\n\t\tdevices::ConfigKey config_key);\n\npublic:\n\tQVariant value() const override;\n\tdata::uint64_range_t uint64_range_value() const;\n\tQString to_string(data::uint64_range_t value) const;\n\tQString to_string(const QVariant &qvar) const override;\n\tQString to_string() const override;\n\tvector<data::uint64_range_t> list_values() const;\n\nprivate:\n\tvector<data::uint64_range_t> values_list_;\n\npublic Q_SLOTS:\n\tbool list_config() override;\n\tvoid change_value(const QVariant &qvar) override;\n\tvoid on_value_changed(Glib::VariantBase gvar) override;\n\n};\n\n} // namespace properties\n} // namespace data\n} // namespace sv\n\n#endif // DATA_PROPERTIES_UINT64RANGEPROPERTY_HPP\n"
  },
  {
    "path": "src/devicemanager.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <functional>\n#include <memory>\n#include <sstream>\n#include <stdexcept>\n#include <string>\n\n#include <glib.h>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QApplication>\n#include <QDebug>\n#include <QObject>\n#include <QProgressDialog>\n\n#include \"devicemanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/measurementdevice.hpp\"\n#include \"src/devices/oscilloscopedevice.hpp\"\n#include \"src/devices/sourcesinkdevice.hpp\"\n\nusing std::bind;\nusing std::list;\nusing std::map;\nusing std::multimap;\nusing std::pair;\nusing std::shared_ptr;\nusing std::string;\nusing std::unique_ptr;\nusing std::vector;\n\nusing Glib::VariantBase;\n\nnamespace sv {\n\nDeviceManager::DeviceManager(shared_ptr<sigrok::Context> context,\n\t\tconst vector<string> &drivers, bool do_scan) :\n\tcontext_(context)\n{\n\tunique_ptr<QProgressDialog> progress(new QProgressDialog(\"\",\n\t\tQObject::tr(\"Cancel\"), 0, (int)context->drivers().size() + 1));\n\tprogress->setWindowModality(Qt::WindowModal);\n\tprogress->setMinimumDuration(1);  // To show the dialog immediately\n\n\tint entry_num = 1;\n\n\t/*\n\t * Check the presence of optional user specs for device scans.\n\t * Determine the driver names and options (in generic format) when\n\t * applicable.\n\t */\n\tmultimap<string, vector<string> > user_drvs_name_opts;\n\tif (!drivers.empty()) {\n\t\tfor (const auto &driver : drivers) {\n\t\t\tvector<string> user_drv_opts = sv::util::split_string(driver, \":\");\n\t\t\tstring user_drv_name = user_drv_opts.front();\n\t\t\tuser_drv_opts.erase(user_drv_opts.begin());\n\n\t\t\tuser_drvs_name_opts.insert(\n\t\t\t\tpair< string, vector<string> >(user_drv_name, user_drv_opts));\n\t\t}\n\t}\n\n\t/*\n\t * Scan for devices. No specific options apply here, this is\n\t * best effort auto detection.\n\t */\n\tfor (const auto &entry : context->drivers()) {\n\t\tif (!do_scan)\n\t\t\tbreak;\n\n\t\t// Skip drivers we won't scan anyway\n\t\tif (!devices::deviceutil::is_supported_driver(entry.second))\n\t\t\tcontinue;\n\n\t\tprogress->setLabelText(QObject::tr(\"Scanning for %1...\")\n\t\t\t.arg(QString::fromStdString(entry.first)));\n\n\t\tif (user_drvs_name_opts.count(entry.first) > 0)\n\t\t\tcontinue;\n\t\tdriver_scan(entry.second, map<const sigrok::ConfigKey *, VariantBase>());\n\n\t\tprogress->setValue(entry_num++);\n\t\tQApplication::processEvents();\n\t\tif (progress->wasCanceled())\n\t\t\tbreak;\n\t}\n\n\t/*\n\t * Optionally run another scan with potentially more specific\n\t * options when requested by the user. This is motivated by\n\t * several different uses: It can find devices that are not\n\t * covered by the above auto detection (UART, TCP). It can\n\t * prefer one out of multiple found devices, and have this\n\t * device pre-selected for new sessions upon user's request.\n\t */\n\tuser_spec_devices_.clear();\n \tif (!drivers.empty() && !user_drvs_name_opts.empty()) {\n\t\tfor( auto it = user_drvs_name_opts.begin(), end = user_drvs_name_opts.end();\n\t\t\tit != end;\n \t\t\tit = user_drvs_name_opts.upper_bound(it->first)) {\n\n\t\t\tauto user_drv_name = it->first;\n\t\t\tauto user_drv_opts = it->second;\n\n\t\t\tlist< shared_ptr<devices::HardwareDevice> > found =\n\t\t\t\tdriver_scan(user_drv_name, user_drv_opts);\n\t\t\tif (!found.empty())\n\t\t\t\tuser_spec_devices_.push_back(found.front());\n\t\t}\n\t}\n\tprogress->setValue(entry_num++);\n}\n\nconst shared_ptr<sigrok::Context>& DeviceManager::context() const\n{\n\treturn context_;\n}\n\nshared_ptr<sigrok::Context> DeviceManager::context()\n{\n\treturn context_;\n}\n\nconst list< shared_ptr<devices::HardwareDevice> >&\nDeviceManager::devices() const\n{\n\treturn devices_;\n}\n\n/**\n * Get the device that was detected with user provided scan options.\n */\nlist< shared_ptr<devices::HardwareDevice> >\nDeviceManager::user_spec_devices() const\n{\n\treturn user_spec_devices_;\n}\n\n/**\n * Convert generic options to data types that are specific to Driver::scan().\n *\n * @param[in] user_spec Vector of tokenized words, string format.\n * @param[in] driver_opts Driver's scan options, result of Driver::scan_options().\n *\n * @return Map of options suitable for Driver::scan().\n */\nmap<const sigrok::ConfigKey *, VariantBase>\nDeviceManager::driver_scan_options(const vector<string> &user_spec,\n\tset<const sigrok::ConfigKey *> driver_opts)\n{\n\tmap<const sigrok::ConfigKey *, VariantBase> result;\n\n\tfor (const auto &entry : user_spec) {\n\t\t/*\n\t\t * Split key=value specs. Accept entries without separator\n\t\t * (for simplified boolean specifications).\n\t\t */\n\t\tstring key;\n\t\tstring val;\n\t\tsize_t pos = entry.find('=');\n\t\tif (pos == std::string::npos) {\n\t\t\tkey = entry;\n\t\t\tval = \"\";\n\t\t} else {\n\t\t\tkey = entry.substr(0, pos);\n\t\t\tval = entry.substr(pos + 1);\n\t\t}\n\n\t\t/*\n\t\t * Skip user specifications that are not a member of the\n\t\t * driver's set of supported options. Have the text format\n\t\t * input spec converted to the required driver specific type.\n\t\t */\n\t\tconst sigrok::ConfigKey *cfg;\n\t\ttry {\n\t\t\tcfg = sigrok::ConfigKey::get_by_identifier(key);\n\t\t\tif (!cfg)\n\t\t\t\tcontinue;\n\t\t\tif (driver_opts.find(cfg) == driver_opts.end())\n\t\t\t\tcontinue;\n\t\t} catch (...) {\n\t\t\tcontinue;\n\t\t}\n\t\tresult[cfg] = cfg->parse_string(val);\n\t}\n\n\treturn result;\n}\n\nlist<shared_ptr<devices::HardwareDevice>>\nDeviceManager::driver_scan(\n\tconst string &driver_name, const vector<string> &driver_opts)\n{\n\tshared_ptr<sigrok::Driver> scan_drv;\n\tmap<const sigrok::ConfigKey *, VariantBase> scan_opts;\n\n\t/*\n\t * Lookup the device driver names.\n\t */\n\tmap<string, shared_ptr<sigrok::Driver>> drivers = context_->drivers();\n\tauto entry = drivers.find(driver_name);\n\tscan_drv = (entry != drivers.end()) ? entry->second : nullptr;\n\n\t/*\n\t * Convert generic string representation of options\n\t * to the driver specific data types.\n\t */\n\tif (scan_drv && !driver_opts.empty()) {\n\t\tauto drv_opts = scan_drv->scan_options();\n\t\tscan_opts = driver_scan_options(driver_opts, drv_opts);\n\t}\n\n\t/*\n\t * Run another scan for the specified driver, passing\n\t * user provided scan options this time.\n\t */\n\tlist<shared_ptr<devices::HardwareDevice>> found;\n\tif (scan_drv)\n\t\tfound = driver_scan(scan_drv, scan_opts);\n\n\treturn found;\n}\n\nlist<shared_ptr<devices::HardwareDevice>>\nDeviceManager::driver_scan(\n\tshared_ptr<sigrok::Driver> sr_driver,\n\tconst map<const sigrok::ConfigKey *, VariantBase> &drvopts)\n{\n\tlist< shared_ptr<devices::HardwareDevice> > driver_devices;\n\n\tassert(sr_driver);\n\n\tif (!devices::deviceutil::is_supported_driver(sr_driver))\n\t\treturn driver_devices;\n\n\t// Remove any device instances from this driver from the device\n\t// list. They will not be valid after the scan.\n\tdevices_.remove_if([&](shared_ptr<devices::HardwareDevice> device) {\n\t\treturn device->sr_hardware_device()->driver() == sr_driver; });\n\n\t// Do the scan\n\tauto sr_devices = sr_driver->scan(drvopts);\n\n\t// Add the scanned devices to the main list, set display names and sort.\n\tfor (const auto &sr_device : sr_devices) {\n\t\tif (devices::deviceutil::is_source_sink_driver(sr_driver)) {\n\t\t\tdriver_devices.push_back(\n\t\t\t\tdevices::SourceSinkDevice::create(context_, sr_device));\n\t\t}\n\t\telse if (devices::deviceutil::is_oscilloscope_driver(sr_driver)) {\n\t\t\tdriver_devices.push_back(\n\t\t\t\tdevices::OscilloscopeDevice::create(context_, sr_device));\n\t\t}\n\t\telse if (devices::deviceutil::is_measurement_driver(sr_driver)) {\n\t\t\tdriver_devices.push_back(\n\t\t\t\tdevices::MeasurementDevice::create(context_, sr_device));\n\t\t}\n\t}\n\n\tdevices_.insert(devices_.end(), driver_devices.begin(),\n\t\tdriver_devices.end());\n\tdevices_.sort(bind(&DeviceManager::compare_devices, this,\n\t\tstd::placeholders::_1, std::placeholders::_2));\n\tdriver_devices.sort(bind(&DeviceManager::compare_devices, this,\n\t\tstd::placeholders::_1, std::placeholders::_2));\n\n\treturn driver_devices;\n}\n\nmap<string, string> DeviceManager::get_device_info(\n\tshared_ptr<devices::BaseDevice> device)\n{\n\tmap<string, string> result;\n\n\tassert(device);\n\n\tconst shared_ptr<sigrok::Device> sr_dev = device->sr_device();\n\tif (sr_dev->vendor().length() > 0)\n\t\tresult[\"vendor\"] = sr_dev->vendor();\n\tif (sr_dev->model().length() > 0)\n\t\tresult[\"model\"] = sr_dev->model();\n\tif (sr_dev->version().length() > 0)\n\t\tresult[\"version\"] = sr_dev->version();\n\tif (sr_dev->serial_number().length() > 0)\n\t\tresult[\"serial_num\"] = sr_dev->serial_number();\n\tif (sr_dev->connection_id().length() > 0)\n\t\tresult[\"connection_id\"] = sr_dev->connection_id();\n\n\treturn result;\n}\n\nshared_ptr<devices::HardwareDevice> DeviceManager::find_device_from_info(\n\tconst map<string, string> &search_info)\n{\n\tshared_ptr<devices::HardwareDevice> last_resort_dev;\n\n\tfor (const auto &dev : devices_) {\n\t\tassert(dev);\n\t\tauto dev_info = get_device_info(dev);\n\n\t\t// If present, vendor and model always have to match.\n\t\tif (dev_info.count(\"vendor\") > 0 && search_info.count(\"vendor\") > 0) {\n\t\t\tif (dev_info.at(\"vendor\") != search_info.at(\"vendor\"))\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tif (dev_info.count(\"model\") > 0 && search_info.count(\"model\") > 0) {\n\t\t\tif (dev_info.at(\"model\") != search_info.at(\"model\"))\n\t\t\t\tcontinue;\n\t\t}\n\n\t\t// Most unique match: vendor/model/serial_num (but don't match a S/N of 0)\n\t\tif (dev_info.count(\"serial_num\") > 0 &&\n\t\t\t\tdev_info.at(\"serial_num\") != \"0\" &&\n\t\t\t\tsearch_info.count(\"serial_num\") > 0) {\n\t\t\tif (dev_info.at(\"serial_num\") == search_info.at(\"serial_num\") &&\n\t\t\t\t\tdev_info.at(\"serial_num\") != \"0\")\n\t\t\t\treturn dev;\n\t\t}\n\n\t\t// Second best match: vendor/model/connection_id\n\t\tif (dev_info.count(\"connection_id\") > 0 &&\n\t\t\t\tsearch_info.count(\"connection_id\") > 0) {\n\t\t\tif (dev_info.at(\"connection_id\") == search_info.at(\"connection_id\"))\n\t\t\t\treturn dev;\n\t\t}\n\n\t\t// Last resort: vendor/model/version\n\t\tif (dev_info.count(\"version\") > 0 && search_info.count(\"version\") > 0) {\n\t\t\tif (dev_info.at(\"version\") == search_info.at(\"version\") &&\n\t\t\t\t\tdev_info.at(\"version\") != \"0\")\n\t\t\t\treturn dev;\n\t\t}\n\n\t\t// For this device, we merely have a vendor/model match.\n\t\tlast_resort_dev = dev;\n\t}\n\n\t// If there wasn't even a vendor/model/version match, we end up here.\n\t// This is usually the case for devices with only vendor/model data.\n\t// The selected device may be wrong with multiple such devices attached\n\t// but it is the best we can do at this point. After all, there may be\n\t// only one such device and we do want to select it in this case.\n\treturn last_resort_dev;\n}\n\nbool DeviceManager::compare_devices(shared_ptr<devices::BaseDevice> device_a,\n\tshared_ptr<devices::BaseDevice> device_b) const\n{\n\tassert(device_a);\n\tassert(device_b);\n\treturn device_a->display_name(*this)\n\t\t.compare(device_b->display_name(*this)) < 0;\n}\n\n} // namespace sv\n"
  },
  {
    "path": "src/devicemanager.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICEMANAGER_HPP\n#define DEVICEMANAGER_HPP\n\n#include <list>\n#include <map>\n#include <memory>\n#include <set>\n#include <string>\n#include <vector>\n\nusing std::list;\nusing std::map;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace Glib {\nclass VariantBase;\n}\n\nnamespace sigrok {\nclass ConfigKey;\nclass Context;\nclass Driver;\n}\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\nclass HardwareDevice;\n}\n\nclass DeviceManager\n{\n\npublic:\n\tDeviceManager(shared_ptr<sigrok::Context> context,\n\t\tconst vector<std::string> &drivers, bool do_scan);\n\n\t~DeviceManager() = default;\n\n\tconst shared_ptr<sigrok::Context> &context() const;\n\n\tshared_ptr<sigrok::Context> context();\n\n\tconst list<shared_ptr<devices::HardwareDevice>> &devices() const;\n\tlist<shared_ptr<devices::HardwareDevice>> user_spec_devices() const;\n\n\tlist<shared_ptr<devices::HardwareDevice>> driver_scan(\n\t\tconst string &driver_name, const vector<string> &driver_opts);\n\n\tlist<shared_ptr<devices::HardwareDevice>> driver_scan(\n\t\tshared_ptr<sigrok::Driver> sr_driver,\n\t\tconst map<const sigrok::ConfigKey *, Glib::VariantBase> &drvopts);\n\n\tmap<string, string> get_device_info(\n\t\tconst shared_ptr<devices::BaseDevice> device);\n\n\tshared_ptr<devices::HardwareDevice> find_device_from_info(\n\t\tconst map<string, string> &search_info);\n\nprivate:\n\tbool compare_devices(shared_ptr<devices::BaseDevice> device_a,\n\t\tshared_ptr<devices::BaseDevice> device_b) const;\n\n\tstatic map<const sigrok::ConfigKey *, Glib::VariantBase>\n\tdriver_scan_options(const vector<string> &user_spec,\n\t\tset<const sigrok::ConfigKey *> driver_opts);\n\nprotected:\n\tshared_ptr<sigrok::Context> context_;\n\tlist<shared_ptr<devices::HardwareDevice>> devices_;\n\tlist<shared_ptr<devices::HardwareDevice>> user_spec_devices_;\n\n};\n\n} // namespace sv\n\n#endif // DEVICEMANAGER_HPP\n"
  },
  {
    "path": "src/devices/basedevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <map>\n#include <memory>\n#include <mutex>\n#include <string>\n#include <utility>\n#include <vector>\n#include <glib.h>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDebug>\n#include <QString>\n#include <QUuid>\n\n#include \"basedevice.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/hardwarechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/channels/userchannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\n#define USER_CHANNEL_START_INDEX 1000\n#define CONFIGURABLE_START_INDEX 5000\n\nusing std::bad_alloc;\nusing std::dynamic_pointer_cast;\nusing std::lock_guard;\nusing std::make_pair;\nusing std::make_shared;\nusing std::map;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace devices {\n\nunsigned int BaseDevice::device_counter = 0;\n\nBaseDevice::BaseDevice(const shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::Device> sr_device) :\n\tsr_context_(sr_context),\n\tsr_device_(sr_device),\n\tis_open_(false),\n\tnext_channel_index_(USER_CHANNEL_START_INDEX),\n\tnext_configurable_index_(CONFIGURABLE_START_INDEX),\n\tframe_began_(false)\n{\n\t// Set up a sigrok session per smuvierw device\n\tsr_session_ = sv::Session::sr_context->create_session();\n\n\t// Every device gets its own unique index\n\tindex_ = BaseDevice::device_counter++;\n\n\t/*\n\t * NOTE: Get the start timestamp from the session.\n\t *       This way, combining signals from different devices (export as\n\t *       CSV, XY-Plots) can be displayed with relative timestamps.\n\t */\n\taquisition_start_timestamp_ = sv::Session::session_start_timestamp;\n}\n\nBaseDevice::~BaseDevice()\n{\n\t// TODO: Not called!! Maybe cyclic refernece?\n\tqWarning() << \"BaseDevice::~BaseDevice(): \" << BaseDevice::full_name();\n\tif (sr_session_)\n\t\tBaseDevice::close();\n}\n\nshared_ptr<sigrok::Device> BaseDevice::sr_device() const\n{\n\treturn sr_device_;\n}\n\nDeviceType BaseDevice::type() const\n{\n\treturn type_;\n}\n\nstring BaseDevice::id() const\n{\n\tstring vendor = SettingsManager::format_key(sr_device_->vendor());\n\tstring model = SettingsManager::format_key(sr_device_->model());\n\tstring id = vendor + \":\" + model;\n\n\tif (!sr_device_->serial_number().empty()) {\n\t\tid +=  \":\" + SettingsManager::format_key(sr_device_->serial_number());\n\t}\n\telse if (!sr_device_->connection_id().empty()) {\n\t\tid += \":\" + SettingsManager::format_key(sr_device_->connection_id());\n\t}\n\telse if (type_ == DeviceType::DemoDev) {\n\t\t// Create a random id for the demo device, to make it available and\n\t\t// identifiable in the device tree or via the python API.\n\t\tid += \":\" + util::format_uuid(QUuid::createUuid());\n\t}\n\n\treturn id;\n}\n\nQString BaseDevice::settings_id() const\n{\n\tif (type_ == DeviceType::DemoDev) {\n\t\tstring vendor = SettingsManager::format_key(sr_device_->vendor());\n\t\tstring model = SettingsManager::format_key(sr_device_->model());\n\t\treturn QString::fromStdString(vendor + \":\" + model);\n\t}\n\treturn QString::fromStdString(this->id());\n}\n\nvoid BaseDevice::open()\n{\n\tif (is_open_)\n\t\tclose();\n\n\ttry {\n\t\tsr_device_->open();\n\t}\n\tcatch (const sigrok::Error &e) {\n\t\t// TODO: UserDevices throws SR_ERR_ARG in device.sr_dev_open(). That's\n\t\t//       ok, b/c the device has no driver.\n\t\t//throw QString(e.what());\n\t}\n\n\t// Add device to session (do this in constructor??)\n\tsr_session_->add_device(sr_device_);\n\n\t// Init all configurables\n\tthis->init_configurables();\n\t// Init all channels\n\tthis->init_channels();\n\t// Init aquisition\n\tthis->init_acquisition();\n\n\tis_open_ = true;\n}\n\nvoid BaseDevice::close()\n{\n\tqWarning() << \"BaseDevice::close(): Trying to close device \" <<\n\t\tBaseDevice::full_name();\n\n\tif (!is_open_)\n\t\treturn;\n\n\tsr_session_->stop();\n\n\t// Check that sampling stopped\n\tif (aquisition_thread_.joinable())\n\t\taquisition_thread_.join();\n\tsr_session_->remove_datafeed_callbacks();\n\taquisition_state_ = AquisitionState::Stopped;\n\n\t/*\n\t * NOTE: The device may already be closed from sr_session_->stop()\n\t *\n\t * sigrok::Session::stop() -> sr_session_stop() -> session_stop_sync() ->\n\t * sr_dev_acquisition_stop() -> via devce api dev_acquisition_stop() ->\n\t * std_serial_dev_acquisition_stop() -> sr_dev_close()\n\t */\n\ttry {\n\t\tsr_device_->close();\n\t}\n\tcatch (const sigrok::Error &e) {\n\t\t// TODO: UserDevices throws SR_ERR_ARG in device.sr_dev_close(). That's\n\t\t//       ok, b/c the device has no driver.\n\t\t//throw QString(e.what());\n\t}\n\n\tif (sr_session_)\n\t\tsr_session_->remove_devices();\n\n\tis_open_ = false;\n\n\tqWarning() << \"BaseDevice::close(): Device closed \" <<\n\t\tBaseDevice::full_name();\n}\n\nvoid BaseDevice::start_aquisition()\n{\n\taquisition_state_ = AquisitionState::Running;\n}\n\nvoid BaseDevice::pause_aquisition()\n{\n\taquisition_state_ = AquisitionState::Paused;\n}\n\nstring BaseDevice::name() const\n{\n\tstring sep;\n\tstring name;\n\n\tif (sr_device_->vendor().length() > 0) {\n\t\tname += sr_device_->vendor();\n\t\tsep = \" \";\n\t}\n\n\tif (sr_device_->model().length() > 0) {\n\t\tname += sep + sr_device_->model();\n\t\tsep = \" \";\n\t}\n\n\tif (sr_device_->connection_id().length() > 0) {\n\t\tname += sep + \"(\" + sr_device_->connection_id() + \")\";\n\t}\n\n\treturn name;\n}\n\nQString BaseDevice::full_name() const\n{\n\tQString sep(\"\");\n\tQString full_name(\"\");\n\n\tif (sr_device_->vendor().length() > 0) {\n\t\tfull_name.append(QString::fromStdString(sr_device_->vendor()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->model().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(QString::fromStdString(sr_device_->model()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->version().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(QString::fromStdString(sr_device_->version()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->serial_number().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(QString::fromStdString(sr_device_->serial_number()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->connection_id().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(\"(\");\n\t\tfull_name.append(QString::fromStdString(sr_device_->connection_id()));\n\t\tfull_name.append(\")\");\n\t}\n\n\treturn full_name;\n}\n\nQString BaseDevice::short_name() const\n{\n\tQString sep(\"\");\n\tQString short_name(\"\");\n\n\tif (sr_device_->vendor().length() > 0) {\n\t\tshort_name.append(QString::fromStdString(sr_device_->vendor()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->model().length() > 0) {\n\t\tshort_name.append(sep);\n\t\tshort_name.append(QString::fromStdString(sr_device_->model()));\n\t}\n\n\treturn short_name;\n}\n\nmap<string, shared_ptr<devices::Configurable>>\n\tBaseDevice::configurable_map() const\n{\n\treturn configurable_map_;\n}\n\nmap<string, shared_ptr<channels::BaseChannel>> BaseDevice::channel_map() const\n{\n\treturn channel_map_;\n}\n\nmap<string, vector<shared_ptr<channels::BaseChannel>>>\n\tBaseDevice::channel_group_map() const\n{\n\treturn channel_group_map_;\n}\n\nmap<shared_ptr<sigrok::Channel>, shared_ptr<channels::BaseChannel>>\n\tBaseDevice::sr_channel_map() const\n{\n\treturn sr_channel_map_;\n}\n\nvector<shared_ptr<data::BaseSignal>> BaseDevice::signals() const\n{\n\tvector<shared_ptr<sv::data::BaseSignal>> signals;\n\tfor (const auto &ch_pair : channel_map_) {\n\t\tfor (const auto &signal_pair : ch_pair.second->signal_map()) {\n\t\t\tfor (const auto &signal : signal_pair.second) {\n\t\t\t\tsignals.push_back(signal);\n\t\t\t}\n\t\t}\n\t}\n\treturn signals;\n}\n\nunsigned int BaseDevice::next_channel_index()\n{\n\treturn next_channel_index_++;\n}\n\n\nvoid BaseDevice::add_channel(shared_ptr<channels::BaseChannel> channel,\n\tconst string &channel_group_name)\n{\n\t// Check if channel already exists. Channel names are unique per device.\n\tif (channel_map_.count(channel->name()) == 0) {\n\t\tconnect(this, &BaseDevice::aquisition_start_timestamp_changed,\n\t\t\tchannel.get(), &channels::BaseChannel::on_aquisition_start_timestamp_changed);\n\n\t\t// map<QString, shared_ptr<channels::BaseChannel>> channel_name_map_;\n\t\tchannel_map_.insert(make_pair(channel->name(), channel));\n\t}\n\n\t// map<QString, vector<shared_ptr<channels::BaseChannel>>> channel_group_name_map_;\n\tif (channel_group_map_.count(channel_group_name) == 0) {\n\t\tchannel_group_map_.insert(make_pair(\n\t\t\tchannel_group_name, vector<shared_ptr<channels::BaseChannel>>()));\n\t}\n\tchannel_group_map_[channel_group_name].push_back(channel);\n\n\tif (channel->channel_group_names().count(channel_group_name) == 0) {\n\t\tchannel->add_channel_group_name(channel_group_name);\n\t}\n\n\tQ_EMIT channel_added(channel);\n}\n\nshared_ptr<channels::BaseChannel> BaseDevice::add_sr_channel(\n\tshared_ptr<sigrok::Channel> sr_channel, const string &channel_group_name)\n{\n\t// Check if channel already exists.\n\t// NOTE: Channel names are unique per device.\n\tshared_ptr<channels::BaseChannel> channel;\n\tif (channel_map_.count(sr_channel->name()) > 0) {\n\t\tchannel = channel_map()[sr_channel->name()];\n\t}\n\telse {\n\t\tset<string> chg_names { channel_group_name };\n\t\tchannel = make_shared<channels::HardwareChannel>(sr_channel,\n\t\t\tshared_from_this(), chg_names, aquisition_start_timestamp_);\n\n\t\t// map<shared_ptr<sigrok::Channel>, shared_ptr<channels::BaseChannel>> sr_channel_map_;\n\t\tsr_channel_map_.insert(make_pair(sr_channel, channel));\n\t}\n\n\tadd_channel(channel, channel_group_name);\n\n\treturn channel;\n}\n\nvoid BaseDevice::add_math_channel(\n\tshared_ptr<channels::MathChannel> math_channel,\n\tconst string &channel_group_name)\n{\n\tadd_channel(math_channel, channel_group_name);\n\n\t/*\n\t * TODO: Remove shared_from_this() / (channel pointer in signal), so that\n\t *       \"add_signal()\" can be called from MathChannel ctor.\n\t */\n\tmath_channel->add_signal(\n\t\tmath_channel->quantity(),\n\t\tmath_channel->quantity_flags(),\n\t\tmath_channel->unit());\n}\n\nshared_ptr<channels::UserChannel> BaseDevice::add_user_channel(\n\tconst string &channel_name, const string &channel_group_name)\n{\n\tshared_ptr<channels::UserChannel> channel =\n\t\tmake_shared<channels::UserChannel>(\n\t\t\tchannel_name, set<string> { channel_group_name },\n\t\t\tshared_from_this(), aquisition_start_timestamp_);\n\tadd_channel(channel, channel_group_name);\n\n\treturn channel;\n}\n\nvoid BaseDevice::init_acquisition()\n{\n\tsr_session_->add_datafeed_callback([=]\n\t\t(shared_ptr<sigrok::Device> sr_device, shared_ptr<sigrok::Packet> sr_packet) {\n\t\t\tdata_feed_in(sr_device, sr_packet);\n\t\t});\n\taquisition_thread_ = std::thread(\n\t\t&BaseDevice::aquisition_thread_proc, this);\n\taquisition_state_ = AquisitionState::Running;\n}\n\nvoid BaseDevice::data_feed_in(shared_ptr<sigrok::Device> sr_device,\n\tshared_ptr<sigrok::Packet> sr_packet)\n{\n\t/*\n\tqWarning() << \"data_feed_in(): sr_packet->type()->id() = \"\n\t\t<< sr_packet->type()->id();\n\tqWarning() << \"data_feed_in(): sr_device->model() = \"\n\t\t<< QString::fromStdString(sr_device->model())\n\t\t<< \", this->model() = \" << QString::fromStdString(sr_device_->model());\n\t*/\n\n\tassert(sr_device);\n\tassert(sr_packet);\n\n\tif (sr_device != sr_device_)\n\t\treturn;\n\n\tswitch (sr_packet->type()->id()) {\n\tcase SR_DF_HEADER:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_HEADER\";\n\t\tfeed_in_header();\n\t\tbreak;\n\n\tcase SR_DF_META:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_META\";\n\t\tfeed_in_meta(\n\t\t\tdynamic_pointer_cast<sigrok::Meta>(sr_packet->payload()));\n\t\tbreak;\n\n\tcase SR_DF_TRIGGER:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_TRIGGER\";\n\t\tfeed_in_trigger();\n\t\tbreak;\n\n\tcase SR_DF_LOGIC:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_LOGIC\";\n\t\tif (aquisition_state_ != AquisitionState::Running)\n\t\t\treturn;\n\n\t\ttry {\n\t\t\tfeed_in_logic(\n\t\t\t\tdynamic_pointer_cast<sigrok::Logic>(sr_packet->payload()));\n\t\t} catch (bad_alloc &) {\n\t\t\t//out_of_memory_ = true;\n\t\t}\n\t\tbreak;\n\n\tcase SR_DF_ANALOG:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_ANALOG\";\n\t\tif (aquisition_state_ != AquisitionState::Running)\n\t\t\treturn;\n\n\t\ttry {\n\t\t\tfeed_in_analog(\n\t\t\t\tdynamic_pointer_cast<sigrok::Analog>(sr_packet->payload()));\n\t\t} catch (bad_alloc &) {\n\t\t\t//out_of_memory_ = true;\n\t\t}\n\t\tbreak;\n\n\tcase SR_DF_FRAME_BEGIN:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_FRAME_BEGIN\";\n\t\tfeed_in_frame_begin();\n\t\tbreak;\n\n\tcase SR_DF_FRAME_END:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_FRAME_END\";\n\t\tfeed_in_frame_end();\n\t\tbreak;\n\n\tcase SR_DF_END:\n\t\t//qWarning() << \"data_feed_in(): SR_DF_END\";\n\t\t// Strictly speaking, this is performed when a frame end marker was\n\t\t// received, so there's no point doing this again. However, not all\n\t\t// devices use frames, and for those devices, we need to do it here.\n\t\t{\n\t\t\tlock_guard<recursive_mutex> lock(data_mutex_);\n\t\t}\n\t\tbreak;\n\n\tdefault:\n\t\tbreak;\n\t}\n}\n\nvoid BaseDevice::aquisition_thread_proc()\n{\n\ttry {\n\t\tsr_session_->start();\n\t}\n\tcatch (sigrok::Error &e) {\n\t\tstring error_detail = string(e.what())\n\t\t\t+ \" when trying to start() the sigrok session\";\n\t\tQ_EMIT device_error(name(), error_detail);\n\t\treturn;\n\t}\n\n\taquisition_state_ = AquisitionState::Running;\n\t/*\n\t// TODO: use std::chrono / std::time\n\t// NOTE: ATM only the session start timestamp is used!\n\taquisition_start_timestamp_ =\n\t\tQDateTime::currentMSecsSinceEpoch() / (double)1000;\n\tQ_EMIT aquisition_start_timestamp_changed(aquisition_start_timestamp_);\n\t*/\n\n\tqWarning()\n\t\t<< \"Start aquisition for \" << short_name()\n\t\t<< \",  aquisition_start_timestamp_ = \"\n\t\t<< util::format_time_date(aquisition_start_timestamp_);\n\n\ttry {\n\t\tsr_session_->run();\n\t}\n\tcatch (sigrok::Error &e) {\n\t\tstring error_detail = string(e.what())\n\t\t\t+ \" when trying to run() the sigrok session\";\n\t\tQ_EMIT device_error(name(), error_detail);\n\t\taquisition_state_ = AquisitionState::Stopped;\n\t\treturn;\n\t}\n\taquisition_state_ = AquisitionState::Stopped;\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/basedevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_BASEDEVICE_HPP\n#define DEVICES_BASEDEVICE_HPP\n\n#include <map>\n#include <memory>\n#include <mutex>\n#include <string>\n#include <thread>\n\n#include <QObject>\n#include <QString>\n\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::map;\nusing std::mutex;\nusing std::recursive_mutex;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sigrok {\nclass Analog;\nclass Channel;\nclass Context;\nclass Device;\nclass Logic;\nclass Meta;\nclass Packet;\nclass Session;\n}\n\nnamespace sv {\n\nclass DeviceManager;\n\nnamespace channels {\nclass BaseChannel;\nclass MathChannel;\nclass UserChannel;\n}\n\nnamespace data {\nclass BaseSignal;\n}\n\nnamespace devices {\n\nclass Configurable;\n\nenum class AquisitionState {\n\tStopped,\n\tRunning,\n\tPaused\n};\n\nclass BaseDevice :\n\tpublic QObject,\n\tpublic std::enable_shared_from_this<BaseDevice>\n{\n\tQ_OBJECT\n\npublic:\n\tBaseDevice(const shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::Device> sr_device);\n\tvirtual ~BaseDevice();\n\n\t/**\n\t *\n\t */\n\tshared_ptr<sigrok::Device> sr_device() const;\n\n\t/**\n\t * Returns the device type\n\t */\n\tDeviceType type() const;\n\n\t/**\n\t * Get the unique Id of the device.\n\t */\n\tstring id() const;\n\n\t/**\n\t * Get the Id of the device, used as a identifier for QSettings.\n\t */\n\tQString settings_id() const;\n\n\t/**\n\t * Builds the name\n\t */\n\tvirtual string name() const;\n\n\t/**\n\t * Builds the full name. It only contains all the fields.\n\t */\n\tvirtual QString full_name() const;\n\n\t/**\n\t * Builds the short name.\n\t */\n\tvirtual QString short_name() const;\n\n\t/**\n\t * Builds the display name. It only contains fields as required.\n\t *\n\t * @param device_manager a reference to the device manager is needed\n\t * so that other similarly titled devices can be detected.\n\t */\n\tvirtual QString display_name(\n\t\tconst DeviceManager &device_manager) const = 0;\n\n\t/**\n\t * Open the device.\n\t */\n\tvirtual void open();\n\n\t/**\n\t * Close the device.\n\t */\n\tvoid close();\n\n\t/**\n\t * Start data aquisition from device after init or pause.\n\t */\n\tvirtual void start_aquisition();\n\n\t/**\n\t * Pause data aquisition from device.\n\t */\n\tvirtual void pause_aquisition();\n\n\t/**\n\t * Get the aquisition state.\n\t */\n\tAquisitionState aquisition_state();\n\n\t/**\n\t * Get the next index for a new channel.\n\t */\n\tunsigned int next_channel_index();\n\n\t/**\n\t * Add a sv::channels:.Channel to the device\n\t */\n\tvirtual void add_channel(shared_ptr<channels::BaseChannel> channel,\n\t\tconst string &channel_group_name);\n\n\t/**\n\t * Add a sigrok::Channel to the device.\n\t */\n\tshared_ptr<channels::BaseChannel> add_sr_channel(\n\t\tshared_ptr<sigrok::Channel> sr_channel,\n\t\tconst string &channel_group_name);\n\n\t/**\n\t * Add a math channel to the device\n\t */\n\tvoid add_math_channel(shared_ptr<channels::MathChannel> math_channel,\n\t\tconst string &channel_group_name);\n\n\t/**\n\t * Add a user channel to the device\n\t */\n\tshared_ptr<channels::UserChannel> add_user_channel(\n\t\tconst string &channel_name, const string &channel_group_name);\n\n\t/**\n\t * Returns a map with all configurables of this device\n\t */\n\tmap<string, shared_ptr<devices::Configurable>> configurable_map() const;\n\n\t/**\n\t * Returns a map with all channels of this device\n\t */\n\tmap<string, shared_ptr<channels::BaseChannel>> channel_map() const;\n\n\t/**\n\t * Returns a map with all channel groups of this device\n\t */\n\tmap<string, vector<shared_ptr<channels::BaseChannel>>> channel_group_map() const;\n\n\t/**\n\t * Get the map between sigrok::Channel and sv::Channels::BaseChannel\n\t */\n\tmap<shared_ptr<sigrok::Channel>, shared_ptr<channels::BaseChannel>> sr_channel_map() const;\n\n\t/**\n\t * Returns all signals of this device\n\t */\n\tvector<shared_ptr<data::BaseSignal>> signals() const;\n\n\nprotected:\n\t/**\n\t * Init all configurables for this device. Implemented in the\n\t * specific device.\n\t */\n\tvirtual void init_configurables() = 0;\n\t/**\n\t * Init all channels for this device. Implemented in the specific device.\n\t */\n\tvirtual void init_channels() = 0;\n\t/**\n\t * Init acquisition for this device.\n\t */\n\tvirtual void init_acquisition();\n\n\tvirtual void feed_in_header() = 0;\n\tvirtual void feed_in_trigger() = 0;\n\tvirtual void feed_in_meta(shared_ptr<sigrok::Meta> sr_meta) = 0;\n\tvirtual void feed_in_frame_begin() = 0;\n\tvirtual void feed_in_frame_end() = 0;\n\tvirtual void feed_in_logic(shared_ptr<sigrok::Logic> sr_logic) = 0;\n\tvirtual void feed_in_analog(shared_ptr<sigrok::Analog> sr_analog) = 0;\n\n\tvoid data_feed_in(shared_ptr<sigrok::Device> sr_device,\n\t\tshared_ptr<sigrok::Packet> sr_packet);\n\n\tstatic unsigned int device_counter;\n\n\tconst shared_ptr<sigrok::Context> sr_context_;\n\tshared_ptr<sigrok::Session> sr_session_;\n\tshared_ptr<sigrok::Device> sr_device_;\n\tDeviceType type_;\n\tunsigned int index_;\n\tbool is_open_;\n\n\tunsigned int next_channel_index_;\n\tunsigned int next_configurable_index_;\n\n\tmap<string, shared_ptr<devices::Configurable>> configurable_map_;\n\tmap<string, shared_ptr<channels::BaseChannel>> channel_map_;\n\tmap<string, vector<shared_ptr<channels::BaseChannel>>> channel_group_map_;\n\tmap<shared_ptr<sigrok::Channel>, shared_ptr<channels::BaseChannel>> sr_channel_map_;\n\n\tmutable mutex aquisition_mutex_; //!< Protects access to capture_state_. // TODO\n\tmutable recursive_mutex data_mutex_; // TODO\n\tAquisitionState aquisition_state_;\n\tdouble aquisition_start_timestamp_;\n\n\tbool frame_began_;\n\nprivate:\n\tvoid aquisition_thread_proc();\n\n\tstd::thread aquisition_thread_;\n\nQ_SIGNALS:\n\tvoid aquisition_start_timestamp_changed(double timestamp);\n\tvoid channel_added(shared_ptr<sv::channels::BaseChannel> channel);\n\tvoid device_error(const std::string &sender, const std::string &msg);\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_BASEDEVICE_HPP\n"
  },
  {
    "path": "src/devices/configurable.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <type_traits>\n#include <map>\n#include <memory>\n#include <set>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <glib.h>\n#include <glibmm.h>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDebug>\n#include <QString>\n\n#include \"configurable.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/boolproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/data/properties/doublerangeproperty.hpp\"\n#include \"src/data/properties/int32property.hpp\"\n#include \"src/data/properties/measuredquantityproperty.hpp\"\n#include \"src/data/properties/rationalproperty.hpp\"\n#include \"src/data/properties/stringproperty.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/data/properties/uint64rangeproperty.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::make_pair;\nusing std::make_shared;\nusing std::set;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace devices {\n\nConfigurable::Configurable(\n\t\tconst shared_ptr<sigrok::Configurable> sr_configurable,\n\t\tunsigned int configurable_index,\n\t\tconst string &device_name, const DeviceType device_type,\n\t\tconst QString &device_settings_id):\n\tsr_configurable_(sr_configurable),\n\tindex_(configurable_index),\n\tdevice_name_(device_name),\n\tdevice_type_(device_type),\n\tdevice_settings_id_(device_settings_id)\n{\n}\n\n/*\ntemplate<typename ...Arg>\nshared_ptr<Configurable> Configurable::create(Arg&&...arg)\n{\n\tstruct make_shared_enabler : public Configurable {\n\t\tmake_shared_enabler(Arg&&...arg) : Configurable(forward<Arg>(arg)...) {}\n\t};\n\n\tshared_ptr<Configurable> configurable =\n\t\tmake_shared<make_shared_enabler>(forward<Arg>(arg)...);\n\tconfigurable->init();\n\n\treturn configurable;\n}\n*/\n\nvoid Configurable::init()\n{\n\tconst auto sr_config_keys = sr_configurable_->config_keys();\n\tfor (const auto &sr_config_key : sr_config_keys) {\n\t\tConfigKey config_key = deviceutil::get_config_key(sr_config_key);\n\t\tif (config_key == ConfigKey::Unknown)\n\t\t\tcontinue;\n\n\t\tqWarning() << \"Configurable::init(): Init \" << display_name()\n\t\t\t<< \" - key \" << deviceutil::format_config_key(config_key);\n\n\t\tconst auto sr_capabilities =\n\t\t\tsr_configurable_->config_capabilities(sr_config_key);\n\t\tif (sr_capabilities.count(sigrok::Capability::GET) > 0)\n\t\t\tgetable_configs_.insert(config_key);\n\t\tif (sr_capabilities.count(sigrok::Capability::SET) > 0)\n\t\t\tsetable_configs_.insert(config_key);\n\t\tif (sr_capabilities.count(sigrok::Capability::LIST) > 0)\n\t\t\tlistable_configs_.insert(config_key);\n\n\t\tshared_ptr<data::properties::BaseProperty> property;\n\t\tconst data::DataType data_type =\n\t\t\tdeviceutil::get_data_type_for_config_key(config_key);\n\t\tswitch (data_type) {\n\t\tcase data::DataType::Int32:\n\t\t\tproperty = make_shared<data::properties::Int32Property>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::UInt64:\n\t\t\tproperty = make_shared<data::properties::UInt64Property>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::Double:\n\t\t\tproperty = make_shared<data::properties::DoubleProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::String:\n\t\t\tproperty = make_shared<data::properties::StringProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::Bool:\n\t\t\tproperty = make_shared<data::properties::BoolProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::MQ:\n\t\t\tproperty = make_shared<data::properties::MeasuredQuantityProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::RationalPeriod:\n\t\tcase data::DataType::RationalVolt:\n\t\t\tproperty = make_shared<data::properties::RationalProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::UInt64Range:\n\t\t\tproperty = make_shared<data::properties::UInt64RangeProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::DoubleRange:\n\t\t\tproperty = make_shared<data::properties::DoubleRangeProperty>(\n\t\t\t\tshared_from_this(), config_key);\n\t\t\tbreak;\n\t\tcase data::DataType::KeyValue:\n\t\t\t// TODO: What is KeyValue?\n\t\tcase data::DataType::Unknown:\n\t\tdefault:\n\t\t\tassert(\"Unknown DataType\");\n\t\t}\n\n\t\tproperty_map_.insert(make_pair(config_key, property));\n\t}\n}\n\nbool Configurable::has_get_config(devices::ConfigKey config_key)  const\n{\n\treturn getable_configs_.count(config_key) > 0;\n}\n\ntemplate bool Configurable::get_config(devices::ConfigKey, bool &value) const;\ntemplate bool Configurable::get_config(devices::ConfigKey, int32_t &value) const;\ntemplate bool Configurable::get_config(devices::ConfigKey, uint64_t &value) const;\ntemplate bool Configurable::get_config(devices::ConfigKey, double &value) const;\ntemplate bool Configurable::get_config(devices::ConfigKey, std::string &value) const;\ntemplate<typename T> bool Configurable::get_config(\n\tdevices::ConfigKey config_key, T &value) const\n{\n\tassert(sr_configurable_);\n\n\tconst sigrok::ConfigKey *sr_key =\n\t\tdevices::deviceutil::get_sr_config_key(config_key);\n\n\tif (!sr_configurable_->config_check(sr_key, sigrok::Capability::GET)) {\n\t\tqWarning() << \"Configurable::get_config(): No getable config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key);\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tvalue = Glib::VariantBase::cast_dynamic<Glib::Variant<T>>(\n\t\t\tsr_configurable_->config_get(sr_key)).get();\n\t}\n\tcatch (sigrok::Error &error) {\n\t\tqWarning() << \"Configurable::get_config(): Failed to get key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \". \"\n\t\t\t<< error.what();\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Configurable::get_container_config(\n\tdevices::ConfigKey config_key, Glib::VariantContainerBase &value) const\n{\n\tassert(sr_configurable_);\n\n\tconst sigrok::ConfigKey *sr_key =\n\t\tdevices::deviceutil::get_sr_config_key(config_key);\n\n\tif (!sr_configurable_->config_check(sr_key, sigrok::Capability::GET)) {\n\t\tqWarning()\n\t\t\t<< \"Configurable::get_container_config(): No getable config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key);\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tGlib::VariantBase gvar = sr_configurable_->config_get(sr_key);\n\t\tif (gvar.is_container()) {\n\t\t\tvalue =\n\t\t\t\tGlib::VariantBase::cast_dynamic<Glib::VariantContainerBase>(gvar);\n\t\t}\n\t\telse {\n\t\t\tvalue = Glib::VariantContainerBase();\n\t\t}\n\t}\n\tcatch (sigrok::Error &error) {\n\t\tqWarning() << \"Configurable::get_container_config(): Failed to get key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \". \"\n\t\t\t<< error.what();\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nbool Configurable::get_measured_quantity_config(\n\tdevices::ConfigKey config_key, data::measured_quantity_t &value) const\n{\n\tGlib::VariantContainerBase gvar;\n\tbool ret = this->get_container_config(config_key, gvar);\n\tif (!ret)\n\t\treturn false;\n\n\tsize_t child_cnt = gvar.get_n_children();\n\tif (child_cnt != 2) {\n\t\tqWarning() << \"Configurable::get_measured_quantity_config(): \"\n\t\t\t<< \"Container (mq) should have 2 child, but has \" << child_cnt;\n\t\treturn false;\n\t}\n\n\tGlib::VariantIter iter(gvar);\n\titer.next_value(gvar);\n\tuint32_t sr_q =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint32_t>>(gvar).get();\n\tdata::Quantity quantity = data::datautil::get_quantity(sr_q);\n\n\titer.next_value(gvar);\n\tuint64_t sr_qflags =\n\t\tGlib::VariantBase::cast_dynamic<Glib::Variant<uint64_t>>(gvar).get();\n\tset<data::QuantityFlag> quantity_flags =\n\t\tdata::datautil::get_quantity_flags(sr_qflags);\n\n\tvalue = make_pair(quantity, quantity_flags);\n\n\treturn true;\n}\n\nbool Configurable::has_set_config(devices::ConfigKey config_key) const\n{\n\treturn setable_configs_.count(config_key) > 0;\n}\n\ntemplate void Configurable::set_config(devices::ConfigKey, const bool);\ntemplate void Configurable::set_config(devices::ConfigKey, const int32_t);\ntemplate void Configurable::set_config(devices::ConfigKey, const uint64_t);\ntemplate void Configurable::set_config(devices::ConfigKey, const double);\ntemplate void Configurable::set_config(devices::ConfigKey, const std::string);\ntemplate void Configurable::set_config(devices::ConfigKey, const Glib::ustring);\ntemplate<typename T> void Configurable::set_config(\n\tdevices::ConfigKey config_key, const T value)\n{\n\tassert(sr_configurable_);\n\n\tconst sigrok::ConfigKey *sr_key =\n\t\tdevices::deviceutil::get_sr_config_key(config_key);\n\n\tif (!sr_configurable_->config_check(sr_key, sigrok::Capability::SET)) {\n\t\tqWarning() << \"Configurable::set_config(): No setable config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key);\n\t\tassert(false);\n\t}\n\n\ttry {\n\t\tsr_configurable_->config_set(sr_key, Glib::Variant<T>::create(value));\n\t}\n\tcatch (sigrok::Error &error) {\n\t\tqWarning() << \"Configurable::set_config(): Failed to set config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \". \"\n\t\t\t<< error.what();\n\t}\n}\n\nvoid Configurable::set_container_config(\n\tdevices::ConfigKey config_key, const vector<Glib::VariantBase> &childs)\n{\n\tassert(sr_configurable_);\n\n\tconst sigrok::ConfigKey *sr_key =\n\t\tdevices::deviceutil::get_sr_config_key(config_key);\n\n\tif (!sr_configurable_->config_check(sr_key, sigrok::Capability::SET)) {\n\t\tqWarning()\n\t\t\t<< \"Configurable::set_container_config(): No setable config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key);\n\t\tassert(false);\n\t}\n\n\ttry {\n\t\tqWarning()\n\t\t\t<< \"Configurable::set_container_config(): Set config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \" to \"\n\t\t\t<< childs;\n\t\tsr_configurable_->config_set(\n\t\t\tsr_key, Glib::VariantContainerBase::create_tuple(childs));\n\t}\n\tcatch (sigrok::Error &error) {\n\t\tqWarning()\n\t\t\t<< \"Configurable::set_container_config(): Failed to set config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \". \"\n\t\t\t<< error.what();\n\t}\n}\n\nvoid Configurable::set_measured_quantity_config(devices::ConfigKey config_key,\n\tconst data::measured_quantity_t &mq)\n{\n\tqWarning()\n\t\t<< \"Configurable::set_measured_quantity_config(): Set config key \"\n\t\t<< devices::deviceutil::format_config_key(config_key) << \" to \"\n\t\t<< data::datautil::format_measured_quantity(mq);\n\n\tuint32_t sr_q_id = data::datautil::get_sr_quantity_id(mq.first);\n\tGlib::VariantBase gvar_q = Glib::Variant<uint32_t>::create(sr_q_id);\n\tuint64_t sr_qfs_id = data::datautil::get_sr_quantity_flags_id(mq.second);\n\tGlib::VariantBase gvar_qfs = Glib::Variant<uint64_t>::create(sr_qfs_id);\n\n\tqWarning()\n\t\t<< \"Configurable::set_measured_quantity_config(): Set config key \"\n\t\t<< devices::deviceutil::format_config_key(config_key) << \" to \"\n\t\t<< sr_q_id << \", \" << sr_qfs_id;\n\n\tvector<Glib::VariantBase> gcontainer;\n\tgcontainer.push_back(gvar_q);\n\tgcontainer.push_back(gvar_qfs);\n\n\tthis->set_container_config(config_key, gcontainer);\n}\n\nbool Configurable::has_list_config(devices::ConfigKey config_key) const\n{\n\treturn listable_configs_.count(config_key) > 0;\n}\n\nbool Configurable::list_config(devices::ConfigKey config_key,\n\tGlib::VariantContainerBase &gvar)\n{\n\tassert(sr_configurable_);\n\n\tconst sigrok::ConfigKey *sr_key =\n\t\tdevices::deviceutil::get_sr_config_key(config_key);\n\n\tif (!sr_configurable_->config_check(sr_key, sigrok::Capability::LIST)) {\n\t\tqWarning()\n\t\t\t<< \"Configurable::list_config(): No config key / no listable config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key);\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tgvar = sr_configurable_->config_list(sr_key);\n\t}\n\tcatch (sigrok::Error &error) {\n\t\tqWarning() << \"Configurable::list_config(): Failed to list config key \"\n\t\t\t<< devices::deviceutil::format_config_key(config_key) << \". \"\n\t\t\t<< error.what();\n\t\treturn false;\n\t}\n\n\treturn true;\n}\n\nstring Configurable::name() const\n{\n\tstring name;\n\tif (auto sr = dynamic_pointer_cast<sigrok::HardwareDevice>(sr_configurable_)) {\n\t\tname = \"\";\n\t}\n\telse if (auto sr = dynamic_pointer_cast<sigrok::ChannelGroup>(sr_configurable_)) {\n\t\tname = sr->name();\n\t}\n\treturn name;\n}\n\nQString Configurable::display_name() const\n{\n\tQString display_name = QString::fromStdString(this->name());\n\tif (display_name.isEmpty())\n\t\tdisplay_name = QString::fromStdString(device_name_);\n\n\treturn display_name;\n}\n\nunsigned int Configurable::index() const\n{\n\treturn index_;\n}\n\nDeviceType Configurable::device_type() const\n{\n\treturn device_type_;\n}\n\nQString Configurable::device_settings_id() const\n{\n\treturn device_settings_id_;\n}\n\nset<devices::ConfigKey> Configurable::getable_configs() const\n{\n\treturn getable_configs_;\n}\n\nset<devices::ConfigKey> Configurable::setable_configs() const\n{\n\treturn setable_configs_;\n}\n\nset<devices::ConfigKey> Configurable::listable_configs() const\n{\n\treturn listable_configs_;\n}\n\nmap<devices::ConfigKey, shared_ptr<data::properties::BaseProperty>>\n\tConfigurable::property_map() const\n{\n\treturn property_map_;\n}\n\nshared_ptr<data::properties::BaseProperty>\n\tConfigurable::get_property(devices::ConfigKey config_key) const\n{\n\tif (property_map_.count(config_key) == 0)\n\t\treturn nullptr;\n\treturn property_map_.at(config_key);\n}\n\nbool Configurable::is_controllable() const\n{\n\treturn !setable_configs_.empty() ||\n\t\t!getable_configs_.empty() ||\n\t\t!listable_configs_.empty();\n}\n\nbool Configurable::feed_in_meta(shared_ptr<sigrok::Meta> sr_meta)\n{\n\t// TODO: Fix in libsigrok: No list for config! That will make the check if\n\t// a configKey is existant in this configurable easier!\n\tfor (const auto &entry : sr_meta->config()) {\n\t\tdevices::ConfigKey config_key =\n\t\t\tdevices::deviceutil::get_config_key(entry.first);\n\n\t\tif (property_map_.count(config_key) == 0) {\n\t\t\tqWarning() << \"Configurable::feed_in_meta(): Unknown config key \"\n\t\t\t\t<< QString::fromStdString(entry.first->name())\n\t\t\t\t<< \" for configurable \" << display_name() << \" received\";\n\t\t\treturn false;\n\t\t}\n\n\t\tproperty_map_[config_key]->on_value_changed(entry.second);\n\n\t\t// TODO: return QVariant from prop->on_value_changed(); and emit\n\t\t//Q_EMIT config_changed(config_key, qvar);\n\t}\n\n\treturn true;\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/configurable.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_CONFIGURABLE_HPP\n#define DEVICES_CONFIGURABLE_HPP\n\n#include <map>\n#include <memory>\n#include <set>\n#include <string>\n#include <tuple>\n#include <utility>\n#include <vector>\n\n#include <glib.h>\n\n#include <QObject>\n#include <QString>\n#include <QVariant>\n\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::forward;\nusing std::make_shared;\nusing std::map;\nusing std::pair;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sigrok {\nclass ConfigKey;\nclass Configurable;\nclass Quantity;\nclass QuantityFlag;\nclass Meta;\n}\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace devices {\n\nclass Configurable :\n\tpublic QObject,\n\tpublic std::enable_shared_from_this<Configurable>\n{\n\tQ_OBJECT\n\nprivate:\n\tConfigurable(const shared_ptr<sigrok::Configurable> sr_configurable,\n\t\tunsigned int configurable_index,\n\t\tconst string &device_name, const DeviceType device_type,\n\t\tconst QString &device_settings_id);\n\npublic:\n\ttemplate<typename ...Arg>\n\tshared_ptr<Configurable> static create(Arg&&...arg)\n\t{\n\t\tstruct make_shared_enabler : public Configurable {\n\t\t\texplicit make_shared_enabler(Arg&&...arg) :\n\t\t\t\tConfigurable(forward<Arg>(arg)...)\n\t\t\t{\n\t\t\t}\n\t\t};\n\n\t\tshared_ptr<Configurable> configurable =\n\t\t\tmake_shared<make_shared_enabler>(forward<Arg>(arg)...);\n\t\tconfigurable->init();\n\n\t\treturn configurable;\n\t}\n\n\n\t/**\n\t * Init the properties (config keys) and default lists.\n\t * Must be called after instantiation and not from the ctor.\n\t */\n\tvoid init();\n\n\tbool has_get_config(devices::ConfigKey config_key) const;\n\ttemplate<typename T> bool get_config(\n\t\tdevices::ConfigKey config_key, T &value) const;\n\t/**\n\t * Special handling for Container Variants (especially std::tuple, used for\n\t * measured quantity, ranges and rationales).\n\t * Tuple types are only supported with version >= 2.52 of glibmm, but we\n\t * need to use version 2.42, because of mxe. Maybe there is also a bug in\n\t * the tuple support?\n\t *\n\t * TODO: Remove when glibmm >= 2.52\n\t */\n\tbool get_container_config(\n\t\tdevices::ConfigKey config_key, Glib::VariantContainerBase &value) const;\n\t/**\n\t * Helper function to map to get_container_config().\n\t *\n\t * TODO: Remove when glibmm >= 2.52\n\t */\n\tbool get_measured_quantity_config(\n\t\tdevices::ConfigKey config_key, data::measured_quantity_t &value) const;\n\n\tbool has_set_config(devices::ConfigKey config_key) const;\n\ttemplate<typename T> void set_config(devices::ConfigKey config_key, const T value);\n\t/**\n\t * Special handling for Container Variants (especially std::tuple, used for\n\t * measured quantity, ranges and rationales).\n\t * Tuple types are only supported with version >= 2.52 of glibmm, but we\n\t * need to use version 2.42, because of mxe. Maybe there is also a bug in\n\t * the tuple support?\n\t *\n\t * TODO: Remove when glibmm >= 2.52\n\t */\n\tvoid set_container_config(devices::ConfigKey config_key,\n\t\tconst vector<Glib::VariantBase> &childs);\n\t/**\n\t * Helper function to map to set_container_config().\n\t *\n\t * TODO: Remove when glibmm >= 2.52\n\t */\n\tvoid set_measured_quantity_config(devices::ConfigKey config_key,\n\t\tconst data::measured_quantity_t &mq);\n\n\tbool has_list_config(devices::ConfigKey config_key) const;\n\tbool list_config(devices::ConfigKey config_key, Glib::VariantContainerBase &gvar);\n\n\t/**\n\t * Get the name of this configurable.\n\t */\n\tstring name() const;\n\n\t/**\n\t * Get the display name of this configurable.\n\t */\n\tQString display_name() const;\n\n\t/**\n\t * Get the unique index number of this configurable.\n\t */\n\tunsigned int index() const;\n\n\t/**\n\t * Get the type of this configurable.\n\t */\n\tDeviceType device_type() const;\n\n\t/**\n\t * Get the settings id of the device this configurable belongs to.\n\t */\n\tQString device_settings_id() const;\n\n\tset<devices::ConfigKey> getable_configs() const;\n\tset<devices::ConfigKey> setable_configs() const;\n\tset<devices::ConfigKey> listable_configs() const;\n\n\tmap<devices::ConfigKey, shared_ptr<data::properties::BaseProperty>> property_map() const;\n\tshared_ptr<data::properties::BaseProperty> get_property(devices::ConfigKey config_key) const;\n\n\tbool is_controllable() const;\n\n\tbool feed_in_meta(shared_ptr<sigrok::Meta> sr_meta);\n\nprivate:\n\tconst shared_ptr<sigrok::Configurable> sr_configurable_;\n\tunsigned int index_;\n\tconst string device_name_;\n\tconst DeviceType device_type_;\n\tconst QString device_settings_id_;\n\n\tset<devices::ConfigKey> getable_configs_;\n\tset<devices::ConfigKey> setable_configs_;\n\tset<devices::ConfigKey> listable_configs_;\n\tmap<devices::ConfigKey, shared_ptr<data::properties::BaseProperty>> property_map_;\n\nQ_SIGNALS:\n\tvoid config_changed(\n\t\tconst devices::ConfigKey config_key, const QVariant &qvar);\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_CONFIGURABLE_HPP\n"
  },
  {
    "path": "src/devices/deviceutil.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n\n#include \"deviceutil.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace devices {\nnamespace deviceutil {\n\ndevice_type_name_map_t get_device_type_name_map()\n{\n\treturn device_type_name_map;\n}\n\nconnection_key_name_map_t get_connection_key_name_map()\n{\n\treturn connection_key_name_map;\n}\n\nconfig_key_name_map_t get_config_key_name_map()\n{\n\treturn config_key_name_map;\n}\n\n\nbool is_supported_driver(shared_ptr<sigrok::Driver> sr_driver)\n{\n\tassert(sr_driver);\n\n\treturn is_source_sink_driver(sr_driver) ||\n\t\tis_measurement_driver(sr_driver) ||\n\t\tis_oscilloscope_driver(sr_driver);\n}\n\nbool is_source_sink_driver(shared_ptr<sigrok::Driver> sr_driver)\n{\n\tassert(sr_driver);\n\n\tconst auto keys = sr_driver->config_keys();\n\treturn keys.count(sigrok::ConfigKey::POWER_SUPPLY) > 0\n\t\t|| keys.count(sigrok::ConfigKey::ELECTRONIC_LOAD) > 0;\n}\n\nbool is_measurement_driver(shared_ptr<sigrok::Driver> sr_driver)\n{\n\tassert(sr_driver);\n\n\tconst auto keys = sr_driver->config_keys();\n\treturn keys.count(sigrok::ConfigKey::MULTIMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::SOUNDLEVELMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::THERMOMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::HYGROMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::ENERGYMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::LCRMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::SCALE) > 0\n\t\t|| keys.count(sigrok::ConfigKey::SIGNAL_GENERATOR) > 0\n\t\t|| keys.count(sigrok::ConfigKey::POWERMETER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::MULTIPLEXER) > 0\n\t\t|| keys.count(sigrok::ConfigKey::DEMO_DEV) > 0;\n}\n\nbool is_demo_driver(shared_ptr<sigrok::Driver> sr_driver)\n{\n\tassert(sr_driver);\n\n\tconst auto keys = sr_driver->config_keys();\n\treturn keys.count(sigrok::ConfigKey::DEMO_DEV) > 0;\n}\n\nbool is_oscilloscope_driver(shared_ptr<sigrok::Driver> sr_driver)\n{\n\tassert(sr_driver);\n\n\tconst auto keys = sr_driver->config_keys();\n\treturn keys.count(sigrok::ConfigKey::OSCILLOSCOPE) > 0;\n}\n\nDeviceType get_device_type(const sigrok::ConfigKey *sr_config_key)\n{\n\tif (sr_config_key_device_type_map.count(sr_config_key) > 0)\n\t\treturn sr_config_key_device_type_map[sr_config_key];\n\treturn DeviceType::Unknown;\n}\n\nDeviceType get_device_type(uint32_t sr_config_key)\n{\n\tconst sigrok::ConfigKey *sr_ck = sigrok::ConfigKey::get(\n\t\tstatic_cast<int>(sr_config_key));\n\treturn get_device_type(sr_ck);\n}\n\nconst sigrok::ConfigKey *get_sr_config_key(DeviceType device_type)\n{\n\treturn device_type_sr_config_key_map[device_type];\n}\n\nuint32_t get_sr_config_key_id(DeviceType device_type)\n{\n\tif (device_type_sr_config_key_map.count(device_type) > 0)\n\t\treturn device_type_sr_config_key_map[device_type]->id();\n\treturn 0;\n}\n\nbool is_valid_sr_config_key(DeviceType device_type)\n{\n\treturn device_type_sr_config_key_map.count(device_type) > 0;\n}\n\n\nConnectionKey get_connection_key(const sigrok::ConfigKey *sr_config_key)\n{\n\tif (sr_config_key_connection_key_map.count(sr_config_key) > 0)\n\t\treturn sr_config_key_connection_key_map[sr_config_key];\n\treturn ConnectionKey::Unknown;\n}\n\nConnectionKey get_connection_key(uint32_t sr_config_key)\n{\n\tconst sigrok::ConfigKey *sr_ck = sigrok::ConfigKey::get(\n\t\tstatic_cast<int>(sr_config_key));\n\treturn get_connection_key(sr_ck);\n}\n\nconst sigrok::ConfigKey *get_sr_config_key(ConnectionKey connection_key)\n{\n\treturn connection_key_sr_config_key_map[connection_key];\n}\n\nuint32_t get_sr_config_key_id(ConnectionKey connection_key)\n{\n\tif (connection_key_sr_config_key_map.count(connection_key) > 0)\n\t\treturn connection_key_sr_config_key_map[connection_key]->id();\n\treturn 0;\n}\n\nbool is_valid_sr_config_key(ConnectionKey connection_key)\n{\n\treturn connection_key_sr_config_key_map.count(connection_key) > 0;\n}\n\n\nConfigKey get_config_key(const sigrok::ConfigKey *sr_config_key)\n{\n\tif (sr_config_key_config_key_map.count(sr_config_key) > 0)\n\t\treturn sr_config_key_config_key_map[sr_config_key];\n\treturn ConfigKey::Unknown;\n}\n\nConfigKey get_config_key(uint32_t sr_config_key)\n{\n\tconst sigrok::ConfigKey *sr_ck = sigrok::ConfigKey::get(\n\t\tstatic_cast<int>(sr_config_key));\n\treturn get_config_key(sr_ck);\n}\n\nconst sigrok::ConfigKey *get_sr_config_key(ConfigKey config_key)\n{\n\treturn config_key_sr_config_key_map[config_key];\n}\n\nuint32_t get_sr_config_key_id(ConfigKey config_key)\n{\n\tif (config_key_sr_config_key_map.count(config_key) > 0)\n\t\treturn config_key_sr_config_key_map[config_key]->id();\n\treturn 0;\n}\n\nbool is_valid_sr_config_key(ConfigKey config_key)\n{\n\treturn config_key_sr_config_key_map.count(config_key) > 0;\n}\n\n\nQString format_device_type(DeviceType device_type)\n{\n\tif (device_type_name_map.count(device_type) > 0)\n\t\treturn device_type_name_map[device_type];\n\treturn device_type_name_map[DeviceType::Unknown];\n}\n\nQString format_connection_key(ConnectionKey connection_key)\n{\n\tif (connection_key_name_map.count(connection_key) > 0)\n\t\treturn connection_key_name_map[connection_key];\n\treturn connection_key_name_map[ConnectionKey::Unknown];\n}\n\nQString format_config_key(ConfigKey config_key)\n{\n\tif (config_key_name_map.count(config_key) > 0)\n\t\treturn config_key_name_map[config_key];\n\treturn config_key_name_map[ConfigKey::Unknown];\n}\n\n\ndata::DataType get_data_type_for_config_key(ConfigKey config_key)\n{\n\tconst sigrok::ConfigKey *sr_ck = get_sr_config_key(config_key);\n\tif (!sr_ck)\n\t\treturn data::DataType::Unknown;\n\n\treturn data::datautil::get_data_type(sr_ck->data_type());\n}\n\ndata::Unit get_unit_for_config_key(ConfigKey config_key)\n{\n\tif (config_key_unit_map.count(config_key) > 0)\n\t\treturn config_key_unit_map[config_key];\n\treturn data::Unit::Unknown;\n}\n\n} // namespace deviceutil\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/deviceutil.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_DEVICEUTIL_HPP\n#define DEVICES_DEVICEUTIL_HPP\n\n#include <map>\n#include <memory>\n#include <set>\n#include <vector>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QObject>\n#include <QString>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::map;\nusing std::set;\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sigrok {\nclass ConfigKey;\n}\n\nnamespace sv {\nnamespace devices {\n\nenum class DeviceType\n{\n\t/** The device can act as logic analyzer. */\n\tLogicAnalyzer,\n\t/** The device can act as an oscilloscope. */\n\tOscilloscope,\n\t/** The device can act as a multimeter. */\n\tMultimeter,\n\t/** The device is a demo device. */\n\tDemoDev,\n\t/** The device can act as a sound level meter. */\n\tSoundLevelMeter,\n\t/** The device can measure temperature. */\n\tThermometer,\n\t/** The device can measure humidity. */\n\tHygrometer,\n\t/** The device can measure energy consumption. */\n\tEnergymeter,\n\t/** The device can act as a signal demodulator. */\n\tDemodulator,\n\t/** The device can act as a programmable power supply. */\n\tPowerSupply,\n\t/** The device can act as an LCR meter. */\n\tLcrMeter,\n\t/** The device can act as an electronic load. */\n\tElectronicLoad,\n\t/** The device can act as a scale. */\n\tScale,\n\t/** The device can act as a function generator. */\n\tSignalGenerator,\n\t/** The device can measure power. */\n\tPowermeter,\n\t/** A Multiplexer / Relay Actuator device. */\n\tMultiplexer,\n\t/** User device */\n\tUserDevice,\n\t/** Unknown device. */\n\tUnknown,\n};\n\nenum class ConnectionKey\n{\n\t/** Specification on how to connect to a device. */\n\tConn,\n\t/** Serial communication specification, in the form: */\n\tSerialComm,\n\t/** Modbus slave address specification. */\n\tModbusAddr,\n\t/** The device supports setting a sample time limit (how long the sample acquisition should run, in ms). */\n\tLimitMsec,\n\t/** The device supports setting a sample number limit (how many samples should be acquired). */\n\tLimitSamples,\n\t/** The device supports setting a frame limit (how many frames should be acquired). */\n\tLimitFrames,\n\t/** The device supports continuous sampling. */\n\tContinuous,\n\t/** Unknown connection key. */\n\tUnknown,\n};\n\nenum class ConfigKey\n{\n\t/** The device supports setting its samplerate, in Hz. */\n\tSamplerate,\n\t/** The device supports setting a pre/post-trigger capture ratio. */\n\tCaptureRatio,\n\t/** The device supports setting a pattern (pattern generator mode). */\n\tPatternMode,\n\t/** The device supports run-length encoding (RLE). */\n\tRLE,\n\t/** The device supports setting trigger slope. */\n\tTriggerSlope,\n\t/** The device supports averaging. */\n\tAveraging,\n\t/** The device supports setting number of samples to be averaged over. */\n\tAvgSamples,\n\t/** Trigger source. */\n\tTriggerSource,\n\t/** Horizontal trigger position. */\n\tHorizTriggerPos,\n\t/** Buffer size. */\n\tBufferSize,\n\t/** Time base. */\n\tTimeBase,\n\t/** Filter. */\n\tFilter,\n\t/** Volts/div. */\n\tVDiv,\n\t/** Coupling. */\n\tCoupling,\n\t/** Trigger matches. */\n\tTriggerMatch,\n\t/** The device supports setting its sample interval, in ms. */\n\tSampleInterval,\n\t/** Number of horizontal divisions, as related to SR_CONF_TIMEBASE. */\n\tNumHDiv,\n\t/** Number of vertical divisions, as related to SR_CONF_VDIV. */\n\tNumVDiv,\n\t/** Sound pressure level frequency weighting. */\n\tSplWeightFreq,\n\t/** Sound pressure level time weighting. */\n\tSplWeightTime,\n\t/** Sound pressure level measurement range. */\n\tSplMeasurementRange,\n\t/** Max hold mode. */\n\tHoldMax,\n\t/** Min hold mode. */\n\tHoldMin,\n\t/** Logic low-high threshold range. */\n\tVoltageThreshold,\n\t/** The device supports using an external clock. */\n\tExternalClock,\n\t/** The device supports swapping channels. */\n\tSwap,\n\t/** Center frequency. */\n\tCenterFrequency,\n\t/** The device supports setting the number of logic channels. */\n\tNumLogicChannels,\n\t/** The device supports setting the number of analog channels. */\n\tNumAnalogChannels,\n\t/** Current voltage. */\n\tVoltage,\n\t/** Maximum target voltage. */\n\tVoltageTarget,\n\t/** Current current. */\n\tCurrent,\n\t/** Current limit. */\n\tCurrentLimit,\n\t/** Enabling/disabling channel. */\n\tEnabled,\n\t/** Channel configuration. */\n\tChannelConfig,\n\t/** Over-voltage protection (OVP) feature. */\n\tOverVoltageProtectionEnabled,\n\t/** Over-voltage protection (OVP) active. */\n\tOverVoltageProtectionActive,\n\t/** Over-voltage protection (OVP) threshold. */\n\tOverVoltageProtectionThreshold,\n\t/** Over-current protection (OCP) feature. */\n\tOverCurrentProtectionEnabled,\n\t/** Over-current protection (OCP) active. */\n\tOverCurrentProtectionActive,\n\t/** Over-current protection (OCP) threshold. */\n\tOverCurrentProtectionThreshold,\n\t/** Over-temperature protection (OTP) */\n\tOverTemperatureProtectionEnabled,\n\t/** Over-temperature protection (OTP) active. */\n\tOverTemperatureProtectionActive,\n\t/** Under-voltage condition. */\n\tUnderVoltageConditionEnabled,\n\t/** Under-voltage condition active. */\n\tUnderVoltageConditionActive,\n\t/** Under-voltage condition threshold. */\n\tUnderVoltageConditionThreshold,\n\t/** Choice of clock edge for external clock (\"r\" or \"f\"). */\n\tClockEdge,\n\t/** Amplitude of a source without strictly-defined MQ. */\n\tAmplitude,\n\t/** Channel regulation get: \"CV\", \"CC\" or \"UR\", denoting constant voltage, constant current or unregulated. */\n\tRegulation,\n\t/** Output frequency in Hz. */\n\tOutputFrequency,\n\t/** Output frequency target in Hz. */\n\tOutputFrequencyTarget,\n\t/** Measured quantity. */\n\tMeasuredQuantity,\n\t/** Equivalent circuit model. */\n\tEquivCircuitModel,\n\t/** Trigger level. */\n\tTriggerLevel,\n\t/** Which external clock source to use if the device supports multiple external clock channels. */\n\tExternalClockSource,\n\t/** Offset of a source without strictly-defined MQ. */\n\tOffset,\n\t/** The device supports setting a pattern for the logic trigger. */\n\tTriggerPattern,\n\t/** High resolution mode. */\n\tHighResolution,\n\t/** Peak detection. */\n\tPeakDetection,\n\t/** Logic threshold: predefined levels (TTL, ECL, CMOS, etc). */\n\tLogicThreshold,\n\t/** Logic threshold: custom numerical value. */\n\tLogicThresholdCustom,\n\t/** The measurement range of a DMM or the output range of a power supply. */\n\tRange,\n\t/** The number of digits (e.g. for a DMM). */\n\tDigits,\n\n\t/** Session filename. */\n\tSessionFile,\n\t/** The device supports specifying a capturefile to inject. */\n\tCaptureFile,\n\t/** The device supports specifying the capturefile unit size. */\n\tCaptureUnitSize,\n\t/** Power off the device. */\n\tPowerOff,\n\t/** Data source for acquisition. */\n\tDataSource,\n\t/** The device supports setting a probe factor. */\n\tProbeFactor,\n\t/** Number of powerline cycles for ADC integration time. */\n\tADCPowerlineCycles,\n\t/** The device has internal storage, into which data is logged. */\n\tDataLog,\n\t/** Device mode for multi-function devices. */\n\tDeviceMode,\n\t/** Self test mode. */\n\tTestMode,\n\t/** Unknown config key. */\n\tUnknown,\n};\n\nnamespace deviceutil {\n\ntypedef map<DeviceType, QString> device_type_name_map_t;\ntypedef map<ConnectionKey, QString> connection_key_name_map_t;\ntypedef map<ConfigKey, QString> config_key_name_map_t;\n\nnamespace {\n\n// TODO: Use tr(), QCoreApplication::translate(), QT_TR_NOOP() or\n//       QT_TRANSLATE_NOOP() for translation.\n//       See: http://doc.qt.io/qt-5/i18n-source-translation.html\ndevice_type_name_map_t device_type_name_map = {\n\t{ DeviceType::LogicAnalyzer, QString(\"Logic Analyzer\") },\n\t{ DeviceType::Oscilloscope, QString(\"Oscilloscope\") },\n\t{ DeviceType::Multimeter, QString(\"Multimeter\") },\n\t{ DeviceType::DemoDev, QString(\"Demo Device\") },\n\t{ DeviceType::SoundLevelMeter, QString(\"Soundlevelmeter\") },\n\t{ DeviceType::Thermometer, QString(\"Thermometer\") },\n\t{ DeviceType::Hygrometer, QString(\"Hygrometer\") },\n\t{ DeviceType::Energymeter, QString(\"Energymeter\") },\n\t{ DeviceType::Demodulator, QString(\"Demodulator\") },\n\t{ DeviceType::PowerSupply, QString(\"Power Supply\") },\n\t{ DeviceType::LcrMeter, QString(\"LCR Meter\") },\n\t{ DeviceType::ElectronicLoad, QString(\"Electronic Load\") },\n\t{ DeviceType::Scale, QString(\"Scale\") },\n\t{ DeviceType::SignalGenerator, QString(\"Signal Generator\") },\n\t{ DeviceType::Powermeter, QString(\"Power Meter\") },\n\t{ DeviceType::Multiplexer, QString(\"Multiplexer\") },\n\t{ DeviceType::UserDevice, QString(\"Virtual User Device\") },\n\t{ DeviceType::Unknown, QString(\"Unknown\") },\n};\n\nconnection_key_name_map_t connection_key_name_map = {\n\t{ ConnectionKey::Conn, QString(\"Connection String\") },\n\t{ ConnectionKey::SerialComm, QString(\"Serial Command\") },\n\t{ ConnectionKey::ModbusAddr, QString(\"ModBus Address\") },\n\t{ ConnectionKey::LimitMsec, QString(\"Limit Milliseconds\") },\n\t{ ConnectionKey::LimitSamples, QString(\"Limit Samples\") },\n\t{ ConnectionKey::LimitFrames, QString(\"Limit Frames\") },\n\t{ ConnectionKey::Continuous, QString(\"Continuous\") },\n\t{ ConnectionKey::Unknown, QString(\"Unknown\") },\n};\n\nconfig_key_name_map_t config_key_name_map = {\n\t{ ConfigKey::Samplerate, QString(\"Samplerate\") },\n\t{ ConfigKey::CaptureRatio, QString(\"Capture Ratio\") },\n\t{ ConfigKey::PatternMode, QString(\"Pattern Mode\") },\n\t{ ConfigKey::RLE, QString(\"Run-Length Encoding\") },\n\t{ ConfigKey::TriggerSlope, QString(\"Trigger Slope\") },\n\t{ ConfigKey::Averaging, QString(\"Averaging\") },\n\t{ ConfigKey::AvgSamples, QString(\"Averaging Samples\") },\n\t{ ConfigKey::TriggerSource, QString(\"Trigger Source\") },\n\t{ ConfigKey::HorizTriggerPos, QString(\"Horizonal Trigger Position\") },\n\t{ ConfigKey::BufferSize, QString(\"Buffer Size\") },\n\t{ ConfigKey::TimeBase, QString(\"Time Base\") },\n\t{ ConfigKey::Filter, QString(\"Filter\") },\n\t{ ConfigKey::VDiv, QString(\"Vertical Division\") },\n\t{ ConfigKey::Coupling, QString(\"Coupling\") },\n\t{ ConfigKey::TriggerMatch, QString(\"Trigger Match\") },\n\t{ ConfigKey::SampleInterval, QString(\"Sample Interval\") },\n\t{ ConfigKey::NumHDiv, QString(\"Number Horizontal Divisions\") },\n\t{ ConfigKey::NumVDiv, QString(\"Number Vertical Divisions\") },\n\t{ ConfigKey::SplWeightFreq, QString(\"SPL-Weight Frequency\") },\n\t{ ConfigKey::SplWeightTime, QString(\"SPL-Weight Time\") },\n\t{ ConfigKey::SplMeasurementRange, QString(\"SPL Measurement Range\") },\n\t{ ConfigKey::HoldMax, QString(\"Hold Max\") },\n\t{ ConfigKey::HoldMin, QString(\"Hold Min\") },\n\t{ ConfigKey::VoltageThreshold, QString(\"Voltage Threshold\") },\n\t{ ConfigKey::ExternalClock, QString(\"External Clock\") },\n\t{ ConfigKey::Swap, QString(\"Swap\") },\n\t{ ConfigKey::CenterFrequency, QString(\"Center Frequency\") },\n\t{ ConfigKey::NumLogicChannels, QString(\"Number of Logic Channels\") },\n\t{ ConfigKey::NumAnalogChannels, QString(\"Number of Analog Channels\") },\n\t{ ConfigKey::Voltage, QString(\"Voltage\") },\n\t{ ConfigKey::VoltageTarget, QString(\"Voltage Target\") },\n\t{ ConfigKey::Current, QString(\"Current\") },\n\t{ ConfigKey::CurrentLimit, QString(\"Current Limit\") },\n\t{ ConfigKey::Enabled, QString(\"Enabled\") },\n\t{ ConfigKey::ChannelConfig, QString(\"ChannelConfig\") },\n\t{ ConfigKey::OverVoltageProtectionEnabled, QString(\"Over Voltage Protection Enabled\") },\n\t{ ConfigKey::OverVoltageProtectionActive, QString(\"Over Voltage Protection Active\") },\n\t{ ConfigKey::OverVoltageProtectionThreshold, QString(\"Over Voltage Protection Threshold\") },\n\t{ ConfigKey::OverCurrentProtectionEnabled, QString(\"Over Current Protection Enabled\") },\n\t{ ConfigKey::OverCurrentProtectionActive, QString(\"Over Current Protection Active\") },\n\t{ ConfigKey::OverCurrentProtectionThreshold, QString(\"Over Current Protection Threshold\") },\n\t{ ConfigKey::OverTemperatureProtectionEnabled, QString(\"Over Temperature Protection Enabled\") },\n\t{ ConfigKey::OverTemperatureProtectionActive, QString(\"Over Temperature Protection Active\") },\n\t{ ConfigKey::UnderVoltageConditionEnabled, QString(\"Under Voltage Condition Enabled\") },\n\t{ ConfigKey::UnderVoltageConditionActive, QString(\"Under Voltage Condition Active\") },\n\t{ ConfigKey::UnderVoltageConditionThreshold, QString(\"Under Voltage Condition Threshold\") },\n\t{ ConfigKey::ClockEdge, QString(\"Clock Edge\") },\n\t{ ConfigKey::Amplitude, QString(\"Amplitude\") },\n\t{ ConfigKey::Regulation, QString(\"Regulation\") },\n\t{ ConfigKey::OutputFrequency, QString(\"Output Frequency\") },\n\t{ ConfigKey::OutputFrequencyTarget, QString(\"Output Frequency Target\") },\n\t{ ConfigKey::MeasuredQuantity, QString(\"Measured Quantity\") },\n\t{ ConfigKey::EquivCircuitModel, QString(\"Equivalent Circuit Model\") },\n\t{ ConfigKey::TriggerLevel, QString(\"Trigger Level\") },\n\t{ ConfigKey::ExternalClockSource, QString(\"External Clock Source\") },\n\t{ ConfigKey::Offset, QString(\"Offset\") },\n\t{ ConfigKey::TriggerPattern, QString(\"Trigger Pattern\") },\n\t{ ConfigKey::HighResolution, QString(\"High Resolution\") },\n\t{ ConfigKey::PeakDetection, QString(\"Peak Detection\") },\n\t{ ConfigKey::LogicThreshold, QString(\"Logic Threshold\") },\n\t{ ConfigKey::LogicThresholdCustom, QString(\"Logic Threshold Custom\") },\n\t{ ConfigKey::Range, QString(\"Range\") },\n\t{ ConfigKey::Digits, QString(\"Digits\") },\n\t{ ConfigKey::SessionFile, QString(\"Session File\") },\n\t{ ConfigKey::CaptureFile, QString(\"Capture File\") },\n\t{ ConfigKey::CaptureUnitSize, QString(\"Capture Unit Size\") },\n\t{ ConfigKey::PowerOff, QString(\"Power Off\") },\n\t{ ConfigKey::DataSource, QString(\"Data Source\") },\n\t{ ConfigKey::ProbeFactor, QString(\"Probe Factor\") },\n\t{ ConfigKey::ADCPowerlineCycles, QString(\"ADC Powerline Cycles\") },\n\t{ ConfigKey::DataLog, QString(\"Data Log\") },\n\t{ ConfigKey::DeviceMode, QString(\"Device Mode\") },\n\t{ ConfigKey::TestMode, QString(\"Test Mode\") },\n\t{ ConfigKey::Unknown, QString(\"Unknown\") },\n};\n\nmap<const sigrok::ConfigKey *, DeviceType> sr_config_key_device_type_map = {\n\t{ sigrok::ConfigKey::LOGIC_ANALYZER, DeviceType::LogicAnalyzer },\n\t{ sigrok::ConfigKey::OSCILLOSCOPE, DeviceType::Oscilloscope },\n\t{ sigrok::ConfigKey::MULTIMETER, DeviceType::Multimeter },\n\t{ sigrok::ConfigKey::DEMO_DEV, DeviceType::DemoDev },\n\t{ sigrok::ConfigKey::SOUNDLEVELMETER, DeviceType::SoundLevelMeter },\n\t{ sigrok::ConfigKey::THERMOMETER, DeviceType::Thermometer },\n\t{ sigrok::ConfigKey::HYGROMETER, DeviceType::Hygrometer },\n\t{ sigrok::ConfigKey::ENERGYMETER, DeviceType::Energymeter },\n\t{ sigrok::ConfigKey::DEMODULATOR, DeviceType::Demodulator },\n\t{ sigrok::ConfigKey::POWER_SUPPLY, DeviceType::PowerSupply },\n\t{ sigrok::ConfigKey::LCRMETER, DeviceType::LcrMeter },\n\t{ sigrok::ConfigKey::ELECTRONIC_LOAD, DeviceType::ElectronicLoad },\n\t{ sigrok::ConfigKey::SCALE, DeviceType::Scale },\n\t{ sigrok::ConfigKey::SIGNAL_GENERATOR, DeviceType::SignalGenerator },\n\t{ sigrok::ConfigKey::POWERMETER, DeviceType::Powermeter },\n\t{ sigrok::ConfigKey::MULTIPLEXER, DeviceType::Multiplexer },\n};\n\nmap<DeviceType, const sigrok::ConfigKey *> device_type_sr_config_key_map = {\n\t{ DeviceType::LogicAnalyzer, sigrok::ConfigKey::LOGIC_ANALYZER },\n\t{ DeviceType::Oscilloscope, sigrok::ConfigKey::OSCILLOSCOPE },\n\t{ DeviceType::Multimeter, sigrok::ConfigKey::MULTIMETER },\n\t{ DeviceType::DemoDev, sigrok::ConfigKey::DEMO_DEV },\n\t{ DeviceType::SoundLevelMeter, sigrok::ConfigKey::SOUNDLEVELMETER },\n\t{ DeviceType::Thermometer, sigrok::ConfigKey::THERMOMETER },\n\t{ DeviceType::Hygrometer, sigrok::ConfigKey::HYGROMETER },\n\t{ DeviceType::Energymeter, sigrok::ConfigKey::ENERGYMETER },\n\t{ DeviceType::Demodulator, sigrok::ConfigKey::DEMODULATOR },\n\t{ DeviceType::PowerSupply, sigrok::ConfigKey::POWER_SUPPLY },\n\t{ DeviceType::LcrMeter, sigrok::ConfigKey::LCRMETER },\n\t{ DeviceType::ElectronicLoad, sigrok::ConfigKey::ELECTRONIC_LOAD },\n\t{ DeviceType::Scale, sigrok::ConfigKey::SCALE },\n\t{ DeviceType::SignalGenerator, sigrok::ConfigKey::SIGNAL_GENERATOR },\n\t{ DeviceType::Powermeter, sigrok::ConfigKey::POWERMETER },\n\t{ DeviceType::Multiplexer, sigrok::ConfigKey::MULTIPLEXER },\n};\n\nmap<const sigrok::ConfigKey *, ConnectionKey> sr_config_key_connection_key_map = {\n\t{ sigrok::ConfigKey::CONN, ConnectionKey::Conn },\n\t{ sigrok::ConfigKey::SERIALCOMM, ConnectionKey::SerialComm },\n\t{ sigrok::ConfigKey::MODBUSADDR, ConnectionKey::ModbusAddr },\n\t{ sigrok::ConfigKey::LIMIT_MSEC, ConnectionKey::LimitMsec },\n\t{ sigrok::ConfigKey::LIMIT_SAMPLES, ConnectionKey::LimitSamples },\n\t{ sigrok::ConfigKey::LIMIT_FRAMES, ConnectionKey::LimitFrames },\n\t{ sigrok::ConfigKey::CONTINUOUS, ConnectionKey::Continuous },\n};\n\nmap<ConnectionKey, const sigrok::ConfigKey *> connection_key_sr_config_key_map = {\n\t{ ConnectionKey::Conn, sigrok::ConfigKey::CONN },\n\t{ ConnectionKey::SerialComm, sigrok::ConfigKey::SERIALCOMM },\n\t{ ConnectionKey::ModbusAddr, sigrok::ConfigKey::MODBUSADDR },\n\t{ ConnectionKey::LimitMsec, sigrok::ConfigKey::LIMIT_MSEC },\n\t{ ConnectionKey::LimitSamples, sigrok::ConfigKey::LIMIT_SAMPLES },\n\t{ ConnectionKey::LimitFrames, sigrok::ConfigKey::LIMIT_FRAMES },\n\t{ ConnectionKey::Continuous, sigrok::ConfigKey::CONTINUOUS },\n};\n\nmap<const sigrok::ConfigKey *, ConfigKey> sr_config_key_config_key_map = {\n\t{ sigrok::ConfigKey::SAMPLERATE, ConfigKey::Samplerate },\n\t{ sigrok::ConfigKey::CAPTURE_RATIO, ConfigKey::CaptureRatio },\n\t{ sigrok::ConfigKey::PATTERN_MODE, ConfigKey::PatternMode },\n\t{ sigrok::ConfigKey::RLE, ConfigKey::RLE },\n\t{ sigrok::ConfigKey::TRIGGER_SLOPE, ConfigKey::TriggerSlope },\n\t{ sigrok::ConfigKey::AVERAGING, ConfigKey::Averaging },\n\t{ sigrok::ConfigKey::AVG_SAMPLES, ConfigKey::AvgSamples },\n\t{ sigrok::ConfigKey::TRIGGER_SOURCE, ConfigKey::TriggerSource },\n\t{ sigrok::ConfigKey::HORIZ_TRIGGERPOS, ConfigKey::HorizTriggerPos },\n\t{ sigrok::ConfigKey::BUFFERSIZE, ConfigKey::BufferSize },\n\t{ sigrok::ConfigKey::TIMEBASE, ConfigKey::TimeBase },\n\t{ sigrok::ConfigKey::FILTER, ConfigKey::Filter },\n\t{ sigrok::ConfigKey::VDIV, ConfigKey::VDiv },\n\t{ sigrok::ConfigKey::COUPLING, ConfigKey::Coupling },\n\t{ sigrok::ConfigKey::TRIGGER_MATCH, ConfigKey::TriggerMatch },\n\t{ sigrok::ConfigKey::SAMPLE_INTERVAL, ConfigKey::SampleInterval },\n\t{ sigrok::ConfigKey::NUM_HDIV, ConfigKey::NumHDiv },\n\t{ sigrok::ConfigKey::NUM_VDIV, ConfigKey::NumVDiv },\n\t{ sigrok::ConfigKey::SPL_WEIGHT_FREQ, ConfigKey::SplWeightFreq },\n\t{ sigrok::ConfigKey::SPL_WEIGHT_TIME, ConfigKey::SplWeightTime },\n\t{ sigrok::ConfigKey::SPL_MEASUREMENT_RANGE, ConfigKey::SplMeasurementRange },\n\t{ sigrok::ConfigKey::HOLD_MAX, ConfigKey::HoldMax },\n\t{ sigrok::ConfigKey::HOLD_MIN, ConfigKey::HoldMin },\n\t{ sigrok::ConfigKey::VOLTAGE_THRESHOLD, ConfigKey::VoltageThreshold },\n\t{ sigrok::ConfigKey::EXTERNAL_CLOCK, ConfigKey::ExternalClock },\n\t{ sigrok::ConfigKey::SWAP, ConfigKey::Swap },\n\t{ sigrok::ConfigKey::CENTER_FREQUENCY, ConfigKey::CenterFrequency },\n\t{ sigrok::ConfigKey::NUM_LOGIC_CHANNELS, ConfigKey::NumLogicChannels },\n\t{ sigrok::ConfigKey::NUM_ANALOG_CHANNELS, ConfigKey::NumAnalogChannels },\n\t{ sigrok::ConfigKey::VOLTAGE, ConfigKey::Voltage },\n\t{ sigrok::ConfigKey::VOLTAGE_TARGET, ConfigKey::VoltageTarget },\n\t{ sigrok::ConfigKey::CURRENT, ConfigKey::Current },\n\t{ sigrok::ConfigKey::CURRENT_LIMIT, ConfigKey::CurrentLimit },\n\t{ sigrok::ConfigKey::ENABLED, ConfigKey::Enabled },\n\t{ sigrok::ConfigKey::CHANNEL_CONFIG, ConfigKey::ChannelConfig },\n\t{ sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_ENABLED, ConfigKey::OverVoltageProtectionEnabled },\n\t{ sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_ACTIVE, ConfigKey::OverVoltageProtectionActive },\n\t{ sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_THRESHOLD, ConfigKey::OverVoltageProtectionThreshold },\n\t{ sigrok::ConfigKey::OVER_CURRENT_PROTECTION_ENABLED, ConfigKey::OverCurrentProtectionEnabled },\n\t{ sigrok::ConfigKey::OVER_CURRENT_PROTECTION_ACTIVE, ConfigKey::OverCurrentProtectionActive },\n\t{ sigrok::ConfigKey::OVER_CURRENT_PROTECTION_THRESHOLD, ConfigKey::OverCurrentProtectionThreshold },\n\t{ sigrok::ConfigKey::OVER_TEMPERATURE_PROTECTION, ConfigKey::OverTemperatureProtectionEnabled },\n\t{ sigrok::ConfigKey::OVER_TEMPERATURE_PROTECTION_ACTIVE, ConfigKey::OverTemperatureProtectionActive },\n\t{ sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION, ConfigKey::UnderVoltageConditionEnabled },\n\t{ sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION_ACTIVE, ConfigKey::UnderVoltageConditionActive },\n\t{ sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION_THRESHOLD, ConfigKey::UnderVoltageConditionThreshold },\n\t{ sigrok::ConfigKey::CLOCK_EDGE, ConfigKey::ClockEdge },\n\t{ sigrok::ConfigKey::AMPLITUDE, ConfigKey::Amplitude },\n\t{ sigrok::ConfigKey::REGULATION, ConfigKey::Regulation },\n\t{ sigrok::ConfigKey::OUTPUT_FREQUENCY, ConfigKey::OutputFrequency },\n\t{ sigrok::ConfigKey::OUTPUT_FREQUENCY_TARGET, ConfigKey::OutputFrequencyTarget },\n\t{ sigrok::ConfigKey::MEASURED_QUANTITY, ConfigKey::MeasuredQuantity },\n\t{ sigrok::ConfigKey::EQUIV_CIRCUIT_MODEL, ConfigKey::EquivCircuitModel },\n\t{ sigrok::ConfigKey::TRIGGER_LEVEL, ConfigKey::TriggerLevel },\n\t{ sigrok::ConfigKey::EXTERNAL_CLOCK_SOURCE, ConfigKey::ExternalClockSource },\n\t{ sigrok::ConfigKey::OFFSET, ConfigKey::Offset },\n\t{ sigrok::ConfigKey::TRIGGER_PATTERN, ConfigKey::TriggerPattern },\n\t{ sigrok::ConfigKey::HIGH_RESOLUTION, ConfigKey::HighResolution },\n\t{ sigrok::ConfigKey::PEAK_DETECTION, ConfigKey::PeakDetection },\n\t{ sigrok::ConfigKey::LOGIC_THRESHOLD, ConfigKey::LogicThreshold },\n\t{ sigrok::ConfigKey::LOGIC_THRESHOLD_CUSTOM, ConfigKey::LogicThresholdCustom },\n\t{ sigrok::ConfigKey::RANGE, ConfigKey::Range },\n\t{ sigrok::ConfigKey::DIGITS, ConfigKey::Digits },\n\t{ sigrok::ConfigKey::SESSIONFILE, ConfigKey::SessionFile },\n\t{ sigrok::ConfigKey::CAPTUREFILE, ConfigKey::CaptureFile },\n\t{ sigrok::ConfigKey::CAPTURE_UNITSIZE, ConfigKey::CaptureUnitSize },\n\t{ sigrok::ConfigKey::POWER_OFF, ConfigKey::PowerOff },\n\t{ sigrok::ConfigKey::DATA_SOURCE, ConfigKey::DataSource },\n\t{ sigrok::ConfigKey::PROBE_FACTOR, ConfigKey::ProbeFactor },\n\t{ sigrok::ConfigKey::ADC_POWERLINE_CYCLES, ConfigKey::ADCPowerlineCycles },\n\t{ sigrok::ConfigKey::DATALOG, ConfigKey::DataLog },\n\t{ sigrok::ConfigKey::DEVICE_MODE, ConfigKey::DeviceMode },\n\t{ sigrok::ConfigKey::TEST_MODE, ConfigKey::TestMode },\n};\n\nmap<ConfigKey, const sigrok::ConfigKey *> config_key_sr_config_key_map = {\n\t{ ConfigKey::Samplerate, sigrok::ConfigKey::SAMPLERATE },\n\t{ ConfigKey::CaptureRatio, sigrok::ConfigKey::CAPTURE_RATIO },\n\t{ ConfigKey::PatternMode, sigrok::ConfigKey::PATTERN_MODE },\n\t{ ConfigKey::RLE, sigrok::ConfigKey::RLE },\n\t{ ConfigKey::TriggerSlope, sigrok::ConfigKey::TRIGGER_SLOPE },\n\t{ ConfigKey::Averaging, sigrok::ConfigKey::AVERAGING },\n\t{ ConfigKey::AvgSamples, sigrok::ConfigKey::AVG_SAMPLES },\n\t{ ConfigKey::TriggerSource, sigrok::ConfigKey::TRIGGER_SOURCE },\n\t{ ConfigKey::HorizTriggerPos, sigrok::ConfigKey::HORIZ_TRIGGERPOS },\n\t{ ConfigKey::BufferSize, sigrok::ConfigKey::BUFFERSIZE },\n\t{ ConfigKey::TimeBase, sigrok::ConfigKey::TIMEBASE },\n\t{ ConfigKey::Filter, sigrok::ConfigKey::FILTER },\n\t{ ConfigKey::VDiv, sigrok::ConfigKey::VDIV },\n\t{ ConfigKey::Coupling, sigrok::ConfigKey::COUPLING },\n\t{ ConfigKey::TriggerMatch, sigrok::ConfigKey::TRIGGER_MATCH },\n\t{ ConfigKey::SampleInterval, sigrok::ConfigKey::SAMPLE_INTERVAL },\n\t{ ConfigKey::NumHDiv, sigrok::ConfigKey::NUM_HDIV },\n\t{ ConfigKey::NumVDiv, sigrok::ConfigKey::NUM_VDIV },\n\t{ ConfigKey::SplWeightFreq, sigrok::ConfigKey::SPL_WEIGHT_FREQ },\n\t{ ConfigKey::SplWeightTime, sigrok::ConfigKey::SPL_WEIGHT_TIME },\n\t{ ConfigKey::SplMeasurementRange, sigrok::ConfigKey::SPL_MEASUREMENT_RANGE },\n\t{ ConfigKey::HoldMax, sigrok::ConfigKey::HOLD_MAX },\n\t{ ConfigKey::HoldMin, sigrok::ConfigKey::HOLD_MIN },\n\t{ ConfigKey::VoltageThreshold, sigrok::ConfigKey::VOLTAGE_THRESHOLD },\n\t{ ConfigKey::ExternalClock, sigrok::ConfigKey::EXTERNAL_CLOCK },\n\t{ ConfigKey::Swap, sigrok::ConfigKey::SWAP },\n\t{ ConfigKey::CenterFrequency, sigrok::ConfigKey::CENTER_FREQUENCY },\n\t{ ConfigKey::NumLogicChannels, sigrok::ConfigKey::NUM_LOGIC_CHANNELS },\n\t{ ConfigKey::NumAnalogChannels, sigrok::ConfigKey::NUM_ANALOG_CHANNELS },\n\t{ ConfigKey::Voltage, sigrok::ConfigKey::VOLTAGE },\n\t{ ConfigKey::VoltageTarget, sigrok::ConfigKey::VOLTAGE_TARGET },\n\t{ ConfigKey::Current, sigrok::ConfigKey::CURRENT },\n\t{ ConfigKey::CurrentLimit, sigrok::ConfigKey::CURRENT_LIMIT },\n\t{ ConfigKey::Enabled, sigrok::ConfigKey::ENABLED },\n\t{ ConfigKey::ChannelConfig, sigrok::ConfigKey::CHANNEL_CONFIG },\n\t{ ConfigKey::OverVoltageProtectionEnabled, sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_ENABLED },\n\t{ ConfigKey::OverVoltageProtectionActive, sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_ACTIVE },\n\t{ ConfigKey::OverVoltageProtectionThreshold, sigrok::ConfigKey::OVER_VOLTAGE_PROTECTION_THRESHOLD },\n\t{ ConfigKey::OverCurrentProtectionEnabled, sigrok::ConfigKey::OVER_CURRENT_PROTECTION_ENABLED },\n\t{ ConfigKey::OverCurrentProtectionActive, sigrok::ConfigKey::OVER_CURRENT_PROTECTION_ACTIVE },\n\t{ ConfigKey::OverCurrentProtectionThreshold, sigrok::ConfigKey::OVER_CURRENT_PROTECTION_THRESHOLD },\n\t{ ConfigKey::OverTemperatureProtectionEnabled, sigrok::ConfigKey::OVER_TEMPERATURE_PROTECTION },\n\t{ ConfigKey::OverTemperatureProtectionActive, sigrok::ConfigKey::OVER_TEMPERATURE_PROTECTION_ACTIVE },\n\t{ ConfigKey::UnderVoltageConditionEnabled, sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION },\n\t{ ConfigKey::UnderVoltageConditionActive, sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION_ACTIVE },\n\t{ ConfigKey::UnderVoltageConditionThreshold, sigrok::ConfigKey::UNDER_VOLTAGE_CONDITION_THRESHOLD },\n\t{ ConfigKey::ClockEdge, sigrok::ConfigKey::CLOCK_EDGE },\n\t{ ConfigKey::Amplitude, sigrok::ConfigKey::AMPLITUDE },\n\t{ ConfigKey::Regulation, sigrok::ConfigKey::REGULATION },\n\t{ ConfigKey::OutputFrequency, sigrok::ConfigKey::OUTPUT_FREQUENCY },\n\t{ ConfigKey::OutputFrequencyTarget, sigrok::ConfigKey::OUTPUT_FREQUENCY_TARGET },\n\t{ ConfigKey::MeasuredQuantity, sigrok::ConfigKey::MEASURED_QUANTITY },\n\t{ ConfigKey::EquivCircuitModel, sigrok::ConfigKey::EQUIV_CIRCUIT_MODEL },\n\t{ ConfigKey::TriggerLevel, sigrok::ConfigKey::TRIGGER_LEVEL },\n\t{ ConfigKey::ExternalClockSource, sigrok::ConfigKey::EXTERNAL_CLOCK_SOURCE },\n\t{ ConfigKey::Offset, sigrok::ConfigKey::OFFSET },\n\t{ ConfigKey::TriggerPattern, sigrok::ConfigKey::TRIGGER_PATTERN },\n\t{ ConfigKey::HighResolution, sigrok::ConfigKey::HIGH_RESOLUTION },\n\t{ ConfigKey::PeakDetection, sigrok::ConfigKey::PEAK_DETECTION },\n\t{ ConfigKey::LogicThreshold, sigrok::ConfigKey::LOGIC_THRESHOLD },\n\t{ ConfigKey::LogicThresholdCustom, sigrok::ConfigKey::LOGIC_THRESHOLD_CUSTOM },\n\t{ ConfigKey::Range, sigrok::ConfigKey::RANGE },\n\t{ ConfigKey::Digits, sigrok::ConfigKey::DIGITS },\n\t{ ConfigKey::SessionFile, sigrok::ConfigKey::SESSIONFILE },\n\t{ ConfigKey::CaptureFile, sigrok::ConfigKey::CAPTUREFILE },\n\t{ ConfigKey::CaptureUnitSize, sigrok::ConfigKey::CAPTURE_UNITSIZE },\n\t{ ConfigKey::PowerOff, sigrok::ConfigKey::POWER_OFF },\n\t{ ConfigKey::DataSource, sigrok::ConfigKey::DATA_SOURCE },\n\t{ ConfigKey::ProbeFactor, sigrok::ConfigKey::PROBE_FACTOR },\n\t{ ConfigKey::ADCPowerlineCycles, sigrok::ConfigKey::ADC_POWERLINE_CYCLES },\n\t{ ConfigKey::DataLog, sigrok::ConfigKey::DATALOG },\n\t{ ConfigKey::DeviceMode, sigrok::ConfigKey::DEVICE_MODE },\n\t{ ConfigKey::TestMode, sigrok::ConfigKey::TEST_MODE },\n};\n\n/**\n * TODO: Find a better way get the Unit/Q/QF from the ConfigKey.\n * Implement in libsr: Add analog.meaning, etc. to the config_key structure.\n */\nmap<ConfigKey, data::Unit> config_key_unit_map = {\n\t{ ConfigKey::Samplerate, data::Unit::Hertz },\n\t{ ConfigKey::CaptureRatio, data::Unit::Unitless },\n\t{ ConfigKey::PatternMode, data::Unit::Unitless },\n\t{ ConfigKey::RLE, data::Unit::Boolean },\n\t{ ConfigKey::TriggerSlope, data::Unit::Unitless },\n\t{ ConfigKey::Averaging, data::Unit::Boolean },\n\t{ ConfigKey::AvgSamples, data::Unit::Unitless },\n\t{ ConfigKey::TriggerSource, data::Unit::Unitless },\n\t{ ConfigKey::HorizTriggerPos, data::Unit::Second },\n\t{ ConfigKey::BufferSize, data::Unit::Unitless }, // TODO Byte, Samples or Points!\n\t{ ConfigKey::TimeBase, data::Unit::Second },\n\t{ ConfigKey::Filter, data::Unit::Boolean },\n\t{ ConfigKey::VDiv, data::Unit::Volt },\n\t{ ConfigKey::Coupling, data::Unit::Unitless },\n\t{ ConfigKey::TriggerMatch, data::Unit::Unknown },\n\t{ ConfigKey::SampleInterval, data::Unit::Second },\n\t{ ConfigKey::NumHDiv, data::Unit::Unitless },\n\t{ ConfigKey::NumVDiv, data::Unit::Unitless },\n\t{ ConfigKey::SplWeightFreq, data::Unit::Unitless },\n\t{ ConfigKey::SplWeightTime, data::Unit::Unitless },\n\t{ ConfigKey::SplMeasurementRange, data::Unit::Unknown },\n\t{ ConfigKey::HoldMax, data::Unit::Boolean },\n\t{ ConfigKey::HoldMin, data::Unit::Boolean },\n\t{ ConfigKey::VoltageThreshold, data::Unit::Volt },\n\t{ ConfigKey::ExternalClock, data::Unit::Boolean },\n\t{ ConfigKey::Swap, data::Unit::Boolean },\n\t{ ConfigKey::CenterFrequency, data::Unit::Hertz },\n\t{ ConfigKey::NumLogicChannels, data::Unit::Unitless },\n\t{ ConfigKey::NumAnalogChannels, data::Unit::Unitless },\n\t{ ConfigKey::Voltage, data::Unit::Volt },\n\t{ ConfigKey::VoltageTarget, data::Unit::Volt },\n\t{ ConfigKey::Current, data::Unit::Ampere },\n\t{ ConfigKey::CurrentLimit, data::Unit::Ampere },\n\t{ ConfigKey::Enabled, data::Unit::Boolean },\n\t{ ConfigKey::ChannelConfig, data::Unit::Unitless },\n\t{ ConfigKey::OverVoltageProtectionEnabled, data::Unit::Boolean },\n\t{ ConfigKey::OverVoltageProtectionActive, data::Unit::Boolean },\n\t{ ConfigKey::OverVoltageProtectionThreshold, data::Unit::Volt },\n\t{ ConfigKey::OverCurrentProtectionEnabled, data::Unit::Boolean },\n\t{ ConfigKey::OverCurrentProtectionActive, data::Unit::Boolean },\n\t{ ConfigKey::OverCurrentProtectionThreshold, data::Unit::Ampere },\n\t{ ConfigKey::OverTemperatureProtectionEnabled, data::Unit::Boolean },\n\t{ ConfigKey::OverTemperatureProtectionActive, data::Unit::Boolean },\n\t{ ConfigKey::UnderVoltageConditionEnabled, data::Unit::Boolean },\n\t{ ConfigKey::UnderVoltageConditionActive, data::Unit::Boolean },\n\t{ ConfigKey::UnderVoltageConditionThreshold, data::Unit::Volt },\n\t{ ConfigKey::ClockEdge, data::Unit::Unitless },\n\t{ ConfigKey::Amplitude, data::Unit::Unknown },\n\t{ ConfigKey::Regulation, data::Unit::Unitless },\n\t{ ConfigKey::OutputFrequency, data::Unit::Hertz },\n\t{ ConfigKey::OutputFrequencyTarget, data::Unit::Hertz },\n\t{ ConfigKey::MeasuredQuantity, data::Unit::Unitless },\n\t{ ConfigKey::EquivCircuitModel, data::Unit::Unitless },\n\t{ ConfigKey::TriggerLevel, data::Unit::Volt },\n\t{ ConfigKey::ExternalClockSource, data::Unit::Unitless },\n\t{ ConfigKey::Offset, data::Unit::Unknown },\n\t{ ConfigKey::TriggerPattern, data::Unit::Unitless },\n\t{ ConfigKey::HighResolution, data::Unit::Unitless },\n\t{ ConfigKey::PeakDetection, data::Unit::Unitless },\n\t{ ConfigKey::LogicThreshold, data::Unit::Unitless },\n\t{ ConfigKey::LogicThresholdCustom, data::Unit::Volt },\n\t{ ConfigKey::Range, data::Unit::Unitless },\n\t{ ConfigKey::Digits, data::Unit::Unitless },\n\t{ ConfigKey::SessionFile, data::Unit::Unitless },\n\t{ ConfigKey::CaptureFile, data::Unit::Unitless },\n\t{ ConfigKey::CaptureUnitSize, data::Unit::Unknown },\n\t{ ConfigKey::PowerOff, data::Unit::Boolean },\n\t{ ConfigKey::DataSource, data::Unit::Unitless },\n\t{ ConfigKey::ProbeFactor, data::Unit::Unitless },\n\t{ ConfigKey::ADCPowerlineCycles, data::Unit::Unitless },\n\t{ ConfigKey::DataLog, data::Unit::Boolean },\n\t{ ConfigKey::DeviceMode, data::Unit::Unitless },\n\t{ ConfigKey::TestMode, data::Unit::Unitless },\n};\n\n} // namespace\n\n/**\n * Return all known device type\n *\n * @return The device type name map\n */\ndevice_type_name_map_t get_device_type_name_map();\n\n/**\n * Return all known connection keys\n *\n * @return The connection key name map\n */\nconnection_key_name_map_t get_connection_key_name_map();\n\n/**\n * Return all known config keys\n *\n * @return The config key name map\n */\nconfig_key_name_map_t get_config_key_name_map();\n\n\n/**\n * Check if the driver is supported by SmuView.\n *\n * @param sr_driver The sigrok Driver to check.\n *\n * @return true, if the driver is supported.\n */\nbool is_supported_driver(shared_ptr<sigrok::Driver> sr_driver);\n\n/**\n * Check if the driver is a power supply or a electronic load.\n *\n * @param sr_driver The sigrok Driver to check.\n *\n * @return true, if the driver is a power supply or a electronic load.\n */\nbool is_source_sink_driver(shared_ptr<sigrok::Driver> sr_driver);\n\n/**\n * Check if the driver is a measurement device (dmm, lcr meter, ...).\n *\n * @param sr_driver The sigrok Driver to check.\n *\n * @return true, if the driver is a measurement device.\n */\n bool is_measurement_driver(shared_ptr<sigrok::Driver> sr_driver);\n\n/**\n * Check if the driver is a demo device.\n *\n * @param sr_driver The sigrok Driver to check.\n *\n * @return true, if the driver is a demo device.\n */\n bool is_demo_driver(shared_ptr<sigrok::Driver> sr_driver);\n\n/**\n * Check if the driver is an oscilloscope.\n *\n * @param sr_driver The sigrok Driver to check.\n *\n * @return true, if the driver is an oscilloscope.\n */\n bool is_oscilloscope_driver(shared_ptr<sigrok::Driver> sr_driver);\n\n/**\n * Return the corresponding DeviceType for a sigrok ConfigKey\n *\n * @param sr_config_key The sigrok ConfigKey\n *\n * @return The DeviceType.\n */\nDeviceType get_device_type(const sigrok::ConfigKey *sr_config_key);\n\n/**\n * Return the corresponding DeviceType for a sigrok ConfigKey (unit32_t)\n *\n * @param sr_config_key The sigrok ConfigKey as uint32_t\n *\n * @return The DeviceType.\n */\nDeviceType get_device_type(uint32_t sr_config_key);\n\n/**\n * Return the corresponding sigrok ConfigKey for a DeviceType\n *\n * @param device_type The DeviceType.\n *\n * @return The sigrok ConfigKeyt.\n */\nconst sigrok::ConfigKey *get_sr_config_key(DeviceType device_type);\n\n/**\n * Return the corresponding sigrok ConfigKey ID for a DeviceType\n *\n * @param device_type The DeviceType\n *\n * @return The sigrok ConfigKey ID as uint32_t.\n */\nuint32_t get_sr_config_key_id(DeviceType device_type);\n\n/**\n * Check if the DeviceType is a known sigrok DeviceType / ConfigKey\n *\n * @param device_type The DeviceType\n *\n * @return true if it is a known sigrok DeviceType / ConfigKey\n */\nbool is_valid_sr_config_key(DeviceType device_type);\n\n\n/**\n * Return the corresponding ConnectionKey for a sigrok ConfigKey\n *\n * @param sr_config_key The sigrok ConfigKey\n *\n * @return The ConnectionKey.\n */\nConnectionKey get_connection_key(const sigrok::ConfigKey *sr_config_key);\n\n/**\n * Return the corresponding ConnectionKey for a sigrok ConfigKey (unit32_t)\n *\n * @param sr_config_key The sigrok ConfigKey as uint32_t\n *\n * @return The ConnectionKey.\n */\nConnectionKey get_connection_key(uint32_t sr_config_key);\n\n/**\n * Return the corresponding sigrok ConfigKey for a ConnectionKey\n *\n * @param connection_key The ConnectionKey.\n *\n * @return The sigrok ConfigKey.\n */\nconst sigrok::ConfigKey *get_sr_config_key(ConnectionKey connection_key);\n\n/**\n * Return the corresponding sigrok ConfigKey ID for a ConnectionKey\n *\n * @param connection_key The ConnectionKey\n *\n * @return The sigrok ConfigKey ID as uint32_t.\n */\nuint32_t get_sr_config_key_id(ConnectionKey connection_key);\n\n/**\n * Check if the ConnectionKey is a known sigrok ConnectionKey / ConfigKey\n *\n * @param connection_key The ConnectionKey\n *\n * @return true if it is a known sigrok ConnectionKey / ConfigKey\n */\nbool is_valid_sr_config_key(ConnectionKey connection_key);\n\n\n/**\n * Return the corresponding ConfigKey for a sigrok ConfigKey\n *\n * @param sr_config_key The sigrok ConfigKey\n *\n * @return The ConfigKey.\n */\nConfigKey get_config_key(const sigrok::ConfigKey *sr_config_key);\n\n/**\n * Return the corresponding ConfigKey for a sigrok ConfigKey (unit32_t)\n *\n * @param sr_config_key The sigrok ConfigKey as uint32_t\n *\n * @return The ConfigKey.\n */\nConfigKey get_config_key(uint32_t sr_config_key);\n\n/**\n * Return the corresponding sigrok ConfigKey for a ConfigKey\n *\n * @param config_key The ConfigKey.\n *\n * @return The sigrok ConfigKey.\n */\nconst sigrok::ConfigKey *get_sr_config_key(ConfigKey config_key);\n\n/**\n * Return the corresponding sigrok ConfigKey ID for a ConfigKey\n *\n * @param config_key The ConfigKey\n *\n * @return The sigrok ConfigKey ID as uint32_t.\n */\nuint32_t get_sr_config_key_id(ConfigKey config_key);\n\n/**\n * Check if the ConfigKey is a known sigrok ConfigKey\n *\n * @param config_key The ConfigKey\n *\n * @return true if it is a known sigrok ConfigKey\n */\nbool is_valid_sr_config_key(ConfigKey config_key);\n\n\n/**\n * Format a DeviceType to a string\n *\n * @param device_type The DeviceType to format.\n *\n * @return The formatted device type.\n */\nQString format_device_type(DeviceType device_type);\n\n/**\n * Format a ConnectionKey to a string\n *\n * @param connection_key The ConnectionKey to format.\n *\n * @return The formatted ConnectionKey.\n */\nQString format_connection_key(ConnectionKey connection_key);\n\n/**\n * Format a ConfigKey to a string\n *\n * @param config_key The ConfigKey to format.\n *\n * @return The formatted ConfigKey.\n */\nQString format_config_key(ConfigKey config_key);\n\n\n/**\n * Get the DataType for a ConfigKey\n *\n * @param config_key The ConfigKey.\n *\n * @return The DataType for the ConfigKey.\n */\ndata::DataType get_data_type_for_config_key(ConfigKey config_key);\n\n/**\n * Get the Unit for a ConfigKey\n *\n * @param config_key The ConfigKey.\n *\n * @return The Unit for the ConfigKey.\n */\ndata::Unit get_unit_for_config_key(ConfigKey config_key);\n\n} // namespace deviceutil\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_DEVICEUTIL_HPP\n"
  },
  {
    "path": "src/devices/hardwaredevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <string>\n#include <thread>\n#include <utility>\n#include <vector>\n\n#include <glib.h>\n\n#include <QDateTime>\n#include <QDebug>\n#include <QString>\n#include <QStringList>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"hardwaredevice.hpp\"\n#include \"src/devicemanager.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/hardwarechannel.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::lock_guard;\nusing std::make_pair;\nusing std::map;\nusing std::shared_ptr;\nusing std::static_pointer_cast;\nusing std::string;\nusing std::unique_ptr;\nusing std::vector;\n\nnamespace sv {\nnamespace devices {\n\nHardwareDevice::HardwareDevice(\n\t\tconst shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device) :\n\tBaseDevice(sr_context, sr_device)\n{\n\t// Set options for different device types\n\t// TODO: Multiple DeviceTypes per HardwareDevice\n\t// TODO: Use deviceutil::is_supported_driver() instead\n\ttype_ = DeviceType::Unknown;\n\tconst auto sr_keys = sr_device->driver()->config_keys();\n\tfor (const auto &sr_key : sr_keys) {\n\t\tDeviceType dt = deviceutil::get_device_type(sr_key);\n\t\tif (dt == DeviceType::PowerSupply ||\n\t\t\t\tdt == DeviceType::ElectronicLoad ||\n\t\t\t\tdt == DeviceType::Oscilloscope ||\n\t\t\t\tdt == DeviceType::DemoDev ||\n\t\t\t\tdt == DeviceType::Multimeter ||\n\t\t\t\tdt == DeviceType::SoundLevelMeter ||\n\t\t\t\tdt == DeviceType::Thermometer ||\n\t\t\t\tdt == DeviceType::Hygrometer ||\n\t\t\t\tdt == DeviceType::Energymeter ||\n\t\t\t\tdt == DeviceType::LcrMeter ||\n\t\t\t\tdt == DeviceType::Scale ||\n\t\t\t\tdt == DeviceType::SignalGenerator ||\n\t\t\t\tdt == DeviceType::Powermeter ||\n\t\t\t\tdt == DeviceType::Multiplexer) {\n\t\t\ttype_ = dt;\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (type_ == DeviceType::Unknown)\n\t\tassert(\"Unknown device\");\n}\n\nQString HardwareDevice::display_name(\n\tconst DeviceManager &device_manager) const\n{\n\tconst auto hw_dev = sr_hardware_device();\n\n\t// If we can find another device with the same model/vendor then\n\t// we have at least two such devices and need to distinguish them.\n\tconst auto &devices = device_manager.devices();\n\tconst bool multiple_dev = hw_dev && any_of(\n\t\tdevices.begin(), devices.end(),\n\t\t[&](shared_ptr<devices::HardwareDevice> dev) {\n\t\t\treturn dev->sr_hardware_device()->vendor() ==\n\t\t\t\t\thw_dev->vendor() &&\n\t\t\t\tdev->sr_hardware_device()->model() ==\n\t\t\t\t\thw_dev->model() &&\n\t\t\t\tdev->sr_device_ != sr_device_;\n\t\t});\n\n\tQStringList parts;\n\n\tif (!sr_device_->vendor().empty())\n\t\tparts << QString::fromStdString(sr_device_->vendor());\n\n\tif (!sr_device_->model().empty())\n\t\tparts << QString::fromStdString(sr_device_->model());\n\n\tif (multiple_dev) {\n\t\tif (!sr_device_->version().empty())\n\t\t\tparts << QString::fromStdString(sr_device_->version());\n\n\t\tif (!sr_device_->serial_number().empty())\n\t\t\tparts << \"[S/N: \" +\n\t\t\t\tQString::fromStdString(sr_device_->serial_number()) + \"]\";\n\t\telse if (!sr_device_->connection_id().empty())\n\t\t\tparts << \"(\" +\n\t\t\t\tQString::fromStdString(sr_device_->connection_id()) + \")\";\n\t}\n\n\treturn parts.join(\" \");\n}\n\nvoid HardwareDevice::open()\n{\n\tBaseDevice::open();\n\n\t// Special handling for device \"demo\": Set a initial moderate samplerate of\n\t// 5 samples per second, to slow down the analog channels.\n\tif (sr_hardware_device()->driver()->name() == \"demo\") {\n\t\tsr_device_->config_set(\n\t\t\tsigrok::ConfigKey::SAMPLERATE,\n\t\t\tGlib::Variant<uint64_t>::create(5));\n\t}\n}\n\nshared_ptr<sigrok::HardwareDevice> HardwareDevice::sr_hardware_device() const\n{\n\treturn static_pointer_cast<sigrok::HardwareDevice>(sr_device_);\n}\n\nvoid HardwareDevice::init_configurables()\n{\n\t// Init Configurables from Channel Groups\n\tfor (const auto &sr_cg_pair : sr_device_->channel_groups()) {\n\t\tauto sr_cg = sr_cg_pair.second;\n\t\tif (sr_cg->config_keys().empty())\n\t\t\tcontinue;\n\n\t\tauto cg_c = Configurable::create(\n\t\t\tsr_cg, next_configurable_index_++,\n\t\t\tshort_name().toStdString(), type_, settings_id());\n\t\tconfigurable_map_.insert(make_pair(sr_cg_pair.first, cg_c));\n\t}\n\n\t/*\n\t * Check if the device configurable has any config key of use for us.\n\t * We will ignore the common device config keys like \"continuous\",\n\t * \"limit_samples\" and \"limit_time\"\n\t */\n\tsize_t device_ck_cnt = 0;\n\tfor (const auto &key : sr_device_->config_keys()) {\n\t\tif (deviceutil::get_config_key(key) != ConfigKey::Unknown)\n\t\t\t++device_ck_cnt;\n\t}\n\tif (device_ck_cnt == 0)\n\t\treturn;\n\n\t// Init Configurable from Device\n\tauto d_c = Configurable::create(\n\t\tsr_device_, next_configurable_index_++,\n\t\tshort_name().toStdString(), type_, settings_id());\n\tconfigurable_map_.insert(make_pair(\"\", d_c));\n\n\t// Sample rate for interleaved samples\n\tif (d_c->has_get_config(ConfigKey::Samplerate)) {\n\t\tsamplerate_prop_ = static_pointer_cast<data::properties::UInt64Property>(\n\t\t\td_c->get_property(ConfigKey::Samplerate));\n\t\tcur_samplerate_ = samplerate_prop_->uint64_value();\n\t}\n}\n\nvoid HardwareDevice::init_channels()\n{\n\tmap<string, shared_ptr<sigrok::ChannelGroup>> sr_channel_groups =\n\t\tsr_device_->channel_groups();\n\n\t// Init Channels from Sigrok Channel Groups\n\tif (!sr_channel_groups.empty()) {\n\t\tfor (const auto &sr_cg_pair : sr_channel_groups) {\n\t\t\tshared_ptr<sigrok::ChannelGroup> sr_cg = sr_cg_pair.second;\n\t\t\tfor (const auto &sr_channel : sr_cg->channels()) {\n\t\t\t\tadd_sr_channel(sr_channel, sr_cg->name());\n\t\t\t}\n\t\t}\n\t}\n\n\t// Init Channels that are not in a channel group\n\tvector<shared_ptr<sigrok::Channel>> sr_channels = sr_device_->channels();\n\tfor (const auto &sr_channel : sr_channels) {\n\t\tif (sr_channel_map_.count(sr_channel) > 0)\n\t\t\tcontinue;\n\t\tadd_sr_channel(sr_channel, \"\");\n\t}\n}\n\nvoid HardwareDevice::feed_in_header()\n{\n}\n\nvoid HardwareDevice::feed_in_trigger()\n{\n}\n\nvoid HardwareDevice::feed_in_meta(shared_ptr<sigrok::Meta> sr_meta)\n{\n\t/*\n\t * TODO: The meta packet is missing the information, to which\n\t * channel group / configurable the config key belongs to.\n\t *\n\t * Workaround: First try the device configurable (channel group \"\"),\n\t * then try the other configurables.\n\t */\n\n\tconst auto configurable = configurable_map_[\"\"];\n\tif (configurable && configurable->feed_in_meta(sr_meta))\n\t\treturn;\n\n\tfor (const auto &c_pair : configurable_map_) {\n\t\tif (c_pair.first.empty())\n\t\t\tcontinue;\n\t\tif (c_pair.second && c_pair.second->feed_in_meta(sr_meta))\n\t\t\treturn;\n\t}\n}\n\nvoid HardwareDevice::feed_in_frame_begin()\n{\n\t// TODO: use std::chrono / std::time\n\tframe_start_timestamp_ =\n\t\tstatic_cast<double>(QDateTime::currentMSecsSinceEpoch()) / 1000;\n\tframe_began_ = true;\n}\n\nvoid HardwareDevice::feed_in_frame_end()\n{\n\tframe_began_ = false;\n}\n\nvoid HardwareDevice::feed_in_logic(shared_ptr<sigrok::Logic> sr_logic)\n{\n\t(void)sr_logic;\n}\n\nvoid HardwareDevice::feed_in_analog(shared_ptr<sigrok::Analog> sr_analog)\n{\n\tsize_t num_samples = sr_analog->num_samples();\n\tif (num_samples == 0)\n\t\treturn;\n\n\tlock_guard<recursive_mutex> lock(data_mutex_);\n\n\tuint64_t samplerate = 0;\n\tif (samplerate_prop_ != nullptr)\n\t\tsamplerate = samplerate_prop_->uint64_value();\n\n\tconst vector<shared_ptr<sigrok::Channel>> sr_channels = sr_analog->channels();\n\n\tunique_ptr<float[]> data(new float[num_samples * sr_channels.size()]);\n\tsr_analog->get_data_as_float(data.get());\n\tfloat *channel_data = data.get();\n\n\tfor (const auto &sr_channel : sr_channels) {\n\t\t/*\n\t\tqWarning() << \"HardwareDevice::feed_in_analog(): HardwareDevice = \" <<\n\t\t\tQString::fromStdString(sr_device_->model()) <<\n\t\t\t\", Channel.Id = \" <<\n\t\t\tQString::fromStdString(sr_channel->name()) <<\n\t\t\t\" channel_data = \" << *channel_data;\n\t\t*/\n\n\t\tif (sr_channel_map_.count(sr_channel) == 0)\n\t\t\tassert(\"Unknown channel\");\n\t\tauto channel = static_pointer_cast<channels::HardwareChannel>(\n\t\t\tsr_channel_map_[sr_channel]);\n\n\t\t// TODO: use std::chrono / std::time\n\t\tdouble timestamp;\n\t\tif (frame_began_)\n\t\t\ttimestamp = frame_start_timestamp_;\n\t\telse\n\t\t\ttimestamp =\n\t\t\t\tstatic_cast<double>(QDateTime::currentMSecsSinceEpoch()) / 1000;\n\n\t\t//channel->push_sample_sr_analog(channel_data++, timestamp, sr_analog);\n\t\tchannel->push_interleaved_samples(channel_data++, num_samples,\n\t\t\tsr_channels.size(), timestamp, samplerate, sr_analog);\n\t}\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/hardwaredevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_HARDWAREDEVICE_HPP\n#define DEVICES_HARDWAREDEVICE_HPP\n\n#include <map>\n#include <mutex>\n#include <string>\n#include <unordered_set>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QString>\n\n#include \"src/devices/basedevice.hpp\"\n\nusing std::bad_alloc;\nusing std::dynamic_pointer_cast;\nusing std::lock_guard;\nusing std::make_shared;\nusing std::set;\nusing std::shared_ptr;\nusing std::static_pointer_cast;\nusing std::string;\nusing std::vector;\nusing std::unique_ptr;\n\nusing std::map;\nusing std::mutex;\nusing std::recursive_mutex;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::unordered_set;\n\nnamespace sigrok {\nclass Channel;\nclass Configurable;\nclass Context;\nclass Quantity;\nclass HardwareDevice;\n}\n\nnamespace sv {\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nnamespace properties {\nclass UInt64Property;\n}\n}\n\nnamespace devices {\n\nclass Configurable;\n\nclass HardwareDevice : public BaseDevice\n{\n\tQ_OBJECT\n\nprotected:\n\tHardwareDevice(const shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device);\n\npublic:\n\t/**\n\t * Returns the sigrok hardware device\n\t */\n\tshared_ptr<sigrok::HardwareDevice> sr_hardware_device() const;\n\n\t/**\n\t * Builds the display name. It only contains fields as required.\n\t * @param device_manager a reference to the device manager is needed\n\t * so that other similarly titled devices can be detected.\n\t */\n\tQString display_name(const DeviceManager &device_manager) const override;\n\n\tvoid open() override;\n\nprotected:\n\t/**\n\t * Init all configurables for this hardware device.\n\t */\n\tvoid init_configurables() override;\n\t/**\n\t * Init all sigrok channles for this hardware device\n\t */\n\tvoid init_channels() override;\n\n\tvoid feed_in_header() override;\n\tvoid feed_in_trigger() override;\n\tvoid feed_in_meta(shared_ptr<sigrok::Meta> sr_meta) override;\n\tvoid feed_in_frame_begin() override;\n\tvoid feed_in_frame_end() override;\n\tvoid feed_in_logic(shared_ptr<sigrok::Logic> sr_logic) override;\n\tvoid feed_in_analog(shared_ptr<sigrok::Analog> sr_analog) override;\n\nprivate:\n\tdouble frame_start_timestamp_;\n\tuint64_t cur_samplerate_;\n\tshared_ptr<data::properties::UInt64Property> samplerate_prop_;\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_HARDWAREDEVICE_HPP\n"
  },
  {
    "path": "src/devices/measurementdevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n\n#include <QDebug>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"measurementdevice.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n\nnamespace sv {\nnamespace devices {\n\nMeasurementDevice::MeasurementDevice(\n\t\tconst shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device) :\n\tHardwareDevice(sr_context, sr_device)\n{\n}\n\nvoid MeasurementDevice::init_configurables()\n{\n\tHardwareDevice::init_configurables();\n\n\tfor (const auto &c_pair : configurable_map_) {\n\t\tauto configurable = c_pair.second;\n\n\t\t// Check if the device has the config key \"Range\". If so, each possible\n\t\t// value of the config key \"MeasuredQuantity\" could have a different\n\t\t// listing for \"Range\"!\n\t\tif (configurable->property_map().count(ConfigKey::Range) > 0 &&\n\t\t\tconfigurable->property_map().count(ConfigKey::MeasuredQuantity) > 0) {\n\n\t\t\tauto range_property = configurable->property_map()[ConfigKey::Range];\n\t\t\tauto mq_property =\n\t\t\t\tconfigurable->property_map()[ConfigKey::MeasuredQuantity];\n\t\t\tconnect(\n\t\t\t\tmq_property.get(), &data::properties::BaseProperty::value_changed,\n\t\t\t\trange_property.get(), &data::properties::BaseProperty::list_config);\n\t\t}\n\t}\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/measurementdevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_MEASUREMENTDEVICE_HPP\n#define DEVICES_MEASUREMENTDEVICE_HPP\n\n#include <memory>\n#include <utility>\n\n#include \"src/devices/hardwaredevice.hpp\"\n\nusing std::forward;\nusing std::shared_ptr;\n\nnamespace sigrok {\nclass Context;\nclass HardwareDevice;\n}\n\nnamespace sv {\nnamespace devices {\n\nclass MeasurementDevice : public HardwareDevice\n{\n\tQ_OBJECT\n\nprivate:\n\texplicit MeasurementDevice(\n\t\tconst shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device);\n\npublic:\n\ttemplate<typename ...Arg>\n\tshared_ptr<MeasurementDevice> static create(Arg&&...arg)\n\t{\n\t\tstruct make_shared_enabler : public MeasurementDevice {\n\t\t\texplicit make_shared_enabler(Arg&&...arg) :\n\t\t\t\tMeasurementDevice(forward<Arg>(arg)...)\n\t\t\t{\n\t\t\t}\n\t\t};\n\n\t\treturn make_shared<make_shared_enabler>(forward<Arg>(arg)...);\n\t}\n\nprotected:\n\tvoid init_configurables() override;\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_MEASUREMENTDEVICE_HPP\n"
  },
  {
    "path": "src/devices/oscilloscopedevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n\n#include <QDebug>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"oscilloscopedevice.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/hardwarechannel.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace devices {\n\nOscilloscopeDevice::OscilloscopeDevice(\n\t\tconst shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device) :\n\tHardwareDevice(sr_context, sr_device)\n{\n}\n\nvoid OscilloscopeDevice::init_configurables()\n{\n\tHardwareDevice::init_configurables();\n\n\tfor (const auto &c_pair : configurable_map_) {\n\t\tauto configurable = c_pair.second;\n\n\t\t// Check if the device has the config key \"VDiv\". If so, each possible\n\t\t// value of the config key \"ProbeFactor\" could have a different\n\t\t// listing for \"VDiv\"!\n\t\tif (configurable->property_map().count(ConfigKey::ProbeFactor) > 0 &&\n\t\t\tconfigurable->property_map().count(ConfigKey::VDiv) > 0) {\n\n\t\t\tauto pf_property = configurable->property_map()[ConfigKey::ProbeFactor];\n\t\t\tauto vdiv_property = configurable->property_map()[ConfigKey::VDiv];\n\t\t\tconnect(\n\t\t\t\tpf_property.get(), &data::properties::BaseProperty::value_changed,\n\t\t\t\tvdiv_property.get(), &data::properties::BaseProperty::list_config);\n\t\t}\n\t}\n}\n\nvoid OscilloscopeDevice::init_channels()\n{\n\tHardwareDevice::init_channels();\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/oscilloscopedevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_OSCILLOSCOPEDEVICE_HPP\n#define DEVICES_OSCILLOSCOPEDEVICE_HPP\n\n#include <memory>\n#include <utility>\n\n#include \"src/devices/hardwaredevice.hpp\"\n\nusing std::forward;\nusing std::shared_ptr;\n\nnamespace sigrok {\nclass Context;\nclass HardwareDevice;\n}\n\nnamespace sv {\nnamespace devices {\n\nclass OscilloscopeDevice : public HardwareDevice\n{\n\tQ_OBJECT\n\nprivate:\n\texplicit OscilloscopeDevice(\n\t\tconst shared_ptr<sigrok::Context> sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device);\n\npublic:\n\ttemplate<typename ...Arg>\n\tshared_ptr<OscilloscopeDevice> static create(Arg&&...arg)\n\t{\n\t\tstruct make_shared_enabler : public OscilloscopeDevice {\n\t\t\texplicit make_shared_enabler(Arg&&...arg) :\n\t\t\t\tOscilloscopeDevice(forward<Arg>(arg)...)\n\t\t\t{\n\t\t\t}\n\t\t};\n\n\t\treturn make_shared<make_shared_enabler>(forward<Arg>(arg)...);\n\t}\n\nprotected:\n\tvoid init_configurables() override;\n\tvoid init_channels() override;\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_OSCILLOSCOPEDEVICE_HPP\n"
  },
  {
    "path": "src/devices/sourcesinkdevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <string>\n#include <vector>\n\n#include <QDebug>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"sourcesinkdevice.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/dividechannel.hpp\"\n#include \"src/channels/hardwarechannel.hpp\"\n#include \"src/channels/integratechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/channels/multiplysschannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::static_pointer_cast;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace devices {\n\nSourceSinkDevice::SourceSinkDevice(\n\t\tconst shared_ptr<sigrok::Context> &sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device) :\n\tHardwareDevice(sr_context, sr_device)\n{\n}\n\nvoid SourceSinkDevice::init_configurables()\n{\n\tHardwareDevice::init_configurables();\n\n\tfor (const auto &c_pair : configurable_map_) {\n\t\tauto configurable = c_pair.second;\n\n\t\t/*\n\t\t * Check if the device has the config key `Range`. If so, the config keys\n\t\t * `VoltageTarget`, `CurrentLimit`, `OverVoltageProtectionThreshold`,\n\t\t * `OverCurrentProtectionThreshold` and `UnderVoltageConditionThreshold`\n\t\t * could have different min/max/step values for each \"Range\" value!\n\t\t */\n\t\tif (configurable->property_map().count(ConfigKey::Range) > 0) {\n\t\t\tauto property_map = configurable->property_map();\n\t\t\tauto range_property = property_map[ConfigKey::Range];\n\n\t\t\tif (property_map.count(ConfigKey::VoltageTarget) > 0) {\n\t\t\t\tauto volt_property =\n\t\t\t\t\tconfigurable->property_map()[ConfigKey::VoltageTarget];\n\t\t\t\tconnect(\n\t\t\t\t\trange_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::value_changed,\n\t\t\t\t\tvolt_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::list_config);\n\t\t\t}\n\n\t\t\tif (property_map.count(ConfigKey::CurrentLimit) > 0) {\n\t\t\t\tauto current_property =\n\t\t\t\t\tconfigurable->property_map()[ConfigKey::CurrentLimit];\n\t\t\t\tconnect(\n\t\t\t\t\trange_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::value_changed,\n\t\t\t\t\tcurrent_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::list_config);\n\t\t\t}\n\n\t\t\tif (property_map.count(ConfigKey::OverVoltageProtectionThreshold) > 0) {\n\t\t\t\tauto ovp_threshold_property =\n\t\t\t\t\tconfigurable->property_map()[ConfigKey::OverVoltageProtectionThreshold];\n\t\t\t\tconnect(\n\t\t\t\t\trange_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::value_changed,\n\t\t\t\t\tovp_threshold_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::list_config);\n\t\t\t}\n\n\t\t\tif (property_map.count(ConfigKey::OverCurrentProtectionThreshold) > 0) {\n\t\t\t\tauto ocp_threshold_property =\n\t\t\t\t\tconfigurable->property_map()[ConfigKey::OverCurrentProtectionThreshold];\n\t\t\t\tconnect(\n\t\t\t\t\trange_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::value_changed,\n\t\t\t\t\tocp_threshold_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::list_config);\n\t\t\t}\n\n\t\t\tif (property_map.count(ConfigKey::UnderVoltageConditionThreshold) > 0) {\n\t\t\t\tauto uvc_threshold_property =\n\t\t\t\t\tconfigurable->property_map()[ConfigKey::UnderVoltageConditionThreshold];\n\t\t\t\tconnect(\n\t\t\t\t\trange_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::value_changed,\n\t\t\t\t\tuvc_threshold_property.get(),\n\t\t\t\t\t&data::properties::BaseProperty::list_config);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/*\n * TODO: Preinit the fixed channels with e.g. channel.meaning.mq and\n *       quantity_flags (AC/DC)! Must be implemented in sigrok!\n *\n * TODO: Handle AC power supplies / loads! Right now AC devices are initialized\n *       as DC, which results in two signals per Voltage and Amp channel.\n *\n * NOTE: The check when adding signals with other mq/mq_flags than specified in\n *       here to a fixed channel was defused in BaseChannel::add_signal() to\n *       prevent a subsequent segfault.\n */\nvoid SourceSinkDevice::init_channels()\n{\n\tHardwareDevice::init_channels();\n\n\t// Preinitialize known fixed channels with a signal\n\tfor (const auto &chg_name_channels_pair : channel_group_map_) {\n\t\tstring ch_suffix;\n\t\tbool ch_suffix_initialized = false;\n\t\tfor (const auto &channel : chg_name_channels_pair.second) {\n\t\t\tif (channel->type() != channels::ChannelType::AnalogChannel)\n\t\t\t\tcontinue;\n\n\t\t\tbool init = false;\n\t\t\tdata::Quantity quantity;\n\t\t\tset<data::QuantityFlag> quantity_flags;\n\t\t\tdata::Unit unit;\n\t\t\tif (util::starts_with(channel->name(), \"V\")) {\n\t\t\t\tquantity = data::Quantity::Voltage;\n\t\t\t\t// TODO: Check for AC/DC when libsigrok preinits the channels!\n\t\t\t\tquantity_flags.insert(data::QuantityFlag::DC);\n\t\t\t\tunit = data::Unit::Volt;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"V\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"I\")) {\n\t\t\t\tquantity = data::Quantity::Current;\n\t\t\t\t// TODO: Check for AC/DC when libsigrok preinits the channels!\n\t\t\t\tquantity_flags.insert(data::QuantityFlag::DC);\n\t\t\t\tunit = data::Unit::Ampere;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"I\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"P\")) {\n\t\t\t\tquantity = data::Quantity::Power;\n\t\t\t\tunit = data::Unit::Watt;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"P\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"R\")) {\n\t\t\t\tquantity = data::Quantity::Resistance;\n\t\t\t\tunit = data::Unit::Ohm;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"R\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"F\")) {\n\t\t\t\tquantity = data::Quantity::Frequency;\n\t\t\t\tunit = data::Unit::Hertz;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"F\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"Wh\") ||\n\t\t\t\t\tutil::starts_with(channel->name(), \"E\")) {\n\t\t\t\tquantity = data::Quantity::Energy;\n\t\t\t\tunit = data::Unit::WattHour;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"Wh\", \"E\" }, ch_suffix_initialized);\n\t\t\t}\n\t\t\telse if (util::starts_with(channel->name(), \"Ah\")) {\n\t\t\t\tquantity = data::Quantity::ElectricCharge;\n\t\t\t\tunit = data::Unit::AmpereHour;\n\t\t\t\tinit = true;\n\t\t\t\tch_suffix_initialized = get_channel_name_suffix(ch_suffix,\n\t\t\t\t\tchannel->name(), { \"Ah\" }, ch_suffix_initialized);\n\t\t\t}\n\n\t\t\tif (init) {\n\t\t\t\tauto hw_channel =\n\t\t\t\t\tstatic_pointer_cast<channels::HardwareChannel>(channel);\n\t\t\t\thw_channel->set_fixed_signal(true);\n\t\t\t\thw_channel->add_signal(quantity, quantity_flags, unit);\n\t\t\t}\n\t\t}\n\n\t\t// Math Channels\n\t\tstring chg_name = chg_name_channels_pair.first;\n\t\tset<string> chg_names { chg_name };\n\t\tshared_ptr<data::AnalogTimeSignal> voltage_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> current_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> power_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> resistance_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> wh_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> ah_signal;\n\t\tfor (const auto &channel : chg_name_channels_pair.second) {\n\t\t\tif (!channel->fixed_signal())\n\t\t\t\tcontinue;\n\t\t\tauto signal = channel->actual_signal();\n\t\t\tif (signal->quantity() == data::Quantity::Voltage) {\n\t\t\t\tvoltage_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t\telse if (signal->quantity() == data::Quantity::Current) {\n\t\t\t\tcurrent_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t\telse if (signal->quantity() == data::Quantity::Power) {\n\t\t\t\tpower_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t\telse if (signal->quantity() == data::Quantity::Resistance) {\n\t\t\t\tresistance_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t\telse if (signal->quantity() == data::Quantity::Energy) {\n\t\t\t\twh_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t\telse if (signal->quantity() == data::Quantity::ElectricCharge) {\n\t\t\t\tah_signal =\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal);\n\t\t\t}\n\t\t}\n\n\t\t// Create power channel\n\t\tif (voltage_signal && current_signal && !power_signal) {\n\t\t\tshared_ptr<channels::MultiplySSChannel> power_channel =\n\t\t\t\tmake_shared<channels::MultiplySSChannel>(\n\t\t\t\t\tdata::Quantity::Power,\n\t\t\t\t\tset<data::QuantityFlag>(),\n\t\t\t\t\tdata::Unit::Watt,\n\t\t\t\t\tvoltage_signal, current_signal,\n\t\t\t\t\tshared_from_this(),\n\t\t\t\t\tchg_names, \"P\" + ch_suffix,\n\t\t\t\t\taquisition_start_timestamp_);\n\t\t\tBaseDevice::add_math_channel(power_channel, chg_name);\n\t\t\tpower_signal = static_pointer_cast<data::AnalogTimeSignal>(\n\t\t\t\tpower_channel->actual_signal());\n\t\t}\n\n\t\t// Create resistance channel\n\t\tif (voltage_signal && current_signal && !resistance_signal) {\n\t\t\tshared_ptr<channels::DivideChannel> resistance_channel =\n\t\t\t\tmake_shared<channels::DivideChannel>(\n\t\t\t\t\tdata::Quantity::Resistance,\n\t\t\t\t\tset<data::QuantityFlag>(),\n\t\t\t\t\tdata::Unit::Ohm,\n\t\t\t\t\tvoltage_signal, current_signal,\n\t\t\t\t\tshared_from_this(),\n\t\t\t\t\tchg_names, \"R\" + ch_suffix,\n\t\t\t\t\taquisition_start_timestamp_);\n\t\t\tBaseDevice::add_math_channel(resistance_channel, chg_name);\n\t\t}\n\n\t\t// Create Wh channel\n\t\tif (power_signal && !wh_signal) {\n\t\t\tshared_ptr<channels::IntegrateChannel> wh_channel =\n\t\t\t\tmake_shared<channels::IntegrateChannel>(\n\t\t\t\t\tdata::Quantity::Energy,\n\t\t\t\t\tset<data::QuantityFlag>(),\n\t\t\t\t\tdata::Unit::WattHour,\n\t\t\t\t\tpower_signal,\n\t\t\t\t\tshared_from_this(),\n\t\t\t\t\tchg_names, \"Wh\" + ch_suffix,\n\t\t\t\t\taquisition_start_timestamp_);\n\t\t\tBaseDevice::add_math_channel(wh_channel, chg_name);\n\t\t}\n\n\t\t// Create Ah channel\n\t\tif (current_signal && !ah_signal) {\n\t\t\tshared_ptr<channels::IntegrateChannel> ah_channel =\n\t\t\t\tmake_shared<channels::IntegrateChannel>(\n\t\t\t\t\tdata::Quantity::ElectricCharge,\n\t\t\t\t\tset<data::QuantityFlag>(),\n\t\t\t\t\tdata::Unit::AmpereHour,\n\t\t\t\t\tcurrent_signal,\n\t\t\t\t\tshared_from_this(),\n\t\t\t\t\tchg_names, \"Ah\" + ch_suffix,\n\t\t\t\t\taquisition_start_timestamp_);\n\t\t\tBaseDevice::add_math_channel(ah_channel, chg_name);\n\t\t}\n\t}\n}\n\nbool SourceSinkDevice::get_channel_name_suffix(string &channel_suffix,\n\tconst string &channel_name, const vector<string> &prefixes,\n\tbool is_initialized)\n{\n\tstring tmp_ch_suffix;\n\n\tfor (const auto &prefix : prefixes) {\n\t\tif (!util::starts_with(channel_name, prefix))\n\t\t\tcontinue;\n\n\t\ttmp_ch_suffix = channel_name.substr(\n\t\t\tprefix.length(), channel_name.length());\n\t\tif (is_initialized && channel_suffix == tmp_ch_suffix)\n\t\t\treturn true;\n\t\tif (!is_initialized) {\n\t\t\tchannel_suffix = tmp_ch_suffix;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\tqCritical() << \"WARNING: Channel suffix for channel \"\n\t\t<< QString::fromStdString(channel_name)\n\t\t<< \"(\" << QString::fromStdString(tmp_ch_suffix) << \")\"\n\t\t<< \" differs from previous suffix \"\n\t\t<< QString::fromStdString(channel_suffix);\n\tqCritical() << \"WARNING: Please fix this in the libsigrok driver!\";\n\treturn false;\n}\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/sourcesinkdevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_SOURCESINKDEVICE_HPP\n#define DEVICES_SOURCESINKDEVICE_HPP\n\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include \"src/devices/hardwaredevice.hpp\"\n\nusing std::forward;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sigrok {\nclass Context;\nclass HardwareDevice;\n}\n\nnamespace sv {\nnamespace devices {\n\nclass SourceSinkDevice : public HardwareDevice\n{\n\tQ_OBJECT\n\nprivate:\n\texplicit SourceSinkDevice(const shared_ptr<sigrok::Context> &sr_context,\n\t\tshared_ptr<sigrok::HardwareDevice> sr_device);\n\n\tbool get_channel_name_suffix(string &channel_suffix,\n\t\tconst string &channel_name, const vector<string> &prefixes,\n\t\tbool is_initialized);\n\npublic:\n\ttemplate<typename ...Arg>\n\tshared_ptr<SourceSinkDevice> static create(Arg&&...arg)\n\t{\n\t\tstruct make_shared_enabler : public SourceSinkDevice {\n\t\t\texplicit make_shared_enabler(Arg&&...arg) :\n\t\t\t\tSourceSinkDevice(forward<Arg>(arg)...)\n\t\t\t{\n\t\t\t}\n\t\t};\n\n\t\treturn make_shared<make_shared_enabler>(forward<Arg>(arg)...);\n\t}\n\nprotected:\n\tvoid init_configurables() override;\n\tvoid init_channels() override;\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_SOURCESINKDEVICE_HPP\n"
  },
  {
    "path": "src/devices/userdevice.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDebug>\n\n#include \"userdevice.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::static_pointer_cast;\n\nnamespace sv {\nnamespace devices {\n\nUserDevice::UserDevice(\n\t\tconst shared_ptr<sigrok::Context> &sr_context,\n\t\tconst string &vendor, const string &model, const string &version) :\n\tBaseDevice(sr_context, nullptr),\n\tvendor_(vendor),\n\tmodel_(model),\n\tversion_(version),\n\tchannel_index_(0)\n{\n\tsr_device_ = sr_context_->create_user_device(vendor_, model_, version_);\n\ttype_ = DeviceType::UserDevice;\n}\n\nstring UserDevice::name() const\n{\n\treturn short_name().toStdString();\n}\n\nQString UserDevice::full_name() const\n{\n\tQString sep(\"\");\n\tQString full_name(\"\");\n\n\tif (sr_device_->vendor().length() > 0) {\n\t\tfull_name.append(QString::fromStdString(sr_device_->vendor()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->model().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(QString::fromStdString(sr_device_->model()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->version().length() > 0) {\n\t\tfull_name.append(sep);\n\t\tfull_name.append(QString::fromStdString(sr_device_->version()));\n\t\tsep = QString(\" \");\n\t}\n\n\treturn full_name;\n}\n\nQString UserDevice::short_name() const\n{\n\tQString sep(\"\");\n\tQString short_name(\"\");\n\n\tif (sr_device_->vendor().length() > 0) {\n\t\tshort_name.append(QString::fromStdString(sr_device_->vendor()));\n\t\tsep = QString(\" \");\n\t}\n\n\tif (sr_device_->model().length() > 0) {\n\t\tshort_name.append(sep);\n\t\tshort_name.append(QString::fromStdString(sr_device_->model()));\n\t}\n\n\treturn short_name;\n}\n\nQString UserDevice::display_name(\n\tconst DeviceManager &device_manager) const\n{\n\t(void)device_manager;\n\treturn full_name();\n}\n\nvoid UserDevice::add_channel(shared_ptr<channels::BaseChannel> channel,\n\tconst string &channel_group_name)\n{\n\tauto sr_user_device = static_pointer_cast<sigrok::UserDevice>(sr_device_);\n\tsr_user_device->add_channel(\n\t\tchannel_index_, sigrok::ChannelType::ANALOG, name());\n\tchannel_index_++;\n\tBaseDevice::add_channel(channel, channel_group_name);\n}\n\nvoid UserDevice::init_configurables()\n{\n}\n\nvoid UserDevice::init_channels()\n{\n}\n\nvoid UserDevice::init_acquisition()\n{\n}\n\nvoid UserDevice::feed_in_header()\n{\n}\n\nvoid UserDevice::feed_in_trigger()\n{\n}\n\nvoid UserDevice::feed_in_meta(shared_ptr<sigrok::Meta> sr_meta)\n{\n\t(void)sr_meta;\n}\n\nvoid UserDevice::feed_in_frame_begin()\n{\n}\n\nvoid UserDevice::feed_in_frame_end()\n{\n}\n\nvoid UserDevice::feed_in_logic(shared_ptr<sigrok::Logic> sr_logic)\n{\n\t(void)sr_logic;\n}\n\nvoid UserDevice::feed_in_analog(shared_ptr<sigrok::Analog> sr_analog)\n{\n\t(void)sr_analog;\n}\n\n\n} // namespace devices\n} // namespace sv\n"
  },
  {
    "path": "src/devices/userdevice.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef DEVICES_USERDEVICE_HPP\n#define DEVICES_USERDEVICE_HPP\n\n#include <memory>\n#include <string>\n\n#include <QObject>\n#include <QString>\n\n#include \"src/devices/basedevice.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sigrok {\nclass Context;\n}\n\nnamespace sv {\nnamespace devices {\n\nclass UserDevice : public BaseDevice\n{\n\tQ_OBJECT\n\npublic:\n\tUserDevice(const shared_ptr<sigrok::Context> &sr_context,\n\t\tconst string &vendor, const string &model, const string &version);\n\n\t/**\n\t * Builds the name\n\t */\n\tstring name() const override;\n\n\t/**\n\t * Builds the full name. It only contains all the fields.\n\t */\n\tQString full_name() const override;\n\n\t/**\n\t * Builds the short name.\n\t */\n\tQString short_name() const override;\n\n\t/**\n\t * Builds the display name. It only contains fields as required.\n\t * @param device_manager a reference to the device manager is needed\n\t * so that other similarly titled devices can be detected.\n\t */\n\tQString display_name(const DeviceManager &device_manager) const override;\n\n\tvoid add_channel(shared_ptr<channels::BaseChannel> channel,\n\t\tconst string &channel_group_name) override;\n\nprotected:\n\t/**\n\t * Init all configurables for this user device. Not used in here!\n\t */\n\tvoid init_configurables() override;\n\t/**\n\t * Init all channles of this user device.\n\t */\n\tvoid init_channels() override;\n\t/**\n\t * Init acquisition for this device.\n\t */\n\tvoid init_acquisition() override;\n\n\tvoid feed_in_header() override;\n\tvoid feed_in_trigger() override;\n\tvoid feed_in_meta(shared_ptr<sigrok::Meta> sr_meta) override;\n\tvoid feed_in_frame_begin() override;\n\tvoid feed_in_frame_end() override;\n\tvoid feed_in_logic(shared_ptr<sigrok::Logic> sr_logic) override;\n\tvoid feed_in_analog(shared_ptr<sigrok::Analog> sr_analog) override;\n\nprivate:\n\tdouble frame_start_timestamp_;\n\tstring vendor_;\n\tstring model_;\n\tstring version_;\n\tunsigned int channel_index_;\n\n};\n\n} // namespace devices\n} // namespace sv\n\n#endif // DEVICES_USERDEVICE_HPP\n"
  },
  {
    "path": "src/mainwindow.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n#include <utility>\n\n#include <QApplication>\n#include <QDebug>\n#include <QDockWidget>\n#include <QFontDatabase>\n#include <QHBoxLayout>\n#include <QLabel>\n#include <QMessageBox>\n#include <QSizePolicy>\n#include <QVBoxLayout>\n\n#include \"mainwindow.hpp\"\n#include \"config.h\"\n#include \"src/devicemanager.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/measurementdevice.hpp\"\n#include \"src/devices/sourcesinkdevice.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n#include \"src/ui/dialogs/connectdialog.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/tabs/smuscripttab.hpp\"\n#include \"src/ui/tabs/tabhelper.hpp\"\n#include \"src/ui/tabs/welcometab.hpp\"\n#include \"src/ui/views/devicesview.hpp\"\n#include \"src/ui/views/smuscripttreeview.hpp\"\n\nusing std::make_pair;\nusing std::shared_ptr;\nusing std::string;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\nQ_DECLARE_METATYPE(std::shared_ptr<sv::devices::BaseDevice>)\nQ_DECLARE_METATYPE(std::shared_ptr<sv::channels::BaseChannel>)\nQ_DECLARE_METATYPE(std::shared_ptr<sv::data::BaseSignal>)\n\nnamespace sv\n{\n\nMainWindow::MainWindow(DeviceManager &device_manager,\n\t\tshared_ptr<Session> session, QWidget *parent) :\n\tQMainWindow(parent),\n\tdevice_manager_(device_manager),\n\tsession_(session)\n{\n\tqRegisterMetaType<util::Timestamp>(\"util::Timestamp\");\n\tqRegisterMetaType<uint64_t>(\"uint64_t\");\n\tqRegisterMetaType<std::string>(\"std::string\");\n\tqRegisterMetaType<Qt::DockWidgetArea>(\"Qt::DockWidgetArea\");\n\tqRegisterMetaType<shared_ptr<devices::BaseDevice>>(\"shared_ptr<sv::devices::BaseDevice>\");\n\tqRegisterMetaType<shared_ptr<devices::Configurable>>(\"shared_ptr<sv::devices::Configurable>\");\n\tqRegisterMetaType<shared_ptr<devices::HardwareDevice>>(\"shared_ptr<sv::devices::HardwareDevice>\");\n\tqRegisterMetaType<shared_ptr<channels::BaseChannel>>(\"shared_ptr<sv::channels::BaseChannel>\");\n\tqRegisterMetaType<shared_ptr<data::BaseSignal>>(\"shared_ptr<sv::data::BaseSignal>\");\n\tqRegisterMetaType<shared_ptr<data::AnalogTimeSignal>>(\"shared_ptr<sv::data::AnalogTimeSignal>\");\n\tqRegisterMetaType<devices::ConfigKey>(\"devices::ConfigKey\");\n\n\t// Add embedded mono space font for the value display.\n\tQFontDatabase::addApplicationFont(\":/fonts/DejaVuSansMono.ttf\");\n\n\tsession_->set_main_window(this);\n\n\tsetup_ui();\n\tif (SettingsManager::restore_settings())\n\t\trestore_settings();\n\tconnect_signals();\n\tinit_device_tabs();\n}\n\nMainWindow::~MainWindow()\n{\n}\n\nvoid MainWindow::add_tab(ui::tabs::BaseTab *tab_window)\n{\n\t// NOTE: This must be before QTabWidget::addTab() and\n\t//       QTabWidget::setCurrentIndex() otherwise the tab_window is null for\n\t//       the SmuScriptTab after inserting into tab_window_map_.\n\ttab_window_map_.insert(make_pair(tab_window->id(), tab_window));\n\n\tint index = tab_widget_->addTab(tab_window, tab_window->title());\n\ttab_widget_->setCurrentIndex(index);\n}\n\nui::tabs::DeviceTab *MainWindow::add_device_tab(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tauto *tab = ui::tabs::tabhelper::get_tab_for_device(*session_, device);\n\tadd_tab(tab);\n\n\t// Connect device error handler to show a message box\n\tconnect(device.get(), &sv::devices::BaseDevice::device_error,\n\t\tthis, &MainWindow::error_handler);\n\n\treturn tab;\n}\n\nui::tabs::WelcomeTab *MainWindow::add_welcome_tab()\n{\n\tauto *tab = new ui::tabs::WelcomeTab(*session_);\n\tadd_tab(tab);\n\treturn tab;\n}\n\nui::tabs::SmuScriptTab *MainWindow::add_smuscript_tab(const string &file_name)\n{\n\tauto *tab = new ui::tabs::SmuScriptTab(*session_, file_name);\n\tadd_tab(tab);\n\treturn tab;\n}\n\nvoid MainWindow::remove_tab(const string &tab_id)\n{\n\tif (tab_window_map_.count(tab_id)  == 0)\n\t\treturn;\n\n\tremove_tab(tab_widget_->indexOf(tab_window_map_[tab_id]));\n}\n\nvoid MainWindow::remove_tab(int tab_index)\n{\n\tQWidget *tab_window = tab_widget_->widget(tab_index);\n\n\ttab_widget_->removeTab(tab_index);\n\n\tfor (const auto &pair : tab_window_map_) {\n\t\tif (pair.second == tab_window) {\n\t\t\ttab_window_map_.erase(pair.first);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Call close() of the tab window to save settings (*Tab::closeEvent())\n\ttab_window->close();\n\ttab_window->deleteLater();\n\n\tif (tab_window_map_.empty()) {\n\t\t// When there are no more tabs, display the WelcomeTab\n\t\tadd_welcome_tab();\n\t}\n}\n\nvoid MainWindow::change_tab_icon(const string &tab_id, const QIcon &icon)\n{\n\tint tab_index = tab_widget_->indexOf(tab_window_map_[tab_id]);\n\ttab_widget_->setTabIcon(tab_index, icon);\n}\n\nvoid MainWindow::change_tab_title(const string &tab_id, const QString &title)\n{\n\tint tab_index = tab_widget_->indexOf(tab_window_map_[tab_id]);\n\ttab_widget_->setTabText(tab_index, title);\n}\n\nui::tabs::BaseTab *MainWindow::get_tab_from_tab_id(const string &id)\n{\n\tif (tab_window_map_.count(id) == 0)\n\t\treturn nullptr;\n\n\treturn tab_window_map_[id];\n}\n\nvoid MainWindow::setup_ui()\n{\n\tQIcon mainIcon;\n\tmainIcon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(mainIcon);\n\n\tQString window_title = QString(\"%1 %2\").\n\t\targ(tr(\"SmuView\"), SV_VERSION_STRING);\n\tthis->setWindowTitle(window_title);\n\n\tQHBoxLayout *centralLayout = new QHBoxLayout();\n\tcentralLayout->setContentsMargins(2, 2, 2, 2);\n\tcentral_widget_ = new QWidget();\n\tcentral_widget_->setLayout(centralLayout);\n\n\t// Tab Widget\n\ttab_widget_ = new QTabWidget();\n\ttab_widget_->setTabsClosable(true);\n\tconnect(tab_widget_, &QTabWidget::tabCloseRequested,\n\t\tthis, &MainWindow::on_tab_close_requested);\n\tcentralLayout->addWidget(tab_widget_);\n\n\tthis->setCentralWidget(central_widget_);\n\n\t// DeviceTreeView Dock\n\tdevices_view_ = new ui::views::DevicesView(*session_);\n\tdevices_view_->setSizePolicy(\n\t\tQSizePolicy::MinimumExpanding, QSizePolicy::Expanding);\n\n\t// A layout must be set to the central widget of the main window\n\t// before dev_dock->setWidget() is called.\n\tQDockWidget* dev_dock = new QDockWidget(devices_view_->title());\n\tdev_dock->setObjectName(\"dev_doc\");\n\tdev_dock->setAllowedAreas(Qt::AllDockWidgetAreas);\n\tdev_dock->setContextMenuPolicy(Qt::PreventContextMenu);\n\tdev_dock->setFeatures(QDockWidget::DockWidgetMovable |\n\t\tQDockWidget::DockWidgetFloatable);\n\tdev_dock->setWidget(devices_view_);\n\tthis->addDockWidget(Qt::LeftDockWidgetArea, dev_dock);\n\n\t// This fixes a qt bug. See: https://bugreports.qt.io/browse/QTBUG-65592\n\tthis->resizeDocks({dev_dock}, {40}, Qt::Horizontal);\n\n\t// SmuScript Tree Dock\n\tsmu_script_tree_view_ = new ui::views::SmuScriptTreeView(*session_);\n\n\tQDockWidget* script_dock = new QDockWidget(smu_script_tree_view_->title());\n\tscript_dock->setObjectName(\"script_dock\");\n\tscript_dock->setAllowedAreas(Qt::AllDockWidgetAreas);\n\tscript_dock->setContextMenuPolicy(Qt::PreventContextMenu);\n\tscript_dock->setFeatures(QDockWidget::DockWidgetMovable |\n\t\tQDockWidget::DockWidgetFloatable);\n\tscript_dock->setWidget(smu_script_tree_view_);\n\tthis->tabifyDockWidget(dev_dock, script_dock);\n\n\t// Select device tree dock tab\n\tdev_dock->show();\n\tdev_dock->raise();\n}\n\nvoid MainWindow::init_device_tabs()\n{\n\tif (device_manager_.user_spec_devices().empty()) {\n\t\t// Display the WelcomeTab if no DeviceTabs will be opened, because\n\t\t// without a tab in the QTabWidget the main window looks so empty...\n\t\tadd_welcome_tab();\n\t\treturn;\n\t}\n\n\tfor (const auto &device : device_manager_.user_spec_devices()) {\n\t\tadd_device_tab(device);\n\t}\n}\n\nvoid MainWindow::connect_signals()\n{\n\t// Connect error handlers\n\tconnect(session_->smu_script_runner().get(), &python::SmuScriptRunner::script_error,\n\t\tthis, &MainWindow::error_handler);\n}\n\nvoid MainWindow::save_settings()\n{\n\tQSettings settings;\n\n\tsmu_script_tree_view_->save_settings(settings);\n\n\tsettings.beginGroup(\"MainWindow\");\n\tsettings.setValue(\"geometry\", saveGeometry());\n\tsettings.setValue(\"state\", saveState());\n\tsettings.endGroup();\n}\n\nvoid MainWindow::restore_settings()\n{\n\tQSettings settings;\n\n\t// Restore main window stuff\n\tsettings.beginGroup(\"MainWindow\");\n\tif (settings.contains(\"geometry\")) {\n\t\trestoreGeometry(settings.value(\"geometry\").toByteArray());\n\t\trestoreState(settings.value(\"state\").toByteArray());\n\t}\n\telse\n\t\tresize(1000, 720);\n\tsettings.endGroup();\n}\n\nvoid MainWindow::error_handler(\n\tconst std::string &sender, const std::string &msg)\n{\n\tQMessageBox msg_box(this);\n\tmsg_box.setText(QString::fromStdString(sender));\n\tmsg_box.setInformativeText(QString::fromStdString(msg));\n\tmsg_box.setStandardButtons(QMessageBox::Ok);\n\tmsg_box.setIcon(QMessageBox::Critical);\n\tmsg_box.exec();\n}\n\nvoid MainWindow::on_tab_close_requested(int tab_index)\n{\n\tauto *tab_window = (ui::tabs::BaseTab *)tab_widget_->widget(tab_index);\n\tif (tab_window->request_close())\n\t\tremove_tab(tab_index);\n}\n\nvoid MainWindow::closeEvent(QCloseEvent *event)\n{\n\tfor (const auto &tab_window_pair : this->tab_window_map_) {\n\t\t// Call close() of the tab window to save settings (*Tab::closeEvent())\n\t\ttab_window_pair.second->close();\n\t}\n\n\tsave_settings();\n\tevent->accept();\n}\n\n} // namespace sv\n"
  },
  {
    "path": "src/mainwindow.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef MAINWINDOW_HPP\n#define MAINWINDOW_HPP\n\n#include <map>\n#include <memory>\n#include <string>\n\n#include <QCloseEvent>\n#include <QMainWindow>\n#include <QSettings>\n\nusing std::map;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass DeviceManager;\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass HardwareDevice;\n}\n\nnamespace ui {\nnamespace tabs {\nclass BaseTab;\nclass DeviceTab;\nclass SmuScriptTab;\nclass WelcomeTab;\n}\nnamespace views {\nclass DevicesView;\nclass SmuScriptTreeView;\n}\n}\n\nclass MainWindow : public QMainWindow\n{\n\tQ_OBJECT\n\npublic:\n\texplicit MainWindow(DeviceManager &device_manager,\n\t\tshared_ptr<Session> session, QWidget *parent = nullptr);\n\n\t~MainWindow();\n\n\n\tui::tabs::DeviceTab *add_device_tab(\n\t\tshared_ptr<sv::devices::BaseDevice> device);\n\tui::tabs::SmuScriptTab *add_smuscript_tab(const string &file_name);\n\tvoid remove_tab(const string &tab_id);\n\tvoid change_tab_icon(const string &tab_id, const QIcon &icon);\n\tvoid change_tab_title(const string &tab_id, const QString &title);\n\tui::tabs::BaseTab *get_tab_from_tab_id(const string &id);\n\nprivate:\n\tvoid setup_ui();\n\tvoid init_device_tabs();\n\tvoid connect_signals();\n\tvoid save_settings();\n\tvoid restore_settings();\n\tvoid add_tab(ui::tabs::BaseTab *tab_window);\n\tui::tabs::WelcomeTab *add_welcome_tab();\n\tvoid remove_tab(int tab_index);\n\n\t/** This event is handling the saving of the settings */\n\tvoid closeEvent(QCloseEvent *event) override;\n\n\tDeviceManager &device_manager_;\n\tshared_ptr<Session> session_;\n\n\tQWidget *central_widget_;\n\tui::views::DevicesView *devices_view_;\n\tui::views::SmuScriptTreeView *smu_script_tree_view_;\n\tQTabWidget *tab_widget_;\n\t/** tab_window_map_ is used to get the index of the tab in the QTabWidget */\n\tmap<string, ui::tabs::BaseTab *> tab_window_map_;\n\nprivate Q_SLOTS:\n\tvoid error_handler(const std::string &sender, const std::string &msg);\n\tvoid on_tab_close_requested(int tab_index);\n\n};\n\n} // namespace sv\n\n#endif // MAINWINDOW_HPP\n"
  },
  {
    "path": "src/python/bindings.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n#include <memory>\n#include <set>\n#include <string>\n#include <pybind11/embed.h>\n#include <pybind11/stl.h>\n\n#include \"bindings.hpp\"\n#include \"config.h\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/hardwarechannel.hpp\"\n#include \"src/channels/userchannel.hpp\"\n#include \"src/data/analogbasesignal.hpp\"\n#include \"src/data/analogsamplesignal.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/python/pystreambuf.hpp\"\n#include \"src/python/uiproxy.hpp\"\n\nusing std::set;\n\nusing namespace pybind11::literals; // for the \"\"_a\nnamespace py = pybind11;\n\n/*\n * NOTE: The documentation for the smuview module is optimized for pdoc3!\n */\n\n\nPYBIND11_EMBEDDED_MODULE(smuview, module) {\n\t// Set options for proper docstring.\n\tpy::options options;\n\toptions.enable_function_signatures();\n\toptions.disable_enum_members_docstring();\n\n\tmodule.doc() = \"The SmuView \" SV_VERSION_STRING \" Python bindings.\\n\\n\"\n\t\t\"The Python bindings are a scripting extension for SmuView to automate, \"\n\t\t\"setup and control complex or repetitive measurements, to process the \"\n\t\t\"incoming data and to create a standardized user interface for those \"\n\t\t\"measurements.\\n\\n\"\n\t\t\"The smuview module offers two default object instances: `Session` and \"\n\t\t\"`UiProxy`.\\n\"\n\t\t\"The `Session` object gives access to already connected devices or connects \"\n\t\t\"new devices. The returned device object can then be used to read data \"\n\t\t\"from the device or control the device.\\n\"\n\t\t\"The `UiProxy` object instance is used to modify the user interface, for \"\n\t\t\"example adding tabs or views.\\n\\n\"\n\t\t\"Here is a short example that connects the HP 3478A DMM via GPIB, reads \"\n\t\t\"a sample and creates the default tab for the device:\\n\"\n\t\t\"```\\n\"\n\t\t\"import smuview\\n\"\n\t\t\"import time\\n\\n\"\n\t\t\"# Connect device.\\n\"\n\t\t\"dmm_dev = Session.connect_device(\\\"hp-3478a:conn=libgpib/hp3478a\\\")[0]\\n\"\n\t\t\"# Sleep 1s to give the devices the chance to create signals.\\n\"\n\t\t\"time.sleep(1)\\n\"\n\t\t\"# Get last sample from channel P1.\\n\"\n\t\t\"sample = dmm_dev.channels()[\\\"P1\\\"].actual_signal().get_last_sample(True)\\n\"\n\t\t\"print(sample)\\n\\n\"\n\t\t\"# Add default tab for the DMM device.\\n\"\n\t\t\"UiProxy.add_device_tab(dmm_dev)\\n\"\n\t\t\"```\\n\\n\"\n\t\t\"For more example scripts, please have a look into the `smuscript` folder.\";\n\n\t// pdoc attribute to render numpy docstrings.\n\tmodule.add_object(\"__docformat__\", py::str(\"numpy\"), false);\n\t// pdoc3 dictionary for enum documentation.\n\tmodule.add_object(\"__pdoc__\", py::dict(), false);\n\n\t// NOTE: The order of initialization is very important! Otherwise types\n\t//       could be unknown when pybind11 is generating the function\n\t//       signatures.\n\tinit_Enums(module);\n\tinit_Signal(module);\n\tinit_Channel(module);\n\tinit_Configurable(module);\n\tinit_Device(module);\n\tinit_Session(module);\n\tinit_UI(module);\n\tinit_StreamBuf(module);\n}\n\nvoid init_Session(py::module &module)\n{\n\tpy::class_<sv::Session> py_session(module, \"Session\");\n\tpy_session.doc() = \"The SmuView `Session` class for accessing the actual state of the application.\";\n\tpy_session.def(\"devices\", &sv::Session::device_map,\n\t\t\"Return all connected devices.\\n\"\n\t\t\"The device id is an (in almost all cases) unique string containing the \"\n\t\t\"manufacturer, the device model name and a more or less unique idenifier \"\n\t\t\"like the devices' serial number or the connection port (e.g. `COM5`, \"\n\t\t\"`/dev/ttyUSB2`).\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Dict[str, BaseDevice]\\n\"\n\t\t\"    A Dict where the key is the device id and the value is the device object.\");\n\tpy_session.def(\"connect_device\", &sv::Session::connect_device,\n\t\tpy::arg(\"conn_str\"),\n\t\t\"Connect a new device. For some devices (like DMMs) you may want to \"\n\t\t\"wait a fixed time, until the first sample has arrived and an `AnalogSignal` \"\n\t\t\"object has been created. Example:\\n\"\n\t\t\"```\\n\"\n\t\t\"import smuview\\n\"\n\t\t\"import time\\n\\n\"\n\t\t\"# Connect device.\\n\"\n\t\t\"dmm_dev = Session.connect_device(\\\"hp-3478a:conn=libgpib/hp3478a\\\")[0]\\n\"\n\t\t\"# Sleep 1s to give the devices the chance to create signals.\\n\"\n\t\t\"time.sleep(1)\\n\"\n\t\t\"```\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"conn_str : str\\n\"\n\t\t\"    The connection string. See https://sigrok.org/wiki/Connection_parameters\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[HardwareDevice]\\n\"\n\t\t\"    A List with the newly connected device objects.\");\n\tpy_session.def(\"add_user_device\", &sv::Session::add_user_device,\n\t\t\"Create a new user device.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"UserDevice\\n\"\n\t\t\"    The created user device object.\");\n\tpy_session.def(\"remove_device\", &sv::Session::remove_device,\n\t\tpy::arg(\"device\"),\n\t\t\"Close a device and remove it from the session. This will also delete all aquired data!\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"-------\\n\"\n\t\t\"device : BaseDevice\\n\"\n\t\t\"    The device to remove.\");\n\n}\n\nvoid init_Device(py::module &module)\n{\n\tpy::class_<sv::devices::BaseDevice, std::shared_ptr<sv::devices::BaseDevice>> py_base_device(module, \"BaseDevice\");\n\tpy_base_device.doc() = \"The base class for all device types.\";\n\tpy_base_device.def(\"name\", &sv::devices::BaseDevice::name,\n\t\t\"Return the name of the device.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The name of the device.\");\n\tpy_base_device.def(\"id\", &sv::devices::BaseDevice::id,\n\t\t\"Return the unique id of the device.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the device.\");\n\tpy_base_device.def(\"channels\", &sv::devices::BaseDevice::channel_map,\n\t\t\"Return all channels of the device.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Dict[str, BaseChannel]\\n\"\n\t\t\"    A Dict where the key is the id of the channel and the value is the channel object.\");\n\tpy_base_device.def(\"configurables\", &sv::devices::BaseDevice::configurable_map,\n\t\t\"Return all configurables of the device.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Dict[str, Configurable]\\n\"\n\t\t\"    A Dict where the key is the id of the `Configurable` and the value is the `Configurable` object.\");\n\tpy_base_device.def(\"add_user_channel\", &sv::devices::BaseDevice::add_user_channel,\n\t\tpy::arg(\"channel_name\"), py::arg(\"channel_group_name\"),\n\t\t\"Add a new user channel to the device.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"channel_name : str\\n\"\n\t\t\"    The name of the new user channel.\\n\"\n\t\t\"channel_group_name : str\\n\"\n\t\t\"    The name of the channel group where to create the user channel. Can be empty.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"UserChannel\\n\"\n\t\t\"    The new user channel object.\");\n\n\tpy::class_<sv::devices::HardwareDevice, std::shared_ptr<sv::devices::HardwareDevice>> py_hardware_device(module, \"HardwareDevice\", py_base_device);\n\tpy_hardware_device.doc() = \"An actual hardware device.\";\n\n\tpy::class_<sv::devices::UserDevice, std::shared_ptr<sv::devices::UserDevice>> py_user_device(module, \"UserDevice\", py_base_device);\n\tpy_user_device.doc() = \"An user generated (virtual) device for storing custom data and showing a custom tab.\";\n}\n\nvoid init_Channel(py::module &module)\n{\n\tpy::class_<sv::channels::BaseChannel, std::shared_ptr<sv::channels::BaseChannel>> py_base_channel(module, \"BaseChannel\");\n\tpy_base_channel.doc() = \"The base class for all channel types.\";\n\tpy_base_channel.def(\"name\", &sv::channels::BaseChannel::name,\n\t\t\"Return the name of the channel.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The name of the channel.\");\n\tpy_base_channel.def(\"add_signal\",\n\t\t(shared_ptr<sv::data::BaseSignal> (sv::channels::BaseChannel::*)\n\t\t(sv::data::Quantity, set<sv::data::QuantityFlag>, sv::data::Unit, std::string))\n\t\t\t&sv::channels::BaseChannel::add_signal,\n\t\tpy::arg(\"quantity\"), py::arg(\"quantity_flags\"), py::arg(\"unit\"),\n\t\tpy::arg(\"custom_name\") = \"\",\n\t\t\"Add a new signal to the channel.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"quantity : Quantity\\n\"\n\t\t\"    The `Quantity` of the new signal.\\n\"\n\t\t\"quantity_flags : Set[QuantityFlag]\\n\"\n\t\t\"    The `QuantityFlag`s of the new signal.\\n\"\n\t\t\"unit : Unit\\n\"\n\t\t\"    The `Unit` of the new signal.\\n\"\n\t\t\"custom_name: str\\n\"\n\t\t\"    A custom name for the new signal. If empty (default), the signal name will be automatically generated.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"BaseSignal\\n\"\n\t\t\"    The new signal object.\");\n\tpy_base_channel.def(\"actual_signal\", &sv::channels::BaseChannel::actual_signal,\n\t\t\"Return the actual signal of the channel.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"BaseSignal\\n\"\n\t\t\"    The actual signal object.\");\n\tpy_base_channel.def(\"signals\", &sv::channels::BaseChannel::signals,\n\t\t\"Return all signals of the channel.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[BaseSignal]\\n\"\n\t\t\"    All signals of the channel.\");\n\n\tpy::class_<sv::channels::HardwareChannel, std::shared_ptr<sv::channels::HardwareChannel>> py_hardware_channel(module, \"HardwareChannel\", py_base_channel);\n\tpy_hardware_channel.doc() = \"An actual hardware channel\";\n\n\tpy::class_<sv::channels::UserChannel, std::shared_ptr<sv::channels::UserChannel>> py_user_channel(module, \"UserChannel\", py_base_channel);\n\tpy_user_channel.doc() = \"An user generated channel for storing custom data.\";\n\tpy_user_channel.def(\"push_sample\", &sv::channels::UserChannel::push_sample,\n\t\tpy::arg(\"sample\"), py::arg(\"timestamp\"), py::arg(\"quantity\"),\n\t\tpy::arg(\"quantity_flags\"), py::arg(\"unit\"), py::arg(\"digits\"),\n\t\tpy::arg(\"decimal_places\"),\n\t\t\"Push a single sample to the channel.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"sample : float\\n\"\n\t\t\"    The sample value.\\n\"\n\t\t\"timestamp : float\\n\"\n\t\t\"    The absolute timestamp in milliseconds.\\n\"\n\t\t\"quantity : Quantity\\n\"\n\t\t\"    The `Quantity` of the new signal.\\n\"\n\t\t\"quantity_flags : Set[QuantityFlag]\\n\"\n\t\t\"    The `QuantityFlag`s of the new signal.\\n\"\n\t\t\"unit : Unit\\n\"\n\t\t\"    The `Unit` of the new signal.\\n\"\n\t\t\"digits : int\\n\"\n\t\t\"    The total number of digits.\\n\"\n\t\t\"decimal_places : int\\n\"\n\t\t\"    The number of decimal places.\");\n}\n\nvoid init_Signal(py::module &module)\n{\n\t/*\n\t * TODO:\n\t *  - get_value_at_timestamp(): reference parameter &value\n\t */\n\n\tpy::class_<sv::data::BaseSignal, std::shared_ptr<sv::data::BaseSignal>> py_base_signal(module, \"BaseSignal\");\n\tpy_base_signal.doc() = \"The base class for all signal types.\";\n\tpy_base_signal.def(\"name\", &sv::data::BaseSignal::name,\n\t\t\"Return the name of the signal.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The name of the signal.\");\n\tpy_base_signal.def(\"set_name\", &sv::data::BaseSignal::set_name,\n\t\t\"Set a custom name for the signal.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"custom_name : str\\n\"\n\t\t\"    A custom name for the signal. If empty, the signal name will be automatically generated.\");\n\tpy_base_signal.def(\"sample_count\", &sv::data::BaseSignal::sample_count,\n\t\t\"Return the number of samples of the signal.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"int\\n\"\n\t\t\"    The number of samples.\");\n\n\tpy::class_<sv::data::AnalogTimeSignal, std::shared_ptr<sv::data::AnalogTimeSignal>> py_analog_time_signal(module, \"AnalogTimeSignal\", py_base_signal);\n\tpy_analog_time_signal.doc() = \"A signal with time-value pairs.\";\n\tpy_analog_time_signal.def(\"get_sample\", &sv::data::AnalogTimeSignal::get_sample,\n\t\tpy::arg(\"pos\"), py::arg(\"relative_time\"),\n\t\t\"Return the sample at the given position.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"pos : int\\n\"\n\t\t\"    The position/number of the sample.\\n\"\n\t\t\"relative_time : bool\\n\"\n\t\t\"    When `True`, the returned timestamp is relative to the start of the SmuView session.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Tuple[float, float]\\n\"\n\t\t\"    The sample with 1. timestamp in milliseconds and 2. the sample value.\");\n\tpy_analog_time_signal.def(\"get_last_sample\", &sv::data::AnalogTimeSignal::get_last_sample,\n\t\tpy::arg(\"relative_time\"),\n\t\t\"Return the last sample of the signal.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"relative_time : bool\\n\"\n\t\t\"    When `True`, the returned timestamp is relative to the start of the SmuView session.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Tuple[float, float]\\n\"\n\t\t\"    The sample with 1. timestamp in milliseconds and 2. the sample value.\");\n\tpy_analog_time_signal.def(\"push_sample\", &sv::data::AnalogTimeSignal::push_sample,\n\t\tpy::arg(\"sample\"), py::arg(\"timestamp\"), py::arg(\"unit_size\"),\n\t\tpy::arg(\"digits\"), py::arg(\"decimal_places\"),\n\t\t\"Push a new sample to the signal.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"sample : float or double\\n\"\n\t\t\"    The sample value.\\n\"\n\t\t\"timestamp : float\\n\"\n\t\t\"    The absolute timestamp in milliseconds.\\n\"\n\t\t\"unit_size : int\\n\"\n\t\t\"    The size of the floating point data type (float=4, double=8) for the `sample` argument.\\n\"\n\t\t\"digits : int\\n\"\n\t\t\"    The total number of digits.\\n\"\n\t\t\"decimal_places : int\\n\"\n\t\t\"    The number of decimal places.\");\n\n\tpy::class_<sv::data::AnalogSampleSignal, std::shared_ptr<sv::data::AnalogSampleSignal>> py_analog_sample_signal(module, \"AnalogSampleSignal\", py_base_signal);\n\tpy_analog_sample_signal.doc() = \"A signal with key-value pairs.\";\n\tpy_analog_sample_signal.def(\"get_sample\", &sv::data::AnalogSampleSignal::get_sample,\n\t\tpy::arg(\"pos\"),\n\t\t\"Return the sample for the given position.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"pos : int\\n\"\n\t\t\"    The position/number of the sample.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Tuple[int, float]\\n\"\n\t\t\"    The sample with 1. the key and 2. the sample value.\");\n\tpy_analog_sample_signal.def(\"push_sample\", &sv::data::AnalogSampleSignal::push_sample,\n\t\tpy::arg(\"sample\"), py::arg(\"pos\"), py::arg(\"unit_size\"),\n\t\tpy::arg(\"digits\"), py::arg(\"decimal_places\"),\n\t\t\"Push a new sample to the signal.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"sample : float or double\\n\"\n\t\t\"    The sample value.\\n\"\n\t\t\"pos : int\\n\"\n\t\t\"    The key (position) of the new sample.\\n\"\n\t\t\"unit_size : int\\n\"\n\t\t\"    The size of the floating point data type (float=4, double=8) for the `sample` argument.\\n\"\n\t\t\"digits : int\\n\"\n\t\t\"    The total number of digits.\\n\"\n\t\t\"decimal_places : int\\n\"\n\t\t\"    The number of decimal places.\");\n}\n\nvoid init_Configurable(py::module &module)\n{\n\t/*\n\t * TODO:\n\t *  - list\n\t */\n\n\tpy::class_<sv::devices::Configurable, std::shared_ptr<sv::devices::Configurable>> py_configurable(module, \"Configurable\");\n\tpy_configurable.doc() = \"A configurable for controlling a device with config keys.\";\n\tpy_configurable.def(\"name\", &sv::devices::Configurable::name,\n\t\t\"Return the name of the configurable.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The name of the configurable.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_config<bool>,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set a boolean value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : bool\\n\"\n\t\t\"    The bool value to set.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_config<int32_t>,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set an integer value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : int\\n\"\n\t\t\"    The int value to set.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_config<uint64_t>,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set an unsigned integer value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : int\\n\"\n\t\t\"    The (unsigned) int value to set.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_config<double>,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set a double value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : float\\n\"\n\t\t\"    The float value to set.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_config<std::string>,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set a string value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : str\\n\"\n\t\t\"    The string value to set.\");\n\tpy_configurable.def(\"set_config\", &sv::devices::Configurable::set_measured_quantity_config,\n\t\tpy::arg(\"config_key\"), py::arg(\"value\"),\n\t\t\"Set a measured quantity value to the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to set.\\n\"\n\t\t\"value : Tuple[Quantity, Set[QuantityFlag]]\\n\"\n\t\t\"    The measured quantity value to set.\");\n\tpy_configurable.def(\"get_bool_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tbool value;\n\t\t\tself.get_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return a boolean value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"bool\\n\"\n\t\t\"    The bool value of the config key.\");\n\tpy_configurable.def(\"get_int_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tint32_t value;\n\t\t\tself.get_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return an integer value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"int\\n\"\n\t\t\"    The int value of the config key.\");\n\tpy_configurable.def(\"get_uint_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tuint64_t value;\n\t\t\tself.get_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return an unsigned integer value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"int\\n\"\n\t\t\"    The (unsigned) int value of the config key.\");\n\tpy_configurable.def(\"get_double_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tdouble value;\n\t\t\tself.get_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return a double value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"float\\n\"\n\t\t\"    The float value of the config key.\");\n\tpy_configurable.def(\"get_string_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tstd::string value;\n\t\t\tself.get_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return a string value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The string value of the config key.\");\n\tpy_configurable.def(\"get_measured_quantity_config\",\n\t\t[](const sv::devices::Configurable &self, sv::devices::ConfigKey config_key) {\n\t\t\tsv::data::measured_quantity_t value;\n\t\t\tself.get_measured_quantity_config(config_key, value);\n\t\t\treturn value;\n\t\t},\n\t\tpy::arg(\"config_key\"),\n\t\t\"Return a measured quantity value from the given config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The `ConfigKey` to get.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"Tuple[Quantity, Set[QuantityFlag]]\\n\"\n\t\t\"    The measured quantity value of the config key.\");\n\tpy_configurable.def(\"getable_configs\", &sv::devices::Configurable::getable_configs,\n\t\t\"Return all getable config keys.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[ConfigKey]\\n\"\n\t\t\"    All getable config keys.\");\n\tpy_configurable.def(\"setable_configs\", &sv::devices::Configurable::setable_configs,\n\t\t\"Return all setable config keys.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[ConfigKey]\\n\"\n\t\t\"    All setable config keys.\");\n\tpy_configurable.def(\"listable_configs\", &sv::devices::Configurable::listable_configs,\n\t\t\"Return all listable config keys.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[ConfigKey]\\n\"\n\t\t\"    All listable config keys.\");\n}\n\nvoid init_UI(py::module &module)\n{\n\tpy::class_<sv::python::UiProxy> py_ui_proxy(module, \"UiProxy\");\n\tpy_ui_proxy.doc() = \"Helper class for accessing the UI.\";\n\tpy_ui_proxy.def(\"add_device_tab\", &sv::python::UiProxy::ui_add_device_tab,\n\t\tpy::arg(\"device\"),\n\t\t\"Add a device tab with standard view for a device to the UI.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"device : BaseDevice\\n\"\n\t\t\"    The device object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new tab or empty if the tab couldn't be added.\");\n\tpy_ui_proxy.def(\"add_data_view\", &sv::python::UiProxy::ui_add_data_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"), py::arg(\"signal\"),\n\t\t\"Add a data view for a signal to the given tab.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\"\n\t\t\"signal : AnalogTimeSignal\\n\"\n\t\t\"    The signal object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\tpy_ui_proxy.def(\"add_control_views\", &sv::python::UiProxy::ui_add_control_views,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"), py::arg(\"configurable\"),\n\t\t\"Add one or more control views for a configurable to the given tab.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\"\n\t\t\"configurable : Configurable\\n\"\n\t\t\"    The `Configurable` object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"List[str]\\n\"\n\t\t\"    A List with the ids of the new views or an empty list if no control views were added.\");\n\tpy_ui_proxy.def(\"add_time_plot_view\",  &sv::python::UiProxy::ui_add_time_plot_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"),\n\t\t\"Add a time plot view to the given tab. Use \"\n\t\t\"[`UiProxy.set_channel_to_time_plot_view()`](UiProxy.set_channel_to_time_plot_view) \"\n\t\t\"to set a channel to the plot view or use \"\n\t\t\"[`UiProxy.add_curve_to_time_plot_view()`](UiProxy.add_curve_to_time_plot_view) \"\n\t\t\"to set a signal to the plot view.\\n\"\n\t\t\"When you have set a channel to the plot, new curves will be automatically \"\n\t\t\"created, when the channel changes (e.g. for multimeters when switching \"\n\t\t\"functions).\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\tpy_ui_proxy.def(\"add_xy_plot_view\", &sv::python::UiProxy::ui_add_xy_plot_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"),\n\t\t\"Add a x/y plot view for two signals to the given tab. Use \"\n\t\t\"[`UiProxy.add_curve_to_xy_plot_view()`](UiProxy.add_curve_to_xy_plot_view) \"\n\t\t\"to add a new curve (a set of two signals) to the plot view.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\tpy_ui_proxy.def(\"add_power_panel_view\", &sv::python::UiProxy::ui_add_power_panel_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"), py::arg(\"voltage_signal\"),\n\t\tpy::arg(\"current_signal\"),\n\t\t\"Add a power panel view for a voltage and a current signal to the given tab.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\"\n\t\t\"voltage_signal : AnalogTimeSignal\\n\"\n\t\t\"    The voltage signal object.\\n\"\n\t\t\"current_signal : AnalogTimeSignal\\n\"\n\t\t\"    The current signal object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\tpy_ui_proxy.def(\"add_value_panel_view\",\n\t\t(std::string (sv::python::UiProxy::*) (const std::string &, Qt::DockWidgetArea, shared_ptr<sv::channels::BaseChannel>))\n\t\t\t&sv::python::UiProxy::ui_add_value_panel_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"), py::arg(\"channel\"),\n\t\t\"Add a value panel view for a channel to the given tab.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\"\n\t\t\"channel : BaseChannel\\n\"\n\t\t\"    The channel object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\tpy_ui_proxy.def(\"add_value_panel_view\",\n\t\t(std::string (sv::python::UiProxy::*) (const std::string &, Qt::DockWidgetArea, shared_ptr<sv::data::AnalogTimeSignal>))\n\t\t\t&sv::python::UiProxy::ui_add_value_panel_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"area\"), py::arg(\"signal\"),\n\t\t\"Add a value panel view for a signal to the given tab.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"area : DockArea\\n\"\n\t\t\"    Where to put the new view.\\n\"\n\t\t\"signal : AnalogTimeSignal\\n\"\n\t\t\"    The signal object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new view or empty if the view couldn't be added.\");\n\n\tpy_ui_proxy.def(\"add_signal_to_data_view\", &sv::python::UiProxy::ui_add_signal_to_data_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"signal\"),\n\t\t\"Add a signal to the given data view.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the data view.\\n\"\n\t\t\"signal : AnalogTimeSignal\\n\"\n\t\t\"    The signal object.\");\n\tpy_ui_proxy.def(\"set_channel_to_time_plot_view\", &sv::python::UiProxy::ui_set_channel_to_time_plot_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"channel\"),\n\t\t\"Set a channel to the given time plot view. New curves will be \"\n\t\t\"automatically created, when the channel changes (e.g. for multimeters \"\n\t\t\"when switching functions).\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the time plot view.\\n\"\n\t\t\"channel : BaseChannel\\n\"\n\t\t\"    The channel object.\");\n\tpy_ui_proxy.def(\"add_curve_to_time_plot_view\", &sv::python::UiProxy::ui_add_curve_to_time_plot_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"signal\"),\n\t\t\"Add a signal to the given time plot view.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the time plot view.\\n\"\n\t\t\"signal : AnalogTimeSignal\\n\"\n\t\t\"    The signal object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new curve or empty if the curve couldn't be added.\");\n\tpy_ui_proxy.def(\"add_curve_to_xy_plot_view\", &sv::python::UiProxy::ui_add_curve_to_xy_plot_view,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"x_signal\"),\n\t\tpy::arg(\"y_signal\"),\n\t\t\"Add x/y signals to the given x/y plot view.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the x/y plot view.\\n\"\n\t\t\"x_signal : AnalogTimeSignal\\n\"\n\t\t\"    The x signal object.\\n\"\n\t\t\"y_signal : AnalogTimeSignal\\n\"\n\t\t\"    The y signal object.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str\\n\"\n\t\t\"    The id of the new curve or empty if the curve couldn't be added.\");\n\tpy_ui_proxy.def(\"set_curve_name\", &sv::python::UiProxy::ui_set_curve_name,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"curve_id\"),\n\t\tpy::arg(\"name\"),\n\t\t\"Set the name of the given curve.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the plot view.\\n\"\n\t\t\"curve_id : str\\n\"\n\t\t\"    The id of the curve.\\n\"\n\t\t\"name : str\\n\"\n\t\t\"    The name for the curve.\");\n\tpy_ui_proxy.def(\"set_curve_color\", &sv::python::UiProxy::ui_set_curve_color,\n\t\tpy::arg(\"tab_id\"), py::arg(\"view_id\"), py::arg(\"curve_id\"),\n\t\tpy::arg(\"color\"),\n\t\t\"Set the color of the given curve.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"tab_id : str\\n\"\n\t\t\"    The id of the tab.\\n\"\n\t\t\"view_id : str\\n\"\n\t\t\"    The id of the plot view.\\n\"\n\t\t\"curve_id : str\\n\"\n\t\t\"    The id of the curve.\\n\"\n\t\t\"color : Tuple[int, int, int]\\n\"\n\t\t\"    The color for the curve as a Tuple with the RGB values.\");\n\tpy_ui_proxy.def(\"show_message_box\", &sv::python::UiProxy::ui_show_message_box,\n\t\tpy::arg(\"title\"), py::arg(\"text\"),\n\t\t\"Show a (info) message box with the given window title and text. \"\n\t\t\"Returns `True` when the Ok button was pressed.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"title : str\\n\"\n\t\t\"    The window title of the message box.\\n\"\n\t\t\"text : str\\n\"\n\t\t\"    The text to display in the message box.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"bool\\n\"\n\t\t\"    `True` when the Ok button was pressed, else `False`.\");\n\tpy_ui_proxy.def(\"show_string_input_dialog\", &sv::python::UiProxy::ui_show_string_input_dialog,\n\t\tpy::arg(\"title\"), py::arg(\"label\"), py::arg(\"value\") = \"\",\n\t\t\"Show a dialog window to get a string value from the user. It returns \"\n\t\t\"the entered string value or `None` if the Cancel button was pressed.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"title : str\\n\"\n\t\t\"    The window title of the input dialog.\\n\"\n\t\t\"label : str\\n\"\n\t\t\"    The label to display in the input dialog.\\n\"\n\t\t\"value : str\\n\"\n\t\t\"    The default value of the string.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"str or None\\n\"\n\t\t\"    The user entered string value or `None` when the Cancel button was pressed.\");\n\tpy_ui_proxy.def(\"show_double_input_dialog\", &sv::python::UiProxy::ui_show_double_input_dialog,\n\t\tpy::arg(\"title\"), py::arg(\"label\"),\n\t\tpy::arg(\"value\") = 0.0, py::arg(\"decimals\") = 1, py::arg(\"step\") = 0.1,\n\t\tpy::arg(\"min\") = std::numeric_limits<double>::min(),\n\t\tpy::arg(\"max\") = std::numeric_limits<double>::max(),\n\t\t\"Show a dialog window to get a float value from the user. It returns \"\n\t\t\"the entered float value or `None` if the Cancel button was pressed.\\n\\n\"\n\t\t\"Only has effect if the used Qt version is equal or greater than 5.10!\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"title : str\\n\"\n\t\t\"    The window title of the input dialog.\\n\"\n\t\t\"label : str\\n\"\n\t\t\"    The label to display in the input dialog.\\n\"\n\t\t\"value : float\\n\"\n\t\t\"    The default value of the float.\\n\"\n\t\t\"decimals : int\\n\"\n\t\t\"    The maximum number of decimal places the number may have. Default is 1.\\n\"\n\t\t\"step : float\\n\"\n\t\t\"    The amount by which the value can be incremented or decremented by the user.\"\n\t\t\"    Default is 0.1.\\n\"\n\t\t\"    Only has effect for Qt versions >= 5.10!\\n\"\n\t\t\"min : float\\n\"\n\t\t\"    The minimum value the user may choose.\\n\"\n\t\t\"max : float\\n\"\n\t\t\"    The maximum value the user may choose.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"float or None\\n\"\n\t\t\"    The user entered float value or `None` when the Cancel button was pressed.\");\n\tpy_ui_proxy.def(\"show_int_input_dialog\", &sv::python::UiProxy::ui_show_int_input_dialog,\n\t\tpy::arg(\"title\"), py::arg(\"label\"),\n\t\tpy::arg(\"value\") = 0, py::arg(\"step\") = 1,\n\t\tpy::arg(\"min\") = std::numeric_limits<int>::min(),\n\t\tpy::arg(\"max\") = std::numeric_limits<int>::max(),\n\t\t\"Show a dialog window to get an integer value from the user. It returns \"\n\t\t\"the entered float value or `None` if the Cancel button was pressed.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"title : str\\n\"\n\t\t\"    The window title of the input dialog.\\n\"\n\t\t\"label : str\\n\"\n\t\t\"    The label to display in the input dialog.\\n\"\n\t\t\"value : int\\n\"\n\t\t\"    The default value of the integer.\\n\"\n\t\t\"step : int\\n\"\n\t\t\"    The amount by which the value can be incremented or decremented by the user. Default is 1.\\n\"\n\t\t\"min : int\\n\"\n\t\t\"    The minimum value the user may choose.\\n\"\n\t\t\"max : int\\n\"\n\t\t\"    The maximum value the user may choose.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"int or None\\n\"\n\t\t\"    The user entered integer value or `None` when the Cancel button was pressed.\");\n}\n\nvoid init_StreamBuf(py::module &module)\n{\n\tpy::class_<sv::python::PyStreamBuf> py_stream_buf(module, \"PyStreamBuf\");\n\tpy_stream_buf.doc() = \"Redirect all Python output to a SmuView console. This class is for internal SmuView use only!\";\n\tpy_stream_buf.def(py::init<const std::string &, const std::string &>());\n\tpy_stream_buf.def(\"close\", &sv::python::PyStreamBuf::py_close,\n\t\t\"Flush and close this stream.\");\n\tpy_stream_buf.def(\"fileno\", &sv::python::PyStreamBuf::py_fileno,\n\t\t\"Raises an `OSError`, because `PyStreamBuf` doesn't use a file descriptor.\");\n\tpy_stream_buf.def(\"flush\", &sv::python::PyStreamBuf::py_flush,\n\t\t\"Flush the write buffers of the stream.\");\n\tpy_stream_buf.def(\"isatty\", &sv::python::PyStreamBuf::py_isatty,\n\t\t\"Always returns `False`.\");\n\tpy_stream_buf.def(\"readable\", &sv::python::PyStreamBuf::py_readable,\n\t\t\"Always returns `False`.\");\n\tpy_stream_buf.def(\"readlines\", &sv::python::PyStreamBuf::py_readlines,\n\t\tpy::arg(\"hint\"),\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is write only.\");\n\tpy_stream_buf.def(\"seekable\", &sv::python::PyStreamBuf::py_seekable,\n\t\t\"Always returns `False`. `PyStreamBuf` is not seekable atm.\");\n\tpy_stream_buf.def(\"truncate\", &sv::python::PyStreamBuf::py_truncate,\n\t\tpy::arg(\"size\"),\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is not seekable.\");\n\tpy_stream_buf.def(\"writable\", &sv::python::PyStreamBuf::py_writable,\n\t\t\"Always return `True`.\");\n\tpy_stream_buf.def(\"writelines\", &sv::python::PyStreamBuf::py_writelines,\n\t\tpy::arg(\"lines\"),\n\t\t\"Write a list of lines to the stream.\");\n\tpy_stream_buf.def(\"__del__\", &sv::python::PyStreamBuf::py_del,\n\t\t\"Prepare for object destruction.\");\n\tpy_stream_buf.def(\"read\", &sv::python::PyStreamBuf::py_read,\n\t\tpy::arg(\"size\"),\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is write only.\");\n\tpy_stream_buf.def(\"readline\", &sv::python::PyStreamBuf::py_readline,\n\t\tpy::arg(\"size\"),\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is write only.\");\n\tpy_stream_buf.def(\"seek\", &sv::python::PyStreamBuf::py_seek,\n\t\tpy::arg(\"offset\"), py::arg(\"whence\"),\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is not seekable.\");\n\tpy_stream_buf.def(\"tell\", &sv::python::PyStreamBuf::py_tell,\n\t\t\"Raises an `OSError`, because `PyStreamBuf` is not seekable.\");\n\tpy_stream_buf.def(\"write\", &sv::python::PyStreamBuf::py_write,\n\t\tpy::arg(\"s\"),\n\t\t\"Write the string `s` to the stream and return the number of characters written.\");\n\tpy_stream_buf.def_readonly(\"closed\", &sv::python::PyStreamBuf::py_closed,\n\t\t\"`True` if the stream is closed.\");\n\tpy_stream_buf.def_readonly(\"encoding\", &sv::python::PyStreamBuf::py_encoding,\n\t\t\"The name of the encoding that is used.\");\n\tpy_stream_buf.def_readonly(\"errors\", &sv::python::PyStreamBuf::py_errors,\n\t\t\"The error setting of the decoder or encoder.\");\n}\n\nvoid init_Enums(py::module &module)\n{\n\tpy::enum_<sv::data::DataType> py_data_type(module, \"DataType\",\n\t\t\"Enum of all available data types.\");\n\tpy_data_type.value(\"UInt64\", sv::data::DataType::UInt64);\n\tmodule.attr(\"__pdoc__\")[\"DataType.UInt64\"] = \"UInt64\";\n\tpy_data_type.value(\"String\", sv::data::DataType::String);\n\tmodule.attr(\"__pdoc__\")[\"DataType.String\"] = \"String\";\n\tpy_data_type.value(\"Bool\", sv::data::DataType::Bool);\n\tmodule.attr(\"__pdoc__\")[\"DataType.Bool\"] = \"Bool\";\n\tpy_data_type.value(\"Double\", sv::data::DataType::Double);\n\tmodule.attr(\"__pdoc__\")[\"DataType.Double\"] = \"Double\";\n\tpy_data_type.value(\"RationalPeriod\", sv::data::DataType::RationalPeriod);\n\tmodule.attr(\"__pdoc__\")[\"DataType.RationalPeriod\"] = \"RationalPeriod\";\n\tpy_data_type.value(\"RationalVolt\", sv::data::DataType::RationalVolt);\n\tmodule.attr(\"__pdoc__\")[\"DataType.RationalVolt\"] = \"RationalVolt\";\n\tpy_data_type.value(\"KeyValue\", sv::data::DataType::KeyValue);\n\tmodule.attr(\"__pdoc__\")[\"DataType.KeyValue\"] = \"KeyValue\";\n\tpy_data_type.value(\"UInt64Range\", sv::data::DataType::UInt64Range);\n\tmodule.attr(\"__pdoc__\")[\"DataType.UInt64Range\"] = \"UInt64Range\";\n\tpy_data_type.value(\"DoubleRange\", sv::data::DataType::DoubleRange);\n\tmodule.attr(\"__pdoc__\")[\"DataType.DoubleRange\"] = \"DoubleRange\";\n\tpy_data_type.value(\"Int32\", sv::data::DataType::Int32);\n\tmodule.attr(\"__pdoc__\")[\"DataType.Int32\"] = \"Int32\";\n\tpy_data_type.value(\"MQ\", sv::data::DataType::MQ);\n\tmodule.attr(\"__pdoc__\")[\"DataType.MQ\"] = \"MQ\";\n\tpy_data_type.value(\"Unknown\", sv::data::DataType::Unknown);\n\tmodule.attr(\"__pdoc__\")[\"DataType.Unknown\"] = \"Unknown\";\n\n\tpy::enum_<sv::devices::ConfigKey> py_config_key(module, \"ConfigKey\",\n\t\t\"Enum of all available config keys for controlling a device.\");\n\tpy_config_key.value(\"Samplerate\", sv::devices::ConfigKey::Samplerate);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Samplerate\"] = \"The samplerate, in Hz.\";\n\tpy_config_key.value(\"CaptureRatio\", sv::devices::ConfigKey::CaptureRatio);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.CaptureRatio\"] = \"The pre/post-trigger capture ratio.\";\n\tpy_config_key.value(\"PatternMode\", sv::devices::ConfigKey::PatternMode);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.PatternMode\"] = \"A pattern (pattern generator mode).\";\n\tpy_config_key.value(\"RLE\", sv::devices::ConfigKey::RLE);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.RLE\"] = \"Run-length encoding (RLE).\";\n\tpy_config_key.value(\"TriggerSlope\", sv::devices::ConfigKey::TriggerSlope);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TriggerSlope\"] = \"The trigger slope.\";\n\tpy_config_key.value(\"Averaging\", sv::devices::ConfigKey::Averaging);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Averaging\"] = \"Averaging.\";\n\tpy_config_key.value(\"AvgSamples\", sv::devices::ConfigKey::AvgSamples);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.AvgSamples\"] = \"The number of samples to be averaged over.\";\n\tpy_config_key.value(\"TriggerSource\", sv::devices::ConfigKey::TriggerSource);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TriggerSource\"] = \"Trigger source.\";\n\tpy_config_key.value(\"HorizTriggerPos\", sv::devices::ConfigKey::HorizTriggerPos);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.HorizTriggerPos\"] = \"Horizontal trigger position.\";\n\tpy_config_key.value(\"BufferSize\", sv::devices::ConfigKey::BufferSize);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.BufferSize\"] = \"Buffer size.\";\n\tpy_config_key.value(\"TimeBase\", sv::devices::ConfigKey::TimeBase);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TimeBase\"] = \"Time base.\";\n\tpy_config_key.value(\"Filter\", sv::devices::ConfigKey::Filter);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Filter\"] = \"Filter.\";\n\tpy_config_key.value(\"VDiv\", sv::devices::ConfigKey::VDiv);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.VDiv\"] = \"Volts/div.\";\n\tpy_config_key.value(\"Coupling\", sv::devices::ConfigKey::Coupling);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Coupling\"] = \"Coupling.\";\n\tpy_config_key.value(\"TriggerMatch\", sv::devices::ConfigKey::TriggerMatch);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TriggerMatch\"] = \"Trigger matches.\";\n\tpy_config_key.value(\"SampleInterval\", sv::devices::ConfigKey::SampleInterval);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.SampleInterval\"] = \"The sample interval, in ms.\";\n\tpy_config_key.value(\"NumHDiv\", sv::devices::ConfigKey::NumHDiv);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.NumHDiv\"] = \"Number of horizontal divisions, as related to `ConfigKey.TimeBase`.\";\n\tpy_config_key.value(\"NumVDiv\", sv::devices::ConfigKey::NumVDiv);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.NumVDiv\"] = \"Number of vertical divisions, as related to `ConfigKey.VDiv`.\";\n\tpy_config_key.value(\"SplWeightFreq\", sv::devices::ConfigKey::SplWeightFreq);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.SplWeightFreq\"] = \"Sound pressure level frequency weighting.\";\n\tpy_config_key.value(\"SplWeightTime\", sv::devices::ConfigKey::SplWeightTime);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.SplWeightTime\"] = \"Sound pressure level time weighting.\";\n\tpy_config_key.value(\"SplMeasurementRange\", sv::devices::ConfigKey::SplMeasurementRange);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.SplMeasurementRange\"] = \"Sound pressure level measurement range.\";\n\tpy_config_key.value(\"HoldMax\", sv::devices::ConfigKey::HoldMax);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.HoldMax\"] = \"Max hold mode.\";\n\tpy_config_key.value(\"HoldMin\", sv::devices::ConfigKey::HoldMin);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.HoldMin\"] = \"Min hold mode.\";\n\tpy_config_key.value(\"VoltageThreshold\", sv::devices::ConfigKey::VoltageThreshold);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.VoltageThreshold\"] = \"Logic low-high threshold range.\";\n\tpy_config_key.value(\"ExternalClock\", sv::devices::ConfigKey::ExternalClock);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ExternalClock\"] = \"Using an external clock.\";\n\tpy_config_key.value(\"Swap\", sv::devices::ConfigKey::Swap);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Swap\"] = \"Swapping channels.\";\n\tpy_config_key.value(\"CenterFrequency\", sv::devices::ConfigKey::CenterFrequency);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.CenterFrequency\"] = \"Center frequency.\";\n\tpy_config_key.value(\"NumLogicChannels\", sv::devices::ConfigKey::NumLogicChannels);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.NumLogicChannels\"] = \"The number of logic channels.\";\n\tpy_config_key.value(\"NumAnalogChannels\", sv::devices::ConfigKey::NumAnalogChannels);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.NumAnalogChannels\"] = \"The number of analog channels.\";\n\tpy_config_key.value(\"Voltage\", sv::devices::ConfigKey::Voltage);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Voltage\"] = \"Current voltage.\";\n\tpy_config_key.value(\"VoltageTarget\", sv::devices::ConfigKey::VoltageTarget);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.VoltageTarget\"] = \"Maximum target voltage.\";\n\tpy_config_key.value(\"Current\", sv::devices::ConfigKey::Current);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Current\"] = \"Current current.\";\n\tpy_config_key.value(\"CurrentLimit\", sv::devices::ConfigKey::CurrentLimit);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.CurrentLimit\"] = \"Current limit.\";\n\tpy_config_key.value(\"Enabled\", sv::devices::ConfigKey::Enabled);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Enabled\"] = \"Enabling/disabling a channel (group).\";\n\tpy_config_key.value(\"ChannelConfig\", sv::devices::ConfigKey::ChannelConfig);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ChannelConfig\"] = \"Channel configuration.\";\n\tpy_config_key.value(\"OverVoltageProtectionEnabled\", sv::devices::ConfigKey::OverVoltageProtectionEnabled);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverVoltageProtectionEnabled\"] = \"Enabling/disable over voltage protection (OVP) feature.\";\n\tpy_config_key.value(\"OverVoltageProtectionActive\", sv::devices::ConfigKey::OverVoltageProtectionActive);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverVoltageProtectionActive\"] = \"Status of over voltage protection (OVP).\";\n\tpy_config_key.value(\"OverVoltageProtectionThreshold\", sv::devices::ConfigKey::OverVoltageProtectionThreshold);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverVoltageProtectionThreshold\"] = \"Over voltage protection (OVP) threshold.\";\n\tpy_config_key.value(\"OverCurrentProtectionEnabled\", sv::devices::ConfigKey::OverCurrentProtectionEnabled);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverCurrentProtectionEnabled\"] = \"Enabling/disable  over current protection (OCP) feature.\";\n\tpy_config_key.value(\"OverCurrentProtectionActive\", sv::devices::ConfigKey::OverCurrentProtectionActive);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverCurrentProtectionActive\"] = \"Status of over current protection (OCP).\";\n\tpy_config_key.value(\"OverCurrentProtectionThreshold\", sv::devices::ConfigKey::OverCurrentProtectionThreshold);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverCurrentProtectionThreshold\"] = \"Over current protection (OCP) threshold.\";\n\tpy_config_key.value(\"OverTemperatureProtectionEnabled\", sv::devices::ConfigKey::OverTemperatureProtectionEnabled);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverTemperatureProtectionEnabled\"] = \"Enabling/disable over temperature protection (OTP) feature.\";\n\tpy_config_key.value(\"OverTemperatureProtectionActive\", sv::devices::ConfigKey::OverTemperatureProtectionActive);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OverTemperatureProtectionActive\"] = \"Status of over temperature protection (OTP).\";\n\tpy_config_key.value(\"UnderVoltageConditionEnabled\", sv::devices::ConfigKey::UnderVoltageConditionEnabled);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.UnderVoltageConditionEnabled\"] = \"Enabling/disable under voltage condition (UVC) feature.\";\n\tpy_config_key.value(\"UnderVoltageConditionActive\", sv::devices::ConfigKey::UnderVoltageConditionActive);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.UnderVoltageConditionActive\"] = \"Status of under voltage condition (UVC).\";\n\tpy_config_key.value(\"UnderVoltageConditionThreshold\", sv::devices::ConfigKey::UnderVoltageConditionThreshold);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.UnderVoltageConditionThreshold\"] = \"Under voltage condition threshold (UVC).\";\n\tpy_config_key.value(\"ClockEdge\", sv::devices::ConfigKey::ClockEdge);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ClockEdge\"] = \"Choice of clock edge for external clock (``r`` or ``f``).\";\n\tpy_config_key.value(\"Amplitude\", sv::devices::ConfigKey::Amplitude);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Amplitude\"] = \"Amplitude of a source without strictly-defined `ConfigKey.MeasuredQuantity`.\";\n\tpy_config_key.value(\"Regulation\", sv::devices::ConfigKey::Regulation);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Regulation\"] =\n\t\t\"Channel regulation. ``CV``, ``CC`` or ``UR``, denoting constant voltage, constant current or \"\n\t\t\"unregulated. ``CC-`` denotes a power supply in current sink mode (e.g. HP 66xxB). An empty \"\n\t\t\"string is used when there is no regulation, e.g. the output is disabled.\";\n\tpy_config_key.value(\"OutputFrequency\", sv::devices::ConfigKey::OutputFrequency);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OutputFrequency\"] = \"Output frequency in Hz.\";\n\tpy_config_key.value(\"OutputFrequencyTarget\", sv::devices::ConfigKey::OutputFrequencyTarget);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.OutputFrequencyTarget\"] = \"Output frequency target in Hz.\";\n\tpy_config_key.value(\"MeasuredQuantity\", sv::devices::ConfigKey::MeasuredQuantity);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.MeasuredQuantity\"] = \"Measured quantity.\";\n\tpy_config_key.value(\"EquivCircuitModel\", sv::devices::ConfigKey::EquivCircuitModel);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.EquivCircuitModel\"] = \"Equivalent circuit model.\";\n\tpy_config_key.value(\"TriggerLevel\", sv::devices::ConfigKey::TriggerLevel);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TriggerLevel\"] = \"Trigger level.\";\n\tpy_config_key.value(\"ExternalClockSource\", sv::devices::ConfigKey::ExternalClockSource);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ExternalClockSource\"] =\n\t\t\"Which external clock source to use if the device supports multiple external clock channels.\";\n\tpy_config_key.value(\"Offset\", sv::devices::ConfigKey::Offset);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Offset\"] =\n\t\t\"Offset of a source without strictly-defined `ConfigKey.MeasuredQuantity`.\";\n\tpy_config_key.value(\"TriggerPattern\", sv::devices::ConfigKey::TriggerPattern);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TriggerPattern\"] = \"The pattern for the logic trigger.\";\n\tpy_config_key.value(\"HighResolution\", sv::devices::ConfigKey::HighResolution);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.HighResolution\"] = \"High resolution mode.\";\n\tpy_config_key.value(\"PeakDetection\", sv::devices::ConfigKey::PeakDetection);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.PeakDetection\"] = \"Peak detection.\";\n\tpy_config_key.value(\"LogicThreshold\", sv::devices::ConfigKey::LogicThreshold);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.LogicThreshold\"] =\n\t\t\"Logic threshold: predefined levels (``TTL``, ``ECL``, ``CMOS``, etc).\";\n\tpy_config_key.value(\"LogicThresholdCustom\", sv::devices::ConfigKey::LogicThresholdCustom);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.LogicThresholdCustom\"] = \"Logic threshold: custom numerical value.\";\n\tpy_config_key.value(\"Range\", sv::devices::ConfigKey::Range);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Range\"] =\n\t\t\"The measurement range of a DMM or the output range of a power supply.\";\n\tpy_config_key.value(\"Digits\", sv::devices::ConfigKey::Digits);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Digits\"] = \"The number of digits (e.g. for a DMM).\";\n\tpy_config_key.value(\"SessionFile\", sv::devices::ConfigKey::SessionFile);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.SessionFile\"] = \"Session filename.\";\n\tpy_config_key.value(\"CaptureFile\", sv::devices::ConfigKey::CaptureFile);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.CaptureFile\"] = \"The capturefile to inject.\";\n\tpy_config_key.value(\"CaptureUnitSize\", sv::devices::ConfigKey::CaptureUnitSize);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.CaptureUnitSize\"] = \"The capturefile unit size.\";\n\tpy_config_key.value(\"PowerOff\", sv::devices::ConfigKey::PowerOff);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.PowerOff\"] = \"Power off the device.\";\n\tpy_config_key.value(\"DataSource\", sv::devices::ConfigKey::DataSource);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.DataSource\"] = \"Data source for acquisition.\";\n\tpy_config_key.value(\"ProbeFactor\", sv::devices::ConfigKey::ProbeFactor);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ProbeFactor\"] = \"The probe factor.\";\n\tpy_config_key.value(\"ADCPowerlineCycles\", sv::devices::ConfigKey::ADCPowerlineCycles);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.ADCPowerlineCycles\"] = \"Number of powerline cycles for ADC integration time.\";\n\tpy_config_key.value(\"DataLog\", sv::devices::ConfigKey::DataLog);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.DataLog\"] = \"The device has internal storage, into which data is logged.\";\n\tpy_config_key.value(\"DeviceMode\", sv::devices::ConfigKey::DeviceMode);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.DeviceMode\"] = \"Device mode for multi-function devices.\";\n\tpy_config_key.value(\"TestMode\", sv::devices::ConfigKey::TestMode);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.TestMode\"] = \"Self test mode.\";\n\tpy_config_key.value(\"Unknown\", sv::devices::ConfigKey::Unknown);\n\tmodule.attr(\"__pdoc__\")[\"ConfigKey.Unknown\"] = \"Unknown config key.\";\n\tpy_config_key.def_static(\"get_data_type\", &sv::devices::deviceutil::get_data_type_for_config_key,\n\t\tpy::arg(\"config_key\"),\n\t\t\"Helper function to get the data type for a config key.\\n\\n\"\n\t\t\"Parameters\\n\"\n\t\t\"----------\\n\"\n\t\t\"config_key : ConfigKey\\n\"\n\t\t\"    The config key.\\n\\n\"\n\t\t\"Returns\\n\"\n\t\t\"-------\\n\"\n\t\t\"DataType\\n\"\n\t\t\"    The data type of the config key.\");\n\n\tpy::enum_<sv::data::Quantity> py_quantity(module, \"Quantity\",\n\t\t\"Enum of all available quantities.\");\n\tpy_quantity.value(\"Voltage\", sv::data::Quantity::Voltage);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Voltage\"] = \"Voltage\";\n\tpy_quantity.value(\"Current\", sv::data::Quantity::Current);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Current\"] = \"Current\";\n\tpy_quantity.value(\"Resistance\", sv::data::Quantity::Resistance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Resistance\"] = \"Resistance\";\n\tpy_quantity.value(\"Capacitance\", sv::data::Quantity::Capacitance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Capacitance\"] = \"Capacitance\";\n\tpy_quantity.value(\"Temperature\", sv::data::Quantity::Temperature);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Temperature\"] = \"Temperature\";\n\tpy_quantity.value(\"Frequency\", sv::data::Quantity::Frequency);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Frequency\"] = \"Frequency\";\n\tpy_quantity.value(\"DutyCyle\", sv::data::Quantity::DutyCyle);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.DutyCyle\"] = \"DutyCyle\";\n\tpy_quantity.value(\"Continuity\", sv::data::Quantity::Continuity);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Continuity\"] = \"Continuity\";\n\tpy_quantity.value(\"PulseWidth\", sv::data::Quantity::PulseWidth);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.PulseWidth\"] = \"PulseWidth\";\n\tpy_quantity.value(\"Conductance\", sv::data::Quantity::Conductance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Conductance\"] = \"Conductance\";\n\tpy_quantity.value(\"Power\", sv::data::Quantity::Power);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Power\"] = \"Electrical power, usually in W, or dBm.\";\n\tpy_quantity.value(\"ElectricCharge\", sv::data::Quantity::ElectricCharge);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.ElectricCharge\"] = \"Electric charge\";\n\tpy_quantity.value(\"Gain\", sv::data::Quantity::Gain);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Gain\"] = \"Gain (a transistor's gain, or hFE, for example).\";\n\tpy_quantity.value(\"SoundPressureLevel\", sv::data::Quantity::SoundPressureLevel);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.SoundPressureLevel\"] =\n\t\t\"Logarithmic representation of sound pressure relative to a reference value.\";\n\tpy_quantity.value(\"CarbonMonoxide\", sv::data::Quantity::CarbonMonoxide);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.CarbonMonoxide\"] = \"Carbon monoxide\";\n\tpy_quantity.value(\"RelativeHumidity\", sv::data::Quantity::RelativeHumidity);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.RelativeHumidity\"] = \"Relative humidity\";\n\tpy_quantity.value(\"Time\", sv::data::Quantity::Time);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Time\"] = \"Time\";\n\tpy_quantity.value(\"WindSpeed\", sv::data::Quantity::WindSpeed);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.WindSpeed\"] = \"Wind speed\";\n\tpy_quantity.value(\"Pressure\", sv::data::Quantity::Pressure);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Pressure\"] = \"Pressure\";\n\tpy_quantity.value(\"ParallelInductance\", sv::data::Quantity::ParallelInductance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.ParallelInductance\"] = \"Parallel inductance\";\n\tpy_quantity.value(\"ParallelCapacitance\", sv::data::Quantity::ParallelCapacitance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.ParallelCapacitance\"] = \"Parallel capacitance\";\n\tpy_quantity.value(\"ParallelResistance\", sv::data::Quantity::ParallelResistance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.ParallelResistance\"] = \"Parallel resistance\";\n\tpy_quantity.value(\"SeriesInductance\", sv::data::Quantity::SeriesInductance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.SeriesInductance\"] = \"Series inductance\";\n\tpy_quantity.value(\"SeriesCapacitance\", sv::data::Quantity::SeriesCapacitance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.SeriesCapacitance\"] = \"Series capacitance\";\n\tpy_quantity.value(\"SeriesResistance\", sv::data::Quantity::SeriesResistance);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.SeriesResistance\"] = \"Series resistance\";\n\tpy_quantity.value(\"DissipationFactor\", sv::data::Quantity::DissipationFactor);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.DissipationFactor\"] = \"Dissipation factor\";\n\tpy_quantity.value(\"QualityFactor\", sv::data::Quantity::QualityFactor);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.QualityFactor\"] = \"Quality factor\";\n\tpy_quantity.value(\"PhaseAngle\", sv::data::Quantity::PhaseAngle);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.PhaseAngle\"] = \"Phase angle\";\n\tpy_quantity.value(\"Difference\", sv::data::Quantity::Difference);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Difference\"] = \"Difference from reference value.\";\n\tpy_quantity.value(\"Count\", sv::data::Quantity::Count);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Count\"] = \"Count\";\n\tpy_quantity.value(\"PowerFactor\", sv::data::Quantity::PowerFactor);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.PowerFactor\"] = \"Power factor\";\n\tpy_quantity.value(\"ApparentPower\", sv::data::Quantity::ApparentPower);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.ApparentPower\"] = \"Apparent power\";\n\tpy_quantity.value(\"Mass\", sv::data::Quantity::Mass);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Mass\"] = \"Mass\";\n\tpy_quantity.value(\"HarmonicRatio\", sv::data::Quantity::HarmonicRatio);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.HarmonicRatio\"] = \"Harmonic ratio\";\n\tpy_quantity.value(\"Energy\", sv::data::Quantity::Energy);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Energy\"] = \"Energy (also Work)\";\n\tpy_quantity.value(\"Unknown\", sv::data::Quantity::Unknown);\n\tmodule.attr(\"__pdoc__\")[\"Quantity.Unknown\"] = \"Unknown\";\n\n\tpy::enum_<sv::data::QuantityFlag> py_quantity_flag(module, \"QuantityFlag\",\n\t\t\"Enum of all available quantity flags.\");\n\tpy_quantity_flag.value(\"AC\", sv::data::QuantityFlag::AC);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.AC\"] = \"Alternating current.\";\n\tpy_quantity_flag.value(\"DC\", sv::data::QuantityFlag::DC);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.DC\"] = \"Direct current.\";\n\tpy_quantity_flag.value(\"RMS\", sv::data::QuantityFlag::RMS);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.RMS\"] = \"Root mean square (RMS).\";\n\tpy_quantity_flag.value(\"Diode\", sv::data::QuantityFlag::Diode);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Diode\"] = \"Value is voltage drop across a diode, or NAN.\";\n\tpy_quantity_flag.value(\"Hold\", sv::data::QuantityFlag::Hold);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Hold\"] = \"Device is in hold mode (repeating the last measurement).\";\n\tpy_quantity_flag.value(\"Max\", sv::data::QuantityFlag::Max);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Max\"] = \"Device is in max mode, only updating upon a new max value.\";\n\tpy_quantity_flag.value(\"Min\", sv::data::QuantityFlag::Min);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Min\"] = \"Device is in min mode, only updating upon a new min value.\";\n\tpy_quantity_flag.value(\"Autorange\", sv::data::QuantityFlag::Autorange);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Autorange\"] = \"Device is in autoranging mode.\";\n\tpy_quantity_flag.value(\"Relative\", sv::data::QuantityFlag::Relative);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Relative\"] = \"Device is in relative mode.\";\n\tpy_quantity_flag.value(\"SplFreqWeightA\", sv::data::QuantityFlag::SplFreqWeightA);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplFreqWeightA\"] =\n\t\t\"Sound pressure level is A-weighted in the frequency domain, according to IEC 61672:2003.\";\n\tpy_quantity_flag.value(\"SplFreqWeightC\", sv::data::QuantityFlag::SplFreqWeightC);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplFreqWeightC\"] =\n\t\t\"Sound pressure level is C-weighted in the frequency domain, according to IEC 61672:2003.\";\n\tpy_quantity_flag.value(\"SplFreqWeightZ\", sv::data::QuantityFlag::SplFreqWeightZ);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplFreqWeightZ\"] = \"Sound pressure level is Z-weighted.\";\n\tpy_quantity_flag.value(\"SplFreqWeightFlat\", sv::data::QuantityFlag::SplFreqWeightFlat);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplFreqWeightFlat\"] =\n\t\t\"Sound pressure level is not weighted in the frequency domain, albeit \"\n\t\t\"without standards-defined low and high frequency limits.\";\n\tpy_quantity_flag.value(\"SplTimeWeightS\", sv::data::QuantityFlag::SplTimeWeightS);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplTimeWeightS\"] =\n\t\t\"Sound pressure level measurement is S-weighted (1s) in the time domain.\";\n\tpy_quantity_flag.value(\"SplTimeWeightF\", sv::data::QuantityFlag::SplTimeWeightF);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplTimeWeightF\"] =\n\t\t\"Sound pressure level measurement is F-weighted (125ms) in the time domain.\";\n\tpy_quantity_flag.value(\"SplLAT\", sv::data::QuantityFlag::SplLAT);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplLAT\"] =\n\t\t\"Sound pressure level is time-averaged (LAT), also known as Equivalent Continuous A-weighted Sound Level (LEQ).\";\n\tpy_quantity_flag.value(\"SplPctOverAlarm\", sv::data::QuantityFlag::SplPctOverAlarm);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.SplPctOverAlarm\"] =\n\t\t\"Sound pressure level represented as a percentage of measurements that were over a preset alarm level.\";\n\tpy_quantity_flag.value(\"Duration\", sv::data::QuantityFlag::Duration);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Duration\"] = \"Time is duration (as opposed to epoch, ...).\";\n\tpy_quantity_flag.value(\"Avg\", sv::data::QuantityFlag::Avg);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Avg\"] = \"Device is in average mode, averaging upon each new value.\";\n\tpy_quantity_flag.value(\"Reference\", sv::data::QuantityFlag::Reference);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Reference\"] = \"Reference value shown.\";\n\tpy_quantity_flag.value(\"Unstable\", sv::data::QuantityFlag::Unstable);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Unstable\"] = \"Unstable value (hasn't settled yet).\";\n\tpy_quantity_flag.value(\"FourWire\", sv::data::QuantityFlag::FourWire);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.FourWire\"] = \"Device is in 4-wire mode.\";\n\tpy_quantity_flag.value(\"Unknown\", sv::data::QuantityFlag::Unknown);\n\tmodule.attr(\"__pdoc__\")[\"QuantityFlag.Unknown\"] = \"Unknown quantity flag.\";\n\n\tpy::enum_<sv::data::Unit> py_unit(module, \"Unit\", \"Enum of all available units.\");\n\tpy_unit.value(\"Volt\", sv::data::Unit::Volt);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Volt\"] = \"Volt\";\n\tpy_unit.value(\"Ampere\", sv::data::Unit::Ampere);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Ampere\"] = \"Ampere\";\n\tpy_unit.value(\"Ohm\", sv::data::Unit::Ohm);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Ohm\"] = \"Ohm\";\n\tpy_unit.value(\"Farad\", sv::data::Unit::Farad);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Farad\"] = \"Farad\";\n\tpy_unit.value(\"Kelvin\", sv::data::Unit::Kelvin);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Kelvin\"] = \"Kelvin\";\n\tpy_unit.value(\"Celsius\", sv::data::Unit::Celsius);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Celsius\"] = \"Celsius\";\n\tpy_unit.value(\"Fahrenheit\", sv::data::Unit::Fahrenheit);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Fahrenheit\"] = \"Fahrenheit\";\n\tpy_unit.value(\"Hertz\", sv::data::Unit::Hertz);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Hertz\"] = \"Hertz\";\n\tpy_unit.value(\"Percentage\", sv::data::Unit::Percentage);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Percentage\"] = \"Percentage\";\n\tpy_unit.value(\"Boolean\", sv::data::Unit::Boolean);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Boolean\"] = \"Boolean\";\n\tpy_unit.value(\"Second\", sv::data::Unit::Second);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Second\"] = \"Second\";\n\tpy_unit.value(\"Siemens\", sv::data::Unit::Siemens);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Siemens\"] = \"Siemens\";\n\tpy_unit.value(\"DecibelMW\", sv::data::Unit::DecibelMW);\n\tmodule.attr(\"__pdoc__\")[\"Unit.DecibelMW\"] = \"Decibel milliWatt (dBm)\";\n\tpy_unit.value(\"DecibelVolt\", sv::data::Unit::DecibelVolt);\n\tmodule.attr(\"__pdoc__\")[\"Unit.DecibelVolt\"] = \"Decibel Volt (dBV)\";\n\tpy_unit.value(\"Unitless\", sv::data::Unit::Unitless);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Unitless\"] = \"Unitless\";\n\tpy_unit.value(\"DecibelSpl\", sv::data::Unit::DecibelSpl);\n\tmodule.attr(\"__pdoc__\")[\"Unit.DecibelSpl\"] = \"Decibel sound pressure level\";\n\tpy_unit.value(\"Concentration\", sv::data::Unit::Concentration);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Concentration\"] = \"Concentration\";\n\tpy_unit.value(\"RevolutionsPerMinute\", sv::data::Unit::RevolutionsPerMinute);\n\tmodule.attr(\"__pdoc__\")[\"Unit.RevolutionsPerMinute\"] = \"Revolutions per minute (RPM)\";\n\tpy_unit.value(\"VoltAmpere\", sv::data::Unit::VoltAmpere);\n\tmodule.attr(\"__pdoc__\")[\"Unit.VoltAmpere\"] = \"VoltAmpere (VA)\";\n\tpy_unit.value(\"Watt\", sv::data::Unit::Watt);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Watt\"] = \"Watt\";\n\tpy_unit.value(\"WattHour\", sv::data::Unit::WattHour);\n\tmodule.attr(\"__pdoc__\")[\"Unit.WattHour\"] = \"WattHour (Wh)\";\n\tpy_unit.value(\"MeterPerSecond\", sv::data::Unit::MeterPerSecond);\n\tmodule.attr(\"__pdoc__\")[\"Unit.MeterPerSecond\"] = \"Meter per second (m/s)\";\n\tpy_unit.value(\"HectoPascal\", sv::data::Unit::HectoPascal);\n\tmodule.attr(\"__pdoc__\")[\"Unit.HectoPascal\"] = \"HectoPascal (hPa)\";\n\tpy_unit.value(\"Humidity293K\", sv::data::Unit::Humidity293K);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Humidity293K\"] = \"Humidity at 293K\";\n\tpy_unit.value(\"Degree\", sv::data::Unit::Degree);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Degree\"] = \"Degree\";\n\tpy_unit.value(\"Henry\", sv::data::Unit::Henry);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Henry\"] = \"Henry\";\n\tpy_unit.value(\"Gram\", sv::data::Unit::Gram);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Gram\"] = \"Weight in gram (g).\";\n\tpy_unit.value(\"Carat\", sv::data::Unit::Carat);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Carat\"] = \"Weight in carat.\";\n\tpy_unit.value(\"Ounce\", sv::data::Unit::Ounce);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Ounce\"] = \"Weight in avoirdupois ounce (oz).\";\n\tpy_unit.value(\"TroyOunce\", sv::data::Unit::TroyOunce);\n\tmodule.attr(\"__pdoc__\")[\"Unit.TroyOunce\"] = \"Weight in troy ounce (oz t).\";\n\tpy_unit.value(\"Pound\", sv::data::Unit::Pound);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Pound\"] = \"Weight in avoirdupois pound (lb).\";\n\tpy_unit.value(\"Pennyweight\", sv::data::Unit::Pennyweight);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Pennyweight\"] = \"Weight in pennyweight.\";\n\tpy_unit.value(\"Grain\", sv::data::Unit::Grain);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Grain\"] = \"Weight in grain.\";\n\tpy_unit.value(\"Tael\", sv::data::Unit::Tael);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Tael\"] = \"Weight in tael.\";\n\tpy_unit.value(\"Momme\", sv::data::Unit::Momme);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Momme\"] = \"Weight in momme.\";\n\tpy_unit.value(\"Tola\", sv::data::Unit::Tola);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Tola\"] = \"Weight in tola.\";\n\tpy_unit.value(\"Piece\", sv::data::Unit::Piece);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Piece\"] = \"Piece\";\n\tpy_unit.value(\"Joule\", sv::data::Unit::Joule);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Joule\"] = \"Joule\";\n\tpy_unit.value(\"AmpereHour\", sv::data::Unit::AmpereHour);\n\tmodule.attr(\"__pdoc__\")[\"Unit.AmpereHour\"] = \"AmpereHour (Ah)\";\n\tpy_unit.value(\"Coulomb\", sv::data::Unit::Coulomb);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Coulomb\"] = \"Coulomb\";\n\t// TODO: Implement in libsigrok\n\t//py_unit.value(\"Decibel\", sv::data::Unit::Decibel);\n\t//m.attr(\"__pdoc__\")[\"Unit.Decibel\"] = \"Decibel (dB)\";\n\tpy_unit.value(\"Unknown\", sv::data::Unit::Unknown);\n\tmodule.attr(\"__pdoc__\")[\"Unit.Unknown\"] = \"Unknown\";\n\n\t// Qt enumerations\n\tpy::enum_<Qt::DockWidgetArea> py_dock_area(module, \"DockArea\",\n\t\t\"Enum of all possible docking locations for a view.\");\n\tpy_dock_area.value(\"LeftDocktArea\", Qt::DockWidgetArea::LeftDockWidgetArea);\n\tmodule.attr(\"__pdoc__\")[\"DockArea.LeftDocktArea\"] = \"Dock to the left dock area.\";\n\tpy_dock_area.value(\"RightDockArea\", Qt::DockWidgetArea::RightDockWidgetArea);\n\tmodule.attr(\"__pdoc__\")[\"DockArea.RightDockArea\"] = \"Dock to the right dock area.\";\n\tpy_dock_area.value(\"TopDockArea\", Qt::DockWidgetArea::TopDockWidgetArea);\n\tmodule.attr(\"__pdoc__\")[\"DockArea.TopDockArea\"] = \"Dock to the top dock area.\";\n\tpy_dock_area.value(\"BottomDockArea\", Qt::DockWidgetArea::BottomDockWidgetArea);\n\tmodule.attr(\"__pdoc__\")[\"DockArea.BottomDockArea\"] = \"Dock to the bottom dock area.\";\n\t//py_dock_area.value(\"AllDockAreas\", Qt::DockWidgetArea::AllDockWidgetAreas);\n\t//m.attr(\"__pdoc__\")[\"DockArea.AllDockAreas\"] = \"Dock to all dock area.\";\n\t//py_dock_area.value(\"NoDockArea\", Qt::DockWidgetArea::NoDockWidgetArea);\n\t//m.attr(\"__pdoc__\")[\"DockArea.NoDockArea\"] = \"Dock to no dock area.\";\n}\n"
  },
  {
    "path": "src/python/bindings.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_BINDINGS_HPP\n#define PYTHON_BINDINGS_HPP\n\n#include \"pybind11/pybind11.h\"\n\nnamespace py = pybind11;\n\nvoid init_Session(py::module &module);\nvoid init_Device(py::module &module);\nvoid init_Channel(py::module &module);\nvoid init_Signal(py::module &module);\nvoid init_Configurable(py::module &module);\nvoid init_UI(py::module &module);\nvoid init_StreamBuf(py::module &module);\nvoid init_Enums(py::module &module);\n\n#endif // PYTHON_BINDINGS_HPP\n"
  },
  {
    "path": "src/python/pystreambuf.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <mutex>\n#include <string>\n#include <vector>\n\n#include <Python.h>\n#include <pyerrors.h>\n\n#include \"pystreambuf.hpp\"\n\nnamespace sv {\nnamespace python {\n\nPyStreamBuf::PyStreamBuf(const std::string &encoding, const std::string &errors) :\n\tpy_closed(false),\n\tpy_encoding(encoding),\n\tpy_errors(errors)\n{\n}\n\nPyStreamBuf::~PyStreamBuf()\n{\n\tpy_close();\n}\n\nvoid PyStreamBuf::py_close()\n{\n\tstd::lock_guard<std::mutex> lock(mutex_);\n\n\t// output anything that is left\n\tif (!string_.empty()) {\n\t\tQ_EMIT send_string(string_);\n\t\tstring_.erase(string_.begin(), string_.end());\n\t}\n\n\tpy_closed = true;\n}\n\nint PyStreamBuf::py_fileno()\n{\n\tPyErr_SetString(PyExc_OSError,\n\t\t\"PyStreamBuf has no underlying file descriptor!\");\n\treturn -1;\n}\n\nvoid PyStreamBuf::py_flush()\n{\n\tstd::lock_guard<std::mutex> lock(mutex_);\n\n\tQ_EMIT send_string(string_);\n\tstring_.erase(string_.begin(), string_.end());\n}\n\nbool PyStreamBuf::py_isatty()\n{\n\treturn false;\n}\n\nbool PyStreamBuf::py_readable()\n{\n\treturn false;\n}\n\nstd::vector<std::string> PyStreamBuf::py_readlines(int hint)\n{\n\t(void)hint;\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is write only!\");\n\treturn std::vector<std::string>();\n}\n\nbool PyStreamBuf::py_seekable()\n{\n\treturn false;\n}\n\nint PyStreamBuf::py_truncate(int size)\n{\n\t(void)size;\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is not seekable!\");\n\treturn 0;\n}\n\nbool PyStreamBuf::py_writable()\n{\n\treturn true;\n}\n\nvoid PyStreamBuf::py_writelines(const std::vector<std::string> &lines)\n{\n\tif (py_closed)\n\t\tPyErr_SetString(PyExc_ValueError, \"PyStreamBuf is already closed!\");\n\n\tfor (const auto &line : lines) {\n\t\tpy_write(line);\n\t}\n}\n\nvoid PyStreamBuf::py_del()\n{\n\tpy_close();\n}\n\nstd::string PyStreamBuf::py_read(int size)\n{\n\t(void)size;\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is write only!\");\n\treturn \"\";\n}\n\nstd::string PyStreamBuf::py_readline(int size)\n{\n\t(void)size;\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is write only!\");\n\treturn \"\";\n}\n\nint PyStreamBuf::py_seek(int offset, int whence)\n{\n\t(void)offset;\n\t(void)whence;\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is not seekable!\");\n\treturn 0;\n}\n\nint PyStreamBuf::py_tell()\n{\n\tPyErr_SetString(PyExc_OSError, \"PyStreamBuf is not seekable!\");\n\treturn 0;\n}\n\nint PyStreamBuf::py_write(const std::string &str)\n{\n\tif (py_closed)\n\t\tPyErr_SetString(PyExc_ValueError, \"PyStreamBuf is already closed!\");\n\n\tstd::lock_guard<std::mutex> lock(mutex_);\n\n\tstring_.append(str);\n\tsize_t pos = 0;\n\twhile (pos != std::string::npos) {\n\t\tpos = string_.find('\\n');\n\t\tif (pos != std::string::npos) {\n\t\t\tstd::string tmp(string_.begin(),\n\t\t\t\tstring_.begin() + static_cast<long>(pos));\n\t\t\tQ_EMIT send_string(tmp);\n\t\t\tstring_.erase(string_.begin(),\n\t\t\t\tstring_.begin() + static_cast<long>(pos) + 1);\n\t\t}\n\t}\n\n\treturn static_cast<int>(str.size());\n}\n\n} // namespace python\n} // namespace sv\n"
  },
  {
    "path": "src/python/pystreambuf.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_PYSTREAMBUF_H\n#define PYTHON_PYSTREAMBUF_H\n\n#include <mutex>\n#include <string>\n#include <vector>\n\n#include <QObject>\n\nnamespace sv {\nnamespace python {\n\n/**\n * Buffer that writes to C++ instead of Python.\n */\nclass PyStreamBuf : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tPyStreamBuf(const std::string &encoding, const std::string &errors);\n\t~PyStreamBuf();\n\n\t/** True if the stream is closed. */\n\tbool py_closed;\n\t/** The name of the encoding that is used. */\n\tconst std::string py_encoding;\n\t/** The error setting of the decoder or encoder. */\n\tconst std::string py_errors;\n\n\t/** Flush and close this stream. */\n\tvoid py_close();\n\t/** Raises an OSError, because PyStreamBuf doesn't use a file descriptor. */\n\tint py_fileno();\n\t/** Flush the write buffers of the stream. */\n\tvoid py_flush();\n\t/** Always return False. */\n\tbool py_isatty();\n\t/** Always return False. */\n\tbool py_readable();\n\t/** Raises an OSError, because PyStreamBuf is write only. */\n\tstd::vector<std::string> py_readlines(int hint = -1);\n\t/** Always return False. PyStreamBuf is not seekable atm. */\n\tbool py_seekable();\n\t/** Raises an OSError, because PyStreamBuf is not seekable. */\n\tint py_truncate(int size = 0);\n\t/** Always return True. */\n\tbool py_writable();\n\t/** Write a list of lines to the stream. */\n\tvoid py_writelines(const std::vector<std::string> &lines);\n\t/** Prepare for object destruction. */\n\tvoid py_del();\n\t/** Raises an OSError, because PyStreamBuf is write only. */\n\tstd::string py_read(int size = -1);\n\t/** Raises an OSError, because PyStreamBuf is write only. */\n\tstd::string py_readline(int size = -1);\n\t/** Raises an OSError, because PyStreamBuf is not seekable. */\n\tint py_seek(int offset, int whence = SEEK_SET);\n\t/** Raises an OSError, because PyStreamBuf is not seekable. */\n\tint py_tell();\n\t/**\n\t * Write the string `str` to the stream and return the number of\n\t * characters written.\n\t */\n\tint py_write(const std::string &str);\n\nprivate:\n\tstd::string string_;\n\tstd::mutex mutex_;\n\nQ_SIGNALS:\n\tvoid send_string(const std::string &text);\n\n};\n\n} // namespace python\n} // namespace sv\n\n#endif // PYTHON_PYSTREAMBUF_H\n"
  },
  {
    "path": "src/python/pystreamredirect.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_PYSTREAMREDIRECT_HPP\n#define PYTHON_PYSTREAMREDIRECT_HPP\n\n#include <iostream>\n#include <memory>\n#include <string>\n\n#include <pybind11/pybind11.h>\n\n#include <QObject>\n\n#include \"src/python/pystreambuf.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace py = pybind11;\n\nnamespace sv {\nnamespace python {\n\nclass __attribute__((visibility(\"hidden\"))) PyStreamRedirect : public QObject\n{\n\tQ_OBJECT\n\npublic:\n    explicit PyStreamRedirect(shared_ptr<SmuScriptRunner> script_runner) :\n\t\tscript_runner_(script_runner)\n\t{\n\t\tauto sys_module = py::module::import(\"sys\");\n\t\told_stdout_ = sys_module.attr(\"stdout\");\n\t\told_stderr_ = sys_module.attr(\"stderr\");\n\n\t\tauto locale_module = py::module::import(\"locale\");\n\t\tauto default_encoding = locale_module.attr(\"getpreferredencoding\")(false);\n\n\t\tstdout_buf_ = new PyStreamBuf(\n\t\t\tpy::str(py::getattr(old_stdout_, \"encoding\", default_encoding)),\n\t\t\tpy::str(py::getattr(old_stdout_, \"errors\", py::str(\"strict\"))));\n\t\tauto py_stdout_buf = py::cast(\n\t\t\tstdout_buf_, py::return_value_policy::reference);\n\t\tconnect(stdout_buf_, &PyStreamBuf::send_string,\n\t\t\tscript_runner_.get(), &SmuScriptRunner::send_py_stdout);\n\n\t\tstderr_buf_ = new PyStreamBuf(\n\t\t\tpy::str(py::getattr(old_stderr_, \"encoding\", default_encoding)),\n\t\t\tpy::str(py::getattr(old_stderr_, \"errors\", py::str(\"backslashreplace\"))));\n\t\tauto py_stderr_buf = py::cast(\n\t\t\tstderr_buf_, py::return_value_policy::reference);\n\t\tconnect(stderr_buf_, &PyStreamBuf::send_string,\n\t\t\tscript_runner_.get(), &SmuScriptRunner::send_py_stderr);\n\n\t\tsys_module.attr(\"stdout\") = py_stdout_buf;\n\t\tsys_module.attr(\"stderr\") = py_stderr_buf;\n\t}\n\n\t~PyStreamRedirect()\n\t{\n\t\ttry {\n\t\t\tauto sys_module = py::module::import(\"sys\");\n\t\t\tsys_module.attr(\"stdout\") = old_stdout_;\n\t\t\tsys_module.attr(\"stderr\") = old_stderr_;\n\t\t}\n\t\tcatch (const py::error_already_set &) {}\n\n\t\tstdout_buf_->py_close();\n\t\tstderr_buf_->py_close();\n\n\t\tdisconnect(stdout_buf_, &PyStreamBuf::send_string,\n\t\t\tscript_runner_.get(), &SmuScriptRunner::send_py_stdout);\n\t\tdisconnect(stderr_buf_, &PyStreamBuf::send_string,\n\t\t\tscript_runner_.get(), &SmuScriptRunner::send_py_stderr);\n\t}\n\nprivate:\n\tshared_ptr<SmuScriptRunner> script_runner_;\n\tpy::object old_stdout_;\n\tpy::object old_stderr_;\n\tPyStreamBuf *stdout_buf_;\n\tPyStreamBuf *stderr_buf_;\n\n};\n\n} // namespace python\n} // namespace sv\n\n#endif // PYTHON_PYSTREAMREDIRECT_HPP\n"
  },
  {
    "path": "src/python/smuscriptrunner.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n#include <thread>\n\n#include <pybind11/embed.h>\n#include <pybind11/stl.h>\n\n#include <QDebug>\n#include <QFileInfo>\n#include <QString>\n\n#include \"smuscriptrunner.hpp\"\n#include \"src/session.hpp\"\n#include \"src/python/bindings.hpp\"\n#include \"src/python/pystreambuf.hpp\"\n#include \"src/python/pystreamredirect.hpp\"\n#include \"src/python/uihelper.hpp\"\n#include \"src/python/uiproxy.hpp\"\n\nusing std::make_shared;\nusing std::string;\n\nusing namespace pybind11::literals; // for the \"\"_a\nnamespace py = pybind11;\n\nnamespace sv {\nnamespace python {\n\nSmuScriptRunner::SmuScriptRunner(Session &session) :\n\tsession_(session),\n\tis_running_(false)\n{\n\tui_helper_ = make_shared<UiHelper>(session_);\n}\n\nSmuScriptRunner::~SmuScriptRunner()\n{\n\t/*\n\tif (script_thread_.joinable())\n\t\tscript_thread_.join();\n\t*/\n}\n\nvoid SmuScriptRunner::run(const string &file_name)\n{\n\tif (file_name.length() == 0) {\n\t\tQ_EMIT script_error(\"SmuScriptRunner\",\n\t\t\ttr(\"No script file specified!\").toStdString());\n\t\treturn;\n\t}\n\n    QFileInfo file_info(QString::fromStdString(file_name));\n\tif (!file_info.exists() || !file_info.isFile()) {\n\t\tQ_EMIT script_error(\"SmuScriptRunner\",\n\t\t\ttr(\"No valide script file specified!\").toStdString());\n\t\treturn;\n\t}\n\n\tscript_file_name_ = file_name;\n\tscript_thread_ = std::thread(&SmuScriptRunner::script_thread_proc, this);\n\tscript_thread_.detach();\n}\n\nvoid SmuScriptRunner::stop() const\n{\n\tif (is_running_)\n\t\tPyErr_SetInterrupt();\n}\n\nbool SmuScriptRunner::is_running() const\n{\n\treturn is_running_;\n}\n\nvoid SmuScriptRunner::script_thread_proc()\n{\n\t// TODO: mutex?\n\n\tqWarning() << \"SmuScriptRunner::script_thread_proc() executing \" <<\n\t\tQString::fromStdString(script_file_name_);\n\n\tis_running_ = true;\n\tQ_EMIT script_started();\n\n\tpy::scoped_interpreter guard{};\n\n\tpy::module smuview_module = py::module::import(\"smuview\");\n\n\t// Redirect python stdout + stderr\n\tPyStreamRedirect py_stream_redirect{ shared_from_this() };\n\n\t/*\n\t * NOTE: Setting Session and UiProxy as locals does not work!\n\t * When executing a script, the globals() inside a function are missing the\n\t * additional stuff like imported modules, function pointer and also\n\t * everyhthing provided by the locals dict. Setting Session and UiProxy in\n\t * addition to py::globals() as globals did the trick. See:\n\t * https://medium.com/just-me-me-programming-life/python-c-and-symbols-4628fb71a257\n\t */\n\tUiProxy *ui_proxy = new UiProxy(session_, ui_helper_);\n\tauto globals = py::dict(\n\t\t**py::globals(),\n\t\t\"Session\"_a=py::cast(session_, py::return_value_policy::reference),\n\t\t\"UiProxy\"_a=py::cast(ui_proxy, py::return_value_policy::reference));\n\n\ttry {\n\t\tpy::eval_file(script_file_name_, globals);\n\t}\n\tcatch (py::error_already_set &ex) {\n\t\tQ_EMIT send_py_stderr(ex.what());\n\t\tQ_EMIT script_error(\"SmuScriptRunner py::error_already_set\", ex.what());\n\t}\n\n\tqWarning() << \"SmuScriptRunner::script_thread_proc() has finished!\";\n\tQ_EMIT script_finished();\n\tis_running_ = false;\n}\n\n} // namespace python\n} // namespace sv\n"
  },
  {
    "path": "src/python/smuscriptrunner.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_SMUSCRIPTRUNNER_HPP\n#define PYTHON_SMUSCRIPTRUNNER_HPP\n\n#include <memory>\n#include <string>\n#include <thread>\n\n#include <QObject>\n#include <QString>\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace python {\n\nclass UiHelper;\n\nclass SmuScriptRunner :\n\tpublic QObject,\n\tpublic std::enable_shared_from_this<SmuScriptRunner>\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SmuScriptRunner(Session &session);\n\t~SmuScriptRunner();\n\n\tvoid run(const std::string &file_name);\n\tvoid stop() const;\n\tbool is_running() const;\n\nprivate:\n\tvoid script_thread_proc();\n\n\tSession &session_;\n\tshared_ptr<UiHelper> ui_helper_;\n\tstring script_file_name_;\n\tstd::thread script_thread_;\n\tbool is_running_;\n\nQ_SIGNALS:\n\tvoid script_error(const std::string &sender, const std::string &msg);\n\tvoid script_started();\n\tvoid script_finished();\n\tvoid send_py_stdout(const std::string &text);\n\tvoid send_py_stderr(const std::string &text);\n\n};\n\n} // namespace python\n} // namespace sv\n\n#endif // PYTHON_SMUSCRIPTRUNNER_HPP\n"
  },
  {
    "path": "src/python/uihelper.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n#include <vector>\n\n#include <QColor>\n#include <QDebug>\n#include <QInputDialog>\n#include <QLineEdit>\n#include <QMessageBox>\n#include <QString>\n\n#include \"uihelper.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/views/baseplotview.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/dataview.hpp\"\n#include \"src/ui/views/powerpanelview.hpp\"\n#include \"src/ui/views/timeplotview.hpp\"\n#include \"src/ui/views/valuepanelview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include \"src/ui/views/xyplotview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace python {\n\nUiHelper::UiHelper(Session &session) :\n\tsession_(session)\n{\n\t// For the views_added signal.\n\tqRegisterMetaType<std::vector<std::string>>(\"std::vector<std::string>\");\n}\n\nvoid UiHelper::add_device_tab(shared_ptr<sv::devices::BaseDevice> device)\n{\n\tif (!session_.main_window()) {\n\t\tQ_EMIT tab_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *tab = session_.main_window()->add_device_tab(device);\n\tQ_EMIT tab_added(tab->id());\n}\n\nvoid UiHelper::add_data_view(const std::string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::DataView(session_);\n\tview->add_signal(signal);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_control_views(const std::string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<sv::devices::Configurable> configurable)\n{\n\tstd::vector<std::string> view_ids;\n\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT views_added(view_ids);\n\t\treturn;\n\t}\n\tauto views = ui::views::viewhelper::get_views_for_configurable(\n\t\tsession_, configurable);\n\tif (views.empty()) {\n\t\tQ_EMIT views_added(view_ids);\n\t\treturn;\n\t}\n\n\tfor (const auto &view : views) {\n\t\ttab->add_view(view, area);\n\t\tview_ids.push_back(view->id());\n\t}\n\tQ_EMIT views_added(view_ids);\n}\n\nvoid UiHelper::add_time_plot_view(const std::string &tab_id,\n\tQt::DockWidgetArea area)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::TimePlotView(session_);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_xy_plot_view(const std::string &tab_id,\n\tQt::DockWidgetArea area)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::XYPlotView(session_);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_power_panel_view(const std::string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<sv::data::AnalogTimeSignal> voltage_signal,\n\tshared_ptr<sv::data::AnalogTimeSignal> current_signal)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::PowerPanelView(session_);\n\tview->set_signals(voltage_signal, current_signal);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_value_panel_view(const std::string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<sv::channels::BaseChannel> channel)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::ValuePanelView(session_);\n\tview->set_channel(channel);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_value_panel_view(const std::string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab) {\n\t\tQ_EMIT view_added(\"\");\n\t\treturn;\n\t}\n\n\tauto *view = new ui::views::ValuePanelView(session_);\n\tview->set_signal(signal);\n\ttab->add_view(view, area);\n\tQ_EMIT view_added(view->id());\n}\n\nvoid UiHelper::add_signal_to_data_view(const std::string &tab_id,\n\tconst std::string &view_id,\n\tshared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tauto *view = get_view(tab_id, view_id);\n\tif (!view)\n\t\treturn;\n\n\t((ui::views::DataView *)view)->add_signal(signal);\n}\n\nvoid UiHelper::set_channel_to_time_plot_view(const std::string &tab_id,\n\tconst std::string &view_id,\n\tshared_ptr<sv::channels::BaseChannel> channel)\n{\n\tauto *plot_view = get_time_plot_view(tab_id, view_id);\n\tif (!plot_view) {\n\t\tQ_EMIT curve_added(\"\");\n\t\treturn;\n\t}\n\n\tplot_view->set_channel(channel);\n}\n\nvoid UiHelper::add_curve_to_time_plot_view(const std::string &tab_id,\n\tconst std::string &view_id,\n\tshared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tauto *plot_view = get_time_plot_view(tab_id, view_id);\n\tif (!plot_view) {\n\t\tQ_EMIT curve_added(\"\");\n\t\treturn;\n\t}\n\n\tstring id = plot_view->add_signal(signal);\n\tQ_EMIT curve_added(id);\n}\n\nvoid UiHelper::add_curve_to_xy_plot_view(const std::string &tab_id,\n\tconst std::string &view_id,\n\tshared_ptr<sv::data::AnalogTimeSignal> x_signal,\n\tshared_ptr<sv::data::AnalogTimeSignal> y_signal)\n{\n\tauto *view = get_view(tab_id, view_id);\n\tif (!view) {\n\t\tQ_EMIT curve_added(\"\");\n\t\treturn;\n\t}\n\tauto *plot_view = qobject_cast<ui::views::XYPlotView *>(view);\n\tif (!plot_view) {\n\t\tqWarning() << \"UiHelper::add_curve_to_xy_plot_view(): View is not a \"\n\t\t\t\"xy plot view: \" << QString::fromStdString(view_id);\n\t\tQ_EMIT curve_added(\"\");\n\t\treturn;\n\t}\n\n\tstring id = plot_view->add_signals(x_signal, y_signal);\n\tQ_EMIT curve_added(id);\n}\n\nvoid UiHelper::set_curve_name(const std::string &tab_id,\n\tconst std::string &view_id, const std::string &curve_id,\n\tconst std::string &name)\n{\n\tauto *plot_view = get_base_plot_view(tab_id, view_id);\n\tif (!plot_view)\n\t\treturn;\n\n\tbool ret = plot_view->set_curve_name(curve_id, QString::fromStdString(name));\n\tif (!ret) {\n\t\tqWarning() << \"UiHelper::set_curve_name(): Curve not found: \" <<\n\t\t\tQString::fromStdString(curve_id);\n\t}\n}\n\nvoid UiHelper::set_curve_color(const std::string &tab_id,\n\tconst std::string &view_id, const std::string &curve_id,\n\tstd::tuple<int, int, int> color)\n{\n\tauto *plot_view = get_base_plot_view(tab_id, view_id);\n\tif (!plot_view)\n\t\treturn;\n\n\tbool ret = plot_view->set_curve_color(curve_id,\n\t\tQColor(std::get<0>(color), std::get<1>(color), std::get<2>(color)));\n\tif (!ret) {\n\t\tqWarning() << \"UiHelper::set_curve_color(): Curve not found: \" <<\n\t\t\tQString::fromStdString(curve_id);\n\t}\n}\n\nvoid UiHelper::show_message_box(const std::string &title,\n\tconst std::string &text)\n{\n\tif (!session_.main_window()) {\n\t\tQ_EMIT message_box_canceled();\n\t\treturn;\n\t}\n\n\tauto button = QMessageBox::information(session_.main_window(),\n\t\tQString::fromStdString(title), QString::fromStdString(text));\n\n\tif (button == QMessageBox::StandardButton::Ok)\n\t\tQ_EMIT message_box_finished();\n\telse\n\t\tQ_EMIT message_box_canceled();\n}\n\nvoid UiHelper::show_string_input_dialog(const std::string &title,\n\tconst std::string &label, const std::string &value)\n{\n\tif (!session_.main_window()) {\n\t\tQ_EMIT input_dialog_canceled();\n\t\treturn;\n\t}\n\n\tbool ok;\n\tQString str = QInputDialog::getText(session_.main_window(),\n\t\tQString::fromStdString(title), QString::fromStdString(label),\n\t\tQLineEdit::Normal, QString::fromStdString(value), &ok,\n\t\tQt::WindowFlags(), Qt::ImhNone);\n\n\tif (ok)\n\t\tQ_EMIT input_dialog_finished(QVariant(str));\n\telse\n\t\tQ_EMIT input_dialog_canceled();\n\n}\n\nvoid UiHelper::show_double_input_dialog(const std::string &title,\n\tconst std::string &label, double value, int decimals, double step,\n\tdouble min, double max)\n{\n\tif (!session_.main_window()) {\n\t\tQ_EMIT input_dialog_canceled();\n\t\treturn;\n\t}\n\n\tbool ok;\n#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)\n\tdouble dec = QInputDialog::getDouble(session_.main_window(),\n\t\tQString::fromStdString(title), QString::fromStdString(label),\n\t\tvalue, min, max, decimals, &ok, Qt::WindowFlags(), step);\n#else\n\t(void)step;\n\tdouble dec = QInputDialog::getDouble(session_.main_window(),\n\t\tQString::fromStdString(title), QString::fromStdString(label),\n\t\tvalue, min, max, decimals, &ok, Qt::WindowFlags());\n#endif\n\n\tif (ok)\n\t\tQ_EMIT input_dialog_finished(QVariant(dec));\n\telse\n\t\tQ_EMIT input_dialog_canceled();\n}\n\nvoid UiHelper::show_int_input_dialog(const std::string &title,\n\tconst std::string &label, int value, int step, int min, int max)\n{\n\tif (!session_.main_window()) {\n\t\tQ_EMIT input_dialog_canceled();\n\t\treturn;\n\t}\n\n\tbool ok;\n\tint number = QInputDialog::getInt(session_.main_window(),\n\t\tQString::fromStdString(title), QString::fromStdString(label),\n\t\tvalue, min, max, step, &ok, Qt::WindowFlags());\n\n\tif (ok)\n\t\tQ_EMIT input_dialog_finished(QVariant(number));\n\telse\n\t\tQ_EMIT input_dialog_canceled();\n}\n\nui::tabs::BaseTab *UiHelper::get_tab(const string &tab_id) const\n{\n\tif (!session_.main_window()) {\n\t\tqWarning() << \"UiHelper::get_tab(): No MainWindow found!\";\n\t\treturn nullptr;\n\t}\n\tauto *tab = session_.main_window()->get_tab_from_tab_id(tab_id);\n\tif (!tab) {\n\t\tqWarning() << \"UiHelper::get_tab(): Tab not found: \" <<\n\t\t\tQString::fromStdString(tab_id);\n\t}\n\treturn tab;\n}\n\nui::views::BaseView *UiHelper::get_view(const string &tab_id,\n\tconst string &view_id) const\n{\n\tauto *tab = get_tab(tab_id);\n\tif (!tab)\n\t\treturn nullptr;\n\tauto *view = tab->get_view_from_view_id(view_id);\n\tif (!view) {\n\t\tqWarning() << \"UiHelper::get_view(): View not found: \" <<\n\t\t\tQString::fromStdString(view_id);\n\t}\n\treturn view;\n}\n\nui::views::BasePlotView *UiHelper::get_base_plot_view(const string &tab_id,\n\tconst string &view_id) const\n{\n\tauto *view = get_view(tab_id, view_id);\n\tif (!view)\n\t\treturn nullptr;\n\tauto *plot_view = qobject_cast<ui::views::BasePlotView *>(view);\n\tif (!plot_view) {\n\t\tqWarning() << \"UiHelper::get_base_plot_view(): View is not a plot \"\n\t\t\t\"view: \" << QString::fromStdString(view_id);\n\t}\n\treturn plot_view;\n}\n\nui::views::TimePlotView *UiHelper::get_time_plot_view(const string &tab_id,\n\tconst string &view_id) const\n{\n\tauto *view = get_view(tab_id, view_id);\n\tif (!view)\n\t\treturn nullptr;\n\tauto *plot_view = qobject_cast<ui::views::TimePlotView *>(view);\n\tif (!plot_view) {\n\t\tqWarning() << \"UiHelper::get_time_plot_view(): View is not a time plot \"\n\t\t\t\"view: \" << QString::fromStdString(view_id);\n\t}\n\treturn plot_view;\n}\n\n} // namespace python\n} // namespace sv\n\n"
  },
  {
    "path": "src/python/uihelper.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_UIHELPER_HPP\n#define PYTHON_UIHELPER_HPP\n\n#include <memory>\n#include <string>\n#include <tuple>\n#include <vector>\n\n#include <QDockWidget>\n#include <QObject>\n#include <QVariant>\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace tabs {\nclass BaseTab;\n}\nnamespace views {\nclass BasePlotView;\nclass BaseView;\nclass TimePlotView;\n}\n}\n\nnamespace python {\n\nclass UiHelper : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\texplicit UiHelper(Session &session);\n\npublic Q_SLOTS:\n\tvoid add_device_tab(shared_ptr<sv::devices::BaseDevice> device);\n\n\tvoid add_data_view(const std::string &tab_id, Qt::DockWidgetArea area,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\tvoid add_control_views(const std::string &tab_id, Qt::DockWidgetArea area,\n\t\tshared_ptr<sv::devices::Configurable> configurable);\n\tvoid add_time_plot_view(const std::string &tab_id, Qt::DockWidgetArea area);\n\tvoid add_xy_plot_view(const std::string &tab_id, Qt::DockWidgetArea area);\n\tvoid add_power_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> voltage_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> current_signal);\n\tvoid add_value_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area, shared_ptr<sv::channels::BaseChannel> channel);\n\tvoid add_value_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area, shared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid add_signal_to_data_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid set_channel_to_time_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::channels::BaseChannel> channel);\n\tvoid add_curve_to_time_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\tvoid add_curve_to_xy_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> x_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> y_signal);\n\tvoid set_curve_name(const std::string &tab_id, const std::string &view_id,\n\t\tconst std::string &curve_id, const std::string &name);\n\tvoid set_curve_color(const std::string &tab_id, const std::string &view_id,\n\t\tconst std::string &curve_id, std::tuple<int, int, int> color);\n\n\tvoid show_message_box(const std::string &title, const std::string &text);\n\tvoid show_string_input_dialog(const std::string &title,\n\t\tconst std::string &label, const std::string &value);\n\tvoid show_double_input_dialog(const std::string &title,\n\t\tconst std::string &label, double value, int decimals, double step,\n\t\tdouble min, double max);\n\tvoid show_int_input_dialog(const std::string &title,\n\t\tconst std::string &label, int value, int step, int min, int max);\n\nprivate:\n\tSession &session_;\n\n\tui::tabs::BaseTab *get_tab(const string &tab_id) const;\n\tui::views::BaseView *get_view(const string &tab_id,\n\t\tconst string &view_id) const;\n\tui::views::BasePlotView *get_base_plot_view(const string &tab_id,\n\t\tconst string &view_id) const;\n\tui::views::TimePlotView *get_time_plot_view(const string &tab_id,\n\t\tconst string &view_id) const;\n\nQ_SIGNALS:\n\tvoid tab_added(const std::string &tab_id);\n\tvoid view_added(const std::string &view_id);\n\tvoid views_added(std::vector<std::string> view_ids);\n\tvoid curve_added(const std::string &curve_id);\n\tvoid message_box_finished();\n\tvoid message_box_canceled();\n\tvoid input_dialog_finished(const QVariant &qvar_input);\n\tvoid input_dialog_canceled();\n\n};\n\n} // namespace python\n} // namespace sv\n\n#endif // PYTHON_UIHELPER_HPP\n"
  },
  {
    "path": "src/python/uiproxy.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n#include <tuple>\n#include <pybind11/pybind11.h>\n\n#include <QDebug>\n#include <QDockWidget>\n#include <QEventLoop>\n#include <QMetaObject>\n#include <QTimer>\n#include <QVariant>\n\n#include \"uiproxy.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/python/uihelper.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\nusing std::tuple;\n\nnamespace py = pybind11;\n\nnamespace sv {\nnamespace python {\n\nUiProxy::UiProxy(Session &session, shared_ptr<UiHelper> ui_helper) :\n\tsession_(session),\n\tui_helper_(ui_helper)\n{\n\t// For the colors tuple:\n\tqRegisterMetaType<std::tuple<int, int, int>>(\"std::tuple<int, int, int>\");\n\n\tconnect(this, &UiProxy::add_device_tab,\n\t\tui_helper_.get(), &UiHelper::add_device_tab);\n\n\tconnect(this, &UiProxy::add_data_view,\n\t\tui_helper_.get(), &UiHelper::add_data_view);\n\n\tconnect(this, &UiProxy::add_control_views,\n\t\tui_helper_.get(), &UiHelper::add_control_views);\n\n\tconnect(this, &UiProxy::add_time_plot_view,\n\t\tui_helper_.get(), &UiHelper::add_time_plot_view);\n\tconnect(this, &UiProxy::add_xy_plot_view,\n\t\tui_helper_.get(), &UiHelper::add_xy_plot_view);\n\n\tconnect(this, &UiProxy::add_power_panel_view,\n\t\tui_helper_.get(), &UiHelper::add_power_panel_view);\n\n\tconnect(this, QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::channels::BaseChannel>>::of(&UiProxy::add_value_panel_view),\n\t\tui_helper_.get(), QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::channels::BaseChannel>>::of(&UiHelper::add_value_panel_view));\n\tconnect(this, QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::data::AnalogTimeSignal>>::of(&UiProxy::add_value_panel_view),\n\t\tui_helper_.get(), QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::data::AnalogTimeSignal>>::of(&UiHelper::add_value_panel_view));\n\n\tconnect(this, &UiProxy::add_signal_to_data_view,\n\t\tui_helper_.get(), &UiHelper::add_signal_to_data_view);\n\n\tconnect(this, &UiProxy::set_channel_to_time_plot_view,\n\t\tui_helper_.get(), &UiHelper::set_channel_to_time_plot_view);\n\tconnect(this, &UiProxy::add_curve_to_time_plot_view,\n\t\tui_helper_.get(), &UiHelper::add_curve_to_time_plot_view);\n\tconnect(this, &UiProxy::add_curve_to_xy_plot_view,\n\t\tui_helper_.get(), &UiHelper::add_curve_to_xy_plot_view);\n\tconnect(this, &UiProxy::set_curve_name,\n\t\tui_helper_.get(), &UiHelper::set_curve_name);\n\tconnect(this, &UiProxy::set_curve_color,\n\t\tui_helper_.get(), &UiHelper::set_curve_color);\n\n\tconnect(this, &UiProxy::show_message_box,\n\t\tui_helper_.get(), &UiHelper::show_message_box);\n\tconnect(this, &UiProxy::show_string_input_dialog,\n\t\tui_helper_.get(), &UiHelper::show_string_input_dialog);\n\tconnect(this, &UiProxy::show_double_input_dialog,\n\t\tui_helper_.get(), &UiHelper::show_double_input_dialog);\n\tconnect(this, &UiProxy::show_int_input_dialog,\n\t\tui_helper_.get(), &UiHelper::show_int_input_dialog);\n}\n\n\nstring UiProxy::ui_add_device_tab(shared_ptr<devices::BaseDevice> device)\n{\n\tstring id;\n\tinit_wait_for_tab_added(id);\n\tQ_EMIT add_device_tab(device);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_data_view(const string &tab_id, Qt::DockWidgetArea area,\n\tshared_ptr<data::AnalogTimeSignal> signal)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_data_view(tab_id, area, signal);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nvector<string> UiProxy::ui_add_control_views(const string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<devices::Configurable> configurable)\n{\n\tvector<string> ids;\n\tinit_wait_for_views_added(ids);\n\tQ_EMIT add_control_views(tab_id, area, configurable);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn ids;\n}\n\nstring UiProxy::ui_add_time_plot_view(const string &tab_id,\n\tQt::DockWidgetArea area)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_time_plot_view(tab_id, area);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_xy_plot_view(const string &tab_id,\n\tQt::DockWidgetArea area)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_xy_plot_view(tab_id, area);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_power_panel_view(const string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<data::AnalogTimeSignal> voltage_signal,\n\tshared_ptr<data::AnalogTimeSignal> current_signal)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_power_panel_view(tab_id, area, voltage_signal, current_signal);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_value_panel_view(const string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<channels::BaseChannel> channel)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_value_panel_view(tab_id, area, channel);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_value_panel_view(const string &tab_id,\n\tQt::DockWidgetArea area,\n\tshared_ptr<data::AnalogTimeSignal> signal)\n{\n\tstring id;\n\tinit_wait_for_view_added(id);\n\tQ_EMIT add_value_panel_view(tab_id, area, signal);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nvoid UiProxy::ui_add_signal_to_data_view(const string &tab_id,\n\tconst string &view_id,\n\tshared_ptr<data::AnalogTimeSignal> signal)\n{\n\tQ_EMIT add_signal_to_data_view(tab_id, view_id, signal);\n}\n\nvoid UiProxy::ui_set_channel_to_time_plot_view(const string &tab_id,\n\tconst string &view_id,\n\tshared_ptr<channels::BaseChannel> channel)\n{\n\tQ_EMIT set_channel_to_time_plot_view(tab_id, view_id, channel);\n}\n\nstring UiProxy::ui_add_curve_to_time_plot_view(const string &tab_id,\n\tconst string &view_id,\n\tshared_ptr<data::AnalogTimeSignal> signal)\n{\n\tstring id;\n\tinit_wait_for_curve_added(id);\n\tQ_EMIT add_curve_to_time_plot_view(tab_id, view_id, signal);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nstring UiProxy::ui_add_curve_to_xy_plot_view(const string &tab_id,\n\tconst string &view_id,\n\tshared_ptr<data::AnalogTimeSignal> x_signal,\n\tshared_ptr<data::AnalogTimeSignal> y_signal)\n{\n\tstring id;\n\tinit_wait_for_curve_added(id);\n\tQ_EMIT add_curve_to_xy_plot_view(tab_id, view_id, x_signal, y_signal);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn id;\n}\n\nvoid UiProxy::ui_set_curve_name(const string &tab_id, const string &view_id,\n\tconst string &curve_id, const string &name)\n{\n\tQ_EMIT set_curve_name(tab_id, view_id, curve_id, name);\n}\n\nvoid UiProxy::ui_set_curve_color(const string &tab_id, const string &view_id,\n\tconst string &curve_id, tuple<int, int, int> color)\n{\n\tQ_EMIT set_curve_color(tab_id, view_id, curve_id, color);\n}\n\n\nbool UiProxy::ui_show_message_box(const std::string &title,\n\tconst std::string &text)\n{\n\tbool ok;\n\tinit_wait_for_message_box(ok);\n\tQ_EMIT show_message_box(title, text);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\treturn ok;\n}\n\npy::object UiProxy::ui_show_string_input_dialog(const string &title,\n\tconst string &label, const string &value)\n{\n\tbool ok;\n\tQVariant qvar;\n\tinit_wait_for_input_dialog(ok, qvar);\n\tQ_EMIT show_string_input_dialog(title, label, value);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\tif (!ok)\n\t\treturn py::cast<py::none>(Py_None);\n\treturn py::cast(qvar.toString().toStdString());\n}\n\npy::object UiProxy::ui_show_double_input_dialog(const string &title,\n\tconst string &label, double value, int decimals, double step,\n\tdouble min, double max)\n{\n\tbool ok;\n\tQVariant qvar;\n\tinit_wait_for_input_dialog(ok, qvar);\n\tQ_EMIT show_double_input_dialog(\n\t\ttitle, label, value, decimals, step, min, max);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\tif (!ok)\n\t\treturn py::cast<py::none>(Py_None);\n\treturn py::cast(qvar.toDouble());\n}\n\npy::object UiProxy::ui_show_int_input_dialog(const string &title,\n\tconst string &label, int value, int step, int min, int max)\n{\n\tbool ok;\n\tQVariant qvar;\n\tinit_wait_for_input_dialog(ok, qvar);\n\tQ_EMIT show_int_input_dialog(title, label, value, step, min, max);\n\tevent_loop_.exec();\n\tfinish_wait_for_signal();\n\n\tif (!ok)\n\t\treturn py::cast<py::none>(Py_None);\n\treturn py::cast(qvar.toInt());\n}\n\nvoid UiProxy::init_wait_for_tab_added(string &id, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::tab_added, this,\n\t\t\t[this, &id](const std::string &tab_id) {\n\t\t\t\tid = tab_id;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::init_wait_for_view_added(string &id, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::view_added, this,\n\t\t\t[this, &id](const std::string &view_id) {\n\t\t\t\tid = view_id;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::init_wait_for_views_added(vector<string> &ids, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::views_added, this,\n\t\t\t[this, &ids](const vector<std::string> &view_ids) {\n\t\t\t\tids = view_ids;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::init_wait_for_curve_added(string &id, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::curve_added, this,\n\t\t\t[this, &id](const std::string &curve_id) {\n\t\t\t\tid = curve_id;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::init_wait_for_message_box(bool &ok, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::message_box_finished, this,\n\t\t\t[this, &ok]() {\n\t\t\t\tok = true;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\tevent_loop_canceled_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::message_box_canceled, this,\n\t\t\t[this, &ok]() {\n\t\t\t\tok = false;;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::init_wait_for_input_dialog(bool &ok, QVariant &qvar, int timeout)\n{\n\tevent_loop_finished_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::input_dialog_finished, this,\n\t\t\t[this, &ok, &qvar](const QVariant &qvar_input) {\n\t\t\t\tok = true;\n\t\t\t\tqvar = qvar_input;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\tevent_loop_canceled_conn_ =\n\t\tconnect(ui_helper_.get(), &UiHelper::input_dialog_canceled, this,\n\t\t\t[this, &ok]() {\n\t\t\t\tok = false;;\n\t\t\t\tevent_loop_.quit();\n\t\t\t});\n\n\tif (timeout > 0) {\n\t\ttimer_.setSingleShot(true);\n\t\ttimer_conn_ = connect(&timer_, &QTimer::timeout,\n\t\t\t&event_loop_, &QEventLoop::quit);\n\t\ttimer_.start(timeout);\n\t}\n}\n\nvoid UiProxy::finish_wait_for_signal()\n{\n\tif (event_loop_finished_conn_)\n\t\tdisconnect(event_loop_finished_conn_);\n\tif (event_loop_canceled_conn_)\n\t\tdisconnect(event_loop_canceled_conn_);\n\tif (timer_conn_)\n\t\tdisconnect(timer_conn_);\n}\n\n} // namespace python\n} // namespace sv\n"
  },
  {
    "path": "src/python/uiproxy.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef PYTHON_UIPROXY_HPP\n#define PYTHON_UIPROXY_HPP\n\n#include <memory>\n#include <string>\n#include <tuple>\n#include <vector>\n#include <pybind11/pybind11.h>\n\n#include <QDockWidget>\n#include <QEventLoop>\n#include <QMetaObject>\n#include <QObject>\n#include <QTimer>\n#include <QVariant>\n\nusing std::shared_ptr;\nusing std::string;\nusing std::tuple;\nusing std::vector;\n\nnamespace py = pybind11;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace python {\n\nclass UiHelper;\n\n/**\n * The python interpreter is executed in its own thread, therefore calling any\n * methods that will manipulate Qt widgets directly won't work.\n * So we are using UiProxy which is communicating with the Qt main loop via\n * signals and slots.\n */\nclass UiProxy : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tUiProxy(Session &session, shared_ptr<UiHelper> ui_helper);\n\n\tstring ui_add_device_tab(shared_ptr<devices::BaseDevice> device);\n\n\tstring ui_add_data_view(const string &tab_id, Qt::DockWidgetArea area,\n\t\tshared_ptr<data::AnalogTimeSignal> signal);\n\tvector<string> ui_add_control_views(const string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<devices::Configurable> configurable);\n\tstring ui_add_time_plot_view(const string &tab_id, Qt::DockWidgetArea area);\n\tstring ui_add_xy_plot_view(const string &tab_id, Qt::DockWidgetArea area);\n\tstring ui_add_power_panel_view(const string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<data::AnalogTimeSignal> voltage_signal,\n\t\tshared_ptr<data::AnalogTimeSignal> current_signal);\n\tstring ui_add_value_panel_view(const string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<channels::BaseChannel> channel);\n\tstring ui_add_value_panel_view(const string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<data::AnalogTimeSignal> signal);\n\n\tvoid ui_add_signal_to_data_view(const string &tab_id, const string &view_id,\n\t\tshared_ptr<data::AnalogTimeSignal> signal);\n\n\tvoid ui_set_channel_to_time_plot_view(const string &tab_id,\n\t\tconst string &view_id,\n\t\tshared_ptr<channels::BaseChannel> channel);\n\tstring ui_add_curve_to_time_plot_view(const string &tab_id,\n\t\tconst string &view_id,\n\t\tshared_ptr<data::AnalogTimeSignal> signal);\n\tstring ui_add_curve_to_xy_plot_view(const string &tab_id,\n\t\tconst string &view_id,\n\t\tshared_ptr<data::AnalogTimeSignal> x_signal,\n\t\tshared_ptr<data::AnalogTimeSignal> y_signal);\n\tvoid ui_set_curve_name(const string &tab_id, const string &view_id,\n\t\tconst string &curve_id, const string &name);\n\tvoid ui_set_curve_color(const string &tab_id, const string &view_id,\n\t\tconst string &curve_id, tuple<int, int, int> color);\n\n\tbool ui_show_message_box(const std::string &title, const std::string &text);\n\tpy::object ui_show_string_input_dialog(const string &title,\n\t\tconst string &label, const string &value);\n\tpy::object ui_show_double_input_dialog(const string &title,\n\t\tconst string &label, double value, int decimals, double step,\n\t\tdouble min, double max);\n\tpy::object ui_show_int_input_dialog(const string &title,\n\t\tconst string &label, int value, int step, int min, int max);\n\nprivate:\n\tvoid init_wait_for_tab_added(string &id, int timeout = 1000);\n\tvoid init_wait_for_view_added(string &id, int timeout = 1000);\n\tvoid init_wait_for_views_added(vector<string> &ids, int timeout = 1000);\n\tvoid init_wait_for_curve_added(string &id, int timeout = 1000);\n\tvoid init_wait_for_message_box(bool &ok, int timeout = 0);\n\tvoid init_wait_for_input_dialog(bool &ok, QVariant &qvar, int timeout = 0);\n\tvoid finish_wait_for_signal();\n\n\tSession &session_;\n\tshared_ptr<UiHelper> ui_helper_;\n\tQEventLoop event_loop_;\n\tQTimer timer_;\n\tQMetaObject::Connection event_loop_finished_conn_;\n\tQMetaObject::Connection event_loop_canceled_conn_;\n\tQMetaObject::Connection timer_conn_;\n\nQ_SIGNALS:\n\tvoid add_device_tab(shared_ptr<sv::devices::BaseDevice> device);\n\n\tvoid add_data_view(const std::string &tab_id, Qt::DockWidgetArea area,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\tvoid add_control_views(const std::string &tab_id, Qt::DockWidgetArea area,\n\t\tshared_ptr<sv::devices::Configurable> configurable);\n\tvoid add_time_plot_view(const std::string &tab_id, Qt::DockWidgetArea area);\n\tvoid add_xy_plot_view(const std::string &tab_id, Qt::DockWidgetArea area);\n\tvoid add_power_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> voltage_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> current_signal);\n\tvoid add_value_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<sv::channels::BaseChannel> channel);\n\tvoid add_value_panel_view(const std::string &tab_id,\n\t\tQt::DockWidgetArea area,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid add_signal_to_data_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid set_channel_to_time_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::channels::BaseChannel> channel);\n\tvoid add_curve_to_time_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> signal);\n\tvoid add_curve_to_xy_plot_view(const std::string &tab_id,\n\t\tconst std::string &view_id,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> x_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> y_signal);\n\tvoid set_curve_name(const std::string &tab_id, const std::string &view_id,\n\t\tconst std::string &curve_id, const std::string &name);\n\tvoid set_curve_color(const std::string &tab_id, const std::string &view_id,\n\t\tconst std::string &curve_id, std::tuple<int, int, int> color);\n\n\tvoid show_message_box(const std::string &title, const std::string &text);\n\tvoid show_string_input_dialog(const std::string &title,\n\t\tconst std::string &label, const std::string &value);\n\tvoid show_double_input_dialog(const std::string &title,\n\t\tconst std::string &label, double value, int decimals, double step,\n\t\tdouble min, double max);\n\tvoid show_int_input_dialog(const std::string &title,\n\t\tconst std::string &label, int value, int step, int min, int max);\n};\n\n} // namespace python\n} // namespace sv\n\n#endif // PYTHON_UIPROXY_HPP\n"
  },
  {
    "path": "src/session.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <list>\n#include <map>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#include <QDebug>\n\n#include \"session.hpp\"\n#include \"config.h\"\n#include \"src/devicemanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n\nusing std::list;\nusing std::make_pair;\nusing std::make_shared;\nusing std::map;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sigrok {\nclass Context;\n}\n\nnamespace sv {\n\nshared_ptr<sigrok::Context> Session::sr_context;\ndouble Session::session_start_timestamp = .0;\n\nSession::Session(DeviceManager &device_manager) :\n\tdevice_manager_(device_manager)\n{\n\tsmu_script_runner_ = make_shared<python::SmuScriptRunner>(*this);\n\tconnect(smu_script_runner_.get(), &python::SmuScriptRunner::script_error,\n\t\tthis, &Session::error_handler);\n\n\t// Connect devices\n\tfor (const auto &device : device_manager.user_spec_devices()) {\n\t\tthis->add_device(device);\n\t}\n}\n\nSession::~Session()\n{\n\tfor (auto &device_pair_ : device_map_)\n\t\tdevice_pair_.second->close();\n}\n\nDeviceManager &Session::device_manager()\n{\n\treturn device_manager_;\n}\n\nconst DeviceManager &Session::device_manager() const\n{\n\treturn device_manager_;\n}\n\nmap<string, shared_ptr<devices::BaseDevice>> Session::device_map() const\n{\n\treturn device_map_;\n}\n\nlist<shared_ptr<devices::HardwareDevice>>\n\tSession::connect_device(const string &conn_string)\n{\n\t// Determine the driver name and options (in generic format).\n\tvector<string> driver_opts = sv::util::split_string(conn_string, \":\");\n\tstring driver_name = driver_opts.front();\n\tdriver_opts.erase(driver_opts.begin());\n\n\t// Scan for the specified driver, passing scan options.\n\tlist<shared_ptr<devices::HardwareDevice>> devices =\n\t\tdevice_manager_.driver_scan(driver_name, driver_opts);\n\n\tfor (const auto &device : devices)\n\t\tadd_device(device);\n\n\treturn devices;\n}\n\nvoid Session::add_device(shared_ptr<devices::BaseDevice> device)\n{\n\tassert(device);\n\n\ttry {\n\t\tdevice->open();\n\t}\n\tcatch (const QString &e) {\n\t\tqCritical() << e;\n\t\tdevice.reset();\n\t}\n\n\tconnect(device.get(), &devices::BaseDevice::device_error,\n\t\tthis, &Session::error_handler);\n\n\tdevice_map_.insert(make_pair(device->id(), device));\n\n\tQ_EMIT device_added(device);\n}\n\nshared_ptr<devices::UserDevice> Session::add_user_device()\n{\n\tstring vendor = \"SmuView\";\n\tstring model = \"User Device\";\n\tstring version = SV_VERSION_STRING;\n\n\tauto device = make_shared<devices::UserDevice>(\n\t\tsr_context, vendor, model, version);\n\tthis->add_device(device);\n\n\treturn device;\n}\n\nvoid Session::remove_device(shared_ptr<devices::BaseDevice> device)\n{\n\tif (device) {\n\t\tdevice->close();\n\n\t\tdisconnect(device.get(), &devices::BaseDevice::device_error,\n\t\t\tthis, &Session::error_handler);\n\n\t\tdevice_map_.erase(device->id());\n\n\t\tQ_EMIT device_removed(device);\n\t}\n}\n\n\nshared_ptr<python::SmuScriptRunner> Session::smu_script_runner()\n{\n\treturn smu_script_runner_;\n}\n\nvoid Session::run_smu_script(const string &script_file)\n{\n\tsmu_script_runner_->run(script_file);\n}\n\nvoid Session::set_main_window(MainWindow *main_window)\n{\n\tmain_window_ = main_window;\n}\n\nMainWindow *Session::main_window() const\n{\n\treturn main_window_;\n}\n\nvoid Session::error_handler(const std::string &sender, const std::string &msg)\n{\n\tqCritical() << QString::fromStdString(sender) <<\n\t\t\" error: \" << QString::fromStdString(msg);\n}\n\n} // namespace sv\n"
  },
  {
    "path": "src/session.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SESSION_HPP\n#define SESSION_HPP\n\n#include <list>\n#include <map>\n#include <memory>\n#include <string>\n\n#include <QObject>\n#include <QSettings>\n\nusing std::list;\nusing std::map;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sigrok {\nclass Context;\n}\n\nnamespace sv {\n\nclass DeviceManager;\nclass MainWindow;\n\nnamespace devices {\nclass BaseDevice;\nclass HardwareDevice;\nclass UserDevice;\n}\n\nnamespace python {\nclass SmuScriptRunner;\n}\n\nclass Session : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tstatic shared_ptr<sigrok::Context> sr_context;\n\t// TODO: use std::chrono / std::time\n\tstatic double session_start_timestamp;\n\npublic:\n\texplicit Session(DeviceManager &device_manager);\n\t~Session();\n\n\tDeviceManager &device_manager();\n\tconst DeviceManager &device_manager() const;\n\n\tmap<string, shared_ptr<devices::BaseDevice>> device_map() const;\n\tlist<shared_ptr<devices::HardwareDevice>> connect_device(\n\t\tconst string &conn_string);\n\tvoid add_device(shared_ptr<devices::BaseDevice> device);\n\tshared_ptr<devices::UserDevice> add_user_device();\n\tvoid remove_device(shared_ptr<devices::BaseDevice> device);\n\n\tshared_ptr<python::SmuScriptRunner> smu_script_runner();\n\tvoid run_smu_script(const string &script_file);\n\n\tvoid set_main_window(MainWindow *main_window);\n\tMainWindow *main_window() const;\n\nprivate:\n\tDeviceManager &device_manager_;\n\tmap<string, shared_ptr<devices::BaseDevice>> device_map_;\n\tMainWindow *main_window_;\n\tshared_ptr<python::SmuScriptRunner> smu_script_runner_;\n\n\tvoid free_unused_memory();\n\nprivate Q_SLOTS:\n\tvoid error_handler(const std::string &sender, const std::string &msg);\n\nQ_SIGNALS:\n\tvoid device_added(shared_ptr<sv::devices::BaseDevice> device);\n\tvoid device_removed(shared_ptr<sv::devices::BaseDevice> device);\n\n};\n\n} // namespace sv\n\n#endif // SESSION_HPP\n"
  },
  {
    "path": "src/settingsmanager.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QSettings>\n\n#include \"settingsmanager.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\nusing sv::devices::DeviceType;\n\nnamespace sv {\n\nbool SettingsManager::restore_settings_ = true;\n\nSettingsManager::SettingsManager()\n{\n}\n\nstring SettingsManager::format_key(const string &str)\n{\n\tstring str_formated = str;\n\tstd::replace(str_formated.begin(), str_formated.end(), ':', '_');\n\tstd::replace(str_formated.begin(), str_formated.end(), '/', '_');\n\tstd::replace(str_formated.begin(), str_formated.end(), '\\\\', '_');\n\treturn str_formated;\n}\n\nbool SettingsManager::restore_settings()\n{\n\treturn SettingsManager::restore_settings_;\n}\n\nvoid SettingsManager::set_restore_settings(bool restore_settings)\n{\n\tSettingsManager::restore_settings_ = restore_settings;\n}\n\nbool SettingsManager::has_device_settings(\n\tshared_ptr<devices::BaseDevice> device)\n{\n\tQSettings settings;\n\treturn settings.childGroups().contains(device->settings_id());\n}\n\nvoid SettingsManager::save_configurable(\n\tconst shared_ptr<devices::Configurable> &configurable,\n\tQSettings &settings, shared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tif (origin_device == nullptr ||\n\t\t\torigin_device->settings_id() != configurable->device_settings_id()) {\n\t\t// Only store the device value if this specific configurable belongs to\n\t\t// an other device than the tab-/device-setting (origin_device) it is\n\t\t// stored into, belongs to (>= 0.0.5).\n\t\tsettings.setValue(key_prefix + \"device\",\n\t\t\tQVariant(configurable->device_settings_id()));\n\t}\n\tsettings.setValue(key_prefix + \"configurable\",\n\t\tQVariant(QString::fromStdString(configurable->name())));\n}\n\nvoid SettingsManager::save_channel(\n\tconst shared_ptr<channels::BaseChannel> &channel,\n\tQSettings &settings, shared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tif (origin_device == nullptr ||\n\t\t\torigin_device->settings_id() != channel->parent_device()->settings_id()) {\n\t\t// Only store the device value if this specific channel belongs to\n\t\t// an other device than the tab-/device-setting (origin_device) it is\n\t\t// stored into, belongs to (>= 0.0.5).\n\t\tsettings.setValue(key_prefix + \"device\",\n\t\t\tQVariant(channel->parent_device()->settings_id()));\n\t}\n\tsettings.setValue(key_prefix + \"channel\",\n\t\tQVariant(QString::fromStdString(channel->name())));\n}\n\nvoid SettingsManager::save_signal(\n\tconst shared_ptr<data::BaseSignal> &signal,\n\tQSettings &settings, shared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tSettingsManager::save_channel(\n\t\tsignal->parent_channel(), settings, origin_device, key_prefix);\n\n\tsettings.setValue(key_prefix + \"signal_sr_q\",\n\t\tdata::datautil::get_sr_quantity_id(signal->quantity()));\n\tsettings.setValue(key_prefix + \"signal_sr_qf\", QVariant::fromValue<uint64_t>(\n\t\tdata::datautil::get_sr_quantity_flags_id(signal->quantity_flags())));\n}\n\nvoid SettingsManager::save_property(\n\tconst shared_ptr<data::properties::BaseProperty> &property,\n\tQSettings &settings, shared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tSettingsManager::save_configurable(\n\t\tproperty->configurable(), settings, origin_device, key_prefix);\n\n\tsettings.setValue(key_prefix + \"property_sr_type\",\n\t\tdevices::deviceutil::get_sr_config_key(property->config_key())->\n\t\t\tdata_type()->id());\n\tsettings.setValue(key_prefix + \"property_sr_ck\",\n\t\tdevices::deviceutil::get_sr_config_key_id(property->config_key()));\n}\n\nstd::shared_ptr< sv::devices::BaseDevice > sv::SettingsManager::restore_device(\n\tSession& session, QSettings& settings,\n\tstd::shared_ptr< sv::devices::BaseDevice > origin_device,\n\tconst QString &key_prefix)\n{\n\tQString device_key = key_prefix + \"device\";\n\n\tif (!settings.contains(device_key)) {\n\t\t// Use the supplied origin_device here when no device (key) is stored in\n\t\t// this setting (>= 0.0.5).\n\t\treturn origin_device;\n\t}\n\tif (origin_device != nullptr && origin_device->type() == DeviceType::DemoDev) {\n\t\t// This is a fallback for older settings (pre 0.0.5):\n\t\treturn origin_device;\n\t}\n\n\t// If a device (key) is stored in the settings, it means, that this device\n\t// differs from the device (origin_device) this tab belongs to.\n\tstring device_id = settings.value(device_key).toString().toStdString();\n\tif (session.device_map().count(device_id) == 0)\n\t\treturn nullptr;\n\n\treturn session.device_map()[device_id];\n}\n\nshared_ptr<devices::Configurable> SettingsManager::restore_configurable(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tQString configurable_key = key_prefix + \"configurable\";\n\n\tauto device = SettingsManager::restore_device(\n\t\tsession, settings, origin_device, key_prefix);\n\tif (!device)\n\t\treturn nullptr;\n\n\tif (!settings.contains(configurable_key))\n\t\treturn nullptr;\n\n\tstring conf_id = settings.value(configurable_key).toString().toStdString();\n\tif (device->configurable_map().count(conf_id) == 0)\n\t\treturn nullptr;\n\n\treturn device->configurable_map()[conf_id];\n}\n\nshared_ptr<data::properties::BaseProperty> SettingsManager::restore_property(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tQString property_key = key_prefix + \"property\";\n\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device, key_prefix);\n\tif (!configurable)\n\t\treturn nullptr;\n\n\tif (!settings.contains(property_key+\"_sr_type\") ||\n\t\t\t!settings.contains(property_key+\"_sr_ck\"))\n\t\treturn nullptr;\n\n\t//auto sr_type = settings.value(property_key+\"_sr_type\").value<int>(); // TODO\n\tauto sr_ck = settings.value(property_key+\"_sr_ck\").value<uint32_t>();\n\tauto ck = devices::deviceutil::get_config_key(sr_ck);\n\tif (configurable->property_map().count(ck) == 0)\n\t\treturn nullptr;\n\n\treturn configurable->property_map()[ck];\n}\n\nshared_ptr<channels::BaseChannel> SettingsManager::restore_channel(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tQString channel_key = key_prefix + \"channel\";\n\n\tauto device = SettingsManager::restore_device(\n\t\tsession, settings, origin_device, key_prefix);\n\tif (!device)\n\t\treturn nullptr;\n\n\tif (!settings.contains(channel_key))\n\t\treturn nullptr;\n\n\tstring channel_id = settings.value(channel_key).toString().toStdString();\n\tif (device->channel_map().count(channel_id) == 0)\n\t\treturn nullptr;\n\n\treturn device->channel_map()[channel_id];\n}\n\nshared_ptr<data::BaseSignal> SettingsManager::restore_signal(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\tconst QString &key_prefix)\n{\n\tQString signal_key = key_prefix + \"signal\";\n\n\tauto channel = SettingsManager::restore_channel(\n\t\tsession, settings, origin_device, key_prefix);\n\tif (!channel)\n\t\treturn nullptr;\n\n\tif (!settings.contains(signal_key+\"_sr_q\") ||\n\t\t\t!settings.contains(signal_key+\"_sr_qf\"))\n\t\treturn nullptr;\n\n\tauto sr_q = settings.value(signal_key+\"_sr_q\").value<uint32_t>();\n\tauto sr_qf = settings.value(signal_key+\"_sr_qf\").value<uint64_t>();\n\tauto mq = make_pair(\n\t\tdata::datautil::get_quantity(sr_q),\n\t\tdata::datautil::get_quantity_flags(sr_qf));\n\tif (channel->signal_map().count(mq) == 0)\n\t\treturn nullptr;\n\n\treturn channel->signal_map()[mq][0];\n}\n\n} // namespace sv\n"
  },
  {
    "path": "src/settingsmanager.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SETTINGSMANAGER_HPP\n#define SETTINGSMANAGER_HPP\n\n#include <memory>\n#include <string>\n\n#include <QSettings>\n#include <QString>\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\nclass BaseSignal;\n}\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nclass SettingsManager\n{\n\npublic:\n\tSettingsManager();\n\n\t/**\n\t * Replace some special character (like ':', '/' or '\\'), to use the given\n\t * string as a settings key.\n\t *\n\t * @param[in] str The string to format.\n\t *\n\t * @return The formated key.\n\t */\n\tstatic string format_key(const string &str);\n\n\t/**\n\t * Check if setting should be restored. This is controlled by the command\n\t * line option -c.\n\t *\n\t * @return true if a setting should be restored.\n\t */\n\tstatic bool restore_settings();\n\n\t/**\n\t * Set if the setting should be restored. This is used by the command\n\t * line option -c.\n\t *\n\t * @param[in] restore_settings The restore_settings flag.\n\t */\n\tstatic void set_restore_settings(bool restore_settings);\n\n\t/**\n\t * Check if a setting for this device exists.\n\t *\n\t * @param[in] device The device.\n\t *\n\t * @return true if a setting exists.\n\t */\n\tstatic bool has_device_settings(shared_ptr<sv::devices::BaseDevice> device);\n\n\t/**\n\t * Save the configurable to the settings.\n\t *\n\t * @param[in] configurable The configurable to save.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the configurable.\n\t */\n\tstatic void save_configurable(\n\t\tconst shared_ptr<sv::devices::Configurable> &configurable,\n\t\tQSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Save the channel to the settings.\n\t *\n\t * @param[in] channel The channel to save.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the channel.\n\t */\n\tstatic void save_channel(\n\t\tconst shared_ptr<sv::channels::BaseChannel> &channel,\n\t\tQSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Save the signal to the settings.\n\t *\n\t * @param[in] signal The signal to save.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the signal.\n\t */\n\tstatic void save_signal(\n\t\tconst shared_ptr<sv::data::BaseSignal> &signal,\n\t\tQSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Save the property to the settings.\n\t *\n\t * @param[in] property The property to save.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the property.\n\t */\n\tstatic void save_property(\n\t\tconst shared_ptr<sv::data::properties::BaseProperty> &property,\n\t\tQSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Restore a device from the settings.\n\t *\n\t * @param[in] session The SmuView session.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the device.\n\t *\n\t * @return The restored device.\n\t */\n\tstatic shared_ptr<sv::devices::BaseDevice> restore_device(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Restore a configurable from the settings.\n\t *\n\t * @param[in] session The SmuView session.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the configurable.\n\t *\n\t * @return The restored configurable.\n\t */\n\tstatic shared_ptr<sv::devices::Configurable> restore_configurable(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Restore a property from the settings.\n\t *\n\t * @param[in] session The SmuView session.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the property.\n\t *\n\t * @return The restored property.\n\t */\n\tstatic shared_ptr<sv::data::properties::BaseProperty> restore_property(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Restore a channel from the settings.\n\t *\n\t * @param[in] session The SmuView session.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the channel.\n\t *\n\t * @return The restored channel.\n\t */\n\tstatic shared_ptr<sv::channels::BaseChannel> restore_channel(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\n\t/**\n\t * Restore a signal from the settings.\n\t *\n\t * @param[in] session The SmuView session.\n\t * @param[in] settings The settings.\n\t * @param[in] origin_device The origin device, this settings belongs to.\n\t * @param[in] key_prefix The prefix of the settings keys for the signal.\n\t *\n\t * @return The restored signal.\n\t */\n\tstatic shared_ptr<sv::data::BaseSignal> restore_signal(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device,\n\t\tconst QString &key_prefix = \"\");\n\nprivate:\n\tstatic bool restore_settings_;\n\n};\n\n} // namespace sv\n\n#endif // SETTINGSMANAGER_HPP\n"
  },
  {
    "path": "src/ui/data/quantitycombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QVariant>\n\n#include \"quantitycombobox.hpp\"\n#include \"src/data/datautil.hpp\"\n\nQ_DECLARE_METATYPE(sv::data::Quantity)\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\n\nQuantityComboBox::QuantityComboBox(QWidget *parent) :\n\tQComboBox(parent)\n{\n\tsetup_ui();\n}\n\nvoid QuantityComboBox::select_quantity(sv::data::Quantity quantity)\n{\n\tQString name = sv::data::datautil::format_quantity(quantity);\n\tthis->setCurrentText(name);\n}\n\nsv::data::Quantity QuantityComboBox::selected_quantity()\n{\n\tQVariant data = this->currentData();\n\treturn data.value<sv::data::Quantity>();\n}\n\nvoid QuantityComboBox::setup_ui()\n{\n\tfor (const auto &q_name_pair : sv::data::datautil::get_quantity_name_map()) {\n\t\tthis->addItem(\n\t\t\tq_name_pair.second, QVariant::fromValue(q_name_pair.first));\n\t}\n}\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/data/quantitycombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATA_QUANTITYCOMBOBOX_HPP\n#define UI_DATA_QUANTITYCOMBOBOX_HPP\n\n#include <QComboBox>\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\nclass QuantityComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QuantityComboBox(QWidget *parent = nullptr);\n\n\tvoid select_quantity(sv::data::Quantity quantity);\n\tsv::data::Quantity selected_quantity();\n\nprivate:\n\tvoid setup_ui();\n\n};\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATA_QUANTITYCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/data/quantityflagslist.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QListView>\n#include <QListWidgetItem>\n#include <QVariant>\n\n#include \"quantityflagslist.hpp\"\n#include \"src/data/datautil.hpp\"\n\nQ_DECLARE_METATYPE(sv::data::QuantityFlag)\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\nQuantityFlagsList::QuantityFlagsList(QWidget *parent) :\n\tQListWidget(parent)\n{\n\tsetup_ui();\n}\n\nvoid QuantityFlagsList::select_quantity_flags(\n\tconst set<sv::data::QuantityFlag> &quantity_flags)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQListWidgetItem* item = this->item(i);\n\t\tsv::data::QuantityFlag qf =\n\t\t\titem->data(Qt::UserRole).value<sv::data::QuantityFlag>();\n\n\t\tif (quantity_flags.count(qf) > 0)\n\t\t\tthis->item(i)->setSelected(true);\n\t\telse\n\t\t\tthis->item(i)->setSelected(false);\n\t}\n}\n\nset<sv::data::QuantityFlag> QuantityFlagsList::selected_quantity_flags()\n{\n\tset<sv::data::QuantityFlag> flags;\n\tconst auto items = this->selectedItems();\n\tfor (const auto &item : items) {\n\t\tQVariant data = item->data(Qt::UserRole);\n\t\tif (data.isNull())\n\t\t\tcontinue;\n\n\t\tflags.insert(data.value<sv::data::QuantityFlag>());\n\t}\n\treturn flags;\n}\n\nvoid QuantityFlagsList::setup_ui()\n{\n\tthis->setSelectionMode(QListView::MultiSelection);\n\n\tfor (const auto &qf_name_pair : sv::data::datautil::get_quantity_flag_name_map()) {\n\t\tQListWidgetItem *item = new QListWidgetItem();\n\t\titem->setText(qf_name_pair.second);\n\t\titem->setFlags(item->flags() | Qt::ItemIsUserCheckable);\n\t\titem->setData(Qt::UserRole, QVariant::fromValue(qf_name_pair.first));\n\t\tthis->addItem(item);\n\t}\n}\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n\n"
  },
  {
    "path": "src/ui/data/quantityflagslist.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATA_QUANTITYFLAGSLIST_HPP\n#define UI_DATA_QUANTITYFLAGSLIST_HPP\n\n#include <set>\n\n#include <QListWidget>\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\nclass QuantityFlagsList : public QListWidget\n{\n\tQ_OBJECT\n\npublic:\n\texplicit QuantityFlagsList(QWidget *parent = nullptr);\n\n\tvoid select_quantity_flags(\n\t\tconst set<sv::data::QuantityFlag> &quantity_flags);\n\tset<sv::data::QuantityFlag> selected_quantity_flags();\n\nprivate:\n\tvoid setup_ui();\n\n};\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATA_QUANTITYFLAGSLIST_HPP\n\n"
  },
  {
    "path": "src/ui/data/unitcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QComboBox>\n#include <QDebug>\n#include <QVariant>\n\n#include \"unitcombobox.hpp\"\n#include \"src/data/datautil.hpp\"\n\nQ_DECLARE_METATYPE(sv::data::Unit)\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\nUnitComboBox::UnitComboBox(QWidget *parent) :\n\tQComboBox(parent)\n{\n\tsetup_ui();\n}\n\nvoid UnitComboBox::select_unit(sv::data::Unit unit)\n{\n\tQString name = sv::data::datautil::format_unit(unit);\n\tthis->setCurrentText(name);\n}\n\nsv::data::Unit UnitComboBox::selected_unit()\n{\n\tQVariant data = this->currentData();\n\treturn data.value<sv::data::Unit>();\n}\n\nvoid UnitComboBox::setup_ui()\n{\n\tfor (const auto &u_name_pair : sv::data::datautil::get_unit_name_map()) {\n\t\tthis->addItem(\n\t\t\tu_name_pair.second, QVariant::fromValue(u_name_pair.first));\n\t}\n}\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n\n"
  },
  {
    "path": "src/ui/data/unitcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATA_UNITCOMBOBOX_HPP\n#define UI_DATA_UNITCOMBOBOX_HPP\n\n#include <QComboBox>\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace data {\n\nclass UnitComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit UnitComboBox(QWidget *parent = nullptr);\n\n\tvoid select_unit(sv::data::Unit unit);\n\tsv::data::Unit selected_unit();\n\nprivate:\n\tvoid setup_ui();\n\n};\n\n} // namespace data\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATA_UNITCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/basewidget.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include \"basewidget.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nBaseWidget::BaseWidget(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update) :\n\tauto_commit_(auto_commit),\n\tauto_update_(auto_update),\n\tproperty_(property)\n{\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/basewidget.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_BASEWIDEGT_HPP\n#define UI_DATATYPES_BASEWIDEGT_HPP\n\n#include <memory>\n\n#include <QVariant>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass BaseWidget\n{\n\npublic:\n\tBaseWidget(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update);\n\n\tvirtual QVariant variant_value() const = 0;\n\nprotected:\n\tconst bool auto_commit_;\n\tconst bool auto_update_;\n\tshared_ptr<sv::data::properties::BaseProperty> property_;\n\n/*\n * NOTE: With Qt, inheriting QObject twice (in the datatype widget classes) will\n *       cause problems in moc! Because of that, this class is not inherited\n *       from QObject and therefore no virtual Q_SLOTS in here!\n *       Also this eliminates the clang-tidy clang-analyzer-optin.cplusplus.VirtualCall\n *       warning.\n */\nprotected Q_SLOTS:\n\t/**\n\t * Signal handling for Widget -> Property\n\t * NOTE: No virtual method for value_changed, because every instance has an\n\t *       other datatype for the parameter.\n\t */\n\t//virtual void value_changed(const double value) = 0;\n\n\t/**\n\t * Signal handling for Property -> Widget\n\t * NOTE: No virtual method for on_value_changed.\n\t */\n\t//virtual void on_value_changed(const QVariant &qvar) = 0;\n\n\t/**\n\t * Signal handling for Property -> Widget\n\t * NOTE: No virtual method for on_list_changed.\n\t */\n\t//virtual void on_list_changed() = 0;\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_BASEWIDEGT_HPP\n"
  },
  {
    "path": "src/ui/datatypes/boolbutton.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QApplication>\n#include <QDebug>\n\n#include \"boolbutton.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nBoolButton::BoolButton(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQPushButton(parent),\n\tBaseWidget(property, auto_commit, auto_update),\n\ton_icon_(\":/icons/status-green.svg\"),\n\toff_icon_(\":/icons/status-red.svg\"),\n\tdis_icon_(\":/icons/status-grey.svg\")\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Bool) {\n\n\t\tQString msg = QString(\"BoolButton with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid BoolButton::setup_ui()\n{\n\tthis->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tthis->setIconSize(QSize(8, 8));\n\tthis->setCheckable(true);\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable()) {\n\t\ton_value_changed(property_->value());\n\t}\n\telse {\n\t\tthis->setIcon(dis_icon_);\n\t\tthis->setText(tr(\"On/Off\"));\n\t\tthis->setChecked(false);\n\t}\n}\n\nvoid BoolButton::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget (no ckeck for getable, comes via meta package!)\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &BoolButton::on_value_changed);\n\t}\n}\n\nvoid BoolButton::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable())\n\t\tconnect(this, &BoolButton::toggled, this, &BoolButton::value_changed);\n}\n\nvoid BoolButton::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &BoolButton::toggled,\n\t\t\tthis, &BoolButton::value_changed);\n\t}\n}\n\nQVariant BoolButton::variant_value() const\n{\n\treturn QVariant(this->isChecked());\n}\n\nvoid BoolButton::value_changed(const bool value)\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(QVariant(value));\n}\n\nvoid BoolButton::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (qvar.toBool()) {\n\t\tthis->setIcon(on_icon_);\n\t\tthis->setText(tr(\"On\"));\n\t\tthis->setChecked(true);\n\t}\n\telse {\n\t\tthis->setIcon(off_icon_);\n\t\tthis->setText(tr(\"Off\"));\n\t\tthis->setChecked(false);\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid BoolButton::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/boolbutton.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_BOOLBUTTON_HPP\n#define UI_DATATYPES_BOOLBUTTON_HPP\n\n#include <memory>\n\n#include <QPushButton>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass BoolButton : public QPushButton, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tBoolButton(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tconst QIcon on_icon_;\n\tconst QIcon off_icon_;\n\tconst QIcon dis_icon_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprotected Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed(const bool value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_BOOLBUTTON_HPP\n"
  },
  {
    "path": "src/ui/datatypes/boolcheckbox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"boolcheckbox.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nBoolCheckBox::BoolCheckBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQCheckBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Bool) {\n\n\t\tQString msg = QString(\"BoolCheckBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid BoolCheckBox::setup_ui()\n{\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(false));\n}\n\nvoid BoolCheckBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget (no ckeck for getable, comes via meta package!)\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &BoolCheckBox::on_value_changed);\n\t}\n}\n\nvoid BoolCheckBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &BoolCheckBox::stateChanged,\n\t\t\tthis, &BoolCheckBox::value_changed);\n\t}\n}\n\nvoid BoolCheckBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &BoolCheckBox::stateChanged,\n\t\t\tthis, &BoolCheckBox::value_changed);\n\t}\n}\n\nQVariant BoolCheckBox::variant_value() const\n{\n\treturn QVariant(this->isChecked());\n}\n\nvoid BoolCheckBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tbool value = this->isChecked();\n\t\tproperty_->change_value(QVariant(value));\n\t}\n}\n\nvoid BoolCheckBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setChecked(qvar.toBool());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid BoolCheckBox::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/boolcheckbox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_BOOLCHECKBOX_HPP\n#define UI_DATATYPES_BOOLCHECKBOX_HPP\n\n#include <memory>\n\n#include <QCheckBox>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass BoolCheckBox : public QCheckBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tBoolCheckBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_BOOLCHECKBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/boolled.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <QHBoxLayout>\n\n#include \"boolled.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nBoolLed::BoolLed(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update,\n\t\tconst QIcon &on_icon, const QIcon &off_icon, const QIcon &dis_icon,\n\t\tconst QString &text, QWidget *parent) :\n\tQWidget(parent),\n\tBaseWidget(property, false, auto_update),\n\ton_icon_(on_icon),\n\toff_icon_(off_icon),\n\tdis_icon_(dis_icon),\n\ttext_(text)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Bool) {\n\n\t\tQString msg = QString(\"BoolLed with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid BoolLed::setup_ui()\n{\n\tQHBoxLayout *layout = new QHBoxLayout();\n\n\t// Led icon\n\tled_label_ = new QLabel();\n\tif (property_ != nullptr && property_->is_getable()) {\n\t\ton_value_changed(property_->value());\n\t}\n\telse {\n\t\tled_label_->setPixmap(\n\t\t\tdis_icon_.pixmap(16, 16, QIcon::Mode::Disabled, QIcon::State::Off));\n\t}\n\tlayout->addWidget(led_label_);\n\n\t// Text\n\tif (property_ != nullptr && text_ == nullptr) {\n\t\ttext_ = devices::deviceutil::format_config_key(\n\t\t\tproperty_->config_key());\n\t}\n\telse if (property_ == nullptr && text_ == nullptr) {\n\t\ttext_ = devices::deviceutil::format_config_key(\n\t\t\tdevices::ConfigKey::Unknown);\n\t}\n\ttext_label_ = new QLabel(text_);\n\tif (property_ == nullptr || !property_->is_getable())\n\t\ttext_label_->setDisabled(true);\n\tlayout->addWidget(text_label_);\n\n\tthis->setLayout(layout);\n}\n\nvoid BoolLed::connect_signals()\n{\n\t// Property -> Widget (no ckeck for getable, comes via meta package!)\n\tif (property_ != nullptr && auto_update_) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &BoolLed::on_value_changed);\n\t}\n}\n\nQVariant BoolLed::variant_value() const\n{\n\t// TODO: Member variable with actual state!\n\treturn QVariant(false);\n}\n\nvoid BoolLed::value_changed(const bool value)\n{\n\t(void)value;\n\t// Nothing to do here.\n}\n\nvoid BoolLed::on_value_changed(const QVariant &qvar)\n{\n\tif (qvar.toBool()) {\n\t\tled_label_->setPixmap(\n\t\t\ton_icon_.pixmap(16, 16, QIcon::Mode::Active, QIcon::State::On));\n\t}\n\telse {\n\t\tled_label_->setPixmap(\n\t\t\toff_icon_.pixmap(16, 16, QIcon::Mode::Active, QIcon::State::Off));\n\t}\n}\n\nvoid BoolLed::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/boolled.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_BOOLLED_HPP\n#define UI_DATATYPES_BOOLLED_HPP\n\n#include <memory>\n\n#include <QIcon>\n#include <QLabel>\n#include <QVariant>\n#include <QWidget>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass BoolLed : public QWidget, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tBoolLed(shared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update,\n\t\tconst QIcon &on_icon, const QIcon &off_icon, const QIcon &dis_icon,\n\t\tconst QString &text = nullptr, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tconst QIcon on_icon_;\n\tconst QIcon off_icon_;\n\tconst QIcon dis_icon_;\n\tQString text_;\n\n\tQLabel *led_label_;\n\tQLabel *text_label_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property. Nothing to do here. */\n\tvoid value_changed(const bool value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_BOOLLED_HPP\n\n"
  },
  {
    "path": "src/ui/datatypes/datatypehelper.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include \"datatypehelper.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/datatypes/boolcheckbox.hpp\"\n#include \"src/ui/datatypes/doublerangecombobox.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n#include \"src/ui/datatypes/int32spinbox.hpp\"\n#include \"src/ui/datatypes/measuredquantitycombobox.hpp\"\n#include \"src/ui/datatypes/rationalcombobox.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n#include \"src/ui/datatypes/uint64combobox.hpp\"\n#include \"src/ui/datatypes/uint64rangecombobox.hpp\"\n#include \"src/ui/datatypes/uint64spinbox.hpp\"\n\nusing std::shared_ptr;\nusing std::static_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\nnamespace datatypehelper {\n\nQWidget *get_widget_for_property(\n\tshared_ptr<sv::data::properties::BaseProperty> property,\n\tbool auto_commit, bool auto_update)\n{\n\tauto data_type = devices::deviceutil::get_data_type_for_config_key(\n\t\tproperty->config_key());\n\n\tswitch (data_type) {\n\tcase data::DataType::Int32:\n\t\treturn new Int32SpinBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::UInt64:\n\t{\n\t\t// Special handling for different list types\n\t\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\t\tstatic_pointer_cast<data::properties::UInt64Property>(property);\n\t\tif (uint64_prop->list_values().empty())\n\t\t\treturn new UInt64SpinBox(property, auto_commit, auto_update);\n\t\telse // NOLINT\n\t\t\treturn new UInt64ComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\t}\n\tcase data::DataType::Double:\n\t\treturn new DoubleSpinBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::RationalPeriod:\n\tcase data::DataType::RationalVolt:\n\t\treturn new RationalComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::String:\n\t\treturn new StringComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::Bool:\n\t\treturn new BoolCheckBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::MQ:\n\t\treturn new MeasuredQuantityComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::DoubleRange:\n\t\treturn new DoubleRangeComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::UInt64Range:\n\t\treturn new UInt64RangeComboBox(property, auto_commit, auto_update);\n\t\tbreak;\n\tcase data::DataType::KeyValue:\n\tdefault:\n\t\treturn nullptr;\n\t\tbreak;\n\t}\n\treturn nullptr;\n}\n\n} // namespace datatypehelper\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/datatypehelper.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DATATYPEHELPER_HPP\n#define UI_DATATYPES_DATATYPEHELPER_HPP\n\n#include <memory>\n\n#include <QWidget>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\nnamespace datatypehelper {\n\n/**\n * Returns the generic datatype widget for the given property type.\n *\n * @param[in] property The Property\n * @param[in] auto_commit Widget is making auto commits\n * @param[in] auto_update Widget is auto updated\n *\n * @return The generic widget for the property type\n */\nQWidget *get_widget_for_property(\n\tshared_ptr<sv::data::properties::BaseProperty>property,\n\tbool auto_commit, bool auto_update);\n\n} // namespace datatypehelper\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DATATYPEHELPER_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doublecontrol.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QVBoxLayout>\n\n#include \"doublecontrol.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/ui/datatypes/doubleslider.hpp\"\n#include \"src/ui/datatypes/doubledisplay.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleControl::DoubleControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent) :\n\tQGroupBox(parent),\n\tBaseWidget(property, auto_commit, auto_update),\n\ttitle_(title)\n{\n\tsetup_ui();\n}\n\nvoid DoubleControl::setup_ui()\n{\n\tthis->setTitle(title_);\n\n\tQSizePolicy size_policy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tsize_policy.setHorizontalStretch(0);\n\tsize_policy.setVerticalStretch(0);\n\tthis->setSizePolicy(size_policy);\n\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tdisplay_ = new DoubleDisplay(property_, true);\n\tlayout->addWidget(display_, 0, Qt::AlignCenter);\n\n\tspin_box_ = new DoubleSpinBox(property_, true, true);\n\tlayout->addWidget(spin_box_);\n\n\tslider_ = new DoubleSlider(property_, true, true);\n\tlayout->addWidget(slider_);\n\n\tthis->setLayout(layout);\n}\n\nQVariant DoubleControl::variant_value() const\n{\n\treturn QVariant(spin_box_->value());\n}\n\nvoid DoubleControl::on_value_changed(const QVariant &qvar)\n{\n\t(void)qvar;\n\t// Nothing to do here.\n}\n\nvoid DoubleControl::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doublecontrol.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLECONTROL_HPP\n#define UI_DATATYPES_DOUBLECONTROL_HPP\n\n#include <memory>\n\n#include <QGroupBox>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleDisplay;\nclass DoubleSlider;\nclass DoubleSpinBox;\n\nclass DoubleControl : public QGroupBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tQString title_;\n\n\tDoubleSpinBox *spin_box_;\n\tDoubleSlider *slider_;\n\tDoubleDisplay *display_;\n\n\tvoid setup_ui();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLECONTROL_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doubledisplay.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"doubledisplay.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/widgets/monofontdisplay.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleDisplay::DoubleDisplay(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent) :\n\twidgets::MonoFontDisplay(widgets::MonoFontDisplayType::FixedRange,\n\t\tQString(\"\"), QString(\"\"), QString(\"\"), false, parent),\n\tBaseWidget(property, false, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Double) {\n\n\t\tQString msg = QString(\"DoubleDisplay with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tDoubleDisplay::setup_ui();\n\tconnect_signals();\n}\n\nvoid DoubleDisplay::setup_ui()\n{\n\tthis->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\t\tthis->set_decimal_places(double_prop->total_digits(), double_prop->decimal_places());\n\t}\n\tif (property_ != nullptr && property_->unit() != data::Unit::Unknown &&\n\t\t\tproperty_->unit() != data::Unit::Unitless) {\n\t\tthis->set_unit(data::datautil::format_unit(property_->unit()));\n\t}\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(.0));\n}\n\nvoid DoubleDisplay::connect_signals()\n{\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &DoubleDisplay::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &DoubleDisplay::on_list_changed);\n\t}\n}\n\nQVariant DoubleDisplay::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid DoubleDisplay::value_changed(const double value)\n{\n\t(void)value;\n\t// Nothing to do here.\n}\n\nvoid DoubleDisplay::on_value_changed(const QVariant &qvar)\n{\n\tthis->set_value(qvar.toDouble());\n}\n\nvoid DoubleDisplay::on_list_changed()\n{\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\t\tthis->set_decimal_places(double_prop->total_digits(), double_prop->decimal_places());\n\n\t\tif (property_->is_getable())\n\t\t\tthis->set_value(double_prop->double_value());\n\t}\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doubledisplay.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLEDISPLAY_HPP\n#define UI_DATATYPES_DOUBLEDISPLAY_HPP\n\n#include <memory>\n\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n#include \"src/ui/widgets/monofontdisplay.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleDisplay : public widgets::MonoFontDisplay, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleDisplay(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui() override;\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property. Nothing to do here. */\n\tvoid value_changed(const double value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLEDISPLAY_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doubleknob.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <qwt_knob.h>\n\n#include \"doubleknob.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleKnob::DoubleKnob(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQwtKnob(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Double) {\n\n\t\tQString msg = QString(\"DoubleKnob with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid DoubleKnob::setup_ui()\n{\n\tthis->setKnobWidth(100);\n\tthis->setNumTurns(1);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\n\t\tthis->setLowerBound(double_prop->min());\n\t\tthis->setUpperBound(double_prop->max());\n\t\t// setSingleSteps(uint), setPageSteps(uint)\n\t\tthis->setTotalSteps(static_cast<uint>(\n\t\t\t(double_prop->max() - double_prop->min()) / double_prop->step()));\n\t\t//setScaleStepSize(double), setScaleMaxMajor(int), setScaleMaxMinor(int)\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(.0));\n}\n\nvoid DoubleKnob::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &DoubleKnob::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &DoubleKnob::on_list_changed);\n\t}\n}\n\nvoid DoubleKnob::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &DoubleKnob::valueChanged,\n\t\t\tthis, &DoubleKnob::value_changed);\n\t}\n}\n\nvoid DoubleKnob::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &DoubleKnob::valueChanged,\n\t\t\tthis, &DoubleKnob::value_changed);\n\t}\n}\n\nQVariant DoubleKnob::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid DoubleKnob::value_changed(const double value)\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(QVariant(value));\n}\n\nvoid DoubleKnob::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setValue(qvar.toDouble());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid DoubleKnob::on_list_changed()\n{\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\t\tthis->setLowerBound(double_prop->min());\n\t\tthis->setUpperBound(double_prop->max());\n\t\tthis->setTotalSteps(static_cast<uint>(\n\t\t\t(double_prop->max() - double_prop->min()) / double_prop->step()));\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setValue(double_prop->double_value());\n\t}\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doubleknob.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLEKNOB_HPP\n#define UI_DATATYPES_DOUBLEKNOB_HPP\n\n#include <memory>\n\n#include <QVariant>\n#include <qwt_knob.h>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleKnob : public QwtKnob, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleKnob(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed(const double value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLEKNOB_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doublerangecombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"doublerangecombobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doublerangeproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleRangeComboBox::DoubleRangeComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::DoubleRange) {\n\n\t\tQString msg = QString(\"DoubleRangeComboBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid DoubleRangeComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleRangeProperty> doublerange_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleRangeProperty>(property_);\n\n\t\tfor (const auto &doublerange : doublerange_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tdoublerange_prop->to_string(doublerange),\n\t\t\t\tQVariant::fromValue(doublerange));\n\t\t}\n\t}\n\telse if (property_ != nullptr && property_->is_getable()) {\n\t\tthis->addItem(property_->to_string(), property_->value());\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid DoubleRangeComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &DoubleRangeComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &DoubleRangeComboBox::on_list_changed);\n\t}\n}\n\nvoid DoubleRangeComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(\n\t\t\tthis, QOverload<int>::of(&DoubleRangeComboBox::currentIndexChanged),\n\t\t\tthis, &DoubleRangeComboBox::value_changed);\n\t}\n}\n\nvoid DoubleRangeComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(\n\t\t\tthis, QOverload<int>::of(&DoubleRangeComboBox::currentIndexChanged),\n\t\t\tthis, &DoubleRangeComboBox::value_changed);\n\t}\n}\n\nQVariant DoubleRangeComboBox::variant_value() const\n{\n\treturn this->currentData();\n}\n\nvoid DoubleRangeComboBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tproperty_->change_value(this->currentData());\n\t}\n}\n\nvoid DoubleRangeComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tshared_ptr<data::properties::DoubleRangeProperty> doublerange_prop =\n\t\tdynamic_pointer_cast<data::properties::DoubleRangeProperty>(property_);\n\tthis->setCurrentText(doublerange_prop->to_string(qvar));;\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid DoubleRangeComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::DoubleRangeProperty> doublerange_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleRangeProperty>(property_);\n\t\tfor (const auto &doublerange : doublerange_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tdoublerange_prop->to_string(doublerange),\n\t\t\t\tQVariant::fromValue(doublerange));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(doublerange_prop->to_string(property_->value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doublerangecombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLERANGECOMBOBOX_HPP\n#define UI_DATATYPES_DOUBLERANGECOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleRangeComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleRangeComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLERANGECOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doubleslider.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <qwt_slider.h>\n\n#include \"doubleslider.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleSlider::DoubleSlider(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQwtSlider(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Double) {\n\n\t\tQString msg = QString(\"DoubleSlider with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid DoubleSlider::setup_ui()\n{\n\tthis->setOrientation(Qt::Horizontal);\n\tthis->setScalePosition(QwtSlider::TrailingScale);\n\tthis->setTrough(true);\n\tthis->setGroove(false);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\n\t\tthis->setLowerBound(double_prop->min());\n\t\tthis->setUpperBound(double_prop->max());\n\t\tthis->setTotalSteps(static_cast<uint>(\n\t\t\t(double_prop->max() - double_prop->min()) / double_prop->step()));\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(.0));\n}\n\nvoid DoubleSlider::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &DoubleSlider::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &DoubleSlider::on_list_changed);\n\t}\n}\n\nvoid DoubleSlider::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &DoubleSlider::valueChanged,\n\t\t\tthis, &DoubleSlider::value_changed);\n\t}\n}\n\nvoid DoubleSlider::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &DoubleSlider::valueChanged,\n\t\t\tthis, &DoubleSlider::value_changed);\n\t}\n}\n\nQVariant DoubleSlider::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid DoubleSlider::value_changed(const double value)\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(QVariant(value));\n}\n\nvoid DoubleSlider::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setValue(qvar.toDouble());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid DoubleSlider::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\t\tthis->setLowerBound(double_prop->min());\n\t\tthis->setUpperBound(double_prop->max());\n\t\tthis->setTotalSteps(static_cast<uint>(\n\t\t\t(double_prop->max() - double_prop->min()) / double_prop->step()));\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setValue(double_prop->double_value());\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doubleslider.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLESLIDER_HPP\n#define UI_DATATYPES_DOUBLESLIDER_HPP\n\n#include <memory>\n\n#include <QVariant>\n#include <qwt_slider.h>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleSlider : public QwtSlider, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleSlider(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed(const double value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLESLIDER_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doublesmallcontrol.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QVBoxLayout>\n\n#include \"doublesmallcontrol.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/ui/datatypes/doubleknob.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleSmallControl::DoubleSmallControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent) :\n\tQGroupBox(parent),\n\tBaseWidget(property, auto_commit, auto_update),\n\ttitle_(title)\n{\n\tsetup_ui();\n}\n\nvoid DoubleSmallControl::setup_ui()\n{\n\tthis->setTitle(title_);\n\n\tQSizePolicy size_policy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tsize_policy.setHorizontalStretch(0);\n\tsize_policy.setVerticalStretch(0);\n\tthis->setSizePolicy(size_policy);\n\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tknob_ = new DoubleKnob(property_, true, true);\n\tlayout->addWidget(knob_);\n\n\tspin_box_ = new DoubleSpinBox(property_, true, true);\n\tlayout->addWidget(spin_box_);\n\n\tthis->setLayout(layout);\n}\n\nQVariant DoubleSmallControl::variant_value() const\n{\n\treturn QVariant(spin_box_->value());\n}\n\nvoid DoubleSmallControl::on_value_changed(const QVariant &qvar)\n{\n\t(void)qvar;\n\t// Nothing to do here.\n}\n\nvoid DoubleSmallControl::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doublesmallcontrol.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLESMALLCONTROL_HPP\n#define UI_DATATYPES_DOUBLESMALLCONTROL_HPP\n\n#include <memory>\n\n#include <QGroupBox>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleKnob;\nclass DoubleSpinBox;\n\nclass DoubleSmallControl : public QGroupBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleSmallControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tQString title_;\n\n\tDoubleSpinBox *spin_box_;\n\tDoubleKnob *knob_;\n\n\tvoid setup_ui();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLESMALLCONTROL_HPP\n"
  },
  {
    "path": "src/ui/datatypes/doublespinbox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"doublespinbox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nDoubleSpinBox::DoubleSpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQDoubleSpinBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Double) {\n\n\t\tQString msg = QString(\"DoubleSpinBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid DoubleSpinBox::setup_ui()\n{\n\tthis->setAlignment(Qt::AlignRight);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\n\t\tthis->setRange(double_prop->min(), double_prop->max());\n\t\tthis->setSingleStep(double_prop->step());\n\t\tthis->setDecimals(double_prop->decimal_places());\n\t}\n\telse {\n\t\tthis->setDecimals(3);\n\t}\n\tif (property_ != nullptr && property_->unit() != data::Unit::Unknown &&\n\t\t\tproperty_->unit() != data::Unit::Unitless) {\n\t\tthis->setSuffix(\n\t\t\tQString(\" %1\").arg(data::datautil::format_unit(property_->unit())));\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(.0));\n}\n\nvoid DoubleSpinBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &DoubleSpinBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &DoubleSpinBox::on_list_changed);\n\t}\n}\n\nvoid DoubleSpinBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &DoubleSpinBox::editingFinished,\n\t\t\tthis, &DoubleSpinBox::value_changed);\n\t}\n}\n\nvoid DoubleSpinBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &DoubleSpinBox::editingFinished,\n\t\t\tthis, &DoubleSpinBox::value_changed);\n\t}\n}\n\nQVariant DoubleSpinBox::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid DoubleSpinBox::value_changed()\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(QVariant(this->value()));\n}\n\nvoid DoubleSpinBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setValue(qvar.toDouble());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid DoubleSpinBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::DoubleProperty> double_prop =\n\t\t\tdynamic_pointer_cast<data::properties::DoubleProperty>(property_);\n\t\tthis->setRange(double_prop->min(), double_prop->max());\n\t\tthis->setSingleStep(double_prop->step());\n\t\tthis->setDecimals(double_prop->decimal_places());\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setValue(double_prop->double_value());\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/doublespinbox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_DOUBLESPINBOX_HPP\n#define UI_DATATYPES_DOUBLESPINBOX_HPP\n\n#include <memory>\n\n#include <QDoubleSpinBox>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass DoubleSpinBox : public QDoubleSpinBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleSpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_DOUBLESPINBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/int32spinbox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"int32spinbox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/int32property.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nInt32SpinBox::Int32SpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQSpinBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::Int32) {\n\n\t\tQString msg = QString(\"Int32SpinBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid Int32SpinBox::setup_ui()\n{\n\tthis->setAlignment(Qt::AlignRight);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::Int32Property> int32_prop =\n\t\t\tdynamic_pointer_cast<data::properties::Int32Property>(property_);\n\n\t\tthis->setRange(int32_prop->min(), int32_prop->max());\n\t\tthis->setSingleStep(int32_prop->step());\n\t}\n\tif (property_ != nullptr && property_->unit() != data::Unit::Unknown &&\n\t\t\tproperty_->unit() != data::Unit::Unitless) {\n\t\tthis->setSuffix(\n\t\t\tQString(\" %1\").arg(data::datautil::format_unit(property_->unit())));\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(0));\n}\n\nvoid Int32SpinBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &Int32SpinBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &Int32SpinBox::on_list_changed);\n\t}\n}\n\nvoid Int32SpinBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &Int32SpinBox::editingFinished,\n\t\t\tthis, &Int32SpinBox::value_changed);\n\t}\n}\n\nvoid Int32SpinBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &Int32SpinBox::editingFinished,\n\t\t\tthis, &Int32SpinBox::value_changed);\n\t}\n}\n\nQVariant Int32SpinBox::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid Int32SpinBox::value_changed()\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(QVariant(this->value()));\n}\n\nvoid Int32SpinBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setValue(qvar.toInt());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid Int32SpinBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::Int32Property> int32_prop =\n\t\t\tdynamic_pointer_cast<data::properties::Int32Property>(property_);\n\t\tthis->setRange(int32_prop->min(), int32_prop->max());\n\t\tthis->setSingleStep(int32_prop->step());\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setValue(int32_prop->int32_value());\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/int32spinbox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_INT32SPINBOX_HPP\n#define UI_DATATYPES_INT32SPINBOX_HPP\n\n#include <memory>\n\n#include <QSpinBox>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass Int32SpinBox : public QSpinBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tInt32SpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_INT32SPINBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/measuredquantitycombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n#include <vector>\n\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"measuredquantitycombobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/measuredquantityproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nQ_DECLARE_METATYPE(sv::data::measured_quantity_t)\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nMeasuredQuantityComboBox::MeasuredQuantityComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::MQ) {\n\n\t\tQString msg =\n\t\t\tQString(\"MeasuredQuantityComboBox with property of type \").append(\n\t\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid MeasuredQuantityComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::MeasuredQuantityProperty> mq_prop =\n\t\t\tdynamic_pointer_cast<data::properties::MeasuredQuantityProperty>(\n\t\t\t\tproperty_);\n\n\t\tfor (const auto &mq : mq_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tdata::datautil::format_measured_quantity(mq),\n\t\t\t\tQVariant::fromValue(mq));\n\t\t}\n\t}\n\telse if (property_ != nullptr && property_->is_getable()) {\n\t\tthis->addItem(property_->to_string(), property_->value());\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid MeasuredQuantityComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &MeasuredQuantityComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &MeasuredQuantityComboBox::on_list_changed);\n\t}\n}\n\nvoid MeasuredQuantityComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(\n\t\t\tthis, QOverload<int>::of(&MeasuredQuantityComboBox::currentIndexChanged),\n\t\t\tthis, &MeasuredQuantityComboBox::value_changed);\n\t}\n}\n\nvoid MeasuredQuantityComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(\n\t\t\tthis, QOverload<int>::of(&MeasuredQuantityComboBox::currentIndexChanged),\n\t\t\tthis, &MeasuredQuantityComboBox::value_changed);\n\t}\n}\n\nQVariant MeasuredQuantityComboBox::variant_value() const\n{\n\treturn this->currentData();\n}\n\nvoid MeasuredQuantityComboBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tproperty_->change_value(this->currentData());\n\t}\n}\n\nvoid MeasuredQuantityComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setCurrentText(data::datautil::format_measured_quantity(\n\t\tqvar.value<data::measured_quantity_t>()));\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid MeasuredQuantityComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::MeasuredQuantityProperty> mq_prop =\n\t\t\tdynamic_pointer_cast<data::properties::MeasuredQuantityProperty>(\n\t\t\t\tproperty_);\n\t\tfor (const auto &mq : mq_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tdata::datautil::format_measured_quantity(mq),\n\t\t\t\tQVariant::fromValue(mq));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(data::datautil::format_measured_quantity(\n\t\t\t\tmq_prop->measured_quantity_value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/measuredquantitycombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_MEASUREDQUANTITYCOMBOBOX_HPP\n#define UI_DATATYPES_MEASUREDQUANTITYCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass MeasuredQuantityComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tMeasuredQuantityComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_MEASUREDQUANTITYCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/rationalcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"rationalcombobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/rationalproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nRationalComboBox::RationalComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::RationalPeriod &&\n\t\t\tproperty_->data_type() != data::DataType::RationalVolt) {\n\n\t\tQString msg = QString(\"RationalComboBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid RationalComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::RationalProperty> rational_prop =\n\t\t\tdynamic_pointer_cast<data::properties::RationalProperty>(\n\t\t\t\tproperty_);\n\n\t\tfor (const auto &rational : rational_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\trational_prop->to_string(rational),\n\t\t\t\tQVariant::fromValue(rational));\n\t\t}\n\t}\n\telse if (property_ != nullptr && property_->is_getable()) {\n\t\tthis->addItem(property_->to_string(), property_->value());\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid RationalComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &RationalComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &RationalComboBox::on_list_changed);\n\t}\n}\n\nvoid RationalComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(\n\t\t\tthis, QOverload<int>::of(&RationalComboBox::currentIndexChanged),\n\t\t\tthis, &RationalComboBox::value_changed);\n\t}\n}\n\nvoid RationalComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(\n\t\t\tthis, QOverload<int>::of(&RationalComboBox::currentIndexChanged),\n\t\t\tthis, &RationalComboBox::value_changed);\n\t}\n}\n\nQVariant RationalComboBox::variant_value() const\n{\n\treturn QVariant(this->currentData());\n}\n\nvoid RationalComboBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tdata::rational_t value =\n\t\t\tthis->currentData().value<data::rational_t>();\n\t\tproperty_->change_value(QVariant::fromValue(value));\n\t}\n}\n\nvoid RationalComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tshared_ptr<data::properties::RationalProperty> rational_prop =\n\t\tdynamic_pointer_cast<data::properties::RationalProperty>(property_);\n\tthis->setCurrentText(rational_prop->to_string(qvar));\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid RationalComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::RationalProperty> rational_prop =\n\t\t\tdynamic_pointer_cast<data::properties::RationalProperty>(\n\t\t\t\tproperty_);\n\n\t\tfor (const auto &rational : rational_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\trational_prop->to_string(rational),\n\t\t\t\tQVariant::fromValue(rational));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(rational_prop->to_string(property_->value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/rationalcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_RATIONALCOMBOBOX_HPP\n#define UI_DATATYPES_RATIONALCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass RationalComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tRationalComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_RATIONALCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/stringcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"stringcombobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/stringproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nStringComboBox::StringComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::String) {\n\n\t\tQString msg = QString(\"StringComboBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid StringComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::StringProperty> string_prop =\n\t\t\tdynamic_pointer_cast<data::properties::StringProperty>(property_);\n\n\t\tconst auto str_values = string_prop->list_values();\n\t\tfor (const auto &str : str_values) {\n\t\t\tthis->addItem(str, QVariant::fromValue(str));\n\t\t}\n\t}\n\telse {\n\t\tthis->setEditable(true);\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid StringComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &StringComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &StringComboBox::on_list_changed);\n\t}\n}\n\nvoid StringComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tif (property_->is_listable()) {\n\t\t\tconnect(\n\t\t\t\tthis, QOverload<int>::of(&StringComboBox::currentIndexChanged),\n\t\t\t\tthis, &StringComboBox::value_changed);\n\t\t}\n\t\telse {\n\t\t\tconnect(this, &StringComboBox::editTextChanged,\n\t\t\t\tthis, &StringComboBox::value_changed);\n\t\t}\n\t}\n}\n\nvoid StringComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tif (property_->is_listable()) {\n\t\t\tdisconnect(\n\t\t\t\tthis, QOverload<int>::of(&StringComboBox::currentIndexChanged),\n\t\t\t\tthis, &StringComboBox::value_changed);\n\t\t}\n\t\telse {\n\t\t\tdisconnect(this, &StringComboBox::editTextChanged,\n\t\t\t\tthis, &StringComboBox::value_changed);\n\t\t}\n\t}\n}\n\nQVariant StringComboBox::variant_value() const\n{\n\treturn QVariant(this->currentData());\n}\n\nvoid StringComboBox::value_changed()\n{\n\tif (property_ != nullptr)\n\t\tproperty_->change_value(this->currentData());\n}\n\nvoid StringComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setCurrentText(qvar.toString());\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid StringComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::StringProperty> string_prop =\n\t\t\tdynamic_pointer_cast<data::properties::StringProperty>(property_);\n\t\tconst auto str_values = string_prop->list_values();\n\t\tfor (const auto &str : str_values) {\n\t\t\tthis->addItem(str, QVariant::fromValue(str));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(string_prop->string_value());\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/stringcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_STRINGCOMBOBOX_HPP\n#define UI_DATATYPES_STRINGCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass StringComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tStringComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_STRINGCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/stringlabel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <QLabel>\n\n#include \"stringlabel.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/stringproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nStringLabel::StringLabel(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent) :\n\tQLabel(parent),\n\tBaseWidget(property, false, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::String) {\n\n\t\tQString msg = QString(\"StringLabel with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid StringLabel::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_getable()) {\n\t\tshared_ptr<data::properties::StringProperty> string_prop =\n\t\t\tdynamic_pointer_cast<data::properties::StringProperty>(property_);\n\n\t\tthis->setText(string_prop->string_value());\n\t}\n\telse {\n\t\tthis->setDisabled(true);\n\t\tthis->setText(tr(\"-\"));\n\t}\n}\n\nvoid StringLabel::connect_signals()\n{\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &StringLabel::on_value_changed);\n\t}\n}\n\nQVariant StringLabel::variant_value() const\n{\n\treturn QVariant(this->text());\n}\n\nvoid StringLabel::value_changed(const QString &value)\n{\n\t(void)value;\n\t// Nothing to do here.\n}\n\nvoid StringLabel::on_value_changed(const QVariant &qvar)\n{\n\tthis->setText(qvar.toString());\n}\n\nvoid StringLabel::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/stringlabel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_STRINGLABEL_HPP\n#define UI_DATATYPES_STRINGLABEL_HPP\n\n#include <memory>\n\n#include <QLabel>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass StringLabel : public QLabel, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tStringLabel(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n\tQString text_;\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property. Nothing to do here. */\n\tvoid value_changed(const QString &value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_STRINGLABEL_HPP\n"
  },
  {
    "path": "src/ui/datatypes/stringled.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <QHBoxLayout>\n\n#include \"stringled.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nStringLed::StringLed(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update,\n\t\tconst QIcon &on_icon, const QIcon &off_icon, const QIcon &dis_icon,\n\t\tconst QString &on_value, const QString &off_value,\n\t\tconst QString &text, QWidget *parent) :\n\tQWidget(parent),\n\tBaseWidget(property, false, auto_update),\n\ton_icon_(on_icon),\n\toff_icon_(off_icon),\n\tdis_icon_(dis_icon),\n\ton_value_(on_value),\n\toff_value_(off_value),\n\ttext_(text)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::String) {\n\n\t\tQString msg = QString(\"StringLed with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid StringLed::setup_ui()\n{\n\tQHBoxLayout *layout = new QHBoxLayout();\n\n\t// Led icon\n\tled_label_ = new QLabel();\n\tif (property_ != nullptr && property_->is_getable()) {\n\t\ton_value_changed(property_->value());\n\t}\n\telse {\n\t\tled_label_->setPixmap(\n\t\t\tdis_icon_.pixmap(16, 16, QIcon::Mode::Disabled, QIcon::State::Off));\n\t}\n\tlayout->addWidget(led_label_);\n\n\t// Text\n\tif (property_ != nullptr && text_ == nullptr) {\n\t\ttext_ = devices::deviceutil::format_config_key(\n\t\t\tproperty_->config_key());\n\t}\n\telse if (property_ == nullptr && text_ == nullptr) {\n\t\ttext_ = devices::deviceutil::format_config_key(\n\t\t\tdevices::ConfigKey::Unknown);\n\t}\n\ttext_label_ = new QLabel(text_);\n\tif (property_ == nullptr || !property_->is_getable())\n\t\ttext_label_->setDisabled(true);\n\tlayout->addWidget(text_label_);\n\n\tthis->setLayout(layout);\n}\n\nvoid StringLed::connect_signals()\n{\n\t// Property -> Widget (no ckeck for getable, comes via meta package!)\n\tif (property_ != nullptr && auto_update_) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &StringLed::on_value_changed);\n\t}\n}\n\nQVariant StringLed::variant_value() const\n{\n\t// TODO: Member variable with actual state!\n\treturn QVariant(QString(\"\"));\n}\n\nvoid StringLed::value_changed(const bool value)\n{\n\t(void)value;\n\t// Nothing to do here.\n}\n\nvoid StringLed::on_value_changed(const QVariant &qvar)\n{\n\tQString value = qvar.toString();\n\tif (on_value_ != nullptr && value == on_value_) {\n\t\tled_label_->setPixmap(\n\t\t\ton_icon_.pixmap(16, 16, QIcon::Mode::Active, QIcon::State::On));\n\t}\n\telse if (off_value_ != nullptr && value == off_value_) {\n\t\tled_label_->setPixmap(\n\t\t\toff_icon_.pixmap(16, 16, QIcon::Mode::Active, QIcon::State::Off));\n\t}\n\telse {\n\t\tled_label_->setPixmap(\n\t\t\tdis_icon_.pixmap(16, 16, QIcon::Mode::Active, QIcon::State::Off));\n\t}\n}\n\nvoid StringLed::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/stringled.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_STRINGLED_HPP\n#define UI_DATATYPES_STRINGLED_HPP\n\n#include <memory>\n\n#include <QIcon>\n#include <QLabel>\n#include <QVariant>\n#include <QWidget>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass StringLed : public QWidget, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tStringLed(shared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update,\n\t\tconst QIcon &on_icon, const QIcon &off_icon, const QIcon &dis_icon,\n\t\tconst QString &on_value, const QString &off_value,\n\t\tconst QString &text = nullptr, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n\tconst QIcon on_icon_;\n\tconst QIcon off_icon_;\n\tconst QIcon dis_icon_;\n\tconst QString on_value_;\n\tconst QString off_value_;\n\tQString text_;\n\n\tQLabel *led_label_;\n\tQLabel *text_label_;\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property. Nothing to do here. */\n\tvoid value_changed(const bool value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_STRINGLED_HPP\n\n"
  },
  {
    "path": "src/ui/datatypes/thresholdcontrol.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QVBoxLayout>\n\n#include \"thresholdcontrol.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/ui/datatypes/boolbutton.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nThresholdControl::ThresholdControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tshared_ptr<sv::data::properties::BaseProperty> bool_prop,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent) :\n\tQGroupBox(parent),\n\tBaseWidget(property, auto_commit, auto_update),\n\tbool_prop_(bool_prop),\n\ttitle_(title)\n{\n\tsetup_ui();\n}\n\nvoid ThresholdControl::setup_ui()\n{\n\tthis->setTitle(title_);\n\n\tQSizePolicy size_policy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tsize_policy.setHorizontalStretch(0);\n\tsize_policy.setVerticalStretch(0);\n\tthis->setSizePolicy(size_policy);\n\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tbutton_ = new BoolButton(bool_prop_, true, true);\n\tbutton_->setSizePolicy(\n\t\tQSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tlayout->addWidget(button_);\n\n\tspin_box_ = new DoubleSpinBox(property_, true, true);\n\tspin_box_->setSizePolicy(\n\t\tQSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tlayout->addWidget(spin_box_);\n\n\tthis->setLayout(layout);\n}\n\nQVariant ThresholdControl::variant_value() const\n{\n\treturn QVariant(spin_box_->value());\n}\n\nvoid ThresholdControl::on_value_changed(const QVariant &qvar)\n{\n\t(void)qvar;\n\t// Nothing to do here.\n}\n\nvoid ThresholdControl::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/thresholdcontrol.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_THRESHOLDCONTROL_HPP\n#define UI_DATATYPES_THRESHOLDCONTROL_HPP\n\n#include <memory>\n\n#include <QGroupBox>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass BoolButton;\nclass DoubleSpinBox;\n\nclass ThresholdControl : public QGroupBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tThresholdControl(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tshared_ptr<sv::data::properties::BaseProperty> bool_prop,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tconst QString &title, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tshared_ptr<sv::data::properties::BaseProperty> bool_prop_;\n\tQString title_;\n\n\tBoolButton *button_;\n\tDoubleSpinBox *spin_box_;\n\n\tvoid setup_ui();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_THRESHOLDCONTROL_HPP\n"
  },
  {
    "path": "src/ui/datatypes/uint64combobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"uint64combobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nUInt64ComboBox::UInt64ComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::UInt64) {\n\n\t\tQString msg = QString(\"UInt64ComboBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid UInt64ComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\n\t\tfor (const auto &uint64 : uint64_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tuint64_prop->to_string(uint64),\n\t\t\t\tQVariant::fromValue(uint64));\n\t\t}\n\t}\n\telse if (property_ != nullptr && property_->is_getable()) {\n\t\tthis->addItem(property_->to_string(), property_->value());\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid UInt64ComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &UInt64ComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &UInt64ComboBox::on_list_changed);\n\t}\n}\n\nvoid UInt64ComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(\n\t\t\tthis, QOverload<int>::of(&UInt64ComboBox::currentIndexChanged),\n\t\t\tthis, &UInt64ComboBox::value_changed);\n\t}\n}\n\nvoid UInt64ComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(\n\t\t\tthis, QOverload<int>::of(&UInt64ComboBox::currentIndexChanged),\n\t\t\tthis, &UInt64ComboBox::value_changed);\n\t}\n}\n\nQVariant UInt64ComboBox::variant_value() const\n{\n\treturn this->currentData();\n}\n\nvoid UInt64ComboBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tproperty_->change_value(this->currentData());\n\t}\n}\n\nvoid UInt64ComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\tthis->setCurrentText(uint64_prop->to_string(qvar));;\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid UInt64ComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\t\tfor (const auto &uint64 : uint64_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tuint64_prop->to_string(uint64),\n\t\t\t\tQVariant::fromValue(uint64));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(uint64_prop->to_string(property_->value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/uint64combobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_UIN64COMBOBOX_HPP\n#define UI_DATATYPES_UIN64COMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass UInt64ComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64ComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_UIN64COMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/uint64label.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n#include <QLabel>\n\n#include \"uint64label.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nUInt64Label::UInt64Label(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent) :\n\tQLabel(parent),\n\tBaseWidget(property, false, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::UInt64) {\n\n\t\tQString msg = QString(\"UInt64Label with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid UInt64Label::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_getable()) {\n\t\tthis->setText(property_->to_string());\n\t}\n\telse {\n\t\tthis->setDisabled(true);\n\t\tthis->setText(tr(\"-\"));\n\t}\n}\n\nvoid UInt64Label::connect_signals()\n{\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &UInt64Label::on_value_changed);\n\t}\n}\n\nQVariant UInt64Label::variant_value() const\n{\n\treturn QVariant(this->text());\n}\n\nvoid UInt64Label::value_changed(const QString &value)\n{\n\t(void)value;\n\t// Nothing to do here.\n}\n\nvoid UInt64Label::on_value_changed(const QVariant &qvar)\n{\n\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\tthis->setText(uint64_prop->to_string(qvar));\n\n}\n\nvoid UInt64Label::on_list_changed()\n{\n\t// Nothing to do here.\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/uint64label.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_UINT64LABEL_HPP\n#define UI_DATATYPES_UINT64LABEL_HPP\n\n#include <memory>\n\n#include <QLabel>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass UInt64Label : public QLabel, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64Label(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_update, QWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n\tQString text_;\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property. Nothing to do here. */\n\tvoid value_changed(const QString &value);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget. Nothing to do here. */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_UINT64LABEL_HPP\n"
  },
  {
    "path": "src/ui/datatypes/uint64rangecombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"uint64rangecombobox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/uint64rangeproperty.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nUInt64RangeComboBox::UInt64RangeComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::UInt64Range) {\n\n\t\tQString msg = QString(\"UInt64RangeComboBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid UInt64RangeComboBox::setup_ui()\n{\n\t//this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::UInt64RangeProperty> uint64range_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64RangeProperty>(property_);\n\n\t\tfor (const auto &uint64range : uint64range_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tuint64range_prop->to_string(uint64range),\n\t\t\t\tQVariant::fromValue(uint64range));\n\t\t}\n\t}\n\telse if (property_ != nullptr && property_->is_getable()) {\n\t\tthis->addItem(property_->to_string(), property_->value());\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n}\n\nvoid UInt64RangeComboBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &UInt64RangeComboBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &UInt64RangeComboBox::on_list_changed);\n\t}\n}\n\nvoid UInt64RangeComboBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(\n\t\t\tthis, QOverload<int>::of(&UInt64RangeComboBox::currentIndexChanged),\n\t\t\tthis, &UInt64RangeComboBox::value_changed);\n\t}\n}\n\nvoid UInt64RangeComboBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(\n\t\t\tthis, QOverload<int>::of(&UInt64RangeComboBox::currentIndexChanged),\n\t\t\tthis, &UInt64RangeComboBox::value_changed);\n\t}\n}\n\nQVariant UInt64RangeComboBox::variant_value() const\n{\n\treturn this->currentData();\n}\n\nvoid UInt64RangeComboBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tproperty_->change_value(this->currentData());\n\t}\n}\n\nvoid UInt64RangeComboBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tshared_ptr<data::properties::UInt64RangeProperty> uint64range_prop =\n\t\tdynamic_pointer_cast<data::properties::UInt64RangeProperty>(property_);\n\tthis->setCurrentText(uint64range_prop->to_string(qvar));;\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid UInt64RangeComboBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tthis->clear();\n\n\t\tshared_ptr<data::properties::UInt64RangeProperty> uint64range_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64RangeProperty>(property_);\n\t\tfor (const auto &uint64range : uint64range_prop->list_values()) {\n\t\t\tthis->addItem(\n\t\t\t\tuint64range_prop->to_string(uint64range),\n\t\t\t\tQVariant::fromValue(uint64range));\n\t\t}\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setCurrentText(uint64range_prop->to_string(property_->value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/uint64rangecombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_UIN64RANGECOMBOBOX_HPP\n#define UI_DATATYPES_UIN64RANGECOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass UInt64RangeComboBox : public QComboBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64RangeComboBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_UIN64RANGECOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/datatypes/uint64spinbox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <stdexcept>\n\n#include <QDebug>\n\n#include \"uint64spinbox.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/uint64property.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace datatypes {\n\nUInt64SpinBox::UInt64SpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent) :\n\tQSpinBox(parent),\n\tBaseWidget(property, auto_commit, auto_update)\n{\n\t// Check property\n\tif (property_ != nullptr &&\n\t\t\tproperty_->data_type() != data::DataType::UInt64) {\n\n\t\tQString msg = QString(\"UInt64SpinBox with property of type \").append(\n\t\t\tdata::datautil::format_data_type(property_->data_type()));\n\t\tthrow std::runtime_error(msg.toStdString());\n\t}\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid UInt64SpinBox::setup_ui()\n{\n\tthis->setAlignment(Qt::AlignRight);\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\n\t\tthis->setRange(static_cast<int>(uint64_prop->min()),\n\t\t\tstatic_cast<int>(uint64_prop->max()));\n\t\tthis->setSingleStep(static_cast<int>(uint64_prop->step()));\n\t}\n\tif (property_ != nullptr && property_->unit() != data::Unit::Unknown &&\n\t\t\tproperty_->unit() != data::Unit::Unitless) {\n\t\tthis->setSuffix(\n\t\t\tQString(\" %1\").arg(data::datautil::format_unit(property_->unit())));\n\t}\n\tif (property_ == nullptr || !property_->is_setable())\n\t\tthis->setDisabled(true);\n\tif (property_ != nullptr && property_->is_getable())\n\t\ton_value_changed(property_->value());\n\telse\n\t\ton_value_changed(QVariant(0));\n}\n\nvoid UInt64SpinBox::connect_signals()\n{\n\t// Widget -> Property\n\tconnect_widget_2_prop_signals();\n\n\t// Property -> Widget\n\tif (auto_update_ && property_ != nullptr) {\n\t\tconnect(property_.get(), &data::properties::BaseProperty::value_changed,\n\t\t\tthis, &UInt64SpinBox::on_value_changed);\n\t\tconnect(property_.get(), &data::properties::BaseProperty::list_changed,\n\t\t\tthis, &UInt64SpinBox::on_list_changed);\n\t}\n}\n\nvoid UInt64SpinBox::connect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tconnect(this, &UInt64SpinBox::editingFinished,\n\t\t\tthis, &UInt64SpinBox::value_changed);\n\t}\n}\n\nvoid UInt64SpinBox::disconnect_widget_2_prop_signals()\n{\n\tif (auto_commit_ && property_ != nullptr && property_->is_setable()) {\n\t\tdisconnect(this, &UInt64SpinBox::editingFinished,\n\t\t\tthis, &UInt64SpinBox::value_changed);\n\t}\n}\n\nQVariant UInt64SpinBox::variant_value() const\n{\n\treturn QVariant(this->value());\n}\n\nvoid UInt64SpinBox::value_changed()\n{\n\tif (property_ != nullptr) {\n\t\tuint64_t value = this->value();\n\t\tproperty_->change_value(QVariant((qulonglong)value));\n\t}\n}\n\nvoid UInt64SpinBox::on_value_changed(const QVariant &qvar)\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tthis->setValue(static_cast<int>(qvar.toULongLong()));\n\n\tconnect_widget_2_prop_signals();\n}\n\nvoid UInt64SpinBox::on_list_changed()\n{\n\t// Disconnect Widget -> Property signal to prevent echoing\n\tdisconnect_widget_2_prop_signals();\n\n\tif (property_ != nullptr && property_->is_listable()) {\n\t\tshared_ptr<data::properties::UInt64Property> uint64_prop =\n\t\t\tdynamic_pointer_cast<data::properties::UInt64Property>(property_);\n\t\tthis->setRange(static_cast<int>(uint64_prop->min()),\n\t\t\tstatic_cast<int>(uint64_prop->max()));\n\t\tthis->setSingleStep(static_cast<int>(uint64_prop->step()));\n\n\t\tif (property_->is_getable())\n\t\t\tthis->setValue(static_cast<int>(uint64_prop->uint64_value()));\n\t}\n\n\tconnect_widget_2_prop_signals();\n}\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/datatypes/uint64spinbox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DATATYPES_UINT64SPINBOX_HPP\n#define UI_DATATYPES_UINT64SPINBOX_HPP\n\n#include <memory>\n\n#include <QSpinBox>\n#include <QVariant>\n\n#include \"src/ui/datatypes/basewidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\n\nnamespace ui {\nnamespace datatypes {\n\nclass UInt64SpinBox : public QSpinBox, public BaseWidget\n{\n\tQ_OBJECT\n\npublic:\n\tUInt64SpinBox(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tconst bool auto_commit, const bool auto_update,\n\t\tQWidget *parent = nullptr);\n\n\tQVariant variant_value() const override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\tvoid connect_widget_2_prop_signals();\n\tvoid disconnect_widget_2_prop_signals();\n\nprivate Q_SLOTS:\n\t/** Signal handling for Widget -> Property */\n\tvoid value_changed();\n\t/** Signal handling for Property -> Widget */\n\tvoid on_value_changed(const QVariant &qvar);\n\t/** Signal handling for Property -> Widget */\n\tvoid on_list_changed();\n\n};\n\n} // namespace datatypes\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DATATYPES_UINT64SPINBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/channelcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <map>\n#include <memory>\n#include <string>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"channelcombobox.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nQ_DECLARE_METATYPE(shared_ptr<sv::channels::BaseChannel>)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nChannelComboBox::ChannelComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tconst QString &channel_group, QWidget *parent) :\n\tQComboBox(parent),\n\tdevice_(device),\n\tchannel_group_(channel_group),\n\tfilter_active_(false)\n{\n\tsetup_ui();\n}\n\nvoid ChannelComboBox::filter_quantity(sv::data::Quantity quantity)\n{\n\tfilter_active_ = true;\n\tfilter_quantity_ = quantity;\n\t// Refill combo box to apply filter.\n\tthis->fill_channels();\n}\n\nvoid ChannelComboBox::select_channel(\n\tshared_ptr<sv::channels::BaseChannel> channel)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQVariant data = this->itemData(i, Qt::UserRole);\n\t\tauto item_channel = data.value<shared_ptr<sv::channels::BaseChannel>>();\n\t\tif (item_channel == channel) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nshared_ptr<sv::channels::BaseChannel> ChannelComboBox::selected_channel() const\n{\n\tQVariant data = this->currentData();\n\treturn data.value<shared_ptr<sv::channels::BaseChannel>>();\n}\n\nvoid ChannelComboBox::setup_ui()\n{\n\tthis->setSizeAdjustPolicy(QComboBox::AdjustToContents);\n\tthis->fill_channels();\n}\n\nvoid ChannelComboBox::fill_channels()\n{\n\tdisconnect(\n\t\tthis, QOverload<int>::of(&ChannelComboBox::currentIndexChanged),\n\t\tthis, &ChannelComboBox::channel_changed);\n\n\tthis->clear();\n\n\tif (device_ == nullptr)\n\t\treturn;\n\n\tif (channel_group_ == nullptr)\n\t\tchannel_group_ = \"\";\n\n\tstring chg_str = channel_group_.toStdString();\n\tif (device_->channel_group_map().count(chg_str) == 0)\n\t\treturn;\n\n\tauto ch_list = device_->channel_group_map()[chg_str];\n\tfor (const auto &ch : ch_list) {\n\t\t// Check if channel contains a signal with the filter quantity.\n\t\tif (filter_active_) {\n\t\t\tbool found = false;\n\t\t\tfor (const auto &signal : ch->signals()) {\n\t\t\t\tif (filter_quantity_ == signal->quantity()) {\n\t\t\t\t\tfound = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!found)\n\t\t\t\tcontinue;\n\t\t}\n\n\t\tthis->addItem(\n\t\t\tQString::fromStdString(ch->name()),\n\t\t\tQVariant::fromValue(ch));\n\t}\n\n\tconnect(\n\t\tthis, QOverload<int>::of(&ChannelComboBox::currentIndexChanged),\n\t\tthis, &ChannelComboBox::channel_changed);\n\tQ_EMIT channel_changed();\n}\n\nvoid ChannelComboBox::change_device_channel_group(\n\tshared_ptr<sv::devices::BaseDevice> device, const QString &channel_group)\n{\n\tdevice_ = device;\n\tchannel_group_ = channel_group;\n\tthis->fill_channels();\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/channelcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_CHANNELCOMBOBOX_HPP\n#define UI_DEVICES_CHANNELCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ChannelComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\tChannelComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tconst QString &channel_group, QWidget *parent = nullptr);\n\n\tvoid filter_quantity(sv::data::Quantity quantity);\n\tvoid select_channel(shared_ptr<sv::channels::BaseChannel> channel);\n\tshared_ptr<sv::channels::BaseChannel> selected_channel() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid fill_channels();\n\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\tQString channel_group_;\n\tbool filter_active_;\n\tsv::data::Quantity filter_quantity_;\n\npublic Q_SLOTS:\n\tvoid change_device_channel_group(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tconst QString &channel_group);\n\nQ_SIGNALS:\n\tvoid channel_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_CHANNELCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/channelgroupcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <map>\n#include <memory>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QString>\n#include <QVariant>\n\n#include \"channelgroupcombobox.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nChannelGroupComboBox::ChannelGroupComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,  QWidget *parent) :\n\tQComboBox(parent),\n\tdevice_(device)\n{\n\tthis->setup_ui();\n}\n\nvoid ChannelGroupComboBox::select_channel_group(const QString &channel_group)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQString cg = this->itemText(i);\n\t\tif (cg == channel_group) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nQString ChannelGroupComboBox::selected_channel_group() const\n{\n\treturn this->currentText();\n}\n\nvoid ChannelGroupComboBox::setup_ui()\n{\n\tthis->setSizeAdjustPolicy(QComboBox::AdjustToContents);\n\tthis->fill_channel_groups();\n}\n\nvoid ChannelGroupComboBox::fill_channel_groups()\n{\n\tdisconnect(\n\t\tthis, QOverload<int>::of(&ChannelGroupComboBox::currentIndexChanged),\n\t\tthis, &ChannelGroupComboBox::channel_group_changed);\n\n\tthis->clear();\n\n\tif (device_ == nullptr)\n\t\treturn;\n\n\tfor (const auto &chg_pair : device_->channel_group_map()) {\n\t\tthis->addItem(QString::fromStdString(chg_pair.first));\n\t}\n\n\tconnect(\n\t\tthis, QOverload<int>::of(&ChannelGroupComboBox::currentIndexChanged),\n\t\tthis, &ChannelGroupComboBox::channel_group_changed);\n\tQ_EMIT channel_group_changed();\n}\n\nvoid ChannelGroupComboBox::change_device(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tdevice_ = device;\n\tthis->fill_channel_groups();\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/channelgroupcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_CHANNELGROUPCOMBOBOX_HPP\n#define UI_DEVICES_CHANNELGROUPCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QString>\n#include <QWidget>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ChannelGroupComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ChannelGroupComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent = nullptr);\n\n\tvoid select_channel_group(const QString &channel_group);\n\tQString selected_channel_group() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid fill_channel_groups();\n\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\npublic Q_SLOTS:\n\tvoid change_device(shared_ptr<sv::devices::BaseDevice> device);\n\nQ_SIGNALS:\n\tvoid channel_group_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_CHANNELGROUPCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/configkeycombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QVariant>\n\n#include \"configkeycombobox.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(sv::devices::ConfigKey)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nConfigKeyComboBox::ConfigKeyComboBox(\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tconfigurable_(configurable)\n{\n\tsetup_ui();\n}\n\nvoid ConfigKeyComboBox::filter_config_keys(\n\tconst set<sv::data::DataType> &data_types)\n{\n\tfilter_data_types_ = data_types;\n\tthis->fill_config_keys();\n}\n\nvoid ConfigKeyComboBox::select_config_key(sv::devices::ConfigKey config_key)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQVariant data = this->itemData(i, Qt::UserRole);\n\t\tauto item_ck = data.value<sv::devices::ConfigKey>();\n\t\tif (item_ck == config_key) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nsv::devices::ConfigKey ConfigKeyComboBox::selected_config_key() const\n{\n\tQVariant data = this->currentData();\n\treturn data.value<sv::devices::ConfigKey>();\n}\n\nvoid ConfigKeyComboBox::setup_ui()\n{\n\tthis->setSizeAdjustPolicy(QComboBox::AdjustToContents);\n\tthis->fill_config_keys();\n}\n\nvoid ConfigKeyComboBox::fill_config_keys()\n{\n\tdisconnect(\n\t\tthis, QOverload<int>::of(&ConfigKeyComboBox::currentIndexChanged),\n\t\tthis, &ConfigKeyComboBox::config_key_changed);\n\n\tthis->clear();\n\n\tif (configurable_ == nullptr)\n\t\treturn;\n\n\t// TODO: Filter for getable, setable, listable\n\tfor (const auto &config_key : configurable_->setable_configs()) {\n\t\tsv::data::DataType dt =\n\t\t\tsv::devices::deviceutil::get_data_type_for_config_key(config_key);\n\t\tif (filter_data_types_.empty() || filter_data_types_.count(dt) > 0) {\n\t\t\tthis->addItem(\n\t\t\t\tsv::devices::deviceutil::format_config_key(config_key),\n\t\t\t\tQVariant::fromValue(config_key));\n\t\t}\n\t}\n\n\tconnect(\n\t\tthis, QOverload<int>::of(&ConfigKeyComboBox::currentIndexChanged),\n\t\tthis, &ConfigKeyComboBox::config_key_changed);\n\tQ_EMIT config_key_changed();\n}\n\nvoid ConfigKeyComboBox::change_configurable(\n\tshared_ptr<sv::devices::Configurable> configurable)\n{\n\tconfigurable_ = configurable;\n\tthis->fill_config_keys();\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/configkeycombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_CONFIGKEYCOMBOBOX_HPP\n#define UI_DEVICES_CONFIGKEYCOMBOBOX_HPP\n\n#include <memory>\n#include <set>\n\n#include <QComboBox>\n#include <QWidget>\n\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass Configurable;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ConfigKeyComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ConfigKeyComboBox(\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQWidget *parent = nullptr);\n\n\tvoid filter_config_keys(const set<sv::data::DataType> &data_types);\n\tvoid select_config_key(sv::devices::ConfigKey config_key);\n\tsv::devices::ConfigKey selected_config_key() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid fill_config_keys();\n\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\tset<sv::data::DataType> filter_data_types_;\n\npublic Q_SLOTS:\n\tvoid change_configurable(\n\t\tshared_ptr<sv::devices::Configurable> configurable);\n\nQ_SIGNALS:\n\tvoid config_key_changed();\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_CONFIGKEYCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/configurablecombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <map>\n#include <memory>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QVariant>\n\n#include \"configurablecombobox.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nConfigurableComboBox::ConfigurableComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tdevice_(device)\n{\n\tsetup_ui();\n}\n\nvoid ConfigurableComboBox::select_configurable(\n\tshared_ptr<sv::devices::Configurable> configurable)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQVariant data = this->itemData(i, Qt::UserRole);\n\t\tauto item_config = data.value<shared_ptr<sv::devices::Configurable>>();\n\t\tif (item_config == configurable) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nshared_ptr<sv::devices::Configurable>\n\tConfigurableComboBox::selected_configurable() const\n{\n\tQVariant data = this->currentData();\n\treturn data.value<shared_ptr<sv::devices::Configurable>>();\n}\n\nvoid ConfigurableComboBox::setup_ui()\n{\n\tthis->setSizeAdjustPolicy(QComboBox::AdjustToContents);\n\tthis->fill_configurables();\n}\n\nvoid ConfigurableComboBox::fill_configurables()\n{\n\tdisconnect(\n\t\tthis, QOverload<int>::of(&ConfigurableComboBox::currentIndexChanged),\n\t\tthis, &ConfigurableComboBox::configurable_changed);\n\n\tthis->clear();\n\n\tif (device_ == nullptr)\n\t\treturn;\n\n\tfor (const auto &c_pair : device_->configurable_map()) {\n\t\t// Only show configurables that either are getable, setable or listable.\n\t\tauto configurable = c_pair.second;\n\t\tif (!configurable->is_controllable())\n\t\t\tcontinue;\n\n\t\tthis->addItem(\n\t\t\tconfigurable->display_name(),\n\t\t\tQVariant::fromValue(configurable));\n\t}\n\n\tconnect(\n\t\tthis, QOverload<int>::of(&ConfigurableComboBox::currentIndexChanged),\n\t\tthis, &ConfigurableComboBox::configurable_changed);\n\tQ_EMIT configurable_changed();\n}\n\nvoid ConfigurableComboBox::change_device(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tdevice_ = device;\n\tthis->fill_configurables();\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/configurablecombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_CONFIGURABLECOMBOBOX_HPP\n#define UI_DEVICES_CONFIGURABLECOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QWidget>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ConfigurableComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ConfigurableComboBox(\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent = nullptr);\n\n\tvoid select_configurable(shared_ptr<sv::devices::Configurable> configurable);\n\tshared_ptr<sv::devices::Configurable> selected_configurable() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid fill_configurables();\n\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\npublic Q_SLOTS:\n\tvoid change_device(shared_ptr<sv::devices::BaseDevice> device);\n\nQ_SIGNALS:\n\tvoid configurable_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_CONFIGURABLECOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/devicecombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QDebug>\n#include <QVariant>\n\n#include \"devicecombobox.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(shared_ptr<sv::devices::BaseDevice>)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nDeviceComboBox::DeviceComboBox(const Session &session, QWidget *parent) :\n\tQComboBox(parent),\n\tsession_(session)\n{\n\tsetup_ui();\n}\n\nvoid DeviceComboBox::select_device(shared_ptr<sv::devices::BaseDevice> device)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQVariant data = this->itemData(i, Qt::UserRole);\n\t\tauto item_device = data.value<shared_ptr<sv::devices::BaseDevice>>();\n\t\tif (item_device == device) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nshared_ptr<sv::devices::BaseDevice> DeviceComboBox::selected_device() const\n{\n\tQVariant data = this->currentData();\n\treturn data.value<shared_ptr<sv::devices::BaseDevice>>();\n}\n\nvoid DeviceComboBox::setup_ui()\n{\n\tfor (const auto &device_pair : session_.device_map()) {\n\t\tthis->addItem(\n\t\t\tdevice_pair.second->full_name(),\n\t\t\tQVariant::fromValue(device_pair.second));\n\t}\n\n\tconnect(this, QOverload<int>::of(&DeviceComboBox::currentIndexChanged),\n\t\tthis, &DeviceComboBox::device_changed);\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/devicecombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_DEVICECOMBOBOX_HPP\n#define UI_DEVICES_DEVICECOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QWidget>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass DeviceComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit DeviceComboBox(const Session &session, QWidget *parent = nullptr);\n\n\tvoid select_device(shared_ptr<sv::devices::BaseDevice> device);\n\tshared_ptr<sv::devices::BaseDevice> selected_device() const;\n\nprivate:\n\tvoid setup_ui();\n\n\tconst Session &session_;\n\nQ_SIGNALS:\n\tvoid device_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_DEVICECOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/devices/devicetree/devicetreemodel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QDebug>\n#include <QStandardItem>\n#include <QStandardItemModel>\n#include <QString>\n#include <QVariant>\n\n#include \"devicetreemodel.hpp\"\n#include \"src/session.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/ui/devices/devicetree/treeitem.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nDeviceTreeModel::DeviceTreeModel(const Session &session,\n\t\tbool is_device_checkable, bool is_channel_group_checkable,\n\t\tbool is_channel_checkable, bool is_signal_checkable,\n\t\tbool is_configurable_checkable, bool is_config_key_checkable,\n\t\tbool show_configurable, QObject *parent) :\n\tQStandardItemModel(parent),\n\tsession_(session),\n\tis_device_checkable_(is_device_checkable),\n\tis_channel_group_checkable_(is_channel_group_checkable),\n\tis_channel_checkable_(is_channel_checkable),\n\tis_signal_checkable_(is_signal_checkable),\n\tis_configurable_checkable_(is_configurable_checkable),\n\tis_config_key_checkable_(is_config_key_checkable),\n\tshow_configurable_(show_configurable)\n{\n\tthis->itemPrototype();\n\tsetup_model();\n}\n\nvoid DeviceTreeModel::setup_model()\n{\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\tsetSortRole(DeviceTreeModel::SortRole);\n\n\tconnect(&session_, &Session::device_added,\n\t\tthis, &DeviceTreeModel::on_device_added);\n\tconnect(&session_, &Session::device_removed,\n\t\tthis, &DeviceTreeModel::on_device_removed);\n\n\tfor (const auto &device_pair : session_.device_map()) {\n\t\tshared_ptr<sv::devices::BaseDevice> device = device_pair.second;\n\t\tadd_device(device);\n\t}\n\n\tinvisibleRootItem()->sortChildren(0);\n}\n\nvoid DeviceTreeModel::add_device(shared_ptr<sv::devices::BaseDevice> device)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\t/*\n\tthis->setFirstItemColumnSpanned(device_item, true);\n\t*/\n\n\t// Look for existing device\n\tTreeItem *device_item = find_device(device);\n\tif (!device_item) {\n\t\tbeginInsertRows(invisibleRootItem()->index(),\n\t\t\tinvisibleRootItem()->rowCount(), invisibleRootItem()->rowCount()+1);\n\t\tdevice_item = new TreeItem(TreeItemType::DeviceItem);\n\t\tdevice_item->setText(device->full_name());\n\t\tdevice_item->setData(QVariant::fromValue(device), DeviceTreeModel::DataRole);\n\t\tdevice_item->setData(device->full_name(), DeviceTreeModel::SortRole);\n\t\tdevice_item->setCheckable(is_device_checkable_);\n\t\tdevice_item->setEditable(false);\n\t\tinvisibleRootItem()->appendRow(device_item);\n\t\tendInsertRows();\n\n\t\tinvisibleRootItem()->sortChildren(0);\n\n\t\tconnect(device.get(), &sv::devices::BaseDevice::channel_added,\n\t\t\tthis, &DeviceTreeModel::on_channel_added);\n\t}\n\n\t// Channels and ChannelGroups\n\tfor (const auto &channel_pair : device->channel_map()) {\n\t\tadd_channel(channel_pair.second,\n\t\t\tchannel_pair.second->channel_group_names(), device_item);\n\t}\n\n\t// Configurables and ConfigKeys\n\tfor (const auto &configurable_pair : device->configurable_map()) {\n\t\tadd_configurable(configurable_pair.second, device_item);\n\t}\n}\n\nTreeItem *DeviceTreeModel::add_channel_group(const string &channel_group_name,\n\tTreeItem *device_item)\n{\n\tif (channel_group_name.empty())\n\t\treturn device_item;\n\n\t// Look for already existing channel group\n\tTreeItem *chg_item = find_channel_group(channel_group_name, device_item);\n\tif (chg_item)\n\t\treturn chg_item;\n\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\tQString chg_name_qstr = QString::fromStdString(channel_group_name);\n\tbeginInsertRows(device_item->index(),\n\t\tdevice_item->rowCount(), device_item->rowCount()+1);\n\tchg_item = new TreeItem(TreeItemType::ChannelGroupItem);\n\tchg_item->setText(chg_name_qstr);\n\tchg_item->setData(chg_name_qstr, DeviceTreeModel::DataRole);\n\tchg_item->setData(chg_name_qstr, DeviceTreeModel::SortRole);\n\tchg_item->setCheckable(is_channel_group_checkable_);\n\tchg_item->setEditable(false);\n\tdevice_item->appendRow(chg_item);\n\tendInsertRows();\n\n\tdevice_item->sortChildren(0);\n\n\treturn chg_item;\n}\n\nvoid DeviceTreeModel::add_channel(shared_ptr<channels::BaseChannel> channel,\n\tconst set<string> &channel_group_names, TreeItem *parent_item)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\t// Find existing channel in all channel groups\n\t// NOLINTNEXTLINE(readability-implicit-bool-conversion)\n\tif (!find_channel(channel, channel->channel_group_names(), parent_item)) {\n\t\tconnect(channel.get(), &channels::BaseChannel::signal_added,\n\t\t\tthis, &DeviceTreeModel::on_signal_added);\n\t}\n\n\tfor (const auto &chg_name : channel_group_names) {\n\t\tTreeItem *new_parent_item = add_channel_group(chg_name, parent_item);\n\n\t\t// Look for existing channel\n\t\tset<string> chg_names { chg_name };\n\t\tTreeItem *channel_item = find_channel(channel, chg_names, parent_item);\n\t\tif (!channel_item) {\n\t\t\tbeginInsertRows(new_parent_item->index(),\n\t\t\t\tnew_parent_item->rowCount(), new_parent_item->rowCount()+1);\n\t\t\tchannel_item = new TreeItem(TreeItemType::ChannelItem);\n\t\t\tchannel_item->setText(QString::fromStdString(channel->name()));\n\t\t\tchannel_item->setData(QVariant::fromValue(channel), DeviceTreeModel::DataRole);\n\t\t\tchannel_item->setData(channel->index(), DeviceTreeModel::SortRole);\n\t\t\tchannel_item->setCheckable(is_channel_checkable_);\n\t\t\tchannel_item->setEditable(false);\n\t\t\tnew_parent_item->appendRow(channel_item);\n\t\t\tendInsertRows();\n\n\t\t\tnew_parent_item->sortChildren(0);\n\t\t}\n\n\t\t// Signals\n\t\tfor (const auto &signal_pair : channel->signal_map()) {\n\t\t\tfor (const auto &signal : signal_pair.second) {\n\t\t\t\tadd_signal(signal, channel_item);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvoid DeviceTreeModel::add_signal(shared_ptr<sv::data::BaseSignal> signal,\n\tTreeItem *parent_item)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\t// Look for existing signal\n\tTreeItem *signal_item = find_signal(signal, parent_item);\n\tif (!signal_item) {\n\t\tbeginInsertRows(parent_item->index(),\n\t\t\tparent_item->rowCount(), parent_item->rowCount()+1);\n\t\tsignal_item = new TreeItem(TreeItemType::SignalItem);\n\t\tsignal_item->setText(signal->display_name());\n\t\tsignal_item->setData(QVariant::fromValue(signal), DeviceTreeModel::DataRole);\n\t\tsignal_item->setData(signal->display_name(), DeviceTreeModel::SortRole); // TODO: signal->index()\n\t\tsignal_item->setCheckable(is_signal_checkable_);\n\t\tsignal_item->setEditable(false);\n\t\tparent_item->appendRow(signal_item);\n\t\tendInsertRows();\n\n\t\tparent_item->sortChildren(0);\n\t}\n}\n\nvoid DeviceTreeModel::add_configurable(\n\tshared_ptr<sv::devices::Configurable> configurable, TreeItem *device_item)\n{\n\tif (!show_configurable_)\n\t\treturn;\n\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\t// Find existing configurable in device and all channel groups\n\tTreeItem *conf_item = find_configurable(configurable, device_item);\n\tif (!conf_item) {\n\t\tTreeItem *new_parent_item = add_channel_group(\n\t\t\tconfigurable->name(), device_item);\n\n\t\t// Add configurable item\n\t\tbeginInsertRows(new_parent_item->index(),\n\t\t\tnew_parent_item->rowCount(), new_parent_item->rowCount()+1);\n\t\tconf_item = new TreeItem(TreeItemType::ConfigurableItem);\n\t\tconf_item->setText(configurable->display_name());\n\t\tconf_item->setData(QVariant::fromValue(configurable), DeviceTreeModel::DataRole);\n\t\tconf_item->setData(configurable->index(), DeviceTreeModel::SortRole);\n\t\tconf_item->setCheckable(false);\n\t\tconf_item->setEditable(false);\n\t\tnew_parent_item->appendRow(conf_item);\n\t\tendInsertRows();\n\n\t\tnew_parent_item->sortChildren(0);\n\t}\n\n\t// ConfigKeys\n\tfor (const auto &property_pair : configurable->property_map()) {\n\t\tadd_property(property_pair.second, conf_item);\n\t}\n}\n\nvoid DeviceTreeModel::add_property(\n\tshared_ptr<sv::data::properties::BaseProperty> property,\n\tTreeItem *configurable_item)\n{\n\tif (!show_configurable_)\n\t\treturn;\n\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\t// Look for existing property\n\tTreeItem *property_item = find_property(property, configurable_item);\n\tif (!property_item) {\n\t\tbeginInsertRows(configurable_item->index(),\n\t\t\tconfigurable_item->rowCount(), configurable_item->rowCount()+1);\n\t\tproperty_item = new TreeItem(TreeItemType::PropertyItem);\n\t\tproperty_item->setText(property->display_name());\n\t\tproperty_item->setData(QVariant::fromValue(property), DeviceTreeModel::DataRole);\n\t\tproperty_item->setData(property->display_name(), DeviceTreeModel::SortRole);\n\t\tproperty_item->setCheckable(is_signal_checkable_);\n\t\tproperty_item->setEditable(false);\n\t\tconfigurable_item->appendRow(property_item);\n\t\tendInsertRows();\n\n\t\tconfigurable_item->sortChildren(0);\n\t}\n}\n\nTreeItem *DeviceTreeModel::find_device(\n\tshared_ptr<sv::devices::BaseDevice> device) const\n{\n\tfor (int i=0; i<invisibleRootItem()->rowCount(); ++i) {\n\t\tauto *child = invisibleRootItem()->child(i);\n\t\tif (child->type() != (int)TreeItemType::DeviceItem)\n\t\t\tcontinue;\n\n\t\tif (device.get() == child->data(DeviceTreeModel::DataRole).\n\t\t\t\tvalue<shared_ptr<sv::devices::BaseDevice>>().get())\n\t\t\treturn static_cast<TreeItem *>(child);\n\t}\n\treturn nullptr;\n}\n\nTreeItem *DeviceTreeModel::find_channel_group(const string &channel_group_name,\n\tTreeItem *parent_item) const\n{\n\tfor (int i=0; i<parent_item->rowCount(); ++i) {\n\t\tauto *child = parent_item->child(i);\n\t\tif (child->type() != (int)TreeItemType::ChannelGroupItem)\n\t\t\tcontinue;\n\n\t\tQString chg_name_qstr = QString::fromStdString(channel_group_name);\n\t\tif (chg_name_qstr == child->data(DeviceTreeModel::DataRole).toString())\n\t\t\treturn static_cast<TreeItem *>(child);\n\t}\n\treturn nullptr;\n}\n\nTreeItem *DeviceTreeModel::find_channel(\n\tshared_ptr<sv::channels::BaseChannel> channel,\n\tconst set<string> &channel_group_names, TreeItem *parent_item) const\n{\n\tTreeItem *new_parent_item;\n\tfor (const auto &chg_name : channel_group_names) {\n\t\tif (!chg_name.empty()) {\n\t\t\tnew_parent_item = find_channel_group(chg_name, parent_item);\n\t\t\tif (!new_parent_item)\n\t\t\t\tcontinue;\n\t\t}\n\t\telse\n\t\t\tnew_parent_item = parent_item;\n\n\t\tfor (int i=0; i<new_parent_item->rowCount(); ++i) {\n\t\t\tauto *child = new_parent_item->child(i);\n\t\t\tif (child->type() != (int)TreeItemType::ChannelItem)\n\t\t\t\tcontinue;\n\n\t\t\tif (channel.get() == child->data(DeviceTreeModel::DataRole).\n\t\t\t\t\tvalue<shared_ptr<sv::channels::BaseChannel>>().get())\n\t\t\t\treturn static_cast<TreeItem *>(child);\n\t\t}\n\t}\n\treturn nullptr;\n}\n\nTreeItem *DeviceTreeModel::find_signal (\n\tshared_ptr<sv::data::BaseSignal> signal, TreeItem *parent_item) const\n{\n\tfor (int i=0; i<parent_item->rowCount(); ++i) {\n\t\tauto *child = parent_item->child(i);\n\t\tif (child->type() != (int)TreeItemType::SignalItem)\n\t\t\tcontinue;\n\n\t\tif (signal.get() == child->data(DeviceTreeModel::DataRole).\n\t\t\t\tvalue<shared_ptr<sv::data::BaseSignal>>().get())\n\t\t\treturn static_cast<TreeItem *>(child);\n\t}\n\treturn nullptr;\n}\n\nTreeItem *DeviceTreeModel::find_configurable(\n\tshared_ptr<sv::devices::Configurable> configurable,\n\tTreeItem *device_item) const\n{\n\tTreeItem *new_parent_item;\n\tif (!configurable->name().empty()) {\n\t\tnew_parent_item = find_channel_group(configurable->name(), device_item);\n\t\tif (!new_parent_item)\n\t\t\treturn nullptr;\n\t}\n\telse {\n\t\tnew_parent_item = device_item;\n\t}\n\n\tfor (int i=0; i<new_parent_item->rowCount(); ++i) {\n\t\tauto *child = new_parent_item->child(i);\n\t\tif (child->type() != (int)TreeItemType::ConfigurableItem)\n\t\t\tcontinue;\n\n\t\tif (configurable.get() == child->data(DeviceTreeModel::DataRole).\n\t\t\t\tvalue<shared_ptr<sv::devices::Configurable>>().get())\n\t\t\treturn static_cast<TreeItem *>(child);\n\t}\n\treturn nullptr;\n}\n\nTreeItem *DeviceTreeModel::find_property(\n\tshared_ptr<sv::data::properties::BaseProperty> property,\n\tTreeItem *configurable_item) const\n{\n\tfor (int i=0; i<configurable_item->rowCount(); ++i) {\n\t\tauto *child = configurable_item->child(i);\n\t\tif (child->type() != (int)TreeItemType::PropertyItem)\n\t\t\tcontinue;\n\n\t\tif (property.get() == child->data(DeviceTreeModel::DataRole).\n\t\t\t\tvalue<shared_ptr<sv::data::properties::BaseProperty>>().get())\n\t\t\treturn static_cast<TreeItem *>(child);\n\t}\n\treturn nullptr;\n}\n\nvoid DeviceTreeModel::on_device_added(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tadd_device(device);\n}\n\nvoid DeviceTreeModel::on_device_removed(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n\n\tTreeItem *item = find_device(device);\n\tif (item) {\n\t\tremoveRow(item->row(), invisibleRootItem()->index());\n\t}\n}\n\nvoid DeviceTreeModel::on_channel_added(\n\tshared_ptr<channels::BaseChannel> channel)\n{\n\tshared_ptr<sv::devices::BaseDevice> device = channel->parent_device();\n\t// Device must exist\n\tTreeItem *device_item = find_device(device);\n\tadd_channel(channel, channel->channel_group_names(), device_item);\n}\n\nvoid DeviceTreeModel::on_channel_removed(\n\tshared_ptr<channels::BaseChannel> channel)\n{\n\t(void)channel;\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n}\n\nvoid DeviceTreeModel::on_signal_added(shared_ptr<sv::data::BaseSignal> signal)\n{\n\tshared_ptr<sv::channels::BaseChannel> channel = signal->parent_channel();\n\ton_channel_added(channel);\n}\n\nvoid DeviceTreeModel::on_signal_removed(shared_ptr<sv::data::BaseSignal> signal)\n{\n\t(void)signal;\n\tstd::lock_guard<std::recursive_mutex> lock(mutex_);\n}\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/devicetree/devicetreemodel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_DEVICETREE_DEVICETREEMODEL_HPP\n#define UI_DEVICES_DEVICETREE_DEVICETREEMODEL_HPP\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n#include <vector>\n\n#include <QStandardItem>\n#include <QStandardItemModel>\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass BaseSignal;\nnamespace properties {\nclass BaseProperty;\n}\n}\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nclass TreeItem;\n\nclass DeviceTreeModel : public QStandardItemModel\n{\n\tQ_OBJECT\n\npublic:\n\texplicit DeviceTreeModel(const Session &session,\n\t\tbool is_device_checkable, bool is_channel_group_checkable,\n\t\tbool is_channel_checkable, bool is_signal_checkable,\n\t\tbool is_configurable_checkable, bool is_config_key_checkable,\n\t\tbool show_configurable, QObject *parent = nullptr);\n\n\tTreeItem *find_device(shared_ptr<sv::devices::BaseDevice> device) const;\n\n\tconst static int DataRole = Qt::UserRole + 1;\n\tconst static int SortRole = Qt::UserRole + 2;\n\nprivate:\n\tvoid setup_model();\n\n\tvoid add_device(shared_ptr<sv::devices::BaseDevice> device);\n\tTreeItem *add_channel_group(\n\t\tconst string &channel_group_name, TreeItem *device_item);\n\tvoid add_channel(shared_ptr<sv::channels::BaseChannel> channel,\n\t\tconst set<string> &channel_group_names, TreeItem *parent_item);\n\tvoid add_signal(shared_ptr<sv::data::BaseSignal> signal,\n\t\tTreeItem *parent_item);\n\tvoid add_configurable(shared_ptr<sv::devices::Configurable> configurable,\n\t\tTreeItem *device_item);\n\tvoid add_property(shared_ptr<sv::data::properties::BaseProperty> property,\n\t\tTreeItem *configurable_item);\n\n\tTreeItem *find_channel_group(const string &channel_group_name,\n\t\tTreeItem *parent_item) const;\n\tTreeItem *find_channel(shared_ptr<sv::channels::BaseChannel> channel,\n\t\tconst set<string> &channel_group_names, TreeItem *parent_item) const;\n\tTreeItem *find_signal(shared_ptr<sv::data::BaseSignal> signal,\n\t\tTreeItem *parent_item) const;\n\tTreeItem *find_configurable(\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tTreeItem *device_item) const;\n\tTreeItem *find_property(\n\t\tshared_ptr<sv::data::properties::BaseProperty> property,\n\t\tTreeItem *configurable_item) const;\n\n\tconst Session &session_;\n\tbool is_device_checkable_;\n\tbool is_channel_group_checkable_;\n\tbool is_channel_checkable_;\n\tbool is_signal_checkable_;\n\tbool is_configurable_checkable_;\n\tbool is_config_key_checkable_;\n\tbool show_configurable_;\n\tstd::recursive_mutex mutex_;\n\nprivate Q_SLOTS:\n\tvoid on_device_added(shared_ptr<sv::devices::BaseDevice> device);\n\tvoid on_device_removed(shared_ptr<sv::devices::BaseDevice> device);\n\tvoid on_channel_added(shared_ptr<sv::channels::BaseChannel> channel);\n\tvoid on_channel_removed(shared_ptr<sv::channels::BaseChannel> channel);\n\tvoid on_signal_added(shared_ptr<sv::data::BaseSignal> signal);\n\tvoid on_signal_removed(shared_ptr<sv::data::BaseSignal> signal);\n\n};\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_DEVICETREE_DEVICETREEMODEL_HPP\n"
  },
  {
    "path": "src/ui/devices/devicetree/devicetreeview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QDebug>\n#include <QItemSelectionModel>\n#include <QList>\n#include <QModelIndex>\n#include <QModelIndexList>\n#include <QTreeView>\n#include <QVariant>\n\n#include \"devicetreeview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/devices/devicetree/devicetreemodel.hpp\"\n#include \"src/ui/devices/devicetree/treeitem.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nDeviceTreeView::DeviceTreeView(const Session &session,\n\t\tbool is_device_checkable, bool is_channel_group_checkable,\n\t\tbool is_channel_checkable, bool is_signal_checkable,\n\t\tbool is_configurable_checkable, bool is_config_key_checkable,\n\t\tbool show_configurable, bool is_auto_expand, QWidget *parent) :\n\tQTreeView(parent),\n\tsession_(session),\n\tis_device_checkable_(is_device_checkable),\n\tis_channel_group_checkable_(is_channel_group_checkable),\n\tis_channel_checkable_(is_channel_checkable),\n\tis_signal_checkable_(is_signal_checkable),\n\tis_configurable_checkable_(is_configurable_checkable),\n\tis_config_key_checkable_(is_config_key_checkable),\n\tshow_configurable_(show_configurable),\n\tis_auto_expand_(is_auto_expand)\n{\n\tsetup_ui();\n}\n\n\nvoid DeviceTreeView::select_device(shared_ptr<sv::devices::BaseDevice> device)\n{\n\tTreeItem *item = tree_model_->find_device(device);\n\tthis->select_item(item);\n}\n\nvoid DeviceTreeView::select_item(TreeItem *item)\n{\n\tselectionModel()->select(item->index(), QItemSelectionModel::Select);\n}\n\nTreeItem *DeviceTreeView::selected_item() const\n{\n\tQModelIndex index = selectionModel()->currentIndex();\n\tif (!index.isValid())\n\t\treturn nullptr;\n\n\t// We can't use item->internalPointer() here, because somehow it points\n\t// to the parent item!?\n\t// TODO: Use qobject_cast()?\n\treturn static_cast<TreeItem *>(static_cast<QStandardItemModel *>(model())->\n\t\titemFromIndex(index));\n}\n\nvoid DeviceTreeView::check_channels(\n\tconst vector<shared_ptr<sv::channels::BaseChannel>> &channels)\n{\n\tif (!is_channel_checkable_)\n\t\treturn;\n\n\tconst QList<QStandardItem *> all_items =\n\t\ttree_model_->findItems(\"\", Qt::MatchContains | Qt::MatchRecursive);\n\n\t// First uncheck all channels\n\tfor (const auto &item : all_items) {\n\t\tif (item->type() == (int)TreeItemType::ChannelItem) {\n\t\t\titem->setCheckState(Qt::Unchecked);\n\t\t}\n\t}\n\n\t// Now check all channels that are in the channels vector\n\tfor (const auto &item : all_items) {\n\t\tif (item->type() == (int)TreeItemType::ChannelItem) {\n\t\t\tauto item_data =\n\t\t\t\titem->data().value<shared_ptr<sv::channels::BaseChannel>>();\n\t\t\tfor (const auto &channel :channels) {\n\t\t\t\tif (item_data.get() == channel.get())\n\t\t\t\t\titem->setCheckState(Qt::Checked);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvector<shared_ptr<sv::channels::BaseChannel>>\n\tDeviceTreeView::checked_channels() const\n{\n\tvector<shared_ptr<channels::BaseChannel>> channels;\n\n\tif (!is_channel_checkable_)\n\t\treturn channels;\n\n\tconst QList<QStandardItem *> all_items =\n\t\ttree_model_->findItems(\"\", Qt::MatchContains | Qt::MatchRecursive);\n\tfor (const auto &item : all_items) {\n\t\tif (item->checkState() > 0 &&\n\t\t\t\titem->type() == (int)TreeItemType::ChannelItem) {\n\t\t\tchannels.push_back(\n\t\t\t\titem->data().value<shared_ptr<sv::channels::BaseChannel>>());\n\t\t}\n\t}\n\treturn channels;\n}\n\nvoid DeviceTreeView::check_signals(\n\tconst vector<shared_ptr<sv::data::BaseSignal>> &signals)\n{\n\tif (!is_signal_checkable_)\n\t\treturn;\n\n\tconst QList<QStandardItem *> all_items =\n\t\ttree_model_->findItems(\"\", Qt::MatchContains | Qt::MatchRecursive);\n\n\t// First uncheck all signals\n\tfor (const auto &item : all_items) {\n\t\tif (item->type() == (int)TreeItemType::SignalItem) {\n\t\t\titem->setCheckState(Qt::Unchecked);\n\t\t}\n\t}\n\n\t// Now check all signals that are in the signals vector\n\tfor (const auto &item : all_items) {\n\t\tif (item->type() == (int)TreeItemType::SignalItem) {\n\t\t\tauto item_data =\n\t\t\t\titem->data().value<shared_ptr<sv::data::BaseSignal>>();\n\t\t\tfor (const auto &signal : signals) {\n\t\t\t\tif (item_data.get() == signal.get())\n\t\t\t\t\titem->setCheckState(Qt::Checked);\n\t\t\t}\n\t\t}\n\t}\n}\n\nvector<shared_ptr<sv::data::BaseSignal>>\n\tDeviceTreeView::checked_signals() const\n{\n\tvector<shared_ptr<sv::data::BaseSignal>> signals;\n\n\tif (!is_signal_checkable_)\n\t\treturn signals;\n\n\tconst QList<QStandardItem *> all_items =\n\t\ttree_model_->findItems(\"\", Qt::MatchContains | Qt::MatchRecursive);\n\tfor (const auto &item : all_items) {\n\t\tif (item->checkState() > 0 &&\n\t\t\t\titem->type() == (int)TreeItemType::SignalItem) {\n\t\t\tsignals.push_back(\n\t\t\t\titem->data().value<shared_ptr<sv::data::BaseSignal>>());\n\t\t}\n\t}\n\treturn signals;\n}\n\nvoid DeviceTreeView::expand_device(shared_ptr<sv::devices::BaseDevice> device)\n{\n\tTreeItem *item = tree_model_->find_device(device);\n\tthis->expand_recursive(item);\n}\n\nvoid DeviceTreeView::setup_ui()\n{\n\ttree_model_ = new DeviceTreeModel(session_,\n\t\tis_device_checkable_, is_channel_group_checkable_,\n\t\tis_channel_checkable_, is_signal_checkable_,\n\t\tis_configurable_checkable_, is_config_key_checkable_,\n\t\tshow_configurable_);\n\n    this->setModel(tree_model_);\n\tthis->setHeaderHidden(true);\n\n\tif (is_auto_expand_)\n\t\tthis->expand_recursive(tree_model_->invisibleRootItem());\n\telse\n\t\tthis->collapseAll();\n\n\tconnect(tree_model_, &DeviceTreeModel::rowsInserted,\n\t\tthis, &DeviceTreeView::on_rows_inserted);\n}\n\nvoid DeviceTreeView::expand_recursive(QStandardItem *item)\n{\n\tif (!item)\n\t\treturn;\n\n\tif (item->type() == (int)TreeItemType::ConfigurableItem)\n\t\treturn;\n\n\tthis->expand(tree_model_->indexFromItem(item));\n\tfor (int i=0; i<item->rowCount(); ++i) {\n\t\texpand_recursive(item->child(i));\n\t}\n}\n\nvoid DeviceTreeView::on_rows_inserted(const QModelIndex &model_index,\n\tint first, int last)\n{\n\t(void)first;\n\t(void)last;\n\n\tif (is_auto_expand_)\n\t\tthis->expand_recursive(tree_model_->itemFromIndex(model_index));\n}\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/devicetree/devicetreeview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_DEVICETREE_DEVICETREEVIEW_HPP\n#define UI_DEVICES_DEVICETREE_DEVICETREEVIEW_HPP\n\n#include <memory>\n#include <vector>\n\n#include <QModelIndex>\n#include <QStandardItem>\n#include <QTreeView>\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass BaseSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nclass DeviceTreeModel;\nclass TreeItem;\n\nclass DeviceTreeView : public QTreeView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit DeviceTreeView(const Session &session,\n\t\tbool is_device_checkable, bool is_channel_group_checkable,\n\t\tbool is_channel_checkable, bool is_signal_checkable,\n\t\tbool is_configurable_checkable, bool is_config_key_checkable,\n\t\tbool show_configurable, bool is_auto_expand, QWidget *parent = nullptr);\n\n\tvoid select_device(shared_ptr<sv::devices::BaseDevice> device);\n\n\tvoid select_item(TreeItem *item);\n\tTreeItem *selected_item() const;\n\n\tvoid check_channels(const vector<shared_ptr<sv::channels::BaseChannel>> &channels);\n\tvector<shared_ptr<sv::channels::BaseChannel>> checked_channels() const;\n\tvoid check_signals(const vector<shared_ptr<sv::data::BaseSignal>> &signals);\n\tvector<shared_ptr<sv::data::BaseSignal>> checked_signals() const;\n\n\tvoid expand_device(shared_ptr<sv::devices::BaseDevice> device);\n\nprivate:\n\tvoid setup_ui();\n\tvoid expand_recursive(QStandardItem *item);\n\n\tconst Session &session_;\n\tbool is_device_checkable_;\n\tbool is_channel_group_checkable_;\n\tbool is_channel_checkable_;\n\tbool is_signal_checkable_;\n\tbool is_configurable_checkable_;\n\tbool is_config_key_checkable_;\n\tbool show_configurable_;\n\tbool is_auto_expand_;\n\tDeviceTreeModel *tree_model_;\n\nprivate Q_SLOTS:\n\tvoid on_rows_inserted(const QModelIndex &model_index, int first, int last);\n\n};\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_DEVICETREE_DEVICETREEVIEW_HPP\n"
  },
  {
    "path": "src/ui/devices/devicetree/treeitem.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QIcon>\n#include <QStandardItem>\n\n#include \"treeitem.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nTreeItem::TreeItem(TreeItemType type) :\n\tQStandardItem(),\n\ttype_(type)\n{\n\tif (type == TreeItemType::DeviceItem) {\n\t\tsetIcon(QIcon(\":/icons/smuview.png\"));\n\t}\n\telse if (type == TreeItemType::ChannelGroupItem) {\n\t\tsetIcon(QIcon::fromTheme(\"document-open-folder\",\n\t\t\tQIcon(\":/icons/document-open-folder.png\")));\n\t}\n\telse if (type == TreeItemType::ChannelItem) {\n\t\tsetIcon(QIcon::fromTheme(\"office-chart-area\",\n\t\t\tQIcon(\":/icons/office-chart-area.png\")));\n\t}\n\telse if (type == TreeItemType::SignalItem) {\n\t\tsetIcon(QIcon::fromTheme(\"office-chart-line\",\n\t\t\tQIcon(\":/icons/office-chart-line.png\")));\n\t}\n\telse if (type == TreeItemType::ConfigurableItem) {\n\t\tsetIcon(QIcon::fromTheme(\"mixer-front\",\n\t\t\tQIcon(\":/icons/mixer-front.png\")));\n\t}\n\telse if (type == TreeItemType::PropertyItem) {\n\t\tsetIcon(QIcon::fromTheme(\"configure\",\n\t\t\tQIcon(\":/icons/configure.png\")));\n\t}\n}\n\nint TreeItem::type() const\n{\n\treturn (int)type_;\n}\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/devicetree/treeitem.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_DEVICETREE_TREEITEM_HPP\n#define UI_DEVICES_DEVICETREE_TREEITEM_HPP\n\n#include <QStandardItem>\n#include <QIcon>\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\nnamespace devicetree {\n\nenum class TreeItemType {\n\tDeviceItem = 1001,\n\tChannelGroupItem = 1002,\n\tChannelItem = 1003,\n\tSignalItem = 1004,\n\tConfigurableItem = 1005,\n\tPropertyItem = 1006,\n};\n\nclass TreeItem : public QStandardItem\n{\n\npublic:\n\texplicit TreeItem(TreeItemType type);\n\n\tint type() const override;\n\nprotected:\n\tTreeItemType type_;\n\n};\n\n} // namespace devicetree\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_DEVICETREE_TREEITEM_HPP\n"
  },
  {
    "path": "src/ui/devices/selectconfigurableform.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QDebug>\n#include <QVariant>\n\n#include \"selectconfigurableform.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/devices/configurablecombobox.hpp\"\n#include \"src/ui/devices/devicecombobox.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(shared_ptr<sv::data::BaseSignal>)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nSelectConfigurableForm::SelectConfigurableForm(\n\t\tconst Session &session, QWidget *parent) :\n\tQFormLayout(parent),\n\tsession_(session)\n{\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid SelectConfigurableForm::select_device(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tdevice_box_->select_device(device);\n}\n\nshared_ptr<sv::devices::Configurable>\n\tSelectConfigurableForm::selected_configurable() const\n{\n\treturn configurable_box_->selected_configurable();\n}\n\nvoid SelectConfigurableForm::setup_ui()\n{\n\tdevice_box_ = new DeviceComboBox(session_);\n\tthis->addRow(tr(\"Device\"), device_box_);\n\n\tconfigurable_box_ = new ConfigurableComboBox(\n\t\tdevice_box_->selected_device());\n\tthis->addRow(tr(\"Configurable\"), configurable_box_);\n}\n\nvoid SelectConfigurableForm::connect_signals()\n{\n\tconnect(device_box_, &DeviceComboBox::device_changed,\n\t\tthis, &SelectConfigurableForm::on_device_changed);\n\tconnect(configurable_box_, &ConfigurableComboBox::configurable_changed,\n\t\tthis, &SelectConfigurableForm::configurable_changed);\n}\n\nvoid SelectConfigurableForm::on_device_changed()\n{\n\tconfigurable_box_->change_device(device_box_->selected_device());\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/selectconfigurableform.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_SELECTCONFIGURABLEFORM_HPP\n#define UI_DEVICES_SELECTCONFIGURABLEFORM_HPP\n\n#include <memory>\n\n#include <QFormLayout>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ConfigurableComboBox;\nclass DeviceComboBox;\n\nclass SelectConfigurableForm : public QFormLayout\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SelectConfigurableForm(const Session &session,\n\t\tQWidget *parent = nullptr);\n\n\tvoid select_device(shared_ptr<sv::devices::BaseDevice> device);\n\tshared_ptr<sv::devices::Configurable> selected_configurable() const;\n\nprivate:\n\tconst Session &session_;\n\n\tDeviceComboBox *device_box_;\n\tConfigurableComboBox *configurable_box_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\tvoid on_device_changed();\n\nQ_SIGNALS:\n\tvoid configurable_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_SELECTCONFIGURABLEFORM_HPP\n"
  },
  {
    "path": "src/ui/devices/selectpropertyform.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n\n#include <QDebug>\n#include <QVariant>\n\n#include \"selectpropertyform.hpp\"\n#include \"src/session.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/devices/configkeycombobox.hpp\"\n#include \"src/ui/devices/configurablecombobox.hpp\"\n#include \"src/ui/devices/devicecombobox.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nSelectPropertyForm::SelectPropertyForm(\n\t\tconst Session &session, QWidget *parent) :\n\tQFormLayout(parent),\n\tsession_(session)\n{\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid SelectPropertyForm::filter_config_keys(\n\tconst set<sv::data::DataType> &data_types)\n{\n\tconfig_key_box_->filter_config_keys(data_types);\n}\n\nvoid SelectPropertyForm::select_device(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tdevice_box_->select_device(device);\n}\n\nvoid SelectPropertyForm::select_configurable(\n\tshared_ptr<sv::devices::Configurable> configurable)\n{\n\tconfigurable_box_->select_configurable(configurable);\n}\n\nvoid SelectPropertyForm::select_config_key(\n\tsv::devices::ConfigKey config_key)\n{\n\tconfig_key_box_->select_config_key(config_key);\n}\n\nshared_ptr<sv::devices::BaseDevice> SelectPropertyForm::selected_device() const\n{\n\treturn device_box_->selected_device();\n}\n\nshared_ptr<sv::devices::Configurable>\n\tSelectPropertyForm::selected_configurable() const\n{\n\treturn configurable_box_->selected_configurable();\n}\n\nshared_ptr<sv::data::properties::BaseProperty>\n\tSelectPropertyForm::selected_property() const\n{\n\treturn configurable_box_->selected_configurable()->get_property(\n\t\tconfig_key_box_->selected_config_key());\n}\n\nsv::devices::ConfigKey SelectPropertyForm::selected_config_key() const\n{\n\treturn config_key_box_->selected_config_key();\n}\n\nvoid SelectPropertyForm::setup_ui()\n{\n\tdevice_box_ = new DeviceComboBox(session_);\n\tthis->addRow(tr(\"Device\"), device_box_);\n\n\tconfigurable_box_ = new ConfigurableComboBox(\n\t\tdevice_box_->selected_device());\n\tthis->addRow(tr(\"Configurable\"), configurable_box_);\n\n\tconfig_key_box_ = new ConfigKeyComboBox(\n\t\tconfigurable_box_->selected_configurable());\n\tthis->addRow(tr(\"Config Key\"), config_key_box_);\n}\n\nvoid SelectPropertyForm::connect_signals()\n{\n\tconnect(device_box_, &DeviceComboBox::device_changed,\n\t\tthis, &SelectPropertyForm::on_device_changed);\n\tconnect(configurable_box_, &ConfigurableComboBox::configurable_changed,\n\t\tthis, &SelectPropertyForm::on_configurable_changed);\n\tconnect(config_key_box_, &ConfigKeyComboBox::config_key_changed,\n\t\tthis, &SelectPropertyForm::config_key_changed);\n}\n\nvoid SelectPropertyForm::on_device_changed()\n{\n\tconfigurable_box_->change_device(device_box_->selected_device());\n}\n\nvoid SelectPropertyForm::on_configurable_changed()\n{\n\tconfig_key_box_->change_configurable(\n\t\tconfigurable_box_->selected_configurable());\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/selectpropertyform.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_SELECTPROPERTYFORM_HPP\n#define UI_DEVICES_SELECTPROPERTYFORM_HPP\n\n#include <memory>\n#include <set>\n\n#include <QFormLayout>\n\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nnamespace properties {\nclass BaseProperty;\n}\n}\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ConfigKeyComboBox;\nclass ConfigurableComboBox;\nclass DeviceComboBox;\n\nclass SelectPropertyForm : public QFormLayout\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SelectPropertyForm(const Session &session,\n\t\tQWidget *parent = nullptr);\n\n\tvoid filter_config_keys(const set<sv::data::DataType> &data_types);\n\tvoid select_device(shared_ptr<sv::devices::BaseDevice> device);\n\tvoid select_configurable(shared_ptr<sv::devices::Configurable> configurable);\n\tvoid select_config_key(sv::devices::ConfigKey config_key);\n\tshared_ptr<sv::devices::BaseDevice> selected_device() const;\n\tshared_ptr<sv::devices::Configurable> selected_configurable() const;\n\tshared_ptr<sv::data::properties::BaseProperty> selected_property() const;\n\tsv::devices::ConfigKey selected_config_key() const;\n\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n\tconst Session &session_;\n\n\tDeviceComboBox *device_box_;\n\tConfigurableComboBox *configurable_box_;\n\tConfigKeyComboBox *config_key_box_;\n\nprivate Q_SLOTS:\n\tvoid on_device_changed();\n\tvoid on_configurable_changed();\n\nQ_SIGNALS:\n\tvoid config_key_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_SELECTPROPERTYFORM_HPP\n"
  },
  {
    "path": "src/ui/devices/selectsignalwidget.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QDebug>\n#include <QVariant>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"selectsignalwidget.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/devices/channelcombobox.hpp\"\n#include \"src/ui/devices/channelgroupcombobox.hpp\"\n#include \"src/ui/devices/devicecombobox.hpp\"\n#include \"src/ui/devices/signalcombobox.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(shared_ptr<sv::data::BaseSignal>)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nSelectSignalWidget::SelectSignalWidget(\n\t\tconst Session &session, QWidget *parent) :\n\tQWidget(parent),\n\tsession_(session)\n{\n\tsetup_ui();\n\tconnect_signals();\n}\n\nvoid SelectSignalWidget::filter_quantity(sv::data::Quantity quantity)\n{\n\t// NOTE: First filter the signal box and then the channel box for\n\t//       signal/slots to work correctly!\n\tsignal_box_->filter_quantity(quantity);\n\tchannel_box_->filter_quantity(quantity);\n}\n\nvoid SelectSignalWidget::select_device(\n\tshared_ptr<sv::devices::BaseDevice> device)\n{\n\tdevice_box_->select_device(device);\n}\n\nshared_ptr<sv::data::BaseSignal> SelectSignalWidget::selected_signal() const\n{\n\treturn signal_box_->selected_signal();\n}\n\nvoid SelectSignalWidget::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tdevice_box_ = new DeviceComboBox(session_);\n\tlayout->addWidget(device_box_);\n\n\tchannel_group_box_ = new ChannelGroupComboBox(\n\t\tdevice_box_->selected_device());\n\tlayout->addWidget(channel_group_box_);\n\n\tchannel_box_ = new ChannelComboBox(\n\t\tdevice_box_->selected_device(),\n\t\tchannel_group_box_->selected_channel_group());\n\tlayout->addWidget(channel_box_);\n\n\tsignal_box_ = new SignalComboBox(channel_box_->selected_channel());\n\tlayout->addWidget(signal_box_);\n\n\tthis->setLayout(layout);\n}\n\nvoid SelectSignalWidget::connect_signals()\n{\n\tconnect(device_box_, &DeviceComboBox::device_changed,\n\t\tthis, &SelectSignalWidget::on_device_changed);\n\tconnect(channel_group_box_, &ChannelGroupComboBox::channel_group_changed,\n\t\tthis, &SelectSignalWidget::on_channel_group_changed);\n\tconnect(channel_box_, &ChannelComboBox::channel_changed,\n\t\tthis, &SelectSignalWidget::on_channel_changed);\n\tconnect(signal_box_, &SignalComboBox::signal_changed,\n\t\tthis, &SelectSignalWidget::signal_changed);\n}\n\nvoid SelectSignalWidget::on_device_changed()\n{\n\tchannel_group_box_->change_device(device_box_->selected_device());\n}\n\nvoid SelectSignalWidget::on_channel_group_changed()\n{\n\tchannel_box_->change_device_channel_group(\n\t\tdevice_box_->selected_device(),\n\t\tchannel_group_box_->selected_channel_group());\n}\n\nvoid SelectSignalWidget::on_channel_changed()\n{\n\tsignal_box_->change_channel(channel_box_->selected_channel());\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/selectsignalwidget.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_SELECTSIGNALWIDGET_HPP\n#define UI_DEVICES_SELECTSIGNALWIDGET_HPP\n\n#include <memory>\n\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass BaseSignal;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass ChannelComboBox;\nclass ChannelGroupComboBox;\nclass DeviceComboBox;\nclass SignalComboBox;\n\nclass SelectSignalWidget : public QWidget\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SelectSignalWidget(const Session &session,\n\t\tQWidget *parent = nullptr);\n\n\tvoid filter_quantity(sv::data::Quantity quantity);\n\tvoid select_device(shared_ptr<sv::devices::BaseDevice> device);\n\tshared_ptr<sv::data::BaseSignal> selected_signal() const;\n\nprivate:\n\tconst Session &session_;\n\n\tDeviceComboBox *device_box_;\n\tChannelGroupComboBox *channel_group_box_;\n\tChannelComboBox *channel_box_;\n\tSignalComboBox *signal_box_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\tvoid on_device_changed();\n\tvoid on_channel_group_changed();\n\tvoid on_channel_changed();\n\nQ_SIGNALS:\n\tvoid signal_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_SELECTSIGNALWIDGET_HPP\n\n"
  },
  {
    "path": "src/ui/devices/signalcombobox.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <map>\n#include <memory>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QVariant>\n\n#include \"signalcombobox.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/channels/basechannel.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(shared_ptr<sv::data::BaseSignal>)\n\nnamespace sv {\nnamespace ui {\nnamespace devices {\n\nSignalComboBox::SignalComboBox(\n\t\tshared_ptr<sv::channels::BaseChannel> channel,\n\t\tQWidget *parent) :\n\tQComboBox(parent),\n\tchannel_(channel),\n\tfilter_active_(false)\n{\n\tsetup_ui();\n}\n\nvoid SignalComboBox::filter_quantity(sv::data::Quantity quantity)\n{\n\tfilter_active_ = true;\n\tfilter_quantity_ = quantity;\n\t// Refill combo box to apply filter.\n\tthis->fill_signals();\n}\n\nvoid SignalComboBox::select_signal(shared_ptr<sv::data::BaseSignal> signal)\n{\n\tfor (int i = 0; i < this->count(); ++i) {\n\t\tQVariant data = this->itemData(i, Qt::UserRole);\n\t\tauto item_signal = data.value<shared_ptr<sv::data::BaseSignal>>();\n\t\tif (item_signal == signal) {\n\t\t\tthis->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\nshared_ptr<sv::data::BaseSignal> SignalComboBox::selected_signal() const\n{\n\tQVariant data = this->currentData();\n\treturn data.value<shared_ptr<sv::data::BaseSignal>>();\n}\n\nvoid SignalComboBox::setup_ui()\n{\n\tthis->setSizeAdjustPolicy(QComboBox::AdjustToContents);\n\tthis->fill_signals();\n}\n\nvoid SignalComboBox::fill_signals()\n{\n\tdisconnect(\n\t\tthis, QOverload<int>::of(&SignalComboBox::currentIndexChanged),\n\t\tthis, &SignalComboBox::signal_changed);\n\n\tthis->clear();\n\n\tif (channel_ == nullptr)\n\t\treturn;\n\n\tfor (const auto &signal_pair : channel_->signal_map()) {\n\t\tfor (const auto &signal : signal_pair.second) {\n\t\t\tif (filter_active_ && filter_quantity_ != signal->quantity())\n\t\t\t\tcontinue;\n\t\t\tthis->addItem(signal->display_name(), QVariant::fromValue(signal));\n\t\t}\n\t}\n\n\tconnect(\n\t\tthis, QOverload<int>::of(&SignalComboBox::currentIndexChanged),\n\t\tthis, &SignalComboBox::signal_changed);\n\tQ_EMIT signal_changed();\n}\n\nvoid SignalComboBox::change_channel(\n\tshared_ptr<sv::channels::BaseChannel> channel)\n{\n\tchannel_ = channel;\n\tthis->fill_signals();\n}\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/devices/signalcombobox.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DEVICES_SIGNALCOMBOBOX_HPP\n#define UI_DEVICES_SIGNALCOMBOBOX_HPP\n\n#include <memory>\n\n#include <QComboBox>\n#include <QWidget>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass BaseSignal;\n}\n\nnamespace ui {\nnamespace devices {\n\nclass SignalComboBox : public QComboBox\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SignalComboBox(\n\t\tshared_ptr<sv::channels::BaseChannel> channel,\n\t\tQWidget *parent = nullptr);\n\n\tvoid filter_quantity(sv::data::Quantity quantity);\n\tvoid select_signal(shared_ptr<sv::data::BaseSignal> signal);\n\tshared_ptr<sv::data::BaseSignal> selected_signal() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid fill_signals();\n\n\tshared_ptr<sv::channels::BaseChannel> channel_;\n\tbool filter_active_;\n\tsv::data::Quantity filter_quantity_;\n\n\npublic Q_SLOTS:\n\tvoid change_channel(shared_ptr<sv::channels::BaseChannel> channel);\n\nQ_SIGNALS:\n\tvoid signal_changed();\n\n};\n\n} // namespace devices\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DEVICES_SIGNALCOMBOBOX_HPP\n"
  },
  {
    "path": "src/ui/dialogs/aboutdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <glib.h>\n#include <boost/version.hpp>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QApplication>\n#include <QDebug>\n#include <QDialogButtonBox>\n#include <QHBoxLayout>\n#include <QLabel>\n#include <QSize>\n#include <QTextBrowser>\n#include <QTextDocument>\n#include <qwt_global.h>\n\n#include \"aboutdialog.hpp\"\n#include \"config.h\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nAboutDialog::AboutDialog(DeviceManager &device_manager,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tdevice_manager_(device_manager),\n\tdevice_(device)\n{\n\tresize(600, 400);\n\n\tconst int icon_size = 64;\n\n\tpage_list = new QListWidget;\n\tpage_list->setViewMode(QListView::IconMode);\n\tpage_list->setIconSize(QSize(icon_size, icon_size));\n\tpage_list->setMovement(QListView::Static);\n\tpage_list->setMaximumWidth(icon_size + (icon_size / 2) + 2);\n\tpage_list->setSpacing(12);\n\t// NOTE: setItemAlignment() is introduced in Qt 5.12, but MXE uses Qt 5.7\n\t//       and Ubuntu 16.04 (AppImage) uses Qt 5.5, but\n\t//       setUniformItemSizes(true) does the trick!\n\t//page_list->setItemAlignment(Qt::AlignHCenter);\n\tpage_list->setUniformItemSizes(true);\n\n\tpages = new QStackedWidget;\n\tcreate_pages();\n\tpage_list->setCurrentIndex(page_list->model()->index(0, 0));\n\n\tQHBoxLayout *tab_layout = new QHBoxLayout;\n\ttab_layout->addWidget(page_list);\n\ttab_layout->addWidget(pages, Qt::AlignLeft);\n\n\tQDialogButtonBox *button_box = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel);\n\n\tQVBoxLayout* root_layout = new QVBoxLayout(this);\n\troot_layout->addLayout(tab_layout);\n\troot_layout->addWidget(button_box);\n\n\tconnect(button_box, &QDialogButtonBox::accepted,\n\t\tthis, &AboutDialog::accept);\n\tconnect(button_box, &QDialogButtonBox::rejected,\n\t\tthis, &AboutDialog::rejected);\n\tconnect(page_list, &QListWidget::currentItemChanged,\n\t\tthis, &AboutDialog::on_page_changed);\n}\n\nvoid AboutDialog::create_pages()\n{\n\t// Device page\n\tif (device_) {\n\t\tpages->addWidget(get_device_page(pages));\n\n\t\tQListWidgetItem *device_button = new QListWidgetItem(page_list);\n\t\tdevice_button->setIcon(QIcon(\":/icons/smuview.svg\"));\n\t\tdevice_button->setText(tr(\"Device\"));\n\t\tdevice_button->setTextAlignment(Qt::AlignHCenter);\n\t\tdevice_button->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);\n\t}\n\n\t// About page\n\tpages->addWidget(get_about_page(pages));\n\n\tQListWidgetItem *about_button = new QListWidgetItem(page_list);\n\tabout_button->setIcon(QIcon(\":/icons/information.svg\"));\n\tabout_button->setText(tr(\"About\"));\n\tabout_button->setTextAlignment(Qt::AlignHCenter);\n\tabout_button->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);\n}\n\nQWidget *AboutDialog::get_about_page(QWidget *parent) const\n{\n\tQLabel *icon = new QLabel();\n\ticon->setPixmap(QPixmap(QString::fromUtf8(\":/icons/smuview.svg\")));\n\n\t/* Setup the version field */\n\tQLabel *version_info = new QLabel();\n\tversion_info->setText(tr(\"%1 %2<br />%3<br /><a href=\\\"http://%4\\\">%4</a>\")\n\t\t.arg(QApplication::applicationName(),\n\t\tQApplication::applicationVersion(),\n\t\ttr(\"GNU GPL, version 3 or later\"),\n\t\tQApplication::organizationDomain()));\n\tversion_info->setOpenExternalLinks(true);\n\n\tshared_ptr<sigrok::Context> context = device_manager_.context();\n\n\tQString html;\n\n\thtml.append(\"<style type=\\\"text/css\\\"> tr .id { white-space: pre; padding-right: 5px; } </style>\");\n\n\thtml.append(\"<table>\");\n\n\t/* Library info */\n\thtml.append(\"<tr><td colspan=\\\"2\\\"><b>\" +\n\t\ttr(\"Libraries and features:\") + \"</b></td></tr>\");\n\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"Qt\"), qVersion()));\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"Qwt\"), QWT_VERSION_STR));\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"glibmm\"), SV_GLIBMM_VERSION));\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"Boost\"), BOOST_LIB_VERSION));\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"pybind11\"), SV_PYBIND11_VERSION));\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2</td></tr>\")\n\t\t.arg(QString(\"Python\"), SV_PYTHON_VERSION));\n\n\thtml.append(QString(\"<tr><td><i>%1</i></td><td>%2/%3 (rt: %4/%5)</td></tr>\")\n\t\t.arg(QString(\"libsigrok\"), SR_PACKAGE_VERSION_STRING,\n\t\tSR_LIB_VERSION_STRING, sr_package_version_string_get(),\n\t\tsr_lib_version_string_get()));\n\n\tGSList *libs_orig = sr_buildinfo_libs_get();\n\tfor (GSList *lib = libs_orig; lib; lib = lib->next) {\n\t\tGSList *lib_data = static_cast<GSList *>(lib->data);\n\t\tconst char *name = static_cast<const char *>(lib_data->data);\n\t\tconst char *version = static_cast<const char *>(lib_data->next->data);\n\t\thtml.append(QString(\"<tr><td><i>- %1</i></td><td>%2</td></tr>\")\n\t\t\t.arg(QString(name), QString(version)));\n\t\tg_slist_free_full(lib_data, g_free);\n\t}\n\tg_slist_free(libs_orig);\n\n\tchar *host = sr_buildinfo_host_get();\n\thtml.append(QString(\"<tr><td><i>- Host</i></td><td>%1</td></tr>\")\n\t\t.arg(QString(host)));\n\tg_free(host);\n\n\tchar *scpi_backends = sr_buildinfo_scpi_backends_get();\n\thtml.append(QString(\"<tr><td><i>- SCPI backends</i></td><td>%1</td></tr>\")\n\t\t.arg(QString(scpi_backends)));\n\tg_free(scpi_backends);\n\n\t/* Set up the supported field */\n\thtml.append(\"<tr><td colspan=\\\"2\\\"></td></tr>\");\n\thtml.append(\"<tr><td colspan=\\\"2\\\"><b>\" +\n\t\ttr(\"Supported hardware drivers:\") + \"</b></td></tr>\");\n\tfor (const auto &entry : context->drivers()) {\n\t\thtml.append(QString(\"<tr><td class=\\\"id\\\"><i>%1</i></td><td>%2</td></tr>\")\n\t\t\t.arg(QString::fromUtf8(entry.first.c_str()),\n\t\t\t\tQString::fromUtf8(entry.second->long_name().c_str())));\n\t}\n\n\t// No need for input formats\n\t/*\n\thtml.append(\"<tr><td colspan=\\\"2\\\"></td></tr>\");\n\thtml.append(\"<tr><td colspan=\\\"2\\\"><b>\" +\n\t\ttr(\"Supported input formats:\") + \"</b></td></tr>\");\n\tfor (const auto &entry : context->input_formats()) {\n\t\thtml.append(QString(\"<tr><td class=\\\"id\\\"><i>%1</i></td><td>%2</td></tr>\")\n\t\t\t.arg(QString::fromUtf8(entry.first.c_str()),\n\t\t\t\tQString::fromUtf8(entry.second->description().c_str())));\n\t}\n\t*/\n\n\t// No need for output formats\n\t/*\n\thtml.append(\"<tr><td colspan=\\\"2\\\"></td></tr>\");\n\thtml.append(\"<tr><td colspan=\\\"2\\\"><b>\" +\n\t\ttr(\"Supported output formats:\") + \"</b></td></tr>\");\n\tfor (const auto &entry : context->output_formats()) {\n\t\thtml.append(QString(\"<tr><td class=\\\"id\\\"><i>%1</i></td><td>%2</td></tr>\")\n\t\t\t.arg(QString::fromUtf8(entry.first.c_str()),\n\t\t\t\tQString::fromUtf8(entry.second->description().c_str())));\n\t}\n\t*/\n\n\thtml.append(\"</table>\");\n\n\tQTextDocument *supported_doc = new QTextDocument();\n\tsupported_doc->setHtml(html);\n\n\tQTextBrowser *support_list = new QTextBrowser();\n\tsupport_list->setDocument(supported_doc);\n\n\tQGridLayout *layout = new QGridLayout();\n\tlayout->addWidget(icon, 0, 0, 1, 1);\n\tlayout->addWidget(version_info, 0, 1, 1, 1);\n\tlayout->addWidget(support_list, 1, 1, 1, 1);\n\n\tQWidget *page = new QWidget(parent);\n\tpage->setLayout(layout);\n\n\treturn page;\n}\n\nQWidget *AboutDialog::get_device_page(QWidget *parent) const\n{\n\tQLabel *icon = new QLabel();\n\ticon->setPixmap(QPixmap(QString::fromUtf8(\":/icons/smuview.svg\")));\n\n\t// Device info\n\tauto sr_device = device_->sr_device();\n\tauto hw_device = dynamic_pointer_cast<devices::HardwareDevice>(device_);\n\tshared_ptr<sigrok::HardwareDevice> sr_hw_device = nullptr;\n\tif (hw_device)\n\t\tsr_hw_device = hw_device->sr_hardware_device();\n\n\tQString device_info_text(\"<b>\");\n\n\tif (sr_device->vendor().length() > 0) {\n\t\tdevice_info_text.append(QString(\"%1 \").arg(\n\t\t\tQString::fromStdString(sr_device->vendor())));\n\t}\n\tdevice_info_text.append(QString(\"%1</b>\").arg(\n\t\tQString::fromStdString(sr_device->model())));\n\tif (sr_device->version().length() > 0) {\n\t\tdevice_info_text.append(QString(\" (%1)\").arg(\n\t\t\tQString::fromStdString(sr_device->version())));\n\t}\n\n\tQString sn(\"-\");\n\tif (sr_device->serial_number().length() > 0)\n\t\tsn = QString::fromStdString(sr_device->serial_number());\n\tdevice_info_text.append(\n\t\tQString(\"<br /><b>\" + tr(\"Serial Number\") + \":</b> %1\").arg(sn));\n\n\tQString conn_id(\"-\");\n\tif (sr_device->connection_id().length() > 0)\n\t\tconn_id = QString::fromStdString(sr_device->connection_id());\n\tdevice_info_text.append(\n\t\tQString(\"<br /><b>\" + tr(\"Connection\") + \":</b> %1\").arg(conn_id));\n\n\tQString id(\"-\");\n\tif (device_->id().length() > 0)\n\t\tid = QString::fromStdString(device_->id());\n\tdevice_info_text.append(\n\t\tQString(\"<br /><b>\" + tr(\"Device ID\") + \":</b> %1\").arg(id));\n\n\tQLabel *device_info = new QLabel();\n\tdevice_info->setText(device_info_text);\n\n\tQString html;\n\thtml.append(\"<style type=\\\"text/css\\\"> tr .id { white-space: pre; padding-right: 5px; } </style>\");\n\thtml.append(\"<table width=\\\"100%\\\" border=\\\"0\\\">\");\n\n\t/* Device functions */\n\thtml.append(\"<tr><td colspan=\\\"7\\\"><b>\" +\n\t\ttr(\"Sigrok device functions:\") + \"</b></td></tr>\");\n\thtml.append(QString(\"<tr><td>&nbsp;</td><td colspan=\\\"6\\\">\"));\n\tif (sr_hw_device) {\n\t\tconst auto sr_keys = sr_hw_device->driver()->config_keys();\n\t\tQString sep(\"\");\n\t\tfor (const auto &sr_key : sr_keys) {\n\t\t\t\thtml.append(sep).append(\n\t\t\t\t\tQString::fromStdString(sr_key->description()));\n\t\t\t\tsep = QString(\", \");\n\t\t}\n\t}\n\thtml.append(QString(\"</td></tr>\"));\n\thtml.append(\"<tr><td colspan=\\\"7\\\"><b>\" +\n\t\ttr(\"SmuView device functions:\") + \"</b></td></tr>\");\n\thtml.append(QString(\"<tr><td>&nbsp;</td><td colspan=\\\"6\\\">%1</td></tr>\")\n\t\t.arg(devices::deviceutil::format_device_type(device_->type())));\n\thtml.append(\"<tr><td colspan=\\\"7\\\">&nbsp;</td></tr>\");\n\n\t/* SmuView device configurables and config keys */\n\tif (hw_device) {\n\t\thtml.append(\"<tr><td colspan=\\\"7\\\"><b>\" +\n\t\t\ttr(\"SmuView device configurables and properties:\") +\n\t\t\t\"</b></td></tr>\");\n\t\tfor (const auto &c_pair : hw_device->configurable_map()) {\n\t\t\tauto configurable = c_pair.second;\n\t\t\thtml.append(QString(\"<tr><td>&nbsp;</td><td>%1</td><b>\")\n\t\t\t\t.arg(configurable->display_name()));\n\t\t\thtml.append(QString(\"</b><td>GET</td><td>Value</td><td>SET</td>\"));\n\t\t\thtml.append(QString(\"<td>LIST</td><td>Values</td></tr>\"));\n\t\t\tauto props = configurable->property_map();\n\t\t\tfor (const auto &prop : props) {\n\t\t\t\thtml.append(QString(\"<tr><td>&nbsp;</td>\"));\n\t\t\t\thtml.append(QString(\"<td><i>%1</i></td>\")\n\t\t\t\t\t.arg(devices::deviceutil::format_config_key(prop.first)));\n\t\t\t\tif (prop.second->is_getable()) {\n\t\t\t\t\thtml.append(QString(\"<td>X</td>\"));\n\t\t\t\t\t//if (prop.second->value().canConvert<QString>())\n\t\t\t\t\t//\thtml.append(QString(\"<td>%1</td>\").arg(\n\t\t\t\t\t//\t\tprop.second->value().toString()));\n\t\t\t\t\t//else\n\t\t\t\t\t\thtml.append(QString(\"<td>?</td>\"));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\thtml.append(QString(\"<td>&nbsp;</td><td>&nbsp;</td>\"));\n\t\t\t\tif (prop.second->is_setable())\n\t\t\t\t\thtml.append(QString(\"<td>X</td>\"));\n\t\t\t\telse\n\t\t\t\t\thtml.append(QString(\"<td>&nbsp;</td>\"));\n\t\t\t\tif (prop.second->is_listable())\n\t\t\t\t\thtml.append(QString(\"<td>X</td><td>&nbsp;</td>\"));\n\t\t\t\telse\n\t\t\t\t\thtml.append(QString(\"<td>&nbsp;</td><td>&nbsp;</td>\"));\n\n\t\t\t\thtml.append(QString(\"</tr>\"));\n\t\t\t}\n\t\t}\n\t\thtml.append(\"<tr><td colspan=\\\"7\\\">&nbsp;</td></tr>\");\n\t}\n\n\thtml.append(\"</table>\");\n\n\tQTextDocument *device_doc = new QTextDocument();\n\tdevice_doc->setHtml(html);\n\n\tQTextBrowser *device_list = new QTextBrowser();\n\tdevice_list->setDocument(device_doc);\n\n\tQGridLayout *layout = new QGridLayout();\n\tlayout->addWidget(icon, 0, 0, 1, 1);\n\tlayout->addWidget(device_info, 0, 1, 1, 1);\n\tlayout->addWidget(device_list, 1, 1, 1, 1);\n\n\tQWidget *page = new QWidget(parent);\n\tpage->setLayout(layout);\n\n\treturn page;\n}\n\nvoid AboutDialog::on_page_changed(\n\tQListWidgetItem *current, QListWidgetItem *previous)\n{\n\tif (!current)\n\t\tcurrent = previous;\n\n\tpages->setCurrentIndex(page_list->row(current));\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/aboutdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_ABOUTDIALOG_HPP\n#define UI_DIALOGS_ABOUTDIALOG_HPP\n\n#include <QDialog>\n#include <QListWidget>\n#include <QStackedWidget>\n\n#include \"src/devicemanager.hpp\"\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace dialogs {\n\nclass AboutDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tAboutDialog(DeviceManager &device_manager,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid create_pages();\n\tQWidget *get_about_page(QWidget *parent) const;\n\tQWidget *get_device_page(QWidget *parent) const;\n\n\tDeviceManager &device_manager_;\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\n\tQListWidget *page_list;\n\tQStackedWidget *pages;\n\nprivate Q_SLOTS:\n\tvoid on_page_changed(QListWidgetItem *current, QListWidgetItem *previous);\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_ABOUTDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/addmathchanneldialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QFormLayout>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QMessageBox>\n#include <QSizePolicy>\n#include <QSpinBox>\n#include <QString>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"addmathchanneldialog.hpp\"\n#include \"src/channels/addscchannel.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/channels/dividechannel.hpp\"\n#include \"src/channels/integratechannel.hpp\"\n#include \"src/channels/mathchannel.hpp\"\n#include \"src/channels/movingavgchannel.hpp\"\n#include \"src/channels/multiplysfchannel.hpp\"\n#include \"src/channels/multiplysschannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/data/quantitycombobox.hpp\"\n#include \"src/ui/data/quantityflagslist.hpp\"\n#include \"src/ui/data/unitcombobox.hpp\"\n#include \"src/ui/devices/channelgroupcombobox.hpp\"\n#include \"src/ui/devices/devicecombobox.hpp\"\n#include \"src/ui/devices/selectsignalwidget.hpp\"\n\nusing std::make_shared;\nusing std::set;\nusing std::static_pointer_cast;\nusing std::string;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nAddMathChannelDialog::AddMathChannelDialog(const Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\tdevice_(device)\n{\n\tassert(device);\n\n\tsetup_ui();\n}\n\nvoid AddMathChannelDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Add Math Channel\"));\n\tthis->setMinimumWidth(550);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout();\n\n\t// General stuff\n\tQFormLayout *form_layout = new QFormLayout();\n\tname_edit_ = new QLineEdit();\n\tform_layout->addRow(tr(\"Name\"), name_edit_);\n\tmain_layout->addLayout(form_layout);\n\n\t// Measured Quantity\n\tQGroupBox *mq_group = new QGroupBox(tr(\"Measured Quantity\"));\n\tQFormLayout *mq_layout = new QFormLayout();\n\tquantity_box_ = new ui::data::QuantityComboBox();\n\tmq_layout->addRow(tr(\"Quantity\"), quantity_box_);\n\tquantity_flags_list_ = new ui::data::QuantityFlagsList();\n\tmq_layout->addRow(tr(\"Quantity Flags\"), quantity_flags_list_);\n\tunit_box_ = new ui::data::UnitComboBox();\n\tmq_layout->addRow(tr(\"Unit\"), unit_box_);\n\tmq_group->setLayout(mq_layout);\n\tmain_layout->addWidget(mq_group);\n\n\t// Add to...\n\tQGroupBox *add_to_group = new QGroupBox(tr(\"Add to...\"));\n\tQFormLayout *add_to_layout = new QFormLayout();\n\tdevice_box_ = new ui::devices::DeviceComboBox(session_);\n\tdevice_box_->select_device(device_);\n\tadd_to_layout->addRow(tr(\"Device\"), device_box_);\n\tchannel_group_box_ = new ui::devices::ChannelGroupComboBox(device_);\n\tchannel_group_box_->addItem(QString(tr(\"Math\")));\n\tconnect(device_box_, &ui::devices::DeviceComboBox::device_changed,\n\t\tthis, &AddMathChannelDialog::on_device_changed);\n\tadd_to_layout->addRow(tr(\"Channel Group\"), channel_group_box_);\n\tadd_to_group->setLayout(add_to_layout);\n\tmain_layout->addWidget(add_to_group);\n\n\t// Tabs\n\ttab_widget_ = new QTabWidget();\n\tthis->setup_ui_multiply_signals_tab();\n\tthis->setup_ui_multiply_signal_tab();\n\tthis->setup_ui_divide_signals_tab();\n\tthis->setup_ui_add_signal_tab();\n\tthis->setup_ui_integrate_signal_tab();\n\tthis->setup_ui_movingavg_signal_tab();\n\ttab_widget_->setCurrentIndex(0);\n\tmain_layout->addWidget(tab_widget_);\n\n\t// Buttons\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &AddMathChannelDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &AddMathChannelDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid AddMathChannelDialog::setup_ui_multiply_signals_tab()\n{\n\tQString title(tr(\"S\\u2081(t) * S\\u2082(t)\"));\n\n\tQWidget *widget = new QWidget();\n\tQHBoxLayout *layout = new QHBoxLayout();\n\n\tQGroupBox *signal1_group = new QGroupBox(tr(\"Signal 1\"));\n\tQVBoxLayout *s1_layout = new QVBoxLayout();\n\tm_ss_signal1_ = new ui::devices::SelectSignalWidget(session_);\n\tm_ss_signal1_->select_device(device_);\n\ts1_layout->addWidget(m_ss_signal1_);\n\tsignal1_group->setLayout(s1_layout);\n\tlayout->addWidget(signal1_group);\n\n\tQGroupBox *signal2_group = new QGroupBox(tr(\"Signal 2\"));\n\tQVBoxLayout *s2_layout = new QVBoxLayout();\n\tm_ss_signal2_ = new ui::devices::SelectSignalWidget(session_);\n\tm_ss_signal2_->select_device(device_);\n\ts2_layout->addWidget(m_ss_signal2_);\n\tsignal2_group->setLayout(s2_layout);\n\tlayout->addWidget(signal2_group);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid AddMathChannelDialog::setup_ui_multiply_signal_tab()\n{\n\tQString title(tr(\"S(t) * f\"));\n\n\tQWidget *widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQGroupBox *signal_group = new QGroupBox(tr(\"Signal\"));\n\tQVBoxLayout *s_layout = new QVBoxLayout();\n\tm_sf_signal_ = new ui::devices::SelectSignalWidget(session_);\n\tm_sf_signal_->select_device(device_);\n\ts_layout->addWidget(m_sf_signal_);\n\tsignal_group->setLayout(s_layout);\n\tlayout->addWidget(signal_group);\n\n\tQFormLayout *f_layout = new QFormLayout();\n\tm_sf_factor_edit_ = new QLineEdit();\n\tf_layout->addRow(tr(\"Factor\"), m_sf_factor_edit_);\n\tlayout->addLayout(f_layout);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid AddMathChannelDialog::setup_ui_divide_signals_tab()\n{\n\tQString title(tr(\"S\\u2081(t) / S\\u2082(t)\"));\n\n\tQWidget *widget = new QWidget();\n\tQHBoxLayout *layout = new QHBoxLayout();\n\n\tQGroupBox *signal1_group = new QGroupBox(tr(\"Signal 1\"));\n\tQVBoxLayout *s1_layout = new QVBoxLayout();\n\td_ss_signal1_ = new ui::devices::SelectSignalWidget(session_);\n\td_ss_signal1_->select_device(device_);\n\ts1_layout->addWidget(d_ss_signal1_);\n\tsignal1_group->setLayout(s1_layout);\n\tlayout->addWidget(signal1_group);\n\n\tQGroupBox *signal2_group = new QGroupBox(tr(\"Signal 2\"));\n\tQVBoxLayout *s2_layout = new QVBoxLayout();\n\td_ss_signal2_ = new ui::devices::SelectSignalWidget(session_);\n\td_ss_signal2_->select_device(device_);\n\ts2_layout->addWidget(d_ss_signal2_);\n\tsignal2_group->setLayout(s2_layout);\n\tlayout->addWidget(signal2_group);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid AddMathChannelDialog::setup_ui_add_signal_tab()\n{\n\tQString title(tr(\"S(t) + c\"));\n\n\tQWidget *widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQGroupBox *signal_group = new QGroupBox(tr(\"Signal\"));\n\tQVBoxLayout *s_layout = new QVBoxLayout();\n\ta_sc_signal_ = new ui::devices::SelectSignalWidget(session_);\n\ta_sc_signal_->select_device(device_);\n\ts_layout->addWidget(a_sc_signal_);\n\tsignal_group->setLayout(s_layout);\n\tlayout->addWidget(signal_group);\n\n\tQFormLayout *c_layout = new QFormLayout();\n\ta_sc_constant_edit_ = new QLineEdit();\n\tc_layout->addRow(tr(\"Constant\"), a_sc_constant_edit_);\n\tlayout->addLayout(c_layout);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid AddMathChannelDialog::setup_ui_integrate_signal_tab()\n{\n\tQString title(tr(\"\\u222B S(t) * dt\"));\n\n\tQWidget *widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQGroupBox *signal_group = new QGroupBox(tr(\"Signal\"));\n\tQVBoxLayout *s_layout = new QVBoxLayout();\n\ti_s_signal_ = new ui::devices::SelectSignalWidget(session_);\n\ti_s_signal_->select_device(device_);\n\ts_layout->addWidget(i_s_signal_);\n\tsignal_group->setLayout(s_layout);\n\tlayout->addWidget(signal_group);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid AddMathChannelDialog::setup_ui_movingavg_signal_tab()\n{\n\tQString title(tr(\"Moving Average\"));\n\n\tQWidget *widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQGroupBox *signal_group = new QGroupBox(tr(\"Signal\"));\n\tQVBoxLayout *s_layout = new QVBoxLayout();\n\tma_signal_ = new ui::devices::SelectSignalWidget(session_);\n\tma_signal_->select_device(device_);\n\ts_layout->addWidget(ma_signal_);\n\tsignal_group->setLayout(s_layout);\n\tlayout->addWidget(signal_group);\n\n\tQFormLayout *ac_layout = new QFormLayout();\n\tma_num_samples_box_ = new QSpinBox();\n\tma_num_samples_box_->setMinimum(1);\n\tac_layout->addRow(tr(\"Sample count\"), ma_num_samples_box_);\n\tlayout->addLayout(ac_layout);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nshared_ptr<channels::MathChannel> AddMathChannelDialog::channel() const\n{\n\treturn channel_;\n}\n\nQString AddMathChannelDialog::channel_group_name() const\n{\n\treturn channel_group_box_->selected_channel_group();\n}\n\nvoid AddMathChannelDialog::accept()\n{\n\tif (name_edit_->text().size() == 0) {\n\t\tQMessageBox::warning(this,\n\t\t\ttr(\"Channel name missing\"),\n\t\t\ttr(\"Please enter a name for the new channel.\"),\n\t\t\tQMessageBox::Ok);\n\t\treturn;\n\t}\n\n\tauto device = device_box_->selected_device();\n\tstring chg_name = channel_group_name().toStdString();\n\tset<string> channel_group_names { chg_name };\n\n\tauto quantity = quantity_box_->selected_quantity();\n\tauto quantity_flags = quantity_flags_list_->selected_quantity_flags();\n\tauto unit = unit_box_->selected_unit();\n\n\tswitch (tab_widget_->currentIndex()) {\n\tcase 0: {\n\t\t\tif (m_ss_signal1_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose signal 1 for the signal multiplication.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal_1 = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\tm_ss_signal1_->selected_signal());\n\n\t\t\tif (m_ss_signal2_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose signal 2 for the signal multiplication.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal_2 = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\tm_ss_signal2_->selected_signal());\n\n\t\t\tdouble start_timestamp = signal_1->signal_start_timestamp();\n\t\t\tif (signal_2->signal_start_timestamp() < start_timestamp)\n\t\t\t\tstart_timestamp = signal_2->signal_start_timestamp();\n\n\t\t\tchannel_ = make_shared<channels::MultiplySSChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal_1, signal_2,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tstart_timestamp);\n\t\t}\n\t\tbreak;\n\tcase 1: {\n\t\t\tif (m_sf_signal_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose a signal for the factor multiplication.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\tm_sf_signal_->selected_signal());\n\n\t\t\tif (m_sf_factor_edit_->text().size() == 0) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Factor missing\"),\n\t\t\t\t\ttr(\"Please enter a factor for the factor multiplication.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbool ok;\n\t\t\tdouble factor = QString(m_sf_factor_edit_->text()).toDouble(&ok);\n\t\t\tif (!ok) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Factor not a number\"),\n\t\t\t\t\ttr(\"Please enter a number as factor for the factor multiplication.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tchannel_ = make_shared<channels::MultiplySFChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal, factor,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tsignal->signal_start_timestamp());\n\t\t}\n\t\tbreak;\n\tcase 2: {\n\t\t\tif (d_ss_signal1_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose signal 1 for the signal division.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal1 = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\td_ss_signal1_->selected_signal());\n\n\t\t\tif (d_ss_signal2_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose signal 2 for the signal division.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal2 = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\td_ss_signal2_->selected_signal());\n\n\t\t\tdouble start_timestamp = signal1->signal_start_timestamp();\n\t\t\tif (signal2->signal_start_timestamp() < start_timestamp)\n\t\t\t\tstart_timestamp = signal2->signal_start_timestamp();\n\n\t\t\tchannel_ = make_shared<channels::DivideChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal1, signal2,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tstart_timestamp);\n\t\t}\n\t\tbreak;\n\tcase 3: {\n\t\t\tif (a_sc_signal_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose a signal for the constant addition.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\ta_sc_signal_->selected_signal());\n\n\t\t\tif (a_sc_constant_edit_->text().size() == 0) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Constant missing\"),\n\t\t\t\t\ttr(\"Please enter a constant for the constant addition.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tbool ok;\n\t\t\tdouble constant = QString(a_sc_constant_edit_->text()).toDouble(&ok);\n\t\t\tif (!ok) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Constant not a number\"),\n\t\t\t\t\ttr(\"Please enter a number as constant for the constant addition.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tchannel_ = make_shared<channels::AddSCChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal, constant,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tsignal->signal_start_timestamp());\n\t\t}\n\t\tbreak;\n\tcase 4: {\n\t\t\tif (i_s_signal_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose a signal for the integration.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\ti_s_signal_->selected_signal());\n\n\t\t\tchannel_ = make_shared<channels::IntegrateChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tsignal->signal_start_timestamp());\n\t\t}\n\t\tbreak;\n\tcase 5: {\n\t\t\tif (ma_signal_->selected_signal() == nullptr) {\n\t\t\t\tQMessageBox::warning(this,\n\t\t\t\t\ttr(\"Signal missing\"),\n\t\t\t\t\ttr(\"Please choose a signal for the moving average.\"),\n\t\t\t\t\tQMessageBox::Ok);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tauto signal = static_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\t\tma_signal_->selected_signal());\n\n\t\t\tuint num_samples = ma_num_samples_box_->value();\n\n\t\t\tchannel_ = make_shared<channels::MovingAvgChannel>(\n\t\t\t\tquantity, quantity_flags, unit,\n\t\t\t\tsignal, num_samples,\n\t\t\t\tdevice, channel_group_names, name_edit_->text().toStdString(),\n\t\t\t\tsignal->signal_start_timestamp());\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tQDialog::accept();\n}\n\nvoid AddMathChannelDialog::on_device_changed()\n{\n\tchannel_group_box_->change_device(device_box_->selected_device());\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/addmathchanneldialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_ADDMATHCHANNELDIALOG_HPP\n#define UI_DIALOGS_ADDMATHCHANNELDIALOG_HPP\n\n#include <memory>\n\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QSpinBox>\n#include <QTabWidget>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\nnamespace channels {\nclass MathChannel;\n}\n\nnamespace ui {\n\nnamespace data {\nclass QuantityComboBox;\nclass QuantityFlagsList;\nclass UnitComboBox;\n}\nnamespace devices {\nclass ChannelGroupComboBox;\nclass DeviceComboBox;\nclass SelectSignalWidget;\n}\n\nnamespace dialogs {\n\nclass AddMathChannelDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tAddMathChannelDialog(const Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent = nullptr);\n\n\tshared_ptr<channels::MathChannel> channel() const;\n\tQString channel_group_name() const;\n\nprivate:\n\tvoid setup_ui();\n\tvoid setup_ui_multiply_signals_tab();\n\tvoid setup_ui_multiply_signal_tab();\n\tvoid setup_ui_divide_signals_tab();\n\tvoid setup_ui_divide_signal_tab();\n\tvoid setup_ui_add_signal_tab();\n\tvoid setup_ui_integrate_signal_tab();\n\tvoid setup_ui_movingavg_signal_tab();\n\n\tconst Session &session_;\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\tshared_ptr<channels::MathChannel> channel_;\n\n\tQTabWidget *tab_widget_;\n\tQLineEdit *name_edit_;\n\tui::data::QuantityComboBox *quantity_box_;\n\tui::data::QuantityFlagsList *quantity_flags_list_;\n\tui::data::UnitComboBox *unit_box_;\n\tui::devices::DeviceComboBox *device_box_;\n\tui::devices::ChannelGroupComboBox *channel_group_box_;\n\tui::devices::SelectSignalWidget *m_ss_signal1_;\n\tui::devices::SelectSignalWidget *m_ss_signal2_;\n\tui::devices::SelectSignalWidget *m_sf_signal_;\n\tQLineEdit *m_sf_factor_edit_;\n\tui::devices::SelectSignalWidget *d_ss_signal1_;\n\tui::devices::SelectSignalWidget *d_ss_signal2_;\n\tui::devices::SelectSignalWidget *a_sc_signal_;\n\tQLineEdit *a_sc_constant_edit_;\n\tui::devices::SelectSignalWidget *i_s_signal_;\n\tui::devices::SelectSignalWidget *ma_signal_;\n\tQSpinBox *ma_num_samples_box_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\nprivate Q_SLOTS:\n\tvoid on_device_changed();\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_ADDMATHCHANNELDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/adduserchanneldialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <string>\n\n#include <QComboBox>\n#include <QDateTime>\n#include <QDebug>\n#include <QFormLayout>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QMessageBox>\n#include <QSizePolicy>\n#include <QString>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"adduserchanneldialog.hpp\"\n#include \"src/channels/userchannel.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/data/quantitycombobox.hpp\"\n#include \"src/ui/data/quantityflagslist.hpp\"\n#include \"src/ui/data/unitcombobox.hpp\"\n#include \"src/ui/devices/channelgroupcombobox.hpp\"\n#include \"src/ui/devices/devicecombobox.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nAddUserChannelDialog::AddUserChannelDialog(const Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\tdevice_(device)\n{\n\tassert(device);\n\n\tsetup_ui();\n}\n\nvoid AddUserChannelDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Add User Channel\"));\n\tthis->setMinimumWidth(550);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout();\n\n\t// General stuff\n\tQFormLayout *form_layout = new QFormLayout();\n\tname_edit_ = new QLineEdit();\n\tform_layout->addRow(tr(\"Name\"), name_edit_);\n\tmain_layout->addLayout(form_layout);\n\n\t// Measured Quantity\n\tQGroupBox *mq_group = new QGroupBox(tr(\"Measured Quantity\"));\n\tQFormLayout *mq_layout = new QFormLayout();\n\tquantity_box_ = new ui::data::QuantityComboBox();\n\tmq_layout->addRow(tr(\"Quantity\"), quantity_box_);\n\tquantity_flags_list_ = new ui::data::QuantityFlagsList();\n\tmq_layout->addRow(tr(\"Quantity Flags\"), quantity_flags_list_);\n\tunit_box_ = new ui::data::UnitComboBox();\n\tmq_layout->addRow(tr(\"Unit\"), unit_box_);\n\tmq_group->setLayout(mq_layout);\n\tmain_layout->addWidget(mq_group);\n\n\t// Add to...\n\tQGroupBox *add_to_group = new QGroupBox(tr(\"Add to...\"));\n\tQFormLayout *add_to_layout = new QFormLayout();\n\tdevice_box_ = new ui::devices::DeviceComboBox(session_);\n\tdevice_box_->select_device(device_);\n\tadd_to_layout->addRow(tr(\"Device\"), device_box_);\n\tchannel_group_box_ = new ui::devices::ChannelGroupComboBox(device_);\n\tchannel_group_box_->addItem(QString(tr(\"User\")));\n\tconnect(device_box_, &ui::devices::DeviceComboBox::device_changed,\n\t\tthis, &AddUserChannelDialog::on_device_changed);\n\tadd_to_layout->addRow(tr(\"Channel Group\"), channel_group_box_);\n\tadd_to_group->setLayout(add_to_layout);\n\tmain_layout->addWidget(add_to_group);\n\n\t// Buttons\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &AddUserChannelDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &AddUserChannelDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nshared_ptr<channels::UserChannel> AddUserChannelDialog::channel()\n{\n\treturn channel_;\n}\n\nvoid AddUserChannelDialog::accept()\n{\n\tif (name_edit_->text().size() == 0) {\n\t\tQMessageBox::warning(this,\n\t\t\ttr(\"Channel name missing\"),\n\t\t\ttr(\"Please enter a name for the new channel.\"),\n\t\t\tQMessageBox::Ok);\n\t\treturn;\n\t}\n\n\tauto device = device_box_->selected_device();\n\n\tchannel_ = device->add_user_channel(\n\t\tname_edit_->text().toStdString(),\n\t\tchannel_group_box_->selected_channel_group().toStdString());\n\n\tQDialog::accept();\n}\n\nvoid AddUserChannelDialog::on_device_changed()\n{\n\tchannel_group_box_->change_device(device_box_->selected_device());\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/adduserchanneldialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_ADDUSERCHANNELDIALOG_HPP\n#define UI_DIALOGS_ADDUSERCHANNELDIALOG_HPP\n\n#include <memory>\n\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\nnamespace channels {\nclass UserChannel;\n}\n\nnamespace ui {\n\nnamespace data {\nclass QuantityComboBox;\nclass QuantityFlagsList;\nclass UnitComboBox;\n}\nnamespace devices {\nclass ChannelGroupComboBox;\nclass DeviceComboBox;\n}\n\nnamespace dialogs {\n\nclass AddUserChannelDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tAddUserChannelDialog(const Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device,\n\t\tQWidget *parent = nullptr);\n\n\tshared_ptr<channels::UserChannel> channel();\n\nprivate:\n\tvoid setup_ui();\n\n\tconst Session &session_;\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\tshared_ptr<channels::UserChannel> channel_;\n\n\tQLineEdit *name_edit_;\n\tui::data::QuantityComboBox *quantity_box_;\n\tui::data::QuantityFlagsList *quantity_flags_list_;\n\tui::data::UnitComboBox *unit_box_;\n\tui::devices::DeviceComboBox *device_box_;\n\tui::devices::ChannelGroupComboBox *channel_group_box_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\nprivate Q_SLOTS:\n\tvoid on_device_changed();\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_ADDUSERCHANNELDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/addviewdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n\n#include <QDebug>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QString>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"addviewdialog.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/devices/selectconfigurableform.hpp\"\n#include \"src/ui/devices/selectpropertyform.hpp\"\n#include \"src/ui/devices/selectsignalwidget.hpp\"\n#include \"src/ui/devices/devicetree/devicetreeview.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/dataview.hpp\"\n#include \"src/ui/views/powerpanelview.hpp\"\n#include \"src/ui/views/sequenceoutputview.hpp\"\n#include \"src/ui/views/timeplotview.hpp\"\n#include \"src/ui/views/valuepanelview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include \"src/ui/views/xyplotview.hpp\"\n\nusing std::set;\nusing std::static_pointer_cast;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nAddViewDialog::AddViewDialog(Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> device,\n\t\tint selected_tab,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\tdevice_(device),\n\tselected_tab_(selected_tab)\n{\n\tsetup_ui();\n}\n\nvoid AddViewDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Add View\"));\n\tthis->setMinimumWidth(500);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout;\n\n\ttab_widget_ = new QTabWidget();\n\tthis->setup_ui_control_tab();\n\tthis->setup_ui_sequence_tab();\n\tthis->setup_ui_panel_tab();\n\tthis->setup_ui_time_plot_tab();\n\tthis->setup_ui_xy_plot_tab();\n\tthis->setup_ui_data_table_tab();\n\tthis->setup_ui_power_panel_tab();\n\ttab_widget_->setCurrentIndex(selected_tab_);\n\tmain_layout->addWidget(tab_widget_);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &AddViewDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &AddViewDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid AddViewDialog::setup_ui_control_tab()\n{\n\tQString title(tr(\"Control\"));\n\tQWidget *control_widget = new QWidget();\n\n\tconfigurable_configurable_form_ =\n\t\tnew ui::devices::SelectConfigurableForm(session_);\n\tconfigurable_configurable_form_->select_device(device_);\n\tcontrol_widget->setLayout(configurable_configurable_form_);\n\n\ttab_widget_->addTab(control_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_sequence_tab()\n{\n\tQString title(tr(\"Sequence Output\"));\n\tQWidget *sequence_widget = new QWidget();\n\n\tsequence_property_form_ = new ui::devices::SelectPropertyForm(session_);\n\tsequence_property_form_->select_device(device_);\n\tsequence_property_form_->filter_config_keys(set<sv::data::DataType>{\n\t\tsv::data::DataType::Double});\n\tsequence_widget->setLayout(sequence_property_form_);\n\n\ttab_widget_->addTab(sequence_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_panel_tab()\n{\n\tQString title(tr(\"Panel\"));\n\tQWidget *panel_widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\tpanel_widget->setLayout(layout);\n\n\tpanel_channel_tree_ = new ui::devices::devicetree::DeviceTreeView(\n\t\tsession_, false, false, true, false, false, false, false, false);\n\tpanel_channel_tree_->expand_device(device_);\n\n\tlayout->addWidget(panel_channel_tree_);\n\n\ttab_widget_->addTab(panel_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_time_plot_tab()\n{\n\tQString title(tr(\"Time Plot\"));\n\tQWidget *plot_widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\tplot_widget->setLayout(layout);\n\n\ttime_plot_channel_tree_ = new ui::devices::devicetree::DeviceTreeView(\n\t\tsession_, false, false, true, true, false, false, false, false);\n\ttime_plot_channel_tree_->expand_device(device_);\n\n\tlayout->addWidget(time_plot_channel_tree_);\n\n\ttab_widget_->addTab(plot_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_xy_plot_tab()\n{\n\tQString title(tr(\"XY Plot\"));\n\tQWidget *plot_widget = new QWidget();\n\tQHBoxLayout *layout = new QHBoxLayout();\n\tplot_widget->setLayout(layout);\n\n\tQGroupBox *x_signal_group = new QGroupBox(tr(\"X Signal\"));\n\tQVBoxLayout *x_layout = new QVBoxLayout();\n\txy_plot_x_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\txy_plot_x_signal_widget_->select_device(device_);\n\tx_layout->addWidget(xy_plot_x_signal_widget_);\n\tx_signal_group->setLayout(x_layout);\n\tlayout->addWidget(x_signal_group);\n\n\tQGroupBox *y_signal_group = new QGroupBox(tr(\"Y Signal\"));\n\tQVBoxLayout *y_layout = new QVBoxLayout();\n\txy_plot_y_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\txy_plot_y_signal_widget_->select_device(device_);\n\ty_layout->addWidget(xy_plot_y_signal_widget_);\n\ty_signal_group->setLayout(y_layout);\n\tlayout->addWidget(y_signal_group);\n\n\ttab_widget_->addTab(plot_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_data_table_tab()\n{\n\tQString title(tr(\"Data Table\"));\n\tQWidget *table_widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\ttable_widget->setLayout(layout);\n\n\tdata_table_signal_tree_ = new ui::devices::devicetree::DeviceTreeView(\n\t\tsession_, false, false, false, true, false, false, false, false);\n\tdata_table_signal_tree_->expand_device(device_);\n\n\tlayout->addWidget(data_table_signal_tree_);\n\n\ttab_widget_->addTab(table_widget, title);\n}\n\nvoid AddViewDialog::setup_ui_power_panel_tab()\n{\n\tQString title(tr(\"Power Panel\"));\n\tQWidget *pp_widget = new QWidget();\n\tQHBoxLayout *layout = new QHBoxLayout();\n\tpp_widget->setLayout(layout);\n\n\tQGroupBox *voltage_signal_group = new QGroupBox(tr(\"Voltage Signal\"));\n\tQVBoxLayout *voltage_layout = new QVBoxLayout();\n\tppanel_voltage_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\tppanel_voltage_signal_widget_->filter_quantity(data::Quantity::Voltage);\n\tppanel_voltage_signal_widget_->select_device(device_);\n\tvoltage_layout->addWidget(ppanel_voltage_signal_widget_);\n\tvoltage_signal_group->setLayout(voltage_layout);\n\tlayout->addWidget(voltage_signal_group);\n\n\tQGroupBox *current_signal_group = new QGroupBox(tr(\"Current Signal\"));\n\tQVBoxLayout *current_layout = new QVBoxLayout();\n\tppanel_current_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\tppanel_current_signal_widget_->filter_quantity(data::Quantity::Current);\n\tppanel_current_signal_widget_->select_device(device_);\n\tcurrent_layout->addWidget(ppanel_current_signal_widget_);\n\tcurrent_signal_group->setLayout(current_layout);\n\tlayout->addWidget(current_signal_group);\n\n\ttab_widget_->addTab(pp_widget, title);\n}\n\nvector<ui::views::BaseView *> AddViewDialog::views()\n{\n\treturn views_;\n}\n\nvoid AddViewDialog::accept()\n{\n\tint tab_index = tab_widget_->currentIndex();\n\tswitch (tab_index) {\n\tcase 0:\n\t\t// Add control view for configurable\n\t\t{\n\t\t\tauto configurable =\n\t\t\t\tconfigurable_configurable_form_->selected_configurable();\n\t\t\tauto conf_views = views::viewhelper::get_views_for_configurable(\n\t\t\t\tsession_, configurable);\n\n\t\t\tfor (const auto &view : conf_views) {\n\t\t\t\tviews_.push_back(view);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase 1:\n\t\t// Add sequence view for property\n\t\t{\n\t\t\tauto property = sequence_property_form_->selected_property();\n\t\t\tauto *conf_views = new ui::views::SequenceOutputView(session_);\n\t\t\tconf_views->set_property(\n\t\t\t\tstatic_pointer_cast<sv::data::properties::DoubleProperty>(property));\n\t\t\tviews_.push_back(conf_views);\n\t\t}\n\t\tbreak;\n\tcase 2:\n\t\t// Add value panel view\n\t\tfor (const auto &channel : panel_channel_tree_->checked_channels()) {\n\t\t\tauto *conf_views = new ui::views::ValuePanelView(session_);\n\t\t\tconf_views->set_channel(channel);\n\t\t\tviews_.push_back(conf_views);\n\t\t}\n\t\tbreak;\n\tcase 3:\n\t\t// Add time plot view\n\t\tfor (const auto &channel : time_plot_channel_tree_->checked_channels()) {\n\t\t\tauto *conf_views = new ui::views::TimePlotView(session_);\n\t\t\tconf_views->set_channel(channel);\n\t\t\tviews_.push_back(conf_views);\n\t\t}\n\t\tfor (const auto &signal : time_plot_channel_tree_->checked_signals()) {\n\t\t\tauto *conf_views = new ui::views::TimePlotView(session_);\n\t\t\tconf_views->add_signal(static_pointer_cast<data::AnalogTimeSignal>(signal));\n\t\t\tviews_.push_back(conf_views);\n\t\t}\n\t\tbreak;\n\tcase 4:\n\t\t// Add x/y plot view\n\t\t{\n\t\t\tauto x_signal = xy_plot_x_signal_widget_->selected_signal();\n\t\t\tauto y_signal = xy_plot_y_signal_widget_->selected_signal();\n\t\t\tif (x_signal != nullptr && y_signal != nullptr) {\n\t\t\t\tauto *view = new ui::views::XYPlotView(session_);\n\t\t\t\tview->add_signals(\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(x_signal),\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(y_signal));\n\t\t\t\tviews_.push_back(view);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase 5:\n\t\t// Add data table view\n\t\t{\n\t\t\tauto signals = data_table_signal_tree_->checked_signals();\n\t\t\tif (!signals.empty()) {\n\t\t\t\tauto *view = new ui::views::DataView(session_);\n\t\t\t\tfor (const auto &signal : signals) {\n\t\t\t\t\tview->add_signal(\n\t\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(signal));\n\t\t\t\t}\n\t\t\t\tviews_.push_back(view);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tcase 6:\n\t\t// Add power panel view\n\t\t{\n\t\t\tauto v_signal = ppanel_voltage_signal_widget_->selected_signal();\n\t\t\tauto c_signal = ppanel_current_signal_widget_->selected_signal();\n\t\t\tif (v_signal != nullptr && c_signal != nullptr) {\n\t\t\t\tauto *view = new ui::views::PowerPanelView(session_);\n\t\t\t\tview->set_signals(\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(v_signal),\n\t\t\t\t\tstatic_pointer_cast<data::AnalogTimeSignal>(c_signal));\n\t\t\t\tviews_.push_back(view);\n\t\t\t}\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n\t}\n\n\tQDialog::accept();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/addviewdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_ADDVIEWDIALOG_HPP\n#define UI_DIALOGS_ADDVIEWDIALOG_HPP\n\n#include <memory>\n\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QTabWidget>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace devices {\nclass SelectConfigurableForm;\nclass SelectPropertyForm;\nclass SelectSignalWidget;\nnamespace devicetree {\nclass DeviceTreeView;\n}\n}\nnamespace views {\nclass BaseView;\n}\n\nnamespace dialogs {\n\nclass AddViewDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tAddViewDialog(Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> device,\n\t\tint selected_tab,\n\t\tQWidget *parent = nullptr);\n\n\tvector<ui::views::BaseView *> views();\n\nprivate:\n\tvoid setup_ui();\n\tvoid setup_ui_control_tab();\n\tvoid setup_ui_sequence_tab();\n\tvoid setup_ui_panel_tab();\n\tvoid setup_ui_time_plot_tab();\n\tvoid setup_ui_xy_plot_tab();\n\tvoid setup_ui_data_table_tab();\n\tvoid setup_ui_power_panel_tab();\n\n\tSession &session_;\n\tconst shared_ptr<sv::devices::BaseDevice> device_;\n\tint selected_tab_;\n\tvector<ui::views::BaseView *> views_;\n\n\tQTabWidget *tab_widget_;\n\tui::devices::SelectConfigurableForm *configurable_configurable_form_;\n\tui::devices::SelectPropertyForm *sequence_property_form_;\n\tui::devices::devicetree::DeviceTreeView *panel_channel_tree_;\n\tui::devices::devicetree::DeviceTreeView *time_plot_channel_tree_;\n\tui::devices::SelectSignalWidget *xy_plot_x_signal_widget_;\n\tui::devices::SelectSignalWidget *xy_plot_y_signal_widget_;\n\tui::devices::devicetree::DeviceTreeView *data_table_signal_tree_;\n\tui::devices::SelectSignalWidget *ppanel_voltage_signal_widget_;\n\tui::devices::SelectSignalWidget *ppanel_current_signal_widget_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_ADDVIEWDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/connectdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012-2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <map>\n#include <memory>\n#include <mutex>\n#include <string>\n#include <thread>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDebug>\n#include <QGroupBox>\n#include <QLabel>\n#include <QRadioButton>\n\n#include \"connectdialog.hpp\"\n#include \"src/devicemanager.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n\nusing std::list;\nusing std::map;\nusing std::shared_ptr;\nusing std::string;\n\nusing Glib::ustring;\nusing Glib::Variant;\nusing Glib::VariantBase;\n\nusing sigrok::ConfigKey;\nusing sigrok::Driver;\n\nusing sv::devices::HardwareDevice;\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nConnectDialog::ConnectDialog(sv::DeviceManager &device_manager,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tdevice_manager_(device_manager),\n\tlayout_(this),\n\tform_(this),\n\tform_layout_(&form_),\n\tdrivers_(&form_),\n\tscan_button_(tr(\"&Scan for devices using driver above\"), this),\n\tdevice_list_(this),\n\tbutton_box_(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,\n\t\tQt::Horizontal, this)\n{\n\tqRegisterMetaType<std::map<std::string, std::string>>(\"std::map<std::string, std::string>\");\n\n\tsetWindowTitle(tr(\"Connect to Device\"));\n\n\tconnect(&button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &ConnectDialog::accept);\n\tconnect(&button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &ConnectDialog::reject);\n\n\tconnect(this, &ConnectDialog::populate_serials_done,\n\t\tthis, &ConnectDialog::populate_serials_finish);\n\n\tpopulate_drivers();\n\tconnect(&drivers_, QOverload<int>::of(&QComboBox::activated),\n\t\tthis, &ConnectDialog::driver_selected);\n\n\tform_.setLayout(&form_layout_);\n\n\tQVBoxLayout *vbox_drv = new QVBoxLayout;\n\tvbox_drv->addWidget(&drivers_);\n\tQGroupBox *groupbox_drv = new QGroupBox(tr(\"Step 1: Choose the driver\"));\n\tgroupbox_drv->setLayout(vbox_drv);\n\tform_layout_.addRow(groupbox_drv);\n\n\tradiobtn_usb_ = new QRadioButton(tr(\"&USB\"), this);\n\tradiobtn_serial_ = new QRadioButton(tr(\"Serial &Port\"), this);\n\tradiobtn_tcp_ = new QRadioButton(tr(\"&TCP/IP\"), this);\n\n\tradiobtn_usb_->setChecked(true);\n\n\tserial_config_ = new QWidget();\n\tQHBoxLayout *serial_config_layout = new QHBoxLayout(serial_config_);\n\tserial_devices_.setEditable(true);\n\tserial_devices_.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);\n\tserial_config_layout->addWidget(&serial_devices_);\n\tserial_baudrate_.setEditable(true);\n\tserial_baudrate_.addItem(\"\");\n\tserial_baudrate_.addItem(\"921600\");\n\tserial_baudrate_.addItem(\"115200\");\n\tserial_baudrate_.addItem(\"57600\");\n\tserial_baudrate_.addItem(\"19200\");\n\tserial_baudrate_.addItem(\"9600\");\n\tserial_config_layout->addWidget(&serial_baudrate_);\n\tserial_config_layout->addWidget(new QLabel(\"baud\"));\n\tserial_config_->setEnabled(false);\n\n\ttcp_config_ = new QWidget();\n\tQHBoxLayout *tcp_config_layout = new QHBoxLayout(tcp_config_);\n\ttcp_host_ = new QLineEdit;\n\ttcp_host_->setText(\"192.168.1.100\");\n\ttcp_config_layout->addWidget(tcp_host_);\n\ttcp_config_layout->addWidget(new QLabel(\":\"));\n\ttcp_port_ = new QSpinBox;\n\ttcp_port_->setRange(1, 65535);\n\ttcp_port_->setValue(5555);\n\ttcp_config_layout->addWidget(tcp_port_);\n\n\ttcp_config_layout->addSpacing(30);\n\ttcp_config_layout->addWidget(new QLabel(tr(\"Protocol:\")));\n\ttcp_protocol_ = new QComboBox();\n\ttcp_protocol_->addItem(\"Raw TCP\", QVariant(\"tcp-raw/%1/%2\"));\n\ttcp_protocol_->addItem(\"VXI\", QVariant(\"vxi/%1/%2\"));\n\ttcp_config_layout->addWidget(tcp_protocol_);\n\ttcp_config_layout->setContentsMargins(0, 0, 0, 0);\n\ttcp_config_->setEnabled(false);\n\n\tcheck_available_libs();\n\n\tQVBoxLayout *vbox_if = new QVBoxLayout;\n\tvbox_if->addWidget(radiobtn_usb_);\n\tvbox_if->addWidget(radiobtn_serial_);\n\tvbox_if->addWidget(serial_config_);\n\tvbox_if->addWidget(radiobtn_tcp_);\n\tvbox_if->addWidget(tcp_config_);\n\n\tQGroupBox *groupbox_if = new QGroupBox(tr(\"Step 2: Choose the interface\"));\n\tgroupbox_if->setLayout(vbox_if);\n\tform_layout_.addRow(groupbox_if);\n\n\tQVBoxLayout *vbox_scan = new QVBoxLayout;\n\tvbox_scan->addWidget(&scan_button_);\n\tQGroupBox *groupbox_scan = new QGroupBox(tr(\"Step 3: Scan for devices\"));\n\tgroupbox_scan->setLayout(vbox_scan);\n\tform_layout_.addRow(groupbox_scan);\n\n\tQVBoxLayout *vbox_select = new QVBoxLayout;\n\t// Let the device list occupy only the minimum space needed\n\tdevice_list_.setMaximumHeight(device_list_.minimumSizeHint().height());\n\tvbox_select->addWidget(&device_list_);\n\tQGroupBox *groupbox_select = new QGroupBox(tr(\"Step 4: Select the device\"));\n\tgroupbox_select->setLayout(vbox_select);\n\tform_layout_.addRow(groupbox_select);\n\n\tunset_connection();\n\n\tconnect(radiobtn_serial_, &QRadioButton::toggled,\n\t\tthis, &ConnectDialog::serial_toggled);\n\tconnect(radiobtn_tcp_, &QRadioButton::toggled,\n\t\tthis, &ConnectDialog::tcp_toggled);\n\tconnect(&scan_button_, &QPushButton::pressed,\n\t\tthis, &ConnectDialog::scan_pressed);\n\n\tif (gpib_avialable_) {\n\t\tradiobtn_gpib_ = new QRadioButton(tr(\"&GPIB\"), this);\n\t\t/*\n\t\t * TODO: Replace with QComboBox and prefill with available GPIB\n\t\t * connection strings (like the serial box).\n\t\t * Must be implemented in libsigrok.\n\t\t */\n\t\tgpib_libgpib_name_ = new QLineEdit;\n\t\tgpib_libgpib_name_->setEnabled(false);\n\t\tvbox_if->addWidget(radiobtn_gpib_);\n\t\tvbox_if->addWidget(gpib_libgpib_name_);\n\n\t\tconnect(radiobtn_gpib_, &QRadioButton::toggled,\n\t\t\tthis, &ConnectDialog::gpib_toggled);\n\t}\n\n\tsetLayout(&layout_);\n\n\tlayout_.addWidget(&form_);\n\tlayout_.addWidget(&button_box_);\n\n\t// Initially populate serials for current selected device\n\tdriver_selected(drivers_.currentIndex());\n}\n\nConnectDialog::~ConnectDialog() {\n\t/*\n\t * NOTE: Wait until a potentially running populate_serials_thread_ thread\n\t *       has finished, otherwise sv will crash.\n\t *       Waiting for the lock/mutex isn't strictly needed (empty d'tor is\n\t *       sufficient), but better safe than sorry. :)\n\t */\n\tstd::lock_guard<std::mutex> lock(populate_serials_mtx_);\n}\n\nshared_ptr<HardwareDevice> ConnectDialog::get_selected_device() const\n{\n\tconst QListWidgetItem *const item = device_list_.currentItem();\n\tif (!item)\n\t\treturn shared_ptr<HardwareDevice>();\n\n\treturn item->data(Qt::UserRole).value<shared_ptr<HardwareDevice>>();\n}\n\nvoid ConnectDialog::populate_drivers()\n{\n\tfor (const auto &entry : device_manager_.context()->drivers()) {\n\t\tauto name = entry.first;\n\t\tauto sr_driver = entry.second;\n\n\t\tif (sv::devices::deviceutil::is_supported_driver(sr_driver)) {\n\t\t\tdrivers_.addItem(QString(\"%1 (%2)\").arg(\n\t\t\t\tsr_driver->long_name().c_str(), name.c_str()),\n\t\t\t\tQVariant::fromValue(sr_driver));\n\t\t}\n\t}\n}\n\nvoid ConnectDialog::check_available_libs()\n{\n\tgpib_avialable_ = false;\n\tQString libgpib(\"libgpib\");\n\n\tGSList *libs_orig = sr_buildinfo_libs_get();\n\tfor (GSList *lib = libs_orig; lib; lib = lib->next) {\n\t\tGSList *lib_data = static_cast<GSList *>(lib->data);\n\t\tQString name(static_cast<const char *>(lib_data->data));\n\n\t\tif (QString::compare(name, libgpib, Qt::CaseInsensitive) == 0) {\n\t\t\tgpib_avialable_ = true;\n\t\t\tg_slist_free_full(lib_data, g_free);\n\t\t\tbreak;\n\t\t}\n\t\tg_slist_free_full(lib_data, g_free);\n\t}\n\tg_slist_free(libs_orig);\n}\n\nvoid ConnectDialog::populate_serials_start(shared_ptr<Driver> driver)\n{\n\tserial_devices_.clear();\n\tserial_devices_.addItem(tr(\"Loading...\"));\n\tserial_config_->setDisabled(true);\n\n\tpopulate_serials_thread_ =\n\t\tstd::thread(&ConnectDialog::populate_serials_thread_proc, this, driver);\n\tpopulate_serials_thread_.detach();\n}\n\nvoid ConnectDialog::populate_serials_finish(\n\tconst std::map<std::string, std::string> &serials)\n{\n\tstd::lock_guard<std::mutex> lock(populate_serials_mtx_);\n\n\tserial_devices_.clear();\n\tfor (const auto &serial : serials) {\n\t\tserial_devices_.addItem(QString(\"%1 (%2)\").arg(\n\t\t\tserial.first.c_str(), serial.second.c_str()),\n\t\t\tQString::fromStdString(serial.first));\n\t}\n\tif (radiobtn_serial_->isChecked())\n\t\tserial_config_->setDisabled(false);\n}\n\nvoid ConnectDialog::populate_serials_thread_proc(shared_ptr<Driver> driver)\n{\n\tstd::unique_lock<std::mutex> lock(populate_serials_mtx_, std::try_to_lock);\n\tif (lock.owns_lock()) {\n\t\tmap<string, string> serials = device_manager_.context()->serials(driver);\n\t\tQ_EMIT populate_serials_done(serials);\n\t}\n}\n\nvoid ConnectDialog::unset_connection()\n{\n\tdevice_list_.clear();\n\tbutton_box_.button(QDialogButtonBox::Ok)->setDisabled(true);\n}\n\nvoid ConnectDialog::serial_toggled(bool checked)\n{\n\tstd::unique_lock<std::mutex> lock(populate_serials_mtx_, std::try_to_lock);\n\tif (lock.owns_lock())\n\t\tserial_config_->setEnabled(checked);\n}\n\nvoid ConnectDialog::tcp_toggled(bool checked)\n{\n\ttcp_config_->setEnabled(checked);\n}\n\nvoid ConnectDialog::gpib_toggled(bool checked)\n{\n\tgpib_libgpib_name_->setEnabled(checked);\n}\n\nvoid ConnectDialog::scan_pressed()\n{\n\tdevice_list_.clear();\n\n\tconst int d_index = drivers_.currentIndex();\n\tif (d_index == -1)\n\t\treturn;\n\n\tshared_ptr<Driver> driver =\n\t\tdrivers_.itemData(d_index).value<shared_ptr<Driver>>();\n\n\tassert(driver);\n\n\tmap<const ConfigKey *, VariantBase> drvopts;\n\n\tif (serial_config_->isEnabled()) {\n\t\tQString serial;\n\t\tconst int s_index = serial_devices_.currentIndex();\n\t\tif (s_index >= 0 && s_index < serial_devices_.count() &&\n\t\t\t\tserial_devices_.currentText() == serial_devices_.itemText(s_index))\n\t\t\tserial = serial_devices_.itemData(s_index).value<QString>();\n\t\telse\n\t\t\tserial = serial_devices_.currentText();\n\t\tdrvopts[ConfigKey::CONN] = Variant<ustring>::create(\n\t\t\tserial.toUtf8().constData());\n\n\t\t// Set baud rate if specified\n\t\tif (serial_baudrate_.currentText().length() > 0)\n\t\t\tdrvopts[ConfigKey::SERIALCOMM] = Variant<ustring>::create(\n\t\t\t\tQString(\"%1/8n1\").arg(serial_baudrate_.currentText()).toUtf8().constData());\n\t}\n\n\tif (tcp_config_->isEnabled()) {\n\t\tQString host = tcp_host_->text();\n\t\tQString port = tcp_port_->text();\n\t\tif (!host.isEmpty()) {\n\t\t\tQString conn = tcp_protocol_->\n\t\t\t\titemData(tcp_protocol_->currentIndex()).toString();\n\t\t\tconn = conn.arg(host, port);\n\n\t\t\tdrvopts[ConfigKey::CONN] = Variant<ustring>::create(\n\t\t\t\tconn.toUtf8().constData());\n\t\t}\n\t}\n\n\tif (gpib_avialable_ && gpib_libgpib_name_->isEnabled()) {\n\t\tQString name = gpib_libgpib_name_->text();\n\t\tQString conn = QString(\"libgpib/%1\").arg(name);\n\n\t\tdrvopts[ConfigKey::CONN] = Variant<ustring>::create(\n\t\t\tconn.toUtf8().constData());\n\t}\n\n\tconst list<shared_ptr<HardwareDevice>> devices =\n\t\tdevice_manager_.driver_scan(driver, drvopts);\n\n\tfor (const auto &device : devices) {\n\t\tassert(device);\n\n\t\tQString text = device->display_name(device_manager_);\n\t\ttext += QString(\" with %1 channels\").arg(\n\t\t\tdevice->sr_device()->channels().size());\n\n\t\tQListWidgetItem *const item = new QListWidgetItem(text,\n\t\t\t&device_list_);\n\t\titem->setData(Qt::UserRole, QVariant::fromValue(device));\n\t\tdevice_list_.addItem(item);\n\t}\n\n\tdevice_list_.setCurrentRow(0);\n\tbutton_box_.button(QDialogButtonBox::Ok)->setDisabled(device_list_.count() == 0);\n}\n\nvoid ConnectDialog::driver_selected(int index)\n{\n\tshared_ptr<Driver> driver =\n\t\tdrivers_.itemData(index).value<shared_ptr<Driver>>();\n\n\tunset_connection();\n\n\tpopulate_serials_start(driver);\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/connectdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012-2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_CONNECTDIALOG_HPP\n#define UI_DIALOGS_CONNECTDIALOG_HPP\n\n#include <map>\n#include <memory>\n#include <mutex>\n#include <string>\n#include <thread>\n\n#include <QCheckBox>\n#include <QComboBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QFormLayout>\n#include <QHBoxLayout>\n#include <QLineEdit>\n#include <QListWidget>\n#include <QPushButton>\n#include <QRadioButton>\n#include <QSpinBox>\n#include <QVBoxLayout>\n\n#include \"src/devices/hardwaredevice.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sigrok {\nclass Driver;\n}\n\nQ_DECLARE_METATYPE(shared_ptr<sigrok::Driver>)\nQ_DECLARE_METATYPE(shared_ptr<sv::devices::HardwareDevice>)\n\nnamespace sv {\n\nclass DeviceManager;\n\nnamespace devices {\nclass HardwareDevice;\n}\n\nnamespace ui {\nnamespace dialogs {\n\nclass ConnectDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ConnectDialog(sv::DeviceManager &device_manager,\n\t\tQWidget *parent = nullptr);\n\t~ConnectDialog();\n\n\tshared_ptr<sv::devices::HardwareDevice> get_selected_device() const;\n\nprivate:\n\tvoid populate_drivers();\n\tvoid populate_serials_start(shared_ptr<sigrok::Driver> driver);\n\tvoid populate_serials_thread_proc(shared_ptr<sigrok::Driver> driver);\n\tvoid check_available_libs();\n\tvoid unset_connection();\n\nprivate Q_SLOTS:\n\tvoid driver_selected(int index);\n\tvoid serial_toggled(bool checked);\n\tvoid tcp_toggled(bool checked);\n\tvoid gpib_toggled(bool checked);\n\tvoid scan_pressed();\n\tvoid populate_serials_finish(\n\t\tconst std::map<std::string, std::string> &serials);\n\nprivate:\n\tsv::DeviceManager &device_manager_;\n\n\tbool gpib_avialable_;\n\n\tQVBoxLayout layout_;\n\n\tQWidget form_;\n\tQFormLayout form_layout_;\n\n\tQComboBox drivers_;\n\n\tQRadioButton *radiobtn_usb_;\n\tQRadioButton *radiobtn_serial_;\n\tQRadioButton *radiobtn_tcp_;\n\tQRadioButton *radiobtn_gpib_;\n\n\tstd::thread populate_serials_thread_;\n\tstd::mutex populate_serials_mtx_;\n\tQWidget *serial_config_;\n\tQComboBox serial_devices_;\n\tQComboBox serial_baudrate_;\n\n\tQWidget *tcp_config_;\n\tQLineEdit *tcp_host_;\n\tQSpinBox *tcp_port_;\n\tQComboBox *tcp_protocol_;\n\n\tQLineEdit *gpib_libgpib_name_;\n\n\tQPushButton scan_button_;\n\tQListWidget device_list_;\n\n\tQDialogButtonBox button_box_;\n\nQ_SIGNALS:\n\tvoid populate_serials_done(std::map<std::string, std::string> serials);\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_CONNECTDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/generatewaveformdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cmath>\n#include <memory>\n#include <vector>\n\n#include <QChar>\n#include <QComboBox>\n#include <QDebug>\n#include <QDialog>\n#include <QDoubleSpinBox>\n#include <QFormLayout>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QIcon>\n#include <QVariant>\n#include <QVBoxLayout>\n\n#include \"generatewaveformdialog.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nQ_DECLARE_METATYPE(sv::ui::dialogs::WaveformType)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nGenerateWaveformDialog::GenerateWaveformDialog(\n\t\tdouble min_value, double max_value, double step, int decimals,\n\t\tconst QString &unit, QWidget *parent) :\n\tQDialog(parent),\n\tmin_value_(min_value),\n\tmax_value_(max_value),\n\tstep_(step),\n\tdecimals_(decimals),\n\tunit_(unit)\n{\n\tsetup_ui();\n}\n\nGenerateWaveformDialog::GenerateWaveformDialog(\n\t\tshared_ptr<sv::data::properties::DoubleProperty> property,\n\t\tQWidget *parent) :\n\tQDialog(parent)\n{\n\tmin_value_ = property->min();\n\tmax_value_ = property->max();\n\tstep_ = property->step();\n\tdecimals_ = property->decimal_places();\n\tsv::data::Unit unit = property->unit();\n\tif (unit != sv::data::Unit::Unitless && unit != sv::data::Unit::Unknown)\n\t\tunit_ = \" \" + sv::data::datautil::format_unit(unit);\n\telse\n\t\tunit_ = \"\";\n\n\tsetup_ui();\n}\n\nvoid GenerateWaveformDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Generate Waveform\"));\n\tthis->setMinimumWidth(500);\n\n\tQFormLayout *layout = new QFormLayout;\n\n\twaveform_box_ = new QComboBox();\n\twaveform_box_->addItem(tr(\"Sine\"),\n\t\tQVariant::fromValue(WaveformType::Sine));\n\twaveform_box_->addItem(tr(\"Square\"),\n\t\tQVariant::fromValue(WaveformType::Square));\n\twaveform_box_->addItem(tr(\"Triangle\"),\n\t\tQVariant::fromValue(WaveformType::Triangle));\n\twaveform_box_->addItem(tr(\"Sawtooth\"),\n\t\tQVariant::fromValue(WaveformType::Sawtooth));\n\twaveform_box_->addItem(tr(\"Sawtooth inverted\"),\n\t\tQVariant::fromValue(WaveformType::SawtoothInv));\n\tconnect(waveform_box_, QOverload<int>::of(&QComboBox::currentIndexChanged),\n\t\t\tthis, &GenerateWaveformDialog::on_waveform_changed);\n\tlayout->addRow(tr(\"Waveform\"), waveform_box_);\n\n\tQGroupBox *amp_group = new QGroupBox(tr(\"Min/Max - Amplitude\"));\n\tQHBoxLayout *amp_layout = new QHBoxLayout;\n\tQFormLayout *ampmm_layout = new QFormLayout;\n\tQFormLayout *ampf_layout = new QFormLayout;\n\n\tmin_value_box_ = new QDoubleSpinBox();\n\tmin_value_box_->setMinimum(min_value_);\n\tmin_value_box_->setMaximum(max_value_);\n\tmin_value_box_->setSingleStep(step_);\n\tmin_value_box_->setDecimals(decimals_);\n\tmin_value_box_->setSuffix(unit_);\n\tconnect(min_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n\tampmm_layout->addRow(tr(\"Min. value\"), min_value_box_);\n\n\tmax_value_box_ = new QDoubleSpinBox();\n\tmax_value_box_->setMinimum(min_value_);\n\tmax_value_box_->setMaximum(max_value_);\n\tmax_value_box_->setSingleStep(step_);\n\tmax_value_box_->setDecimals(decimals_);\n\tmax_value_box_->setSuffix(unit_);\n\tconnect(max_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n\tampmm_layout->addRow(tr(\"Max. value\"), max_value_box_);\n\tamp_layout->addLayout(ampmm_layout);\n\n\tamplitude_box_ = new QDoubleSpinBox();\n\tamplitude_box_->setMinimum(min_value_);\n\tamplitude_box_->setMaximum(max_value_);\n\tamplitude_box_->setSingleStep(step_);\n\tamplitude_box_->setDecimals(decimals_);\n\tamplitude_box_->setSuffix(unit_);\n\tconnect(amplitude_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n\tampf_layout->addRow(tr(\"Amplitude\"), amplitude_box_);\n\n\toffset_box_ = new QDoubleSpinBox();\n\toffset_box_->setMinimum(min_value_);\n\toffset_box_->setMaximum(max_value_);\n\toffset_box_->setSingleStep(step_);\n\toffset_box_->setDecimals(decimals_);\n\toffset_box_->setSuffix(unit_);\n\tconnect(offset_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n\tampf_layout->addRow(tr(\"Offset\"), offset_box_);\n\tamp_layout->addLayout(ampf_layout);\n\tamp_group->setLayout(amp_layout);\n\tlayout->addRow(amp_group);\n\n\tQGroupBox *freq_group = new QGroupBox(tr(\"Periode - Frequency\"));\n\tQHBoxLayout *freq_layout = new QHBoxLayout;\n\tQFormLayout *freqp_layout = new QFormLayout;\n\tQFormLayout *freqf_layout = new QFormLayout;\n\n\tperiode_box_ = new QDoubleSpinBox();\n\tperiode_box_->setMinimum(0);\n\tperiode_box_->setMaximum(500000);\n\tperiode_box_->setSingleStep(0.1);\n\tperiode_box_->setDecimals(3);\n\tperiode_box_->setSuffix(\" s\");\n\tconnect(periode_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_periode_changed);\n\tfreqp_layout->addRow(tr(\"Periode\"), periode_box_);\n\tfreq_layout->addLayout(freqp_layout);\n\n\tfrequency_box_ = new QDoubleSpinBox();\n\tfrequency_box_->setMinimum(0);\n\tfrequency_box_->setMaximum(5000);\n\tfrequency_box_->setSingleStep(0.001);\n\tfrequency_box_->setDecimals(4);\n\tfrequency_box_->setSuffix(\" Hz\");\n\tconnect(frequency_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_frequency_changed);\n\tfreqf_layout->addRow(tr(\"Frequency\"), frequency_box_);\n\tfreq_layout->addLayout(freqf_layout);\n\tfreq_group->setLayout(freq_layout);\n\tlayout->addRow(freq_group);\n\n\tQGroupBox *samples_group = new QGroupBox(tr(\"Samples\"));\n\tQHBoxLayout *samples_layout = new QHBoxLayout;\n\tQFormLayout *samplesi_layout = new QFormLayout;\n\tQFormLayout *samplesc_layout = new QFormLayout;\n\n\tinterval_box_ = new QDoubleSpinBox();\n\tinterval_box_->setMinimum(0);\n\tinterval_box_->setMaximum(100000);\n\tinterval_box_->setSingleStep(0.1);\n\tinterval_box_->setDecimals(3);\n\tinterval_box_->setSuffix(\" s\");\n\tconnect(interval_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_interval_changed);\n\tsamplesi_layout->addRow(tr(\"Time between samples\"), interval_box_);\n\tsamples_layout->addLayout(samplesi_layout);\n\n\tsample_count_box_ = new QSpinBox();\n\tsample_count_box_->setMinimum(0);\n\tsample_count_box_->setMaximum(1000000);\n\tconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n\tsamplesc_layout->addRow(tr(\"Number of samples\"), sample_count_box_);\n\tsamples_layout->addLayout(samplesc_layout);\n\tsamples_group->setLayout(samples_layout);\n\tlayout->addRow(samples_group);\n\n\tQGroupBox *phi_group = new QGroupBox(tr(\"Phase offset\"));\n\tQHBoxLayout *phi_layout = new QHBoxLayout;\n\tQFormLayout *phid_layout = new QFormLayout;\n\tQFormLayout *phir_layout = new QFormLayout;\n\n\tphi_deg_box_ = new QDoubleSpinBox();\n\tphi_deg_box_->setMinimum(-360);\n\tphi_deg_box_->setMaximum(360);\n\tphi_deg_box_->setSingleStep(0.1);\n\tphi_deg_box_->setDecimals(1);\n\tphi_deg_box_->setSuffix(QString(\" %1\").arg(QChar(0x00B0)));\n\tconnect(phi_deg_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_deg_changed);\n\tphid_layout->addRow(tr(\"%1 (deg)\").arg(QChar(0x03C6)), phi_deg_box_);\n\tphi_layout->addLayout(phid_layout);\n\n\tphi_rad_box_ = new QDoubleSpinBox();\n\tphi_rad_box_->setMinimum(-2 * pi);\n\tphi_rad_box_->setMaximum(2 * pi);\n\tphi_rad_box_->setSingleStep(0.01);\n\tphi_rad_box_->setDecimals(3);\n\tconnect(phi_rad_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_rad_changed);\n\tphir_layout->addRow(tr(\"%1 (rad)\").arg(QChar(0x03C6)), phi_rad_box_);\n\tphi_layout->addLayout(phir_layout);\n\tphi_group->setLayout(phi_layout);\n\tlayout->addRow(phi_group);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tlayout->addRow(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &GenerateWaveformDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &GenerateWaveformDialog::reject);\n\n\t// Set values\n\tmin_value_box_->setValue(min_value_);\n\tmax_value_box_->setValue(max_value_);\n\tperiode_box_->setValue(60);\n\tinterval_box_->setValue(0.1);\n\tphi_deg_box_->setValue(270);\n\n\tthis->setLayout(layout);\n}\n\nvector<double> GenerateWaveformDialog::sequence_values() const\n{\n\treturn sequence_values_;\n}\n\nvector<double> GenerateWaveformDialog::sequence_delays() const\n{\n\treturn sequence_delays_;\n}\n\nvoid GenerateWaveformDialog::accept()\n{\n\tdouble amplitude = amplitude_box_->value();\n\tdouble offset = offset_box_->value();\n\tdouble interval = interval_box_->value();\n\tdouble periode;\n\tdouble frequency;\n\t// Get the most precise values for periode and frequency, because\n\t// the values from the spin boxes are truncated!\n\tif (frequency_box_->value() > 1) {\n\t\tfrequency = frequency_box_->value();\n\t\tperiode = 1 / frequency;\n\t}\n\telse {\n\t\tperiode = periode_box_->value();\n\t\tfrequency = 1 / periode;\n\t}\n\tdouble phi = phi_rad_box_->value();\n\tdouble omega = 2 * pi * frequency;\n\n\tWaveformType w_type = waveform_box_->currentData().value<WaveformType>();\n\t// NOTE: We must not rely on floating point types for loop termination.\n\t//       Resolves clang-analyzer-security.FloatLoopCounter warnings.\n\tdouble time = .0;\n\tsize_t const count = std::floor(periode / interval);\n\tfor (size_t i = 0; i < count; ++i) {\n\t\tdouble x = omega * time + phi; // NOLINT(readability-identifier-length)\n\t\ttime += interval;\n\t\tdouble value;\n\t\tif (w_type == WaveformType::Sine)\n\t\t\tvalue = std::sin(x);\n\t\telse if (w_type == WaveformType::Square)\n\t\t\tvalue = std::sin(x) < 0 ? -1 : 1;\n\t\telse if (w_type == WaveformType::Triangle)\n\t\t\tvalue = (std::asin(std::sin(x))) / (pi/2);\n\t\telse if (w_type == WaveformType::Sawtooth)\n\t\t\t// y = −arctan(cotan(x))\n\t\t\tvalue = -1 * std::atan(1 / std::tan(x)) / (pi/2);\n\t\telse if (w_type == WaveformType::SawtoothInv)\n\t\t\tvalue = std::atan(1 / std::tan(x)) / (pi/2);\n\t\telse\n\t\t\tvalue = 0;\n\n\t\tvalue = (amplitude * value) + offset;\n\t\tsequence_values_.push_back(value);\n\t\tsequence_delays_.push_back(interval);\n\t}\n\n\tQDialog::accept();\n}\n\nvoid GenerateWaveformDialog::on_waveform_changed()\n{\n\tWaveformType w_type = waveform_box_->currentData().value<WaveformType>();\n\tif (w_type == WaveformType::Sine || w_type == WaveformType::Triangle)\n\t\tphi_deg_box_->setValue(270);\n\telse\n\t\tphi_deg_box_->setValue(0);\n}\n\nvoid GenerateWaveformDialog::on_min_max_changed()\n{\n\tdisconnect(amplitude_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n\tdisconnect(offset_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n\n\tamplitude_box_->setValue((max_value_box_->value() - min_value_box_->value()) / 2);\n\toffset_box_->setValue(amplitude_box_->value() +  min_value_box_->value());\n\n\tconnect(amplitude_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n\tconnect(offset_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_amp_offs_changed);\n}\n\nvoid GenerateWaveformDialog::on_amp_offs_changed()\n{\n\tdisconnect(min_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n\tdisconnect(max_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n\n\tmin_value_box_->setValue(offset_box_->value() - amplitude_box_->value());\n\tmax_value_box_->setValue(offset_box_->value() + amplitude_box_->value());\n\n\tconnect(min_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n\tconnect(max_value_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_min_max_changed);\n}\n\nvoid GenerateWaveformDialog::on_periode_changed()\n{\n\tdisconnect(frequency_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_frequency_changed);\n\tdisconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n\n\tfrequency_box_->setValue(1 / periode_box_->value());\n\tsample_count_box_->setValue(\n\t\tstd::floor(periode_box_->value() / interval_box_->value()));\n\n\tconnect(frequency_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_frequency_changed);\n\tconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n}\n\nvoid GenerateWaveformDialog::on_frequency_changed()\n{\n\tdisconnect(periode_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_periode_changed);\n\tdisconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n\n\tperiode_box_->setValue(1 / frequency_box_->value());\n\tsample_count_box_->setValue(\n\t\tstd::floor(periode_box_->value() / interval_box_->value()));\n\n\tconnect(periode_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_periode_changed);\n\tconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n}\n\nvoid GenerateWaveformDialog::on_interval_changed()\n{\n\tdisconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n\n\tsample_count_box_->setValue(\n\t\tstd::floor(periode_box_->value() / interval_box_->value()));\n\n\tconnect(sample_count_box_, QOverload<int>::of(&QSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_sample_cnt_changed);\n}\n\nvoid GenerateWaveformDialog::on_sample_cnt_changed()\n{\n\tdisconnect(interval_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_interval_changed);\n\n\tinterval_box_->setValue(periode_box_->value() / sample_count_box_->value());\n\n\tconnect(interval_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_interval_changed);\n}\n\nvoid GenerateWaveformDialog::on_phi_deg_changed()\n{\n\tdisconnect(phi_rad_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_rad_changed);\n\n\tphi_rad_box_->setValue(phi_deg_box_->value() * (pi/180));\n\n\tconnect(phi_rad_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_rad_changed);\n}\n\nvoid GenerateWaveformDialog::on_phi_rad_changed()\n{\n\tdisconnect(phi_deg_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_deg_changed);\n\n\tphi_deg_box_->setValue(phi_rad_box_->value() * (180/pi));\n\n\tconnect(phi_deg_box_, QOverload<double>::of(&QDoubleSpinBox::valueChanged),\n\t\tthis, &GenerateWaveformDialog::on_phi_deg_changed);\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/generatewaveformdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_GENERATEWAVEFORMDIALOG_HPP\n#define UI_DIALOGS_GENERATEWAVEFORMDIALOG_HPP\n\n#include <cmath>\n#include <memory>\n#include <vector>\n\n#include <QComboBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QDoubleSpinBox>\n#include <QSpinBox>\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nnamespace data {\nnamespace properties {\nclass DoubleProperty;\n}\n}\n\nnamespace ui {\nnamespace dialogs {\n\nenum class WaveformType {\n\tSine,\n\tSquare,\n\tTriangle,\n\tSawtooth,\n\tSawtoothInv,\n};\n\nclass GenerateWaveformDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tGenerateWaveformDialog(double min_value, double max_value, double step,\n\t\tint decimals = 3, const QString &unit = \"\", QWidget *parent = nullptr);\n\texplicit GenerateWaveformDialog(\n\t\tshared_ptr<sv::data::properties::DoubleProperty> property,\n\t\tQWidget *parent = nullptr);\n\n\tvector<double> sequence_values() const;\n\tvector<double> sequence_delays() const;\n\nprivate:\n\tvoid setup_ui();\n\n\tconst double pi = std::acos(-1);\n\n\tdouble min_value_;\n\tdouble max_value_;\n\tdouble step_;\n\tint decimals_;\n\tQString unit_;\n\tvector<double> sequence_values_;\n\tvector<double> sequence_delays_;\n\tQComboBox *waveform_box_;\n\tQDoubleSpinBox *min_value_box_;\n\tQDoubleSpinBox *max_value_box_;\n\tQDoubleSpinBox *amplitude_box_;\n\tQDoubleSpinBox *offset_box_;\n\tQDoubleSpinBox *periode_box_;\n\tQDoubleSpinBox *frequency_box_;\n\tQDoubleSpinBox *interval_box_;\n\tQSpinBox *sample_count_box_;\n\tQDoubleSpinBox *phi_deg_box_;\n\tQDoubleSpinBox *phi_rad_box_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\nprivate Q_SLOTS:\n\tvoid on_waveform_changed();\n\tvoid on_min_max_changed();\n\tvoid on_amp_offs_changed();\n\tvoid on_periode_changed();\n\tvoid on_frequency_changed();\n\tvoid on_interval_changed();\n\tvoid on_sample_cnt_changed();\n\tvoid on_phi_deg_changed();\n\tvoid on_phi_rad_changed();\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_GENERATEWAVEFORMDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/plotconfigdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cmath>\n#include <map>\n#include <set>\n\n#include <QApplication>\n#include <QColor>\n#include <QColorDialog>\n#include <QComboBox>\n#include <QDebug>\n#include <QDialog>\n#include <QDoubleValidator>\n#include <QFormLayout>\n#include <QHeaderView>\n#include <QIcon>\n#include <QLineEdit>\n#include <QString>\n#include <QStyle>\n#include <QStyleOptionViewItem>\n#include <QTableWidget>\n#include <QTableWidgetItem>\n#include <QTabWidget>\n#include <QVariant>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"plotconfigdialog.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/ui/views/baseplotview.hpp\"\n#include \"src/ui/widgets/plot/curve.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nQ_DECLARE_METATYPE(sv::ui::widgets::plot::PlotUpdateMode)\n\nusing std::set;\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nColorItemDelegate::ColorItemDelegate(QObject *parent) :\n\tQStyledItemDelegate(parent)\n{\n}\n\nQWidget *ColorItemDelegate::createEditor(QWidget *parent,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\t(void)option;\n\t(void)index;\n\n\tQColorDialog *dialog = new QColorDialog(parent);\n    dialog->setModal(true);\n    return dialog;\n}\n\nvoid ColorItemDelegate::paint(QPainter *painter,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\t// Set background color\n\tQColor color = index.model()->data(index, Qt::EditRole).value<QColor>();\n\tpainter->fillRect(option.rect, color);\n\n\t// Set text and text color depending on background color\n\tQStyleOptionViewItem item_option(option);\n    initStyleOption(&item_option, index);\n\titem_option.text = color.name();\n\tdouble brightness = std::sqrt(\n\t\tcolor.red() * color.red() * 0.241 +\n\t\tcolor.green() * color.green() * 0.691 +\n\t\tcolor.blue() * color.blue() * 0.068);\n\tif (brightness >= 130)\n\t\titem_option.palette.setColor(QPalette::Text, Qt::black);\n\telse\n\t\titem_option.palette.setColor(QPalette::Text, Qt::white);\n    QApplication::style()->drawControl(\n\t\tQStyle::CE_ItemViewItem, &item_option, painter);\n}\n\nvoid ColorItemDelegate::setEditorData(QWidget *editor,\n\tconst QModelIndex &index) const\n{\n\tQColor color = index.model()->data(index, Qt::EditRole).value<QColor>();\n\tQColorDialog *dialog = qobject_cast<QColorDialog *>(editor);\n\tdialog->setCurrentColor(color);\n}\n\nvoid ColorItemDelegate::setModelData(QWidget *editor,\n\tQAbstractItemModel *model, const QModelIndex &index) const\n{\n\tQColorDialog *dialog = qobject_cast<QColorDialog *>(editor);\n\tmodel->setData(index, QVariant(dialog->currentColor()), Qt::EditRole);\n}\n\nvoid ColorItemDelegate::updateEditorGeometry(QWidget *editor,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\t(void)index;\n\n\teditor->setGeometry(option.rect);\n}\n\n\nPlotConfigDialog::PlotConfigDialog(widgets::plot::Plot *plot,\n\t\tviews::PlotType plot_type, QWidget *parent) :\n\tQDialog(parent),\n\tplot_(plot),\n\tplot_type_(plot_type)\n{\n\tsetup_ui();\n}\n\nvoid PlotConfigDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Plot Config\"));\n\tthis->setMinimumWidth(500);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout();\n\n\t// Tabs\n\ttab_widget_ = new QTabWidget();\n\tif (plot_type_ == views::PlotType::TimePlot) {\n\t\tthis->setup_ui_plot_mode_tab();\n\t}\n\tthis->setup_ui_markers_tab();\n\t//this->setup_ui_style_tab();\n\tthis->setup_ui_curve_colors_tab();\n\ttab_widget_->setCurrentIndex(0);\n\tmain_layout->addWidget(tab_widget_);\n\n\t// Buttons\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &PlotConfigDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &PlotConfigDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid PlotConfigDialog::setup_ui_plot_mode_tab()\n{\n\tQString title(tr(\"Plot mode\"));\n\n\tQWidget *widget = new QWidget();\n\tQFormLayout *layout = new QFormLayout();\n\n\tplot_update_mode_combobox_ = new QComboBox();\n\tint cb_index = 0;\n\tfor (const auto &update_mode_pair : widgets::plot::plot_update_mode_name_map) {\n\t\tplot_update_mode_combobox_->addItem(\n\t\t\tupdate_mode_pair.second,\n\t\t\tQVariant::fromValue(update_mode_pair.first));\n\t\tif (plot_->update_mode() == update_mode_pair.first)\n\t\t\tplot_update_mode_combobox_->setCurrentIndex(cb_index);\n\t\t++cb_index;\n\t}\n\tconnect(\n\t\tplot_update_mode_combobox_, QOverload<int>::of(&QComboBox::currentIndexChanged),\n\t\tthis, &PlotConfigDialog::on_update_mode_changed);\n\tlayout->addRow(tr(\"Plot mode\"), plot_update_mode_combobox_);\n\n\ttime_span_edit_ = new QLineEdit();\n\ttime_span_edit_->setValidator(new QDoubleValidator);\n\ttime_span_edit_->setText(QString(\"%1\").arg(plot_->time_span(), 0, 'f'));\n\tlayout->addRow(tr(\"Time span\"), time_span_edit_);\n\n\tadd_time_edit_ = new QLineEdit();\n\tadd_time_edit_->setValidator(new QDoubleValidator);\n\tadd_time_edit_->setText(QString(\"%1\").arg(plot_->add_time(), 0, 'f'));\n\tlayout->addRow(tr(\"Add time\"), add_time_edit_);\n\n\tswitch (plot_->update_mode()) {\n\tcase widgets::plot::PlotUpdateMode::Additive:\n\t\tsetup_ui_additive();\n\t\tbreak;\n\tcase widgets::plot::PlotUpdateMode::Rolling:\n\t\tsetup_ui_rolling();\n\t\tbreak;\n\tcase widgets::plot::PlotUpdateMode::Oscilloscope:\n\t\tsetup_ui_oscilloscope();\n\t\tbreak;\n\t}\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid PlotConfigDialog::setup_ui_markers_tab()\n{\n\tQString title(tr(\"Markers\"));\n\n\tQWidget *widget = new QWidget();\n\tQFormLayout *layout = new QFormLayout();\n\n\tmarkers_box_pos_combobox_ = new QComboBox();\n\tmarkers_box_pos_combobox_->addItem(tr(\"Top left\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignTop | Qt::AlignmentFlag::AlignLeft)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Top center\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignTop | Qt::AlignmentFlag::AlignHCenter)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Top right\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignTop | Qt::AlignmentFlag::AlignRight)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Center left\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignLeft)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Center\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignHCenter)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Center right\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignVCenter | Qt::AlignmentFlag::AlignRight)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Bottom left\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignBottom | Qt::AlignmentFlag::AlignLeft)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Bottom center\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignBottom | Qt::AlignmentFlag::AlignHCenter)));\n\tmarkers_box_pos_combobox_->addItem(tr(\"Bottom right\"), QVariant::fromValue(\n\t\t(int)(Qt::AlignmentFlag::AlignBottom | Qt::AlignmentFlag::AlignRight)));\n\n\tfor (int i = 0; i < markers_box_pos_combobox_->count(); ++i) {\n\t\tQVariant data_var = markers_box_pos_combobox_->itemData(i);\n\t\tif (data_var.toInt() == plot_->markers_label_alignment()) {\n\t\t\tmarkers_box_pos_combobox_->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlayout->addRow(tr(\"Info box position\"), markers_box_pos_combobox_);\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid PlotConfigDialog::setup_ui_style_tab()\n{\n\tQString title(tr(\"Style\"));\n\n\tQWidget *widget = new QWidget();\n\tQFormLayout *layout = new QFormLayout();\n\n\t// TODO: Plot background color? Axis position? What else?\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid PlotConfigDialog::setup_ui_curve_colors_tab()\n{\n\tQString title(tr(\"Default Curve Colors\"));\n\n\tQWidget *widget = new QWidget();\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tcolor_table_ = new QTableWidget();\n\tcolor_table_->setColumnCount(2);\n\n\tQTableWidgetItem *quantity_header_item = new QTableWidgetItem(tr(\"Quantity\"));\n\tquantity_header_item->setTextAlignment(Qt::AlignVCenter);\n\tcolor_table_->setHorizontalHeaderItem(0, quantity_header_item);\n\tcolor_table_->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);\n\tQTableWidgetItem *color_header_item = new QTableWidgetItem(tr(\"Color\"));\n\tcolor_header_item->setTextAlignment(Qt::AlignVCenter);\n\tcolor_table_->setHorizontalHeaderItem(1, color_header_item);\n\tcolor_table_->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);\n\n\tcolor_table_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);\n\tcolor_table_->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);\n\tcolor_table_->setSelectionMode(QTableWidget::NoSelection);\n\tcolor_table_->setItemDelegateForColumn(1, new ColorItemDelegate());\n\n\tfor (const auto &q_n_pair : data::datautil::get_quantity_name_map()) {\n\t\tint last_row = color_table_->rowCount();\n\t\tcolor_table_->insertRow(last_row);\n\t\tQTableWidgetItem *quantity_item = new QTableWidgetItem(q_n_pair.second);\n\t\tquantity_item->setData(Qt::UserRole, QString(\"%1_0\").arg(\n\t\t\tdata::datautil::get_sr_quantity_id(q_n_pair.first)));\n\t\tquantity_item->setFlags(quantity_item->flags() ^ Qt::ItemIsEditable);\n\t\tcolor_table_->setItem(last_row, 0, quantity_item);\n\t\tQTableWidgetItem *color_item = new QTableWidgetItem(q_n_pair.second);\n\t\tcolor_item->setData(Qt::EditRole, widgets::plot::Curve::default_color(\n\t\t\tq_n_pair.first, set<data::QuantityFlag>()));\n\t\tcolor_table_->setItem(last_row, 1, color_item);\n\n\t\t// For Voltage and Current, we want to make AC/DC also configurable.\n\t\tif (q_n_pair.first == data::Quantity::Voltage ||\n\t\t\t\tq_n_pair.first == data::Quantity::Current) {\n\t\t\tfor (auto const &qf : {data::QuantityFlag::AC, data::QuantityFlag::DC}) {\n\t\t\t\tQString name = QString(\"%1 %2\").arg(\n\t\t\t\t\tq_n_pair.second, data::datautil::format_quantity_flag(qf));\n\t\t\t\tauto qfs = set<data::QuantityFlag>{qf};\n\t\t\t\tlast_row = color_table_->rowCount();\n\t\t\t\tcolor_table_->insertRow(last_row);\n\t\t\t\tQTableWidgetItem *q_item = new QTableWidgetItem(name);\n\t\t\t\tq_item->setData(Qt::UserRole, QString(\"%1_%2\").\n\t\t\t\t\targ(data::datautil::get_sr_quantity_id(q_n_pair.first)).\n\t\t\t\t\targ(data::datautil::get_sr_quantity_flags_id(qfs)));\n\t\t\t\tq_item->setFlags(q_item->flags() ^ Qt::ItemIsEditable);\n\t\t\t\tcolor_table_->setItem(last_row, 0, q_item);\n\t\t\t\tQTableWidgetItem *c_item = new QTableWidgetItem(name);\n\t\t\t\tc_item->setData(Qt::EditRole,\n\t\t\t\t\twidgets::plot::Curve::default_color(q_n_pair.first, qfs));\n\t\t\t\tcolor_table_->setItem(last_row, 1, c_item);\n\t\t\t}\n\t\t}\n\t}\n\n\tlayout->addWidget(color_table_);\n\n\twidget->setLayout(layout);\n\ttab_widget_->addTab(widget, title);\n}\n\nvoid PlotConfigDialog::setup_ui_additive()\n{\n\ttime_span_edit_->setDisabled(true);\n\tadd_time_edit_->setDisabled(false);\n}\n\nvoid PlotConfigDialog::setup_ui_rolling()\n{\n\ttime_span_edit_->setDisabled(false);\n\tadd_time_edit_->setDisabled(false);\n}\n\nvoid PlotConfigDialog::setup_ui_oscilloscope()\n{\n\ttime_span_edit_->setDisabled(false);\n\tadd_time_edit_->setDisabled(true);\n}\n\nvoid PlotConfigDialog::on_update_mode_changed()\n{\n\tQVariant update_mode_var = plot_update_mode_combobox_->currentData();\n\tswitch (update_mode_var.value<sv::ui::widgets::plot::PlotUpdateMode>()) {\n\tcase widgets::plot::PlotUpdateMode::Additive:\n\t\tsetup_ui_additive();\n\t\tbreak;\n\tcase widgets::plot::PlotUpdateMode::Rolling:\n\t\tsetup_ui_rolling();\n\t\tbreak;\n\tcase widgets::plot::PlotUpdateMode::Oscilloscope:\n\t\tsetup_ui_oscilloscope();\n\t\tbreak;\n\t}\n}\n\nvoid PlotConfigDialog::accept()\n{\n\tif (plot_type_ == views::PlotType::TimePlot) {\n\t\tQVariant update_mode_var = plot_update_mode_combobox_->currentData();\n\t\tsv::ui::widgets::plot::PlotUpdateMode update_mode =\n\t\t\tupdate_mode_var.value<sv::ui::widgets::plot::PlotUpdateMode>();\n\t\tplot_->set_update_mode(update_mode);\n\t\tif (update_mode == widgets::plot::PlotUpdateMode::Rolling ||\n\t\t\t\tupdate_mode == widgets::plot::PlotUpdateMode::Oscilloscope)\n\t\t\tplot_->set_time_span(time_span_edit_->text().toDouble());\n\t\tif (update_mode == widgets::plot::PlotUpdateMode::Additive ||\n\t\t\t\tupdate_mode == widgets::plot::PlotUpdateMode::Rolling)\n\t\t\tplot_->set_add_time(add_time_edit_->text().toDouble());\n\t}\n\n\tplot_->set_markers_label_alignment(\n\t\tmarkers_box_pos_combobox_->currentData().toInt());\n\n\tQSettings settings;\n\tsettings.beginGroup(\"DefaultCurveColors\");\n\tfor (int i=0; i<color_table_->rowCount(); i++) {\n\t\tsettings.setValue(\n\t\t\tcolor_table_->item(i, 0)->data(Qt::UserRole).toString(),\n\t\t\tcolor_table_->item(i, 1)->data(Qt::EditRole));\n\t}\n\tsettings.endGroup();\n\n\tQDialog::accept();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/plotconfigdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_PLOTCONFIGDIALOG_HPP\n#define UI_DIALOGS_PLOTCONFIGDIALOG_HPP\n\n#include <map>\n\n#include <QAbstractItemModel>\n#include <QComboBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QLocale>\n#include <QModelIndex>\n#include <QPainter>\n#include <QString>\n#include <QStyledItemDelegate>\n#include <QStyleOptionViewItem>\n#include <QTableWidget>\n#include <QTabWidget>\n#include <QWidget>\n\n#include \"src/ui/widgets/plot/plot.hpp\"\n#include \"src/ui/views/baseplotview.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nclass ColorItemDelegate : public QStyledItemDelegate\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ColorItemDelegate(QObject *parent = nullptr);\n\n\tQWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n\tvoid paint(QPainter *painter, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n\tvoid setEditorData(QWidget *editor,\n\t\tconst QModelIndex &index) const override;\n\tvoid setModelData(QWidget *editor, QAbstractItemModel *model,\n\t\tconst QModelIndex &index) const override;\n\tvoid updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n};\n\nclass PlotConfigDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tPlotConfigDialog(widgets::plot::Plot *plot, views::PlotType plot_type,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\tvoid setup_ui_plot_mode_tab();\n\tvoid setup_ui_markers_tab();\n\tvoid setup_ui_style_tab();\n\tvoid setup_ui_curve_colors_tab();\n\tvoid setup_ui_additive();\n\tvoid setup_ui_rolling();\n\tvoid setup_ui_oscilloscope();\n\n\twidgets::plot::Plot *plot_;\n\tviews::PlotType plot_type_;\n\tQTabWidget *tab_widget_;\n\tQComboBox *plot_update_mode_combobox_;\n\tQLineEdit *time_span_edit_;\n\tQLineEdit *add_time_edit_;\n\tQComboBox *markers_box_pos_combobox_;\n\tQTableWidget *color_table_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid on_update_mode_changed();\n\tvoid accept() override;\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_PLOTCONFIGDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/plotcurveconfigdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n\n#include <QCheckBox>\n#include <QComboBox>\n#include <QBrush>\n#include <QDebug>\n#include <QFormLayout>\n#include <QIcon>\n#include <QLineEdit>\n#include <QPen>\n#include <QPushButton>\n#include <QSize>\n#include <QWidget>\n#include <qwt_plot_curve.h>\n#include <qwt_symbol.h>\n\n#include \"plotcurveconfigdialog.hpp\"\n#include \"src/ui/widgets/plot/curve.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n#include \"src/ui/widgets/colorbutton.hpp\"\n\nQ_DECLARE_METATYPE(Qt::PenStyle)\nQ_DECLARE_METATYPE(QwtSymbol::Style)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nPlotCurveConfigDialog::PlotCurveConfigDialog(widgets::plot::Curve *curve,\n\t\twidgets::plot::Plot *plot, QWidget *parent) :\n\tQDialog(parent),\n\tcurve_(curve),\n\tplot_(plot)\n{\n\tassert(curve_);\n\tassert(plot_);\n\n\tsetup_ui();\n}\n\nvoid PlotCurveConfigDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Curve Config\"));\n\tthis->setMinimumWidth(500);\n\n\tQFormLayout *main_layout = new QFormLayout;\n\n\tname_edit_ = new QLineEdit();\n\tname_edit_->setText(curve_->name());\n\tmain_layout->addRow(tr(\"Name\"), name_edit_);\n\n\tvisible_checkbox_ = new QCheckBox();\n\tvisible_checkbox_->setChecked(curve_->plot_curve()->isVisible());\n\tmain_layout->addRow(tr(\"Visible\"), visible_checkbox_);\n\n\tcolor_button_ = new widgets::ColorButton();\n\tcolor_button_->set_color(curve_->color());\n\tmain_layout->addRow(tr(\"Color\"), color_button_);\n\n\tline_type_box_ = new QComboBox();\n\tline_type_box_->addItem(tr(\"None\"), QVariant::fromValue(Qt::NoPen));\n\tline_type_box_->addItem(tr(\"Solid\"), QVariant::fromValue(Qt::SolidLine));\n\tline_type_box_->addItem(tr(\"Dots\"), QVariant::fromValue(Qt::DotLine));\n\tline_type_box_->addItem(tr(\"Dashes\"), QVariant::fromValue(Qt::DashLine));\n\tfor (int i=0; i<line_type_box_->count(); ++i)  {\n\t\tif (line_type_box_->itemData(i).value<Qt::PenStyle>() ==\n\t\t\t\tcurve_->style()) {\n\t\t\tline_type_box_->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n\tmain_layout->addRow(tr(\"Line type\"), line_type_box_);\n\n\tsymbol_type_box_ = new QComboBox();\n\tsymbol_type_box_->addItem(tr(\"None\"), QwtSymbol::NoSymbol);\n\tsymbol_type_box_->addItem(tr(\"Dot\"), QwtSymbol::Ellipse);\n\tsymbol_type_box_->addItem(tr(\"Cross\"), QwtSymbol::XCross);\n\tfor (int i=0; i<line_type_box_->count(); ++i)  {\n\t\tif (symbol_type_box_->itemData(i).value<QwtSymbol::Style>() ==\n\t\t\t\tcurve_->symbol()) {\n\t\t\tsymbol_type_box_->setCurrentIndex(i);\n\t\t\tbreak;\n\t\t}\n\t}\n\tmain_layout->addRow(tr(\"Symbol type\"), symbol_type_box_);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tQPushButton *remove_button = new QPushButton(\n\t\tQIcon::fromTheme(\"edit-delete\", QIcon(\":/icons/edit-delete.png\")),\n\t\ttr(\"Remove Curve\"));\n\tbutton_box_->addButton(remove_button, QDialogButtonBox::DestructiveRole);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &PlotCurveConfigDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &PlotCurveConfigDialog::reject);\n\tconnect(remove_button, &QPushButton::clicked,\n\t\tthis, &PlotCurveConfigDialog::remove_curve);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid PlotCurveConfigDialog::accept()\n{\n\tcurve_->set_name(name_edit_->text());\n\tcurve_->plot_curve()->setVisible(visible_checkbox_->isChecked());\n\tcurve_->set_color(color_button_->color());\n\tcurve_->set_style(line_type_box_->currentData().value<Qt::PenStyle>());\n\tcurve_->set_symbol(symbol_type_box_->currentData().value<QwtSymbol::Style>());\n\n\tQDialog::accept();\n}\n\nvoid PlotCurveConfigDialog::remove_curve()\n{\n\tplot_->remove_curve(curve_);\n\tQDialog::close();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/plotcurveconfigdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_PLOTCURVECONFIGDIALOG_HPP\n#define UI_DIALOGS_PLOTCURVECONFIGDIALOG_HPP\n\n#include <QCheckBox>\n#include <QComboBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QWidget>\n\nnamespace sv {\nnamespace ui {\n\nnamespace widgets {\nclass ColorButton;\nnamespace plot {\nclass Curve;\nclass Plot;\n}\n}\n\nnamespace dialogs {\n\nclass PlotCurveConfigDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tPlotCurveConfigDialog(widgets::plot::Curve *curve,\n\t\twidgets::plot::Plot *plot, QWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\n\twidgets::plot::Curve *curve_;\n\twidgets::plot::Plot *plot_;\n\tQLineEdit *name_edit_;\n\tQCheckBox *visible_checkbox_;\n\twidgets::ColorButton *color_button_;\n\tQComboBox *line_type_box_;\n\tQComboBox *symbol_type_box_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\tvoid remove_curve();\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_PLOTCURVECONFIGDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/plotdiffmarkerdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <map>\n\n#include <QComboBox>\n#include <QDebug>\n#include <QDialog>\n#include <QFormLayout>\n#include <QIcon>\n#include <QVariant>\n#include <QVBoxLayout>\n#include <QWidget>\n#include <qwt_plot_marker.h>\n\n#include \"plotdiffmarkerdialog.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nQ_DECLARE_METATYPE(QwtPlotMarker *)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nPlotDiffMarkerDialog::PlotDiffMarkerDialog(\n\t\twidgets::plot::Plot *plot, QWidget *parent) :\n\tQDialog(parent),\n\tplot_(plot)\n{\n\tsetup_ui();\n}\n\nvoid PlotDiffMarkerDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Plot Diff Merker\"));\n\tthis->setMinimumWidth(250);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout();\n\tQFormLayout *form_layout = new QFormLayout();\n\n\tmarker_1_combobox_ = new QComboBox();\n\tfor (const auto &mc_pair : plot_->marker_curve_map()) {\n\t\tmarker_1_combobox_->addItem(\n\t\t\tmc_pair.first->title().text(), QVariant::fromValue(mc_pair.first));\n\t}\n\tif (!plot_->marker_curve_map().empty())\n\t\tmarker_1_combobox_->setCurrentIndex(0);\n\tform_layout->addRow(tr(\"Marker 1\"), marker_1_combobox_);\n\n\tmarker_2_combobox_ = new QComboBox();\n\tfor (const auto &mc_pair : plot_->marker_curve_map()) {\n\t\tmarker_2_combobox_->addItem(\n\t\t\tmc_pair.first->title().text(), QVariant::fromValue(mc_pair.first));\n\t}\n\tif (plot_->marker_curve_map().size() >= 2)\n\t\tmarker_2_combobox_->setCurrentIndex(1);\n\telse if (!plot_->marker_curve_map().empty())\n\t\tmarker_2_combobox_->setCurrentIndex(0);\n\tform_layout->addRow(tr(\"Marker 2\"), marker_2_combobox_);\n\n\tmain_layout->addLayout(form_layout);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &PlotDiffMarkerDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &PlotDiffMarkerDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid PlotDiffMarkerDialog::accept()\n{\n\tQVariant marker_1_var = marker_1_combobox_->currentData();\n\tQVariant marker_2_var = marker_2_combobox_->currentData();\n\tplot_->add_diff_marker(\n\t\tmarker_1_var.value<QwtPlotMarker *>(),\n\t\tmarker_2_var.value<QwtPlotMarker *>());\n\n\tQDialog::accept();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/plotdiffmarkerdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_PLOTDIFFMARKERDIALOG_HPP\n#define UI_DIALOGS_PLOTDIFFMARKERDIALOG_HPP\n\n#include <map>\n\n#include <QComboBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QString>\n#include <QWidget>\n\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nclass PlotDiffMarkerDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\texplicit PlotDiffMarkerDialog(widgets::plot::Plot *plot,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\n\twidgets::plot::Plot *plot_;\n\tQComboBox *marker_1_combobox_;\n\tQComboBox *marker_2_combobox_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_PLOTDIFFMARKERDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/selectsignaldialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <vector>\n\n#include <QDebug>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QIcon>\n#include <QSize>\n#include <QString>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"selectsignaldialog.hpp\"\n#include \"src/session.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/devices/devicetree/devicetreeview.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nSelectSignalDialog::SelectSignalDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> expanded_device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\texpanded_device_(expanded_device)\n{\n\tsetup_ui();\n}\n\nvoid SelectSignalDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Select Signal\"));\n\tthis->setMinimumWidth(500);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout;\n\n\tdevice_tree_ = new devices::devicetree::DeviceTreeView(session_,\n\t\tfalse, false, false, true, false, false, false, false);\n\tdevice_tree_->expand_device(expanded_device_);\n\tmain_layout->addWidget(device_tree_);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &SelectSignalDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &SelectSignalDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvector<shared_ptr<sv::data::BaseSignal>> SelectSignalDialog::signals()\n{\n\treturn signals_;\n}\n\nvoid SelectSignalDialog::accept()\n{\n\tfor (const auto &signal : device_tree_->checked_signals()) {\n\t\tsignals_.push_back(signal);\n\t}\n\n\tQDialog::accept();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/selectsignaldialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_SELECTSIGNALDIALOG_HPP\n#define UI_DIALOGS_SELECTSIGNALDIALOG_HPP\n\n#include <memory>\n#include <vector>\n\n#include <QDialog>\n#include <QDialogButtonBox>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nnamespace data {\nclass BaseSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace devices {\nnamespace devicetree {\nclass DeviceTreeView;\n}\n}\n\nnamespace dialogs {\n\nclass SelectSignalDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tSelectSignalDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> expanded_device,\n\t\tQWidget *parent = nullptr);\n\n\tvector<shared_ptr<sv::data::BaseSignal>> signals();\n\nprivate:\n\tvoid setup_ui();\n\n\tconst Session &session_;\n\tconst shared_ptr<sv::devices::BaseDevice> expanded_device_;\n\tvector<shared_ptr<sv::data::BaseSignal>> signals_;\n\n\tui::devices::devicetree::DeviceTreeView *device_tree_;\n\tQDialogButtonBox *button_box_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_SELECTSIGNALDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/selectxysignalsdialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QDebug>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QIcon>\n#include <QSize>\n#include <QString>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"selectxysignalsdialog.hpp\"\n#include \"src/session.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/devices/selectsignalwidget.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nSelectXYSignalsDialog::SelectXYSignalsDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> selected_device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\tselected_device_(selected_device)\n{\n\tsetup_ui();\n}\n\nvoid SelectXYSignalsDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Select X/Y Signals\"));\n\tthis->setMinimumWidth(500);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout;\n\tQHBoxLayout *signals_layout = new QHBoxLayout();\n\n\tQGroupBox *x_signal_group = new QGroupBox(tr(\"X Signal\"));\n\tQVBoxLayout *x_layout = new QVBoxLayout();\n\tx_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\tx_signal_widget_->select_device(selected_device_);\n\tx_layout->addWidget(x_signal_widget_);\n\tx_signal_group->setLayout(x_layout);\n\tsignals_layout->addWidget(x_signal_group);\n\n\tQGroupBox *y_signal_group = new QGroupBox(tr(\"Y Signal\"));\n\tQVBoxLayout *y_layout = new QVBoxLayout();\n\ty_signal_widget_ = new ui::devices::SelectSignalWidget(session_);\n\ty_signal_widget_->select_device(selected_device_);\n\ty_layout->addWidget(y_signal_widget_);\n\ty_signal_group->setLayout(y_layout);\n\tsignals_layout->addWidget(y_signal_group);\n\tmain_layout->addLayout(signals_layout);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &SelectXYSignalsDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &SelectXYSignalsDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nshared_ptr<sv::data::BaseSignal> SelectXYSignalsDialog::x_signal()\n{\n\treturn x_signal_widget_->selected_signal();\n}\n\nshared_ptr<sv::data::BaseSignal> SelectXYSignalsDialog::y_signal()\n{\n\treturn y_signal_widget_->selected_signal();\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/selectxysignalsdialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_SELECTXYSIGNALSDIALOG_HPP\n#define UI_DIALOGS_SELECTXYSIGNALSDIALOG_HPP\n\n#include <memory>\n\n#include <QDialog>\n#include <QDialogButtonBox>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nnamespace data {\nclass BaseSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace devices {\nclass SelectSignalWidget;\n}\n\nnamespace dialogs {\n\nclass SelectXYSignalsDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tSelectXYSignalsDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> selected_device,\n\t\tQWidget *parent = nullptr);\n\n\tshared_ptr<sv::data::BaseSignal> x_signal();\n\tshared_ptr<sv::data::BaseSignal> y_signal();\n\nprivate:\n\tvoid setup_ui();\n\n\tconst Session &session_;\n\tconst shared_ptr<sv::devices::BaseDevice> selected_device_;\n\n\tui::devices::SelectSignalWidget *x_signal_widget_;\n\tui::devices::SelectSignalWidget *y_signal_widget_;\n\tQDialogButtonBox *button_box_;\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_SELECTXYSIGNALSDIALOG_HPP\n"
  },
  {
    "path": "src/ui/dialogs/signalsavedialog.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cmath>\n#include <iostream>\n#include <fstream>\n#include <limits>\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QDir>\n#include <QFileDialog>\n#include <QFormLayout>\n#include <QHBoxLayout>\n#include <QLabel>\n#include <QMessageBox>\n#include <QProgressDialog>\n#include <QSettings>\n#include <QSpinBox>\n#include <QVBoxLayout>\n\n#include \"signalsavedialog.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/ui/devices/devicetree/devicetreeview.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::ofstream;\nusing std::string;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace dialogs {\n\nSignalSaveDialog::SignalSaveDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> selected_device,\n\t\tQWidget *parent) :\n\tQDialog(parent),\n\tsession_(session),\n\tselected_device_(selected_device)\n{\n\tsetup_ui();\n\n\tQSettings settings;\n\tif (SettingsManager::restore_settings() &&\n\t\t\tsettings.childGroups().contains(\"SignalSaveDialog\")) {\n\t\trestore_settings(settings);\n\t}\n\telse {\n\t\tfile_dialog_path_ = QDir::homePath();\n\t}\n}\n\nvoid SignalSaveDialog::setup_ui()\n{\n\tQIcon main_icon;\n\tmain_icon.addFile(QStringLiteral(\":/icons/smuview.ico\"),\n\t\tQSize(), QIcon::Normal, QIcon::Off);\n\tthis->setWindowIcon(main_icon);\n\tthis->setWindowTitle(tr(\"Save Signals\"));\n\tthis->setMinimumWidth(450);\n\tthis->setMinimumHeight(400);\n\n\tQVBoxLayout *main_layout = new QVBoxLayout;\n\n\tdevice_tree_ = new ui::devices::devicetree::DeviceTreeView(\n\t\tsession_, false, false, false, true, false, false, false, false);\n\tdevice_tree_->expand_device(selected_device_);\n\tdevice_tree_->check_signals(selected_device_->signals());\n\tmain_layout->addWidget(device_tree_);\n\n\tQFormLayout *form_layout = new QFormLayout();\n\n\ttimestamps_combined_ = new QCheckBox(tr(\"Combine all timestamps\"));\n\tform_layout->addRow(\"\", timestamps_combined_);\n\n\ttimestamps_combined_timeframe_ = new QSpinBox();\n\ttimestamps_combined_timeframe_->setValue(0);\n\ttimestamps_combined_timeframe_->setRange(\n\t\t0, std::numeric_limits<int32_t>::max());\n\ttimestamps_combined_timeframe_->setSuffix(\" ms\");\n\ttimestamps_combined_timeframe_->setDisabled(\n\t\t!timestamps_combined_->isChecked());\n\tform_layout->addRow(tr(\"Combination time frame\"),\n\t\ttimestamps_combined_timeframe_);\n\n\ttime_absolut_ = new QCheckBox(tr(\"Absolut time\"));\n\tform_layout->addRow(\"\", time_absolut_);\n\n\tseparator_edit_ = new QLineEdit();\n\tseparator_edit_->setText(\",\");\n\tform_layout->addRow(tr(\"CSV separator\"), separator_edit_);\n\n\tmain_layout->addLayout(form_layout);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tmain_layout->addWidget(button_box_);\n\n\tconnect(timestamps_combined_, &QCheckBox::stateChanged,\n\t\tthis, &SignalSaveDialog::toggle_combined);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &SignalSaveDialog::accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &SignalSaveDialog::reject);\n\n\tthis->setLayout(main_layout);\n}\n\nvoid SignalSaveDialog::save(const QString &file_name)\n{\n\tofstream output_file;\n\tstring str_file_name = file_name.toStdString();\n\tvector<size_t> sample_counts;\n\n\toutput_file.open(str_file_name);\n\n\tauto signals = device_tree_->checked_signals();\n\tbool relative_time = !time_absolut_->isChecked();\n\tstring sep = separator_edit_->text().toStdString();\n\tsize_t max_sample_count = 0;\n\n\t// Header\n\tstring start_sep;\n\tstring device_header_line;\n\tstring chg_name_header_line;\n\tstring ch_name_header_line;\n\tstring signal_name_header_line;\n\tfor (const auto &signal : signals) {\n\t\t// Only handle AnalogSignals\n\t\tauto analog_signal =\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\tif (!analog_signal)\n\t\t\tcontinue;\n\n\t\tsize_t sample_count = analog_signal->sample_count();\n\t\tif (sample_count > max_sample_count)\n\t\t\tmax_sample_count = sample_count;\n\t\tsample_counts.push_back(sample_count);\n\n\t\tstring name = analog_signal->name();\n\t\tshared_ptr<sv::channels::BaseChannel> parent_channel =\n\t\t\tanalog_signal->parent_channel();\n\n\t\tqWarning() << \"SaveDialog::save(): signal.name() = \" <<\n\t\t\tQString::fromStdString(name);\n\t\tqWarning() << \"SaveDialog::save(): signal.parent_channel().name() = \" <<\n\t\t\tQString::fromStdString(parent_channel->name());\n\t\tqWarning() << \"SaveDialog::save(): signal.parent_channel().parent_device().name() = \" <<\n\t\t\tQString::fromStdString(parent_channel->parent_device()->name());\n\n\t\tstring chg_names;\n\t\tstring chg_sep;\n\t\tfor (const auto &chg_name : parent_channel->channel_group_names()) {\n\t\t\tchg_names += chg_sep;\n\t\t\tif (chg_name.empty())\n\t\t\t\tchg_names += \"\\\"\\\"\";\n\t\t\telse\n\t\t\t\tchg_names += chg_name;\n\t\t\t// TODO: Ugly workaround. Implement escaping or quotation characters?\n\t\t\tchg_sep = sep == \",\" ? \"; \" : \", \";\n\t\t}\n\n\t\tdevice_header_line += start_sep;\n\t\tdevice_header_line += parent_channel->parent_device()->name(); // Time\n\t\tdevice_header_line += sep;\n\t\tdevice_header_line += parent_channel->parent_device()->name(); // Value\n\t\tchg_name_header_line += start_sep;\n\t\tchg_name_header_line += chg_names; // Time\n\t\tchg_name_header_line += sep;\n\t\tchg_name_header_line += chg_names; // Value\n\t\tch_name_header_line += start_sep;\n\t\tch_name_header_line += parent_channel->name(); // Time\n\t\tch_name_header_line += sep;\n\t\tch_name_header_line += parent_channel->name(); // Value\n\t\tsignal_name_header_line += start_sep;\n\t\tsignal_name_header_line += \"Time \";\n\t\tsignal_name_header_line += name; // Time\n\t\tsignal_name_header_line += sep;\n\t\tsignal_name_header_line += name; // Value\n\n\t\tstart_sep = sep;\n\t}\n\toutput_file << device_header_line << std::endl;\n\toutput_file << chg_name_header_line << std::endl;\n\toutput_file << ch_name_header_line << std::endl;\n\toutput_file << signal_name_header_line << std::endl;\n\n\t// Data\n\t// TODO: we asume here, that the vector size is the same for all vectors....\n\tfor (size_t index = 0; index < max_sample_count; index++) {\n\t\tstart_sep = \"\";\n\t\tQString line(\"\");\n\t\tint sample_count_index = 0;\n\t\tfor (const auto &signal : signals) {\n\t\t\t// Only handle AnalogSignals\n\t\t\tauto analog_signal =\n\t\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\t\tif (!analog_signal)\n\t\t\t\tcontinue;\n\n\t\t\tQString time(\"\");\n\t\t\tQString value(\"\");\n\n\t\t\tsize_t sample_count = sample_counts[sample_count_index];\n\t\t\tif (index < sample_count-1) {\n\t\t\t\t// More samples for this signal\n\t\t\t\tauto sample = analog_signal->get_sample(index, relative_time);\n\t\t\t\tvalue = QString(\"%1\").arg(sample.second);\n\t\t\t\tif (relative_time)\n\t\t\t\t\ttime = QString(\"%1\").arg(sample.first, 0, 'f', 4);\n\t\t\t\telse\n\t\t\t\t\ttime = util::format_time_date(sample.first);\n\t\t\t}\n\n\t\t\tline.append(QString(\"%1%2%3%4\").arg(\n\t\t\t\tQString::fromStdString(start_sep), time,\n\t\t\t\tQString::fromStdString(sep), value));\n\t\t\tstart_sep = sep;\n\n\t\t\t++sample_count_index;\n\t\t}\n\t\toutput_file << line.toStdString() << std::endl;\n\t}\n\n\toutput_file.close();\n}\n\nvoid SignalSaveDialog::save_combined(const QString &file_name)\n{\n\tofstream output_file;\n\tstring str_file_name = file_name.toStdString();\n\tvector<size_t> sample_counts;\n\tvector<size_t> sample_pos;\n\n\toutput_file.open(str_file_name);\n\n\tdouble combined_timeframe = .0;\n\tint combined_timeframe_ms = timestamps_combined_timeframe_->value();\n\tif (combined_timeframe_ms != 0)\n\t\tcombined_timeframe = ((double)combined_timeframe_ms) / 1000;\n\n\tauto signals = device_tree_->checked_signals();\n\tbool relative_time = !time_absolut_->isChecked();\n\tstring sep = separator_edit_->text().toStdString();\n\n\t// Header\n\tstring device_header_line(\"Time\"); // Time\n\tstring chg_name_header_line(\"Time\"); // Time\n\tstring ch_name_header_line(\"Time\"); // Time\n\tstring signal_name_header_line(\"Time\"); // Time\n\tfor (const auto &signal : signals) {\n\t\t// Only handle AnalogSignals\n\t\tauto analog_signal =\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\tif (!analog_signal)\n\t\t\tcontinue;\n\n\t\tshared_ptr<sv::channels::BaseChannel> parent_channel =\n\t\t\tanalog_signal->parent_channel();\n\n\t\tsample_counts.push_back(analog_signal->sample_count());\n\t\tsample_pos.push_back(0);\n\n\t\tstring chg_names;\n\t\tstring chg_sep;\n\t\tfor (const auto &chg_name : parent_channel->channel_group_names()) {\n\t\t\tchg_names += chg_sep;\n\t\t\tif (chg_name.empty())\n\t\t\t\tchg_names += \"\\\"\\\"\";\n\t\t\telse\n\t\t\t\tchg_names += chg_name;\n\t\t\t// TODO: Ugly workaround. Implement escaping or quotation characters?\n\t\t\tchg_sep = sep == \",\" ? \"; \" : \", \";\n\t\t}\n\n\t\tdevice_header_line += sep;\n\t\tdevice_header_line += parent_channel->parent_device()->name(); // Value\n\t\tchg_name_header_line += sep;\n\t\tchg_name_header_line += chg_names; // Value\n\t\tch_name_header_line += sep;\n\t\tch_name_header_line += parent_channel->name(); // Value\n\t\tsignal_name_header_line += sep;\n\t\tsignal_name_header_line += analog_signal->name(); // Value\n\t}\n\toutput_file << device_header_line << std::endl;\n\toutput_file << chg_name_header_line << std::endl;\n\toutput_file << ch_name_header_line << std::endl;\n\toutput_file << signal_name_header_line << std::endl;\n\n\t// Data\n\twhile (true) {\n\t\tdouble next_timestamp = -1;\n\t\tint index = 0;\n\t\tfor (const auto &signal : signals) {\n\t\t\t// Only handle AnalogSignals\n\t\t\tauto analog_signal =\n\t\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\t\tif (!analog_signal)\n\t\t\t\tcontinue;\n\n\t\t\tif (sample_pos[index] >= sample_counts[index]-1)\n\t\t\t\tcontinue;\n\n\t\t\tdouble timestamp =\n\t\t\t\tanalog_signal->get_sample(sample_pos[index], relative_time).first;\n\t\t\tif (next_timestamp < 0 || timestamp < next_timestamp)\n\t\t\t\tnext_timestamp = timestamp;\n\n\t\t\t++index;\n\t\t}\n\n\t\tif (next_timestamp < 0)\n\t\t\tbreak;\n\n\t\t// Timestamp\n\t\tQString line;\n\t\tif (relative_time)\n\t\t\tline = QString(\"%1\").arg(next_timestamp, 0, 'f', 4);\n\t\telse\n\t\t\tline = util::format_time_date(next_timestamp);\n\n\t\t// Values\n\t\tindex = 0;\n\t\tfor (const auto &signal : signals) {\n\t\t\t// Only handle AnalogSignals\n\t\t\tauto analog_signal =\n\t\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\t\tif (!analog_signal)\n\t\t\t\tcontinue;\n\n\t\t\tline.append(QString::fromStdString(sep));\n\n\t\t\tauto sample =\n\t\t\t\tanalog_signal->get_sample(sample_pos[index], relative_time);\n\t\t\tdouble timestamp = sample.first;\n\t\t\tif (timestamp + combined_timeframe >= next_timestamp) {\n\t\t\t\tline.append(QString(\"%1\").arg(sample.second, 0, 'g', -1));\n\t\t\t\t++sample_pos[index];\n\t\t\t}\n\n\t\t\t++index;\n\t\t}\n\t\toutput_file << line.toStdString() << std::endl;\n\t}\n\n\toutput_file.close();\n}\n\nbool SignalSaveDialog::validate_combined_timeframe()\n{\n\tint combined_timeframe_ms = timestamps_combined_timeframe_->value();\n\tif (combined_timeframe_ms == 0)\n\t\treturn true;\n\tconst double combined_timeframe = ((double)combined_timeframe_ms) / 1000;\n\n\tint num_signals = static_cast<int>(device_tree_->checked_signals().size());\n\tint act_signal = 0;\n\tQProgressDialog progress(tr(\"Validating combined timeframe ...\"),\n\t\ttr(\"Abort validation\"), 0, num_signals, this);\n\tprogress.setMinimumDuration(500);\n\tprogress.setWindowModality(Qt::WindowModal);\n\n\tdouble min_delta = combined_timeframe;\n\tfor (const auto &signal : device_tree_->checked_signals()) {\n\t\tprogress.setValue(act_signal++);\n\t\tsize_t count = signal->sample_count();\n\t\tif (count < 2)\n\t\t\tcontinue;\n\n\t\t// Only handle AnalogSignals\n\t\tauto analog_signal =\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal);\n\t\tif (!analog_signal)\n\t\t\tcontinue;\n\n\t\tdouble ts1 = analog_signal->get_sample(0, false).first;\n\t\tfor (size_t i = 1; i<count; i++) {\n\t\t\tconst double ts2 = analog_signal->get_sample(i, false).first;\n\t\t\tconst double delta = ts2 - ts1;\n\t\t\tif (delta < min_delta)\n\t\t\t\tmin_delta = delta;\n\t\t\tts1 = ts2;\n\n\t\t\tif (progress.wasCanceled())\n\t\t\t\treturn false;\n\t\t}\n\t}\n\n\tprogress.setValue(num_signals);\n\n\tif (min_delta < combined_timeframe) {\n\t\tint min_delta_ms = (int)std::floor(min_delta * 1000);\n\t\tQMessageBox::critical(this,\n\t\t\ttr(\"Combination time frame too large\"),\n\t\t\ttr(\"The combination time frame is too large. Time span must be \"\n\t\t\t\t\"smaller than %1 ms.\").arg(min_delta_ms),\n\t\t\tQMessageBox::Ok);\n\t\ttimestamps_combined_timeframe_->setValue(min_delta_ms - 1);\n\t\treturn false;\n\t}\n\treturn true;\n}\n\nvoid SignalSaveDialog::save_settings(QSettings &settings) const\n{\n\tsettings.beginGroup(\"SignalSaveDialog\");\n\tsettings.remove(\"\");  // Remove all keys in this group\n\n\tsettings.setValue(\"timestamps_combined\", timestamps_combined_->isChecked());\n\tsettings.setValue(\"timestamps_combined_timeframe\",\n\t\ttimestamps_combined_timeframe_->value());\n\tsettings.setValue(\"time_absolut\", time_absolut_->isChecked());\n\tsettings.setValue(\"csv_separator\", separator_edit_->text());\n\tsettings.setValue(\"file_dialog_path\", file_dialog_path_);\n\n\tsettings.endGroup();\n}\n\nvoid SignalSaveDialog::restore_settings(QSettings &settings)\n{\n\tsettings.beginGroup(\"SignalSaveDialog\");\n\n\tif (settings.contains(\"timestamps_combined\")) {\n\t\ttimestamps_combined_->setChecked(\n\t\t\tsettings.value(\"timestamps_combined\").toBool());\n\t}\n\tif (settings.contains(\"timestamps_combined_timeframe\")) {\n\t\ttimestamps_combined_timeframe_->setValue(\n\t\t\tsettings.value(\"timestamps_combined_timeframe\").toInt());\n\t}\n\tif (settings.contains(\"time_absolut\")) {\n\t\ttime_absolut_->setChecked(settings.value(\"time_absolut\").toBool());\n\t}\n\tif (settings.contains(\"csv_separator\")) {\n\t\tseparator_edit_->setText(settings.value(\"csv_separator\").toString());\n\t}\n\tif (settings.contains(\"file_dialog_path\")) {\n\t\tfile_dialog_path_ =\n\t\t\tsettings.value(\"file_dialog_path\", QDir::homePath()).toString();\n\t}\n\n\tsettings.endGroup();\n}\n\nvoid SignalSaveDialog::accept()\n{\n\t// Get file name\n\tQString file_name = QFileDialog::getSaveFileName(this,\n\t\ttr(\"Save CSV-File\"), file_dialog_path_, tr(\"CSV Files (*.csv)\"));\n\tif (file_name.isEmpty())\n\t\treturn;\n\n\tfile_dialog_path_ = QDir().absoluteFilePath(file_name);\n\n\tif (timestamps_combined_->isChecked()) {\n\t\tif (!validate_combined_timeframe())\n\t\t\treturn;\n\t\tsave_combined(file_name);\n\t}\n\telse {\n\t\tsave(file_name);\n\t}\n\n\tQDialog::accept();\n}\n\nvoid SignalSaveDialog::done(int result)\n{\n\tQSettings settings;\n\tsave_settings(settings);\n\n\tQDialog::done(result);\n}\n\nvoid SignalSaveDialog::toggle_combined()\n{\n\ttimestamps_combined_timeframe_->setDisabled(\n\t\t!timestamps_combined_->isChecked());\n}\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/dialogs/signalsavedialog.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_DIALOGS_SIGNALSAVEDIALOG_HPP\n#define UI_DIALOGS_SIGNALSAVEDIALOG_HPP\n\n#include <memory>\n#include <vector>\n\n#include <QCheckBox>\n#include <QDialog>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QSettings>\n#include <QSpinBox>\n#include <QString>\n#include <QTreeWidget>\n\n#include \"src/session.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace devices {\nnamespace devicetree {\nclass DeviceTreeView;\n}\n}\n\nnamespace dialogs {\n\nclass SignalSaveDialog : public QDialog\n{\n\tQ_OBJECT\n\npublic:\n\tSignalSaveDialog(const Session &session,\n\t\tconst shared_ptr<sv::devices::BaseDevice> selected_device,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\tvoid save(const QString &file_name);\n\tvoid save_combined(const QString &file_name);\n\tbool validate_combined_timeframe();\n\tvoid save_settings(QSettings &settings) const;\n\tvoid restore_settings(QSettings &settings);\n\n\tconst Session &session_;\n\tconst shared_ptr<sv::devices::BaseDevice> selected_device_;\n\n\tui::devices::devicetree::DeviceTreeView *device_tree_;\n\tQCheckBox *timestamps_combined_;\n\tQSpinBox *timestamps_combined_timeframe_;\n\tQCheckBox *time_absolut_;\n\tQLineEdit *separator_edit_;\n\tQDialogButtonBox *button_box_;\n\tQString file_dialog_path_;\n\npublic Q_SLOTS:\n\tvoid accept() override;\n\t/** The done() slot is handling the saving of the settings */\n\tvoid done(int result) override;\n\nprivate Q_SLOTS:\n\tvoid toggle_combined();\n\n};\n\n} // namespace dialogs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_DIALOGS_SIGNALSAVEDIALOG_HPP\n"
  },
  {
    "path": "src/ui/tabs/basetab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QMainWindow>\n#include <QSizePolicy>\n\n#include \"basetab.hpp\"\n#include \"src/session.hpp\"\n#include \"src/ui/tabs/tabdockwidget.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nBaseTab::BaseTab(Session &session, QWidget *parent) :\n\tQMainWindow(parent),\n\tsession_(session)\n{\n\t// Remove Qt::Window flag\n\tthis->setWindowFlags(Qt::Widget);\n\tthis->setDockNestingEnabled(true);\n\tthis->setCentralWidget(new QWidget());\n\n\t// Hide the central widget of the tab, so the  views (dock widgets) can use\n\t// all of the available space.\n\tthis->centralWidget()->hide();\n}\n\nSession& BaseTab::session()\n{\n\treturn session_;\n}\n\nconst Session& BaseTab::session() const\n{\n\treturn session_;\n}\n\nstring BaseTab::id() const\n{\n\treturn id_;\n}\n\nviews::BaseView *BaseTab::get_view_from_view_id(const string &id)\n{\n\treturn view_id_map_[id];\n}\n\nTabDockWidget *BaseTab::create_dock_widget(views::BaseView *view,\n\tQDockWidget::DockWidgetFeatures features)\n{\n\t// The dock widget must be created here, because the layout must be set to\n\t// the central widget of the view main window before dock->setWidget() is\n\t// called.\n\t// Otherwise the application will flicker at startup....\n\tTabDockWidget *dock = new TabDockWidget(view->title(), view);\n\t// An objectName is needed for QSettings\n\tdock->setObjectName(settings_id_ + \":\" + QString::fromStdString(view->id()));\n\tdock->setAttribute(Qt::WA_DeleteOnClose);\n\tdock->setAllowedAreas(Qt::AllDockWidgetAreas);\n\tdock->setContextMenuPolicy(Qt::PreventContextMenu);\n\tdock->setFeatures(features);\n\n\tview_docks_map_[view] = dock;\n\tview_id_map_[view->id()] = view;\n\n\tconnect(dock, &TabDockWidget::closed, this, &BaseTab::remove_view);\n\n\treturn dock;\n}\n\nvoid BaseTab::closeEvent(QCloseEvent *event)\n{\n\tsave_settings();\n\tevent->accept();\n}\n\nvoid BaseTab::add_view(views::BaseView *view, Qt::DockWidgetArea area,\n\tint features)\n{\n\tif (!view)\n\t\treturn;\n\n\tQDockWidget *dock = create_dock_widget(\n\t\tview, (QDockWidget::DockWidgetFeatures)features);\n\tthis->addDockWidget(area, dock);\n\n\t// This fixes a qt bug. See: https://bugreports.qt.io/browse/QTBUG-65592\n\tthis->resizeDocks({dock}, {40}, Qt::Horizontal);\n}\n\nvoid BaseTab::add_view_ontop(views::BaseView *view,\n\tviews::BaseView *existing_view, int features)\n{\n\tif (!view)\n\t\treturn;\n\n\tQDockWidget *dock = create_dock_widget(\n\t\tview, (QDockWidget::DockWidgetFeatures)features);\n\tthis->tabifyDockWidget(view_docks_map_[existing_view], dock);\n\n\t// This fixes a qt bug. See: https://bugreports.qt.io/browse/QTBUG-65592\n\tthis->resizeDocks({dock}, {40}, Qt::Horizontal);\n}\n\nvoid BaseTab::remove_view(const std::string &view_id)\n{\n\tauto *view = view_id_map_[view_id];\n\tview_docks_map_.erase(view);\n\tview_id_map_.erase(view_id);\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/basetab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_BASETAB_HPP\n#define UI_TABS_BASETAB_HPP\n\n#include <string>\n\n#include <QDockWidget>\n#include <QMainWindow>\n#include <QSettings>\n#include <QString>\n#include <QWidget>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::map;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace ui {\nnamespace tabs {\n\nclass TabDockWidget;\n\nenum class TabType {\n\tMeasurementTab,\n\tSourceSinkTab,\n\tUserTab,\n\tWelcomeTab\n};\n\n/**\n * Use a QMainWindow (as tab widget) to allow for a tool bar.\n */\nclass BaseTab : public QMainWindow\n{\n\tQ_OBJECT\n\npublic:\n\texplicit BaseTab(Session &session, QWidget *parent = nullptr);\n\n\tSession &session();\n\tconst Session &session() const;\n\n\tstring id() const;\n\tvirtual QString title() = 0;\n\tviews::BaseView *get_view_from_view_id(const string &id);\n\tvirtual bool request_close() = 0;\n\nprivate:\n\tTabDockWidget *create_dock_widget(views::BaseView *view,\n\t\tQDockWidget::DockWidgetFeatures features);\n\n\t/** This event is handling the saving of the settings. */\n\tvoid closeEvent(QCloseEvent *event) override;\n\nprotected:\n\tSession &session_;\n\t/**\n\t * id_ is used for accessing the tab (e.g. for the python bindings UiProxy).\n\t */\n\tstring id_;\n\t/**\n\t * settings_id_ is used for the objectNames of the tab and its views for\n\t * identification in the settings (e.g. geometry and status).\n\t */\n\tQString settings_id_;\n\tmap<views::BaseView *, TabDockWidget *> view_docks_map_;\n\tmap<string, views::BaseView *> view_id_map_;\n\n\tvirtual void save_settings() const = 0;\n\tvirtual void restore_settings() = 0;\n\npublic Q_SLOTS:\n\t/*\n\t * When using QDockWidget::DockWidgetFeatures instead of int for features,\n\t * the given flags are or'ed to the default flags instead of replacing\n\t * the default falgs.\n\t */\n\tvoid add_view(views::BaseView *view, Qt::DockWidgetArea area,\n\t\tint features = QDockWidget::DockWidgetMovable |\n\t\t\tQDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);\n\t/*\n\t * When using QDockWidget::DockWidgetFeatures instead of int for features,\n\t * the given flags are or'ed to the default flags instead of replacing\n\t * the default falgs.\n\t */\n\tvoid add_view_ontop(views::BaseView *view, views::BaseView *existing_view,\n\t\tint features = QDockWidget::DockWidgetMovable |\n\t\t\tQDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);\n\nprivate Q_SLOTS:\n\tvoid remove_view(const std::string &view_id);\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_BASETAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/devicetab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QCloseEvent>\n#include <QDebug>\n#include <QMainWindow>\n#include <QMessageBox>\n#include <QToolButton>\n#include <QWidget>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"devicetab.hpp\"\n#include \"src/session.hpp\"\n#include \"src/channels/userchannel.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/dialogs/aboutdialog.hpp\"\n#include \"src/ui/dialogs/addmathchanneldialog.hpp\"\n#include \"src/ui/dialogs/addviewdialog.hpp\"\n#include \"src/ui/dialogs/signalsavedialog.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n#include \"src/ui/tabs/tabdockwidget.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nconst std::string DeviceTab::TAB_ID_PREFIX = \"devicetab:\";\n\nDeviceTab::DeviceTab(Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device, QWidget *parent) :\n\tBaseTab(session, parent),\n\tdevice_(device),\n\taction_aquire_(new QAction(this)),\n\taction_save_as_(new QAction(this)),\n\taction_add_control_view_(new QAction(this)),\n\taction_add_panel_view_(new QAction(this)),\n\taction_add_plot_view_(new QAction(this)),\n\taction_add_table_view_(new QAction(this)),\n\taction_add_math_channel_(new QAction(this)),\n\taction_about_(new QAction(this))\n{\n\tid_ = TAB_ID_PREFIX + device_->id();\n\tsettings_id_ = QString::fromStdString(TAB_ID_PREFIX) + device_->settings_id();\n\n\tsetup_toolbar();\n}\n\n\nQString DeviceTab::title()\n{\n\treturn device_->short_name();\n}\n\nbool DeviceTab::request_close()\n{\n\tQMessageBox::StandardButton reply = QMessageBox::information(this,\n\t\ttr(\"Close device tab\"),\n\t\ttr(\"Closing the device tab will leave the device connected!\"),\n\t\tQMessageBox::Ok | QMessageBox::Cancel);\n\n\treturn reply == QMessageBox::Ok;\n}\n\nvoid DeviceTab::clear_signals()\n{\n}\n\nvoid DeviceTab::setup_toolbar()\n{\n\taction_aquire_->setText(tr(\"Stop\"));\n\taction_aquire_->setIconText(tr(\"Stop\"));\n\taction_aquire_->setIcon(QIcon(\":/icons/status-green.svg\"));\n\taction_aquire_->setCheckable(true);\n\taction_aquire_->setChecked(true);\n\tconnect(action_aquire_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_aquire_triggered);\n\n\tQToolButton *aquire_button_ = new QToolButton();\n\taquire_button_->setDefaultAction(action_aquire_);\n\taquire_button_->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);\n\n\taction_save_as_->setText(tr(\"&Save As...\"));\n\taction_save_as_->setIconText(\"\");\n\taction_save_as_->setIcon(\n\t\tQIcon::fromTheme(\"document-save\",\n\t\tQIcon(\":/icons/document-save.png\")));\n\taction_save_as_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));\n\tconnect(action_save_as_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_save_as_triggered);\n\n\taction_add_control_view_->setText(tr(\"Add Control\"));\n\taction_add_control_view_->setIcon(\n\t\tQIcon::fromTheme(\"mixer-front\",\n\t\tQIcon(\":/icons/mixer-front.png\")));\n\tconnect(action_add_control_view_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_add_control_view_triggered);\n\n\taction_add_panel_view_->setText(tr(\"Add Panel\"));\n\taction_add_panel_view_->setIcon(\n\t\tQIcon::fromTheme(\"chronometer\",\n\t\tQIcon(\":/icons/chronometer.png\")));\n\tconnect(action_add_panel_view_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_add_panel_view_triggered);\n\n\taction_add_plot_view_->setText(tr(\"Add Plot\"));\n\taction_add_plot_view_->setIcon(\n\t\tQIcon::fromTheme(\"office-chart-line\",\n\t\tQIcon(\":/icons/office-chart-line.png\")));\n\tconnect(action_add_plot_view_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_add_plot_view_triggered);\n\n\taction_add_table_view_->setText(tr(\"Add data table\"));\n\taction_add_table_view_->setIcon(\n\t\tQIcon::fromTheme(\"view-form-table\",\n\t\tQIcon(\":/icons/view-form-table.png\")));\n\tconnect(action_add_table_view_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_add_table_view_triggered);\n\n\taction_add_math_channel_->setText(tr(\"Add Math Channel\"));\n\taction_add_math_channel_->setIcon(\n\t\tQIcon::fromTheme(\"office-chart-line-percentage\",\n\t\tQIcon(\":/icons/office-chart-line-percentage.png\")));\n\tconnect(action_add_math_channel_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_add_math_channel_triggered);\n\n\taction_about_->setText(tr(\"About\"));\n\taction_about_->setIcon(\n\t\tQIcon::fromTheme(\"help-about\",\n\t\tQIcon(\":/icons/help-about.png\")));\n\tconnect(action_about_, &QAction::triggered,\n\t\tthis, &DeviceTab::on_action_about_triggered);\n\n\ttoolbar_ = new QToolBar(\"Device Toolbar\");\n\t// objectName is needed for QSettings\n\ttoolbar_->setObjectName(\"toolbar:\" + settings_id_);\n\ttoolbar_->addWidget(aquire_button_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_save_as_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_add_control_view_);\n\ttoolbar_->addAction(action_add_panel_view_);\n\ttoolbar_->addAction(action_add_plot_view_);\n\ttoolbar_->addAction(action_add_table_view_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_add_math_channel_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_about_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid DeviceTab::restore_settings()\n{\n\tQSettings settings;\n\n\t// Restore device views\n\tsettings.beginGroup(device_->settings_id());\n\n\tconst QStringList view_keys = settings.childGroups();\n\tfor (const auto &view_key : view_keys) {\n\t\tsettings.beginGroup(view_key);\n\t\tauto *view = views::viewhelper::get_view_from_settings(\n\t\t\tsession_, settings, device_);\n\t\tif (view)\n\t\t\tadd_view(view, Qt::DockWidgetArea::TopDockWidgetArea);\n\t\tsettings.endGroup();\n\t}\n\n\t// Restore state and geometry for all view widgets.\n\t// NOTE: restoreGeometry() must be called _and_ the sizeHint() of the widget\n\t//       (view) must be set to the last size, in order to restore the\n\t//       correct size of the dock widget. Calling/Setting only one of them\n\t//       is not working!\n\tif (settings.contains(\"geometry\"))\n\t\trestoreGeometry(settings.value(\"geometry\").toByteArray());\n\tif (settings.contains(\"state\"))\n\t\trestoreState(settings.value(\"state\").toByteArray());\n\n\tsettings.endGroup();\n}\n\nvoid DeviceTab::save_settings() const\n{\n\tQSettings settings;\n\n\tsettings.beginGroup(device_->settings_id());\n\tsettings.remove(\"\");  // Remove all keys in this group\n\n\tsize_t index = 0;\n\tfor (const auto &view_dock_pair : view_docks_map_) {\n\t\tsettings.beginGroup(QString(\"view%1\").arg(index));\n\t\tview_dock_pair.first->save_settings(settings, device_);\n\t\tsettings.endGroup();\n\t\t++index;\n\t}\n\n\t// Save state and geometry for all view widgets.\n\t// NOTE: geometry must be saved. See restore_settings().\n\tsettings.setValue(\"geometry\", saveGeometry());\n\tsettings.setValue(\"state\", saveState());\n\n\tsettings.endGroup();\n}\n\nvoid DeviceTab::on_action_aquire_triggered()\n{\n\tif (action_aquire_->isChecked()) {\n\t\taction_aquire_->setText(tr(\"Stop\"));\n\t\taction_aquire_->setIconText(tr(\"Stop\"));\n\t\taction_aquire_->setIcon(QIcon(\":/icons/status-green.svg\"));\n\t\tdevice_->start_aquisition();\n\t}\n\telse {\n\t\taction_aquire_->setText(tr(\"Start\"));\n\t\taction_aquire_->setIconText(tr(\"Start\"));\n\t\taction_aquire_->setIcon(QIcon(\":/icons/status-red.svg\"));\n\t\tdevice_->pause_aquisition();\n\t}\n}\n\nvoid DeviceTab::on_action_save_as_triggered()\n{\n\tui::dialogs::SignalSaveDialog dlg(session(), device_);\n\tdlg.exec();\n}\n\nvoid DeviceTab::on_action_add_control_view_triggered()\n{\n\tshared_ptr<sv::devices::BaseDevice> device = nullptr;\n\tif (device_->type() != sv::devices::DeviceType::UserDevice)\n\t\tdevice = device_;\n\n\tui::dialogs::AddViewDialog dlg(session(), device, 0);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &view : dlg.views())\n\t\tadd_view(view, Qt::TopDockWidgetArea);\n}\n\nvoid DeviceTab::on_action_add_panel_view_triggered()\n{\n\tui::dialogs::AddViewDialog dlg(session(), device_, 2);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &view : dlg.views())\n\t\tadd_view(view, Qt::TopDockWidgetArea);\n}\n\nvoid DeviceTab::on_action_add_plot_view_triggered()\n{\n\tui::dialogs::AddViewDialog dlg(session(), device_, 3);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &view : dlg.views())\n\t\tadd_view(view, Qt::BottomDockWidgetArea);\n}\n\nvoid DeviceTab::on_action_add_table_view_triggered()\n{\n\tui::dialogs::AddViewDialog dlg(session(), device_, 5);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &view : dlg.views())\n\t\tadd_view(view, Qt::TopDockWidgetArea);\n}\n\nvoid DeviceTab::on_action_add_math_channel_triggered()\n{\n\tui::dialogs::AddMathChannelDialog dlg(session(), device_);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tauto channel = dlg.channel();\n\tif (channel != nullptr) {\n\t\tdevice_->add_math_channel(\n\t\t\tchannel, dlg.channel_group_name().toStdString());\n\t}\n}\n\nvoid DeviceTab::on_action_about_triggered()\n{\n\tui::dialogs::AboutDialog dlg(this->session().device_manager(), device_);\n\tdlg.exec();\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/devicetab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_DEVICETAB_HPP\n#define UI_TABS_DEVICETAB_HPP\n\n#include <memory>\n#include <string>\n\n#include <QAction>\n#include <QCloseEvent>\n#include <QToolBar>\n#include <QWidget>\n\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace ui {\nnamespace tabs {\n\nclass DeviceTab : public BaseTab\n{\n\tQ_OBJECT\n\nprivate:\n\npublic:\n\tDeviceTab(Session &session,\n\t\tshared_ptr<sv::devices::BaseDevice> device, QWidget *parent = nullptr);\n\n\tstatic const string TAB_ID_PREFIX;\n\n\tQString title() override;\n\tbool request_close() override;\n\tvirtual void clear_signals();\n\nprotected:\n\tvoid save_settings() const override;\n\tvoid restore_settings() override;\n\n\tshared_ptr<sv::devices::BaseDevice> device_;\n\tutil::TimeUnit time_unit_;\n\nprivate:\n\tvoid setup_toolbar();\n\n\tQAction *const action_aquire_;\n\tQAction *const action_save_as_;\n\tQAction *const action_add_control_view_;\n\tQAction *const action_add_panel_view_;\n\tQAction *const action_add_plot_view_;\n\tQAction *const action_add_table_view_;\n\tQAction *const action_add_math_channel_;\n\tQAction *const action_about_;\n\tQToolBar *toolbar_;\n\npublic Q_SLOTS:\n\nprivate Q_SLOTS:\n\tvoid on_action_aquire_triggered();\n\tvoid on_action_save_as_triggered();\n\tvoid on_action_add_control_view_triggered();\n\tvoid on_action_add_panel_view_triggered();\n\tvoid on_action_add_plot_view_triggered();\n\tvoid on_action_add_table_view_triggered();\n\tvoid on_action_add_math_channel_triggered();\n\tvoid on_action_about_triggered();\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_DEVICETAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/measurementtab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QHBoxLayout>\n#include <QGroupBox>\n#include <QWidget>\n\n#include \"measurementtab.hpp\"\n#include \"src/util.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/measurementdevice.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/timeplotview.hpp\"\n#include \"src/ui/views/valuepanelview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nMeasurementTab::MeasurementTab(Session &session,\n\t\tshared_ptr<sv::devices::MeasurementDevice> device, QWidget *parent) :\n\tDeviceTab(session, device, parent),\n\tmeasurement_device_(device)\n{\n\tif (SettingsManager::restore_settings() &&\n\t\t\tSettingsManager::has_device_settings(device)) {\n\t\trestore_settings();\n\t}\n\telse\n\t\tsetup_ui();\n}\n\nvoid MeasurementTab::setup_ui()\n{\n\tauto hw_device = static_pointer_cast<sv::devices::HardwareDevice>(device_);\n\n\t// Device controls\n\tviews::BaseView *first_conf_view = nullptr;\n\tsize_t conf_view_count = 0;\n\tfor (const auto &c_pair : hw_device->configurable_map()) {\n\t\t// Ignore logic controls from the demo devive.\n\t\tif (c_pair.first == \"Logic\")\n\t\t\tcontinue;\n\n\t\tauto configurable = c_pair.second;\n\t\tif (!configurable->is_controllable())\n\t\t\tcontinue;\n\n\t\tauto configurable_views = views::viewhelper::get_views_for_configurable(\n\t\t\tsession_, configurable);\n\t\tfor (const auto &configurable_view : configurable_views) {\n\t\t\tconf_view_count++;\n\t\t\tif (!first_conf_view) {\n\t\t\t\tfirst_conf_view = configurable_view;\n\t\t\t\tadd_view(configurable_view, Qt::TopDockWidgetArea);\n\t\t\t}\n\t\t\telse\n\t\t\t\tadd_view_ontop(configurable_view, first_conf_view);\n\t\t}\n\t}\n\tif (first_conf_view != nullptr && conf_view_count > 1) {\n\t\tfirst_conf_view->show();\n\t\tfirst_conf_view->raise();\n\t}\n\n\tviews::BaseView *first_panel_view = nullptr;\n\tfor (const auto &ch_pair : measurement_device_->channel_map()) {\n\t\t// Ignore digital channels (starting with \"D\") from the demo devive.\n\t\tif (util::starts_with(ch_pair.first, \"D\"))\n\t\t\tcontinue;\n\n\t\tauto channel = ch_pair.second;\n\n\t\t// Value panel(s)\n\t\tauto *value_panel_view = new ui::views::ValuePanelView(session_);\n\t\tvalue_panel_view->set_channel(channel);\n\t\tif (!first_panel_view) {\n\t\t\tfirst_panel_view = value_panel_view;\n\t\t\tadd_view(value_panel_view, Qt::TopDockWidgetArea);\n\t\t}\n\t\telse\n\t\t\tadd_view_ontop(value_panel_view, first_panel_view);\n\n\t\t// Value plot(s)\n\t\tauto *value_plot_view = new ui::views::TimePlotView(session_);\n\t\tvalue_plot_view->set_channel(channel);\n\t\tadd_view(value_plot_view, Qt::BottomDockWidgetArea);\n\t}\n\tif (first_panel_view != nullptr &&\n\t\t\tmeasurement_device_->channel_map().size() > 1) {\n\t\tfirst_panel_view->show();\n\t\tfirst_panel_view->raise();\n\t}\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/measurementtab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_MEASUREMENTTAB_HPP\n#define UI_TABS_MEASUREMENTTAB_HPP\n\n#include <memory>\n\n#include <QWidget>\n\n#include \"src/ui/tabs/devicetab.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass MeasurementDevice;\n}\n\nnamespace ui {\nnamespace tabs {\n\nclass MeasurementTab : public DeviceTab\n{\n\tQ_OBJECT\n\npublic:\n\tMeasurementTab(Session &session,\n \t\tshared_ptr<sv::devices::MeasurementDevice> device,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\n\t// TODO: remove, generic solution in hw_device\n\tshared_ptr<sv::devices::MeasurementDevice> measurement_device_;\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_MEASUREMENTTAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/oscilloscopetab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QHBoxLayout>\n#include <QGroupBox>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"oscilloscopetab.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/views/scopetriggercontrolview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nOscilloscopeTab::OscilloscopeTab(Session &session,\n\t\tshared_ptr<sv::devices::HardwareDevice> device, QWidget *parent) :\n\tDeviceTab(session, device, parent)\n{\n\tif (SettingsManager::restore_settings() &&\n\t\t\tSettingsManager::has_device_settings(device)) {\n\t\trestore_settings();\n\t}\n\telse\n\t\tsetup_ui();\n}\n\nvoid OscilloscopeTab::setup_ui()\n{\n\tauto hw_device = static_pointer_cast<sv::devices::HardwareDevice>(device_);\n\n\t// Device control(s)\n\tfor (const auto &c_pair : hw_device->configurable_map()) {\n\t\tauto configurable = c_pair.second;\n\t\tif (!configurable->is_controllable())\n\t\t\tcontinue;\n\n\t\tauto configurable_views = views::viewhelper::get_views_for_configurable(\n\t\t\tsession_, configurable);\n\t\tfor (const auto &configurable_view : configurable_views) {\n\t\t\tadd_view(configurable_view, Qt::BottomDockWidgetArea);\n\t\t}\n\t}\n\n\tsize_t added_channels = 0;\n\t//ui::views::TimePlotView *plot_view = NULL;\n\tfor (const auto &chg_pair : device_->channel_group_map()) {\n\t\t/* TODO: for now, only the first two channles are displayed. */\n\t\tif (added_channels >= 2)\n\t\t\tbreak;\n\n\t\t/* TODO: We assume, that every channel group has just one channel. */\n\t\t// Only get the first channel, and ignore the others\n\t\tauto channel = chg_pair.second.at(0);\n\t\tif (!channel)\n\t\t\tcontinue;\n\n\t\t//shared_ptr<data::AnalogScopeSignal> signal; // TODO\n\t\tauto signal = static_pointer_cast<data::AnalogTimeSignal>(\n\t\t\tchannel->actual_signal());\n\t\t++added_channels;\n\n\t\t// TODO: Voltage plot\n\t\t/*\n\t\tif (!plot_view) {\n\t\t\tplot_view = new ui::views::PlotView(session_, signal);\n\t\t\tadd_view(plot_view, Qt::TopDockWidgetArea);\n\t\t}\n\t\telse\n\t\t\tplot_view->add_time_curve(signal);\n\t\t*/\n\t}\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/oscilloscopetab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_OSCILLOSCOPETAB_HPP\n#define UI_TABS_OSCILLOSCOPETAB_HPP\n\n#include <memory>\n\n#include <QWidget>\n\n#include \"src/ui/tabs/devicetab.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass HardwareDevice;\n}\n\nnamespace ui {\nnamespace tabs {\n\nclass OscilloscopeTab : public DeviceTab\n{\n\tQ_OBJECT\n\npublic:\n\tOscilloscopeTab(Session &session,\n\t\tshared_ptr<sv::devices::HardwareDevice> device,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_OSCILLOSCOPETAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/smuscripttab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string>\n\n#include <QDebug>\n#include <QDockWidget>\n#include <QString>\n\n#include \"smuscripttab.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n#include \"src/ui/tabs/tabdockwidget.hpp\"\n#include \"src/ui/views/smuscriptoutputview.hpp\"\n#include \"src/ui/views/smuscriptview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nSmuScriptTab::SmuScriptTab(Session &session,\n\t\tconst string &script_file_name, QWidget *parent) :\n\tBaseTab(session, parent),\n\tscript_file_name_(script_file_name)\n{\n\tid_ = \"smuscripttab:\" + SettingsManager::format_key(script_file_name);\n\t// The settings_id_ is the same for all SmuScriptTabs, so they all look the\n\t// same when restored from the settings, independed of the filename.\n\tsettings_id_ = \"smuscripttab:\";\n\n\tsetup_ui();\n\tconnect_signals();\n\n\tQSettings settings;\n\tif (SettingsManager::restore_settings() &&\n\t\t\tsettings.childGroups().contains(\"SmuScriptTab\")) {\n\t\tSmuScriptTab::restore_settings();\n\t}\n}\n\n\nQString SmuScriptTab::title()\n{\n\treturn smu_script_view_->title();\n}\n\nbool SmuScriptTab::request_close()\n{\n\treturn smu_script_view_->ask_to_save(tr(\"Close SmuScript tab\"));\n}\n\nvoid SmuScriptTab::setup_ui()\n{\n\tsmu_script_view_ = new views::SmuScriptView(session_);\n\tsmu_script_view_->load_file(script_file_name_);\n\tadd_view(smu_script_view_, Qt::TopDockWidgetArea,\n\t\tQDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);\n\n\tsmu_script_output_view_ = new views::SmuScriptOutputView(session_);\n\tadd_view(smu_script_output_view_, Qt::BottomDockWidgetArea,\n\t\tQDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);\n}\n\nvoid SmuScriptTab::connect_signals()\n{\n\tconnect(smu_script_view_, &views::SmuScriptView::file_name_changed,\n\t\tthis, &SmuScriptTab::on_file_name_changed);\n\tconnect(smu_script_view_, &views::SmuScriptView::file_save_state_changed,\n\t\tthis, &SmuScriptTab::on_file_save_state_changed);\n\n\t// This is for redirecting the python output\n\tconnect(smu_script_view_, &views::SmuScriptView::script_started,\n\t\tthis, &SmuScriptTab::on_script_started);\n\tconnect(smu_script_view_, &views::SmuScriptView::script_finished,\n\t\tthis, &SmuScriptTab::on_script_finished);\n}\n\nvoid SmuScriptTab::run_script()\n{\n\tsmu_script_view_->run_script();\n}\n\nvoid SmuScriptTab::stop_script()\n{\n\tsmu_script_view_->stop_script();\n}\n\nvoid SmuScriptTab::restore_settings()\n{\n\tQSettings settings;\n\n\tsettings.beginGroup(\"SmuScriptTab\");\n\n\t// Both views are fixed and will not be restored by their uuid, to give all\n\t// SmuScriptTabs the same setings.\n\n\tsettings.beginGroup(\"view0\");\n\tsmu_script_view_->restore_settings(settings);\n\tsettings.endGroup();\n\n\tsettings.beginGroup(\"view1\");\n\tsmu_script_output_view_->restore_settings(settings);\n\tsettings.endGroup();\n\n\t// NOTE: restoreGeometry() must be called _and_ the sizeHint() of the widget\n\t//       (view) must be set to the last size, in order to restore the\n\t//       correct size of the dock widget. Calling/Setting only one of them\n\t//       is not working!\n\tif (settings.contains(\"geometry\"))\n\t\trestoreGeometry(settings.value(\"geometry\").toByteArray());\n\tif (settings.contains(\"state\"))\n\t\trestoreState(settings.value(\"state\").toByteArray());\n\n\tsettings.endGroup();\n}\n\nvoid SmuScriptTab::save_settings() const\n{\n\tQSettings settings;\n\n\tsettings.beginGroup(\"SmuScriptTab\");\n\tsettings.remove(\"\");\n\n\t// Both views are fixed and will not be restored by their uuid, to give all\n\t// SmuScriptTabs the same setings.\n\n\tsettings.beginGroup(\"view0\");\n\tsmu_script_view_->save_settings(settings);\n\tsettings.endGroup();\n\n\tsettings.beginGroup(\"view1\");\n\tsmu_script_output_view_->save_settings(settings);\n\tsettings.endGroup();\n\n\t// Save state and geometry for all view widgets.\n\t// NOTE: geometry must be saved. See restore_settings().\n\tsettings.setValue(\"geometry\", saveGeometry());\n\tsettings.setValue(\"state\", saveState());\n\n\tsettings.endGroup();\n}\n\nvoid SmuScriptTab::on_file_name_changed(const QString &file_name)\n{\n\t(void)file_name;\n\tview_docks_map_[smu_script_view_]->setWindowTitle(smu_script_view_->title());\n\tsession_.main_window()->change_tab_title(id_, smu_script_view_->title());\n}\n\nvoid SmuScriptTab::on_file_save_state_changed(bool is_unsaved)\n{\n\tif (is_unsaved)\n\t\tsession_.main_window()->change_tab_icon(id_,\n\t\t\tQIcon::fromTheme(\"document-save\", QIcon(\":/icons/document-save.png\")));\n\telse\n\t\tsession_.main_window()->change_tab_icon(id_, QIcon());\n}\n\nvoid SmuScriptTab::on_script_started()\n{\n\t// Redirect python output to SmuScriptOutputView\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::send_py_stdout,\n\t\tsmu_script_output_view_, &views::SmuScriptOutputView::append_out_text);\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::send_py_stderr,\n\t\tsmu_script_output_view_, &views::SmuScriptOutputView::append_err_text);\n}\n\nvoid SmuScriptTab::on_script_finished()\n{\n\tdisconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::send_py_stdout,\n\t\tsmu_script_output_view_, &views::SmuScriptOutputView::append_out_text);\n\tdisconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::send_py_stderr,\n\t\tsmu_script_output_view_, &views::SmuScriptOutputView::append_err_text);\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/smuscripttab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_SMUSCRIPTTAB_HPP\n#define UI_TABS_SMUSCRIPTTAB_HPP\n\n# include <string>\n\n#include <QString>\n#include <QWidget>\n\n#include \"src/ui/tabs/basetab.hpp\"\n\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace ui {\n\nnamespace views {\nclass SmuScriptOutputView;\nclass SmuScriptView;\n}\n\nnamespace tabs {\n\nclass SmuScriptTab : public BaseTab\n{\n\tQ_OBJECT\n\nprivate:\n\npublic:\n\tSmuScriptTab(Session &session, const string &script_file_name,\n\t\tQWidget *parent = nullptr);\n\n\tQString title() override;\n\tbool request_close() override;\n\nprotected:\n\tvoid save_settings() const override;\n\tvoid restore_settings() override;\n\nprivate:\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n\tstring script_file_name_;\n\tviews::SmuScriptView *smu_script_view_;\n\tviews::SmuScriptOutputView *smu_script_output_view_;\n\npublic Q_SLOTS:\n\tvoid run_script();\n\tvoid stop_script();\n\nprivate Q_SLOTS:\n\tvoid on_file_name_changed(const QString &file_name);\n\tvoid on_file_save_state_changed(bool is_unsaved);\n\tvoid on_script_started();\n\tvoid on_script_finished();\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_SMUSCRIPTTAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/sourcesinktab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QDebug>\n#include <QGroupBox>\n#include <QHBoxLayout>\n#include <QWidget>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include \"sourcesinktab.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/powerpanelview.hpp\"\n#include \"src/ui/views/timeplotview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nSourceSinkTab::SourceSinkTab(Session &session,\n\t\tshared_ptr<sv::devices::HardwareDevice> device, QWidget *parent) :\n\tDeviceTab(session, device, parent)\n{\n\tif (SettingsManager::restore_settings() &&\n\t\t\tSettingsManager::has_device_settings(device)) {\n\t\trestore_settings();\n\t}\n\telse\n\t\tsetup_ui();\n}\n\nvoid SourceSinkTab::setup_ui()\n{\n\tauto hw_device = static_pointer_cast<sv::devices::HardwareDevice>(device_);\n\n\t// Device control(s)\n\tviews::BaseView *first_conf_view = nullptr;\n\tsize_t conf_view_count = 0;\n\tfor (const auto &c_pair : hw_device->configurable_map()) {\n\t\tauto configurable = c_pair.second;\n\t\tif (!configurable->is_controllable())\n\t\t\tcontinue;\n\n\t\tauto configurable_views = views::viewhelper::get_views_for_configurable(\n\t\t\tsession_, configurable);\n\t\tfor (const auto &configurable_view : configurable_views) {\n\t\t\tconf_view_count++;\n\t\t\tif (!first_conf_view) {\n\t\t\t\tfirst_conf_view = configurable_view;\n\t\t\t\tadd_view(configurable_view, Qt::TopDockWidgetArea);\n\t\t\t}\n\t\t\telse\n\t\t\t\tadd_view_ontop(configurable_view, first_conf_view);\n\t\t}\n\t}\n\tif (first_conf_view != nullptr && conf_view_count > 1) {\n\t\tfirst_conf_view->show();\n\t\tfirst_conf_view->raise();\n\t}\n\n\t// Get signals by their channel group. The signals in a channel are \"fixed\"\n\t// for power supplys and loads.\n\tviews::BaseView *first_pp_view = nullptr;\n\tfor (const auto &chg_pair : device_->channel_group_map()) {\n\t\tui::views::TimePlotView *plot_view = nullptr;\n\t\tshared_ptr<data::AnalogTimeSignal> voltage_signal;\n\t\tshared_ptr<data::AnalogTimeSignal> current_signal;\n\t\tfor (const auto &channel : chg_pair.second) {\n\t\t\tif (channel->fixed_signal()) {\n\t\t\t\tauto signal = static_pointer_cast<data::AnalogTimeSignal>(\n\t\t\t\t\tchannel->actual_signal());\n\n\t\t\t\t// Only plot voltage and current\n\t\t\t\tif (signal->quantity() == data::Quantity::Voltage) {\n\t\t\t\t\tvoltage_signal = signal;\n\t\t\t\t\t// Voltage plot(s)\n\t\t\t\t\tif (!plot_view) {\n\t\t\t\t\t\tplot_view = new ui::views::TimePlotView(session_);\n\t\t\t\t\t\tadd_view(plot_view, Qt::BottomDockWidgetArea);\n\t\t\t\t\t}\n\t\t\t\t\tplot_view->add_signal(voltage_signal);\n\t\t\t\t}\n\t\t\t\tif (signal->quantity() == data::Quantity::Current) {\n\t\t\t\t\tcurrent_signal = signal;\n\t\t\t\t\t// Current plot(s)\n\t\t\t\t\tif (!plot_view) {\n\t\t\t\t\t\tplot_view = new ui::views::TimePlotView(session_);\n\t\t\t\t\t\tadd_view(plot_view, Qt::BottomDockWidgetArea);\n\t\t\t\t\t}\n\t\t\t\t\tplot_view->add_signal(current_signal);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (voltage_signal && current_signal) {\n\t\t\t// PowerPanel(s)\n\t\t\tauto *power_panel_view = new ui::views::PowerPanelView(session_);\n\t\t\tpower_panel_view->set_signals(voltage_signal, current_signal);\n\t\t\tif (!first_pp_view) {\n\t\t\t\tfirst_pp_view = power_panel_view;\n\t\t\t\tadd_view(power_panel_view, Qt::TopDockWidgetArea);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// NOLINTNEXTLINE(readability-suspicious-call-argument)\n\t\t\t\tadd_view_ontop(power_panel_view, first_pp_view);\n\t\t\t}\n\t\t}\n\t}\n\tif (first_pp_view != nullptr && device_->channel_group_map().size() > 1) {\n\t\tfirst_pp_view->show();\n\t\tfirst_pp_view->raise();\n\t}\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/sourcesinktab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_SOURCESINKTAB_HPP\n#define UI_TABS_SOURCESINKTAB_HPP\n\n#include <memory>\n\n#include <QWidget>\n\n#include \"src/ui/tabs/devicetab.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass HardwareDevice;\n}\n\nnamespace ui {\nnamespace tabs {\n\nclass SourceSinkTab : public DeviceTab\n{\n\tQ_OBJECT\n\npublic:\n\tSourceSinkTab(Session &session,\n\t\tshared_ptr<sv::devices::HardwareDevice> device,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid setup_ui();\n\npublic Q_SLOTS:\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_SOURCESINKTAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/tabdockwidget.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <string>\n\n#include <QCloseEvent>\n#include <QDebug>\n#include <QDockWidget>\n#include <QString>\n#include <QWidget>\n\n#include \"tabdockwidget.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nTabDockWidget::TabDockWidget(const QString &title, views::BaseView *view,\n\t\tQWidget *parent) :\n\tQDockWidget(title, parent)\n{\n\tsetWidget(view);\n\tconnect(view, &views::BaseView::title_changed,\n\t\tthis, &TabDockWidget::on_view_title_changed);\n}\n\nvoid TabDockWidget::closeEvent(QCloseEvent *event)\n{\n\tstring view_id = qobject_cast<views::BaseView *>(widget())->id();\n\tQ_EMIT closed(view_id);\n\tevent->accept();\n}\n\nvoid TabDockWidget::on_view_title_changed()\n{\n\tQString title = qobject_cast<views::BaseView *>(widget())->title();\n\tsetWindowTitle(title);\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/tabdockwidget.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_TABDOCKWIDGET_HPP\n#define UI_TABS_TABDOCKWIDGET_HPP\n\n#include <QCloseEvent>\n#include <QDockWidget>\n#include <QString>\n\nusing std::string;\n\nnamespace sv {\nnamespace ui {\n\nnamespace views {\nclass BaseView;\n}\n\nnamespace tabs {\n\nclass TabDockWidget : public QDockWidget\n{\n\tQ_OBJECT\n\npublic:\n\tTabDockWidget(const QString &title, views::BaseView *view,\n\t\tQWidget *parent = nullptr);\n\nprivate:\n\tvoid closeEvent(QCloseEvent *event) override;\n\nprivate Q_SLOTS:\n\tvoid on_view_title_changed();\n\nQ_SIGNALS:\n\tvoid closed(const std::string &view_id);\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_TABDOCKWIDGET_HPP\n"
  },
  {
    "path": "src/ui/tabs/tabhelper.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QWidget>\n\n#include \"tabhelper.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/devices/measurementdevice.hpp\"\n#include \"src/devices/oscilloscopedevice.hpp\"\n#include \"src/devices/sourcesinkdevice.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/tabs/measurementtab.hpp\"\n#include \"src/ui/tabs/oscilloscopetab.hpp\"\n#include \"src/ui/tabs/sourcesinktab.hpp\"\n#include \"src/ui/tabs/usertab.hpp\"\n\nusing std::shared_ptr;\nusing std::static_pointer_cast;\nusing sv::devices::DeviceType;\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\nnamespace tabhelper {\n\nDeviceTab *get_tab_for_device(Session &session,\n\tshared_ptr<devices::BaseDevice> device, QWidget *parent)\n{\n\tif (!device)\n\t\treturn nullptr;\n\n\t// Power supplies or electronic loads\n\tif (device->type() == DeviceType::PowerSupply ||\n\t\tdevice->type() == DeviceType::ElectronicLoad) {\n\n\t\treturn new SourceSinkTab(session,\n\t\t\tstatic_pointer_cast<devices::SourceSinkDevice>(device), parent);\n\t}\n\n\t// Oscilloscopes\n\tif (device->type() == DeviceType::Oscilloscope) {\n\t\treturn new OscilloscopeTab(session,\n\t\t\tstatic_pointer_cast<devices::OscilloscopeDevice>(device), parent);\n\t}\n\n\t// Measurement devices like DMMs, scales, LCR meters, etc., but also\n\t// the demo device(s)\n\tif (device->type() == DeviceType::Multimeter ||\n\t\tdevice->type() == DeviceType::SoundLevelMeter ||\n\t\tdevice->type() == DeviceType::Thermometer ||\n\t\tdevice->type() == DeviceType::Hygrometer ||\n\t\tdevice->type() == DeviceType::Energymeter ||\n\t\tdevice->type() == DeviceType::LcrMeter ||\n\t\tdevice->type() == DeviceType::Scale ||\n\t\tdevice->type() == DeviceType::SignalGenerator ||\n\t\tdevice->type() == DeviceType::Powermeter ||\n\t\tdevice->type() == DeviceType::Multiplexer ||\n\t\tdevice->type() == DeviceType::DemoDev) {\n\n\t\treturn new MeasurementTab(session,\n\t\t\tstatic_pointer_cast<devices::MeasurementDevice>(device), parent);\n\t}\n\n\t// User device tab\n\tif (device->type() == DeviceType::UserDevice) {\n\t\treturn new UserTab(session,\n\t\t\tstatic_pointer_cast<devices::UserDevice>(device), parent);\n\t}\n\n\treturn nullptr;\n}\n\n} // namespace tabhelper\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/tabhelper.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_TABHELPER_HPP\n#define UI_TABS_TABHELPER_HPP\n\n#include <memory>\n\n#include <QWidget>\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace tabs {\n\nclass DeviceTab;\n\nnamespace tabhelper {\n\n/**\n * Returns the fitting tab for the given device, by checking the device type.\n *\n * @param[in] session The reference to the actual SmuView session\n * @param[in] device The base device\n * @param[in] parent The parent of the tab (normaly nullptr)\n *\n * @return The tab for the device\n */\nDeviceTab *get_tab_for_device(Session &session,\n\tshared_ptr<sv::devices::BaseDevice> device, QWidget *parent = nullptr);\n\n} // namespace tabhelper\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_TABHELPER_HPP\n"
  },
  {
    "path": "src/ui/tabs/usertab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QWidget>\n\n#include \"usertab.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nUserTab::UserTab(Session &session,\n\t\tshared_ptr<sv::devices::UserDevice> device, QWidget *parent) :\n\tDeviceTab(session, device, parent)\n{\n}\n\nvoid UserTab::restore_settings()\n{\n}\n\nvoid UserTab::save_settings() const\n{\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/usertab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_USERTAB_HPP\n#define UI_TABS_USERTAB_HPP\n\n#include <QObject>\n#include <QWidget>\n\n#include \"src/ui/tabs/devicetab.hpp\"\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass UserDevice;\n}\n\nnamespace ui {\nnamespace tabs {\n\nclass UserTab : public DeviceTab\n{\n\tQ_OBJECT\n\npublic:\n\tUserTab(Session &session,\n \t\tshared_ptr<sv::devices::UserDevice> device, QWidget *parent = nullptr);\n\nprotected:\n\tvoid save_settings() const override;\n\tvoid restore_settings() override;\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_USERTAB_HPP\n"
  },
  {
    "path": "src/ui/tabs/welcometab.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QLabel>\n#include <QVBoxLayout>\n#include <QWidget>\n\n#include \"welcometab.hpp\"\n#include \"src/session.hpp\"\n#include \"src/ui/tabs/basetab.hpp\"\n#include <config.h>\n\nnamespace sv {\nnamespace ui {\nnamespace tabs {\n\nWelcomeTab::WelcomeTab(Session &session, QWidget *parent) :\n\tBaseTab(session, parent)\n{\n\tid_ = \"welcometab:0\";\n\tsettings_id_ = \"welcometab:0\";\n\n\tsetup_ui();\n}\n\n\nQString WelcomeTab::title()\n{\n\treturn tr(\"Welcome\");\n}\n\nbool WelcomeTab::request_close()\n{\n\treturn true;\n}\n\nvoid WelcomeTab::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQString welcome(\"\");\n\twelcome.\n\t\tappend(\"<center>\").\n\t\tappend(\"<big>Welcome to <b>SmuView</b></big><br>\").\n\t\tappend(\"Multimeters, Power Supplies and Loads<br><br>\").\n\t\tappend(\"Version \").append(SV_VERSION_STRING).append(\"<br><br>\").\n\t\tappend(\"Copyright 2017-2022, Frank Stettner<br>\").\n\t\tappend(\"Lizenz: <a href=\\\"https://www.gnu.org/licenses/gpl.html\\\">GNU General Public License Version 3</a><br><br>\").\n\t\tappend(\"<a href=\\\"https://github.com/knarfS/smuview\\\">github.com/knarfS/smuview</a><br>\").\n\t\tappend(\"</center>\");\n\n\tQLabel *welcome_label = new QLabel();\n\twelcome_label->setTextFormat(Qt::RichText);\n\twelcome_label->setTextInteractionFlags(Qt::TextBrowserInteraction);\n\twelcome_label->setOpenExternalLinks(true);\n\twelcome_label->setText(welcome);\n\tlayout->addWidget(welcome_label);\n\n\t// Show the central widget of the tab (hidden by BaseTab)\n\tthis->centralWidget()->show();\n\tthis->centralWidget()->setLayout(layout);\n}\n\nvoid WelcomeTab::restore_settings()\n{\n}\n\nvoid WelcomeTab::save_settings() const\n{\n}\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/tabs/welcometab.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_TABS_WELCOMETAB_HPP\n#define UI_TABS_WELCOMETAB_HPP\n\n#include <QString>\n#include <QWidget>\n\n#include \"src/ui/tabs/basetab.hpp\"\n\nnamespace sv {\n\nclass Session;\n\nnamespace ui {\nnamespace tabs {\n\nclass WelcomeTab : public BaseTab\n{\n\tQ_OBJECT\n\nprivate:\n\npublic:\n\texplicit WelcomeTab(Session &session, QWidget *parent = nullptr);\n\n\tQString title() override;\n\t/** The WelcomeTab can always be closed */\n\tbool request_close() override;\n\nprotected:\n\tvoid save_settings() const override;\n\tvoid restore_settings() override;\n\nprivate:\n\tvoid setup_ui();\n\n};\n\n} // namespace tabs\n} // namespace ui\n} // namespace sv\n\n#endif // UI_TABS_WELCOMETAB_HPP\n"
  },
  {
    "path": "src/ui/views/baseplotview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QImageWriter>\n#include <QFileDialog>\n#include <QSettings>\n#include <QString>\n#include <QToolButton>\n#include <QUuid>\n#include <QVBoxLayout>\n#include <qwt_plot_renderer.h>\n\n#include \"baseplotview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/dialogs/plotconfigdialog.hpp\"\n#include \"src/ui/dialogs/plotdiffmarkerdialog.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/widgets/plot/curve.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(sv::ui::widgets::plot::Curve *)\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nBasePlotView::BasePlotView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\taction_add_marker_(new QAction(this)),\n\taction_add_diff_marker_(new QAction(this)),\n\taction_zoom_best_fit_(new QAction(this)),\n\taction_add_curve_(new QAction(this)),\n\taction_save_(new QAction(this)),\n\taction_config_plot_(new QAction(this))\n{\n\tsetup_ui();\n\tsetup_toolbar();\n\tconnect_signals();\n\n\tplot_->start();\n}\n\nvoid BasePlotView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tplot_ = new widgets::plot::Plot(session_);\n\tplot_->set_update_mode(widgets::plot::PlotUpdateMode::Additive);\n\tplot_->set_plot_interval(200); // 200ms\n\n\tlayout->addWidget(plot_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid BasePlotView::setup_toolbar()\n{\n\tadd_marker_menu_ = new QMenu();\n\tupdate_add_marker_menu();\n\n\tadd_marker_button_ = new QToolButton();\n\tadd_marker_button_->setText(tr(\"Add marker\"));\n\tadd_marker_button_->setIcon(\n\t\tQIcon::fromTheme(\"snap-orthogonal\",\n\t\tQIcon(\":/icons/snap-orthogonal.png\")));\n\tadd_marker_button_->setMenu(add_marker_menu_);\n\tadd_marker_button_->setPopupMode(QToolButton::MenuButtonPopup);\n\n\taction_add_diff_marker_->setText(tr(\"Add diff-marker\"));\n\taction_add_diff_marker_->setIcon(\n\t\tQIcon::fromTheme(\"snap-guideline\",\n\t\tQIcon(\":/icons/snap-guideline.png\")));\n\taction_add_diff_marker_->setDisabled(true);\n\tconnect(action_add_diff_marker_, &QAction::triggered,\n\t\tthis, &BasePlotView::on_action_add_diff_marker_triggered);\n\n\taction_zoom_best_fit_->setText(tr(\"Best fit\"));\n\taction_zoom_best_fit_->setIcon(\n\t\tQIcon::fromTheme(\"zoom-fit-best\",\n\t\tQIcon(\":/icons/zoom-fit-best.png\")));\n\tconnect(action_zoom_best_fit_, &QAction::triggered,\n\t\tthis, &BasePlotView::on_action_zoom_best_fit_triggered);\n\n\taction_add_curve_->setText(tr(\"Add Curve\"));\n\taction_add_curve_->setIcon(\n\t\tQIcon::fromTheme(\"office-chart-line\",\n\t\tQIcon(\":/icons/office-chart-line.png\")));\n\tconnect(action_add_curve_, &QAction::triggered,\n\t\tthis, &BasePlotView::on_action_add_curve_triggered);\n\n\taction_save_->setText(tr(\"Save\"));\n\taction_save_->setIcon(\n\t\tQIcon::fromTheme(\"document-save\",\n\t\tQIcon(\":/icons/document-save.png\")));\n\tconnect(action_save_, &QAction::triggered,\n\t\tthis, &BasePlotView::on_action_save_triggered);\n\n\taction_config_plot_->setText(tr(\"Configure Plot\"));\n\taction_config_plot_->setIcon(\n\t\tQIcon::fromTheme(\"configure\",\n\t\tQIcon(\":/icons/configure.png\")));\n\tconnect(action_config_plot_, &QAction::triggered,\n\t\tthis, &BasePlotView::on_action_config_plot_triggered);\n\n\ttoolbar_ = new QToolBar(\"Plot Toolbar\");\n\ttoolbar_->addWidget(add_marker_button_);\n\ttoolbar_->addAction(action_add_diff_marker_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_zoom_best_fit_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_add_curve_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_save_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_config_plot_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid BasePlotView::update_add_marker_menu()\n{\n\t// First remove all existing actions\n\tconst auto actions = add_marker_menu_->actions();\n\tfor (QAction *action : actions) {\n\t\tdisconnect(action, &QAction::triggered,\n\t\t\tthis, &BasePlotView::on_action_add_marker_triggered);\n\t\tadd_marker_menu_->removeAction(action);\n\t\tdelete action;\n\t}\n\n\t// One \"add marker\" action for each curve\n\tfor (const auto &curve : plot_->curve_map()) {\n\t\tQAction *action = new QAction(this);\n\t\taction->setText(curve.second->name());\n\t\taction->setData(QVariant::fromValue(curve.second));\n\t\tconnect(action, &QAction::triggered,\n\t\t\tthis, &BasePlotView::on_action_add_marker_triggered);\n\t\tadd_marker_menu_->addAction(action);\n\t}\n}\n\nvoid BasePlotView::connect_signals()\n{\n\tconnect(plot_, &ui::widgets::plot::Plot::curve_added,\n\t\tthis, &BasePlotView::update_add_marker_menu);\n\tconnect(plot_, &ui::widgets::plot::Plot::curve_removed,\n\t\tthis, &BasePlotView::update_add_marker_menu);\n}\n\n\nbool BasePlotView::set_curve_name(const string &curve_id, const QString &name)\n{\n\tif (plot_->curve_map().count(curve_id) == 0)\n\t\treturn false;\n\n\tplot_->curve_map()[curve_id]->set_name(name);\n\treturn true;\n}\n\n\nbool BasePlotView::set_curve_color(const string &curve_id, const QColor &color)\n{\n\tif (plot_->curve_map().count(curve_id) == 0)\n\t\treturn false;\n\n\tplot_->curve_map()[curve_id]->set_color(color);\n\treturn true;\n}\n\nvoid BasePlotView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\n\tsettings.setValue(\"markers_label_alignment\",\n\t\tplot_->markers_label_alignment());\n}\n\nvoid BasePlotView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\n\tif (settings.contains(\"markers_label_alignment\")) {\n\t\tplot_->set_markers_label_alignment(\n\t\t\tsettings.value(\"markers_label_alignment\").toInt());\n\t}\n}\n\nvoid BasePlotView::on_action_add_marker_triggered()\n{\n\tQAction *action = qobject_cast<QAction *>(sender());\n\tif (action)\n\t\tplot_->add_marker(action->data().value<widgets::plot::Curve *>());\n\n\tif (plot_->marker_curve_map().size() >= 2)\n\t\taction_add_diff_marker_->setDisabled(false);\n\telse\n\t\taction_add_diff_marker_->setDisabled(true);\n}\n\nvoid BasePlotView::on_action_add_diff_marker_triggered()\n{\n\tui::dialogs::PlotDiffMarkerDialog dlg(plot_);\n\tdlg.exec();\n}\n\nvoid BasePlotView::on_action_zoom_best_fit_triggered()\n{\n\tplot_->set_all_axis_locked(false);\n}\n\nvoid BasePlotView::on_action_save_triggered()\n{\n\tQString filter(\"SVG Image (*.svg);;PDF File (*.pdf)\");\n\tconst auto supported_formats = QImageWriter::supportedImageFormats();\n\tfor (const auto &supported : supported_formats) {\n\t\tfilter += \";;\" + supported.toUpper() + \" Image (*.\" + supported + \")\";\n\t}\n\tQString *selected_filter = new QString(\"SVG Image (*.svg)\");\n\tQString file_name = QFileDialog::getSaveFileName(this,\n\t\ttr(\"Save Plot\"), QDir::homePath(), filter, selected_filter);\n\tdelete selected_filter;\n\tif (file_name.length() <= 0)\n\t\treturn;\n\n\t// TODO\n\tQSizeF size(300, 300);\n\tint resolution = 90;\n\tQwtPlotRenderer renderer;\n\trenderer.renderDocument(plot_, file_name, size, resolution);\n}\n\nvoid BasePlotView::on_action_config_plot_triggered()\n{\n\tui::dialogs::PlotConfigDialog dlg(plot_, plot_type_);\n\tdlg.exec();\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/baseplotview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_BASEPLOTVIEW_HPP\n#define UI_VIEWS_BASEPLOTVIEW_HPP\n\n#include <memory>\n#include <string>\n#include <vector>\n\n#include <QAction>\n#include <QColor>\n#include <QMenu>\n#include <QSettings>\n#include <QString>\n#include <QToolBar>\n#include <QToolButton>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace widgets {\nnamespace plot {\nclass BaseCurveData;\nclass Plot;\n}\n}\n\nnamespace views {\n\nenum class PlotType {\n\tTimePlot,\n\tXYPlot,\n};\n\nclass BasePlotView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit BasePlotView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\t/** Helper function to change a curve name. */\n\tbool set_curve_name(const string &curve_id, const QString &name);\n\t/** Helper function to change a curve color. */\n\tbool set_curve_color(const string &curve_id, const QColor &color);\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprotected:\n\tPlotType plot_type_;\n\twidgets::plot::Plot *plot_;\n\nprivate:\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid connect_signals();\n\n\tQMenu *add_marker_menu_;\n\tQToolButton *add_marker_button_;\n\tQAction *const action_add_marker_;\n\tQAction *const action_add_diff_marker_;\n\tQAction *const action_zoom_best_fit_;\n\tQAction *const action_add_curve_;\n\tQAction *const action_save_;\n\tQAction *const action_config_plot_;\n\tQToolBar *toolbar_;\n\nprotected Q_SLOTS:\n\tvoid update_add_marker_menu();\n\tvirtual void on_action_add_curve_triggered() = 0;\n\nprivate Q_SLOTS:\n\tvoid on_action_add_marker_triggered();\n\tvoid on_action_add_diff_marker_triggered();\n\tvoid on_action_zoom_best_fit_triggered();\n\tvoid on_action_save_triggered();\n\tvoid on_action_config_plot_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_BASEPLOTVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/baseview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QSettings>\n#include <QSize>\n#include <QString>\n#include <QUuid>\n#include <QVariant>\n\n#include \"baseview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nBaseView::BaseView(Session &session, QUuid uuid, QWidget *parent) :\n\tQMainWindow(parent),\n\tsession_(session),\n\tsize_(QSize(-1, -1))\n{\n\t// Every view gets its own unique id\n\tuuid_ = uuid.isNull() ? QUuid::createUuid() : uuid;\n\n\t// Remove Qt::Window flag\n\tthis->setWindowFlags(Qt::Widget);\n\n\t// Use a QMainWindow (in the dock widget) to allow for a tool bar\n\tcentral_widget_ = new QWidget();\n\tthis->setCentralWidget(central_widget_);\n}\n\n\nSession &BaseView::session()\n{\n\treturn session_;\n}\n\nconst Session &BaseView::session() const\n{\n\treturn session_;\n}\n\nQUuid BaseView::uuid() const\n{\n\treturn uuid_;\n}\n\nstring BaseView::id() const\n{\n\treturn id_;\n}\n\nvoid BaseView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\t(void)origin_device;\n\n\tsettings.setValue(\"uuid\", QVariant(uuid()));\n\tsettings.setValue(\"id\", QVariant(QString::fromStdString(id())));\n\t// NOTE: The size must be saved together with the geometry (saveGeometry())\n\t//       of all dock widgets, see DeviceTab::save_settings().\n\tsettings.setValue(\"size\", size());\n}\n\nvoid BaseView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\t(void)origin_device;\n\n\t// NOTE: The size must be restored together with the geometry\n\t//       (restoreGeometry()) of all dock widgets, see\n\t//       DeviceTab::restore_settings().\n\tsize_ = settings.value(\"size\").toSize();\n}\n\nQSize BaseView::sizeHint() const\n{\n\tif (size_.width() >= 0 && size_.height() >= 0)\n\t\treturn size_;\n\treturn QMainWindow::sizeHint();\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/baseview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_BASEVIEW_HPP\n#define UI_VIEWS_BASEVIEW_HPP\n\n#include <memory>\n#include <string>\n\n#include <QMainWindow>\n#include <QSettings>\n#include <QSize>\n#include <QString>\n#include <QUuid>\n#include <QWidget>\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nenum class ViewType {\n\tDataView,\n\tDemoControlView,\n\tDeviceTreeView,\n\tMeasurementControlView,\n\tPlotView,\n\tPowerPanelView,\n\tSourceSinkControlView,\n\tValuePanelView\n};\n\nclass BaseView : public QMainWindow\n{\n\tQ_OBJECT\n\npublic:\n\texplicit BaseView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tSession &session();\n\tconst Session &session() const;\n\n\tQUuid uuid() const;\n\tstring id() const;\n\tvirtual QString title() const = 0;\n\n\tvirtual void save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const;\n\tvirtual void restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr);\n\n\t/** Return a size hint for restoring the correct view size from QSettings. */\n\tQSize sizeHint() const override;\n\nprotected:\n\tSession &session_;\n\tQWidget *central_widget_;\n\tQUuid uuid_;\n\tstring id_;\n\t/** The size for sizeHint(). */\n\tQSize size_;\n\nQ_SIGNALS:\n\tvoid title_changed();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_BASEVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/dataview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n\n#include <QAction>\n#include <QDebug>\n#include <QList>\n#include <QSettings>\n#include <QScrollBar>\n#include <QTableWidget>\n#include <QTableWidgetItem>\n#include <QToolBar>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"dataview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogbasesignal.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/dialogs/selectsignaldialog.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\nusing std::dynamic_pointer_cast;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nDataView::DataView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tauto_scroll_(true),\n\taction_auto_scroll_(new QAction(this)),\n\taction_add_signal_(new QAction(this))\n{\n\tid_ = \"data:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tsetup_toolbar();\n}\n\nQString DataView::title() const\n{\n\tQString title = tr(\"Data\");\n\tif (!signals_.empty())\n\t\ttitle = title.append(\" \").append(signals_.at(0)->display_name());\n\treturn title;\n}\n\nvoid DataView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tdata_table_ = new QTableWidget();\n\tdata_table_->setColumnCount(1);\n\tQTableWidgetItem *time_header_item = new QTableWidgetItem(tr(\"Time [s]\"));\n\ttime_header_item->setTextAlignment(Qt::AlignVCenter);\n\tdata_table_->setHorizontalHeaderItem(0, time_header_item);\n\tdata_table_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);\n\tlayout->addWidget(data_table_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid DataView::setup_toolbar()\n{\n\taction_auto_scroll_->setText(tr(\"Auto scroll\"));\n\taction_auto_scroll_->setIcon(\n\t\tQIcon::fromTheme(\"go-bottom\",\n\t\tQIcon(\":/icons/go-bottom.png\")));\n\taction_auto_scroll_->setCheckable(true);\n\taction_auto_scroll_->setChecked(auto_scroll_);\n\tconnect(action_auto_scroll_, &QAction::triggered,\n\t\tthis, &DataView::on_action_auto_scroll_triggered);\n\n\taction_add_signal_->setText(tr(\"Add signal\"));\n\taction_add_signal_->setIcon(\n\t\tQIcon::fromTheme(\"office-chart-line\",\n\t\tQIcon(\":/icons/office-chart-line.png\")));\n\tconnect(action_add_signal_, &QAction::triggered,\n\t\tthis, &DataView::on_action_add_signal_triggered);\n\n\ttoolbar_ = new QToolBar(\"Data View Toolbar\");\n\ttoolbar_->addAction(action_auto_scroll_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_add_signal_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid DataView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\n\tsize_t index = 0;\n\tfor (const auto &signal : signals_) {\n\t\tsettings.beginGroup(QString(\"signal%1\").arg(index++));\n\t\tSettingsManager::save_signal(signal, settings, origin_device);\n\t\tsettings.endGroup();\n\t}\n}\n\nvoid DataView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\n\tconst auto groups = settings.childGroups();\n\tfor (const auto &group : groups) {\n\t\tif (group.startsWith(\"signal\")) {\n\t\t\tsettings.beginGroup(group);\n\t\t\tauto signal = SettingsManager::restore_signal(\n\t\t\t\tsession_, settings, origin_device);\n\t\t\tif (signal) {\n\t\t\t\tadd_signal(\n\t\t\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal));\n\t\t\t}\n\t\t\tsettings.endGroup();\n\t\t}\n\t}\n}\n\nvoid DataView::add_signal(shared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tsignals_.push_back(signal);\n\tnext_signal_pos_.push_back(0);\n\tlast_timestamp_.push_back(nullptr);\n\tint pos = static_cast<int>(signals_.size());\n\n\tQTableWidgetItem *value_header_item = new QTableWidgetItem(\n\t\tsignal->display_name());\n\tvalue_header_item->setTextAlignment(Qt::AlignVCenter);\n\tdata_table_->insertColumn(pos);\n\tdata_table_->setHorizontalHeaderItem(pos, value_header_item);\n\n\tthis->populate_table();\n\tconnect(signal.get(), &data::AnalogBaseSignal::sample_appended,\n\t\tthis, &DataView::populate_table);\n\n\tQ_EMIT title_changed();\n}\n\nvoid DataView::populate_table()\n{\n\tstd::unique_lock<std::mutex> lock(populate_mutex_, std::try_to_lock);\n\tif (!lock.owns_lock())\n\t\treturn;\n\n\tfor (size_t i=0; i<signals_.size(); ++i) {\n\t\tsize_t signal_size = signals_[i]->sample_count();\n\t\twhile (next_signal_pos_[i] < signal_size) {\n\t\t\tauto sample = signals_[i]->get_sample(next_signal_pos_[i], true);\n\t\t\tint row_count  = data_table_->rowCount();\n\n\t\t\tint last_row  = -1;\n\t\t\tif (last_timestamp_[i])\n\t\t\t\tlast_row = data_table_->row(last_timestamp_[i]);\n\n\t\t\tbool new_row = false;\n\t\t\tif (row_count <= last_row+1) {\n\t\t\t\tdata_table_->insertRow(last_row+1);\n\t\t\t\tnew_row = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Find position of new sample\n\t\t\t\twhile (last_row+1 < row_count) {\n\t\t\t\t\tauto *item = data_table_->item(last_row+1, 0);\n\t\t\t\t\tdouble timestamp = item->data(0).toDouble();\n\t\t\t\t\tif (timestamp > sample.first) {\n\t\t\t\t\t\tdata_table_->insertRow(last_row+1);\n\t\t\t\t\t\tnew_row = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (timestamp == sample.first) {\n\t\t\t\t\t\tlast_timestamp_[i] = item;\n\t\t\t\t\t\tnew_row = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (row_count == last_row+2) {\n\t\t\t\t\t\t++last_row;\n\t\t\t\t\t\tdata_table_->insertRow(last_row+1);\n\t\t\t\t\t\tnew_row = true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tlast_row++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (new_row) {\n\t\t\t\tQTableWidgetItem *time_item = new QTableWidgetItem(\n\t\t\t\t\tQString::number(sample.first, 'f', 3));\n\t\t\t\ttime_item->setData(0, QVariant(sample.first));\n\t\t\t\tdata_table_->setItem(last_row+1, 0, time_item);\n\t\t\t\tlast_timestamp_[i] = time_item;\n\t\t\t}\n\t\t\tint prefix = util::prefix_from_value(\n\t\t\t\tsample.second, signals_[i]->sr_digits());\n\t\t\tint decimal_places = util::decimal_places_from_prefix(\n\t\t\t\tprefix, signals_[i]->sr_digits());\n\t\t\tQTableWidgetItem *value_item = new QTableWidgetItem(\n\t\t\t\tQString::number(sample.second, 'f', decimal_places));\n\t\t\tvalue_item->setData(0, QVariant(sample.second));\n\t\t\tdata_table_->setItem(last_row+1, (int)i+1, value_item);\n\n\t\t\t++next_signal_pos_[i];\n\t\t}\n\t}\n\tif (auto_scroll_)\n\t\tdata_table_->scrollToBottom();\n}\n\nvoid DataView::on_action_auto_scroll_triggered()\n{\n\tauto_scroll_ = !auto_scroll_;\n\taction_auto_scroll_->setChecked(auto_scroll_);\n}\n\nvoid DataView::on_action_add_signal_triggered()\n{\n\tshared_ptr<sv::devices::BaseDevice> selected_device;\n\tif (signals_[0])\n\t\tselected_device = signals_[0]->parent_channel()->parent_device();\n\n\tui::dialogs::SelectSignalDialog dlg(session(), selected_device);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &signal : dlg.signals()) {\n\t\tadd_signal(dynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal));\n\t}\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n"
  },
  {
    "path": "src/ui/views/dataview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_DATAVIEW_HPP\n#define UI_VIEWS_DATAVIEW_HPP\n\n#include <memory>\n#include <mutex>\n#include <vector>\n\n#include <QAction>\n#include <QSettings>\n#include <QTableWidget>\n#include <QToolBar>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass DataView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit DataView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\tvoid add_signal(shared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tvector<shared_ptr<sv::data::AnalogTimeSignal>> signals_;\n\tvector<size_t> next_signal_pos_;\n\tvector<QTableWidgetItem *> last_timestamp_;\n\tbool auto_scroll_;\n\tstd::mutex populate_mutex_;\n\n\tQAction *const action_auto_scroll_;\n\tQAction *const action_add_signal_;\n\tQToolBar *toolbar_;\n\tQTableWidget *data_table_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\nprivate Q_SLOTS:\n\tvoid populate_table();\n\tvoid on_action_auto_scroll_triggered();\n\tvoid on_action_add_signal_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_DATAVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/democontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QHBoxLayout>\n#include <QPushButton>\n#include <QSettings>\n#include <QUuid>\n#include <QVBoxLayout>\n#include <QVariant>\n\n#include \"democontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/data/properties/measuredquantityproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/data/quantitycombobox.hpp\"\n#include \"src/ui/data/quantityflagslist.hpp\"\n#include \"src/ui/datatypes/doublecontrol.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\nusing std::static_pointer_cast;\nusing sv::devices::ConfigKey;\n\nQ_DECLARE_METATYPE(sv::data::measured_quantity_t)\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nDemoControlView::DemoControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"democontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nQString DemoControlView::title() const\n{\n\treturn tr(\"Control\") + \" \" + configurable_->display_name();\n}\n\nvoid DemoControlView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tif (configurable_->has_get_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable_->has_set_config(ConfigKey::MeasuredQuantity)) {\n\n\t\t// The demo dmm device has no listable measurement quantities /\n\t\t// quantity flags, so we use all...\n\t\tauto mq_prop =\n\t\t\tstatic_pointer_cast<sv::data::properties::MeasuredQuantityProperty>(\n\t\t\t\tconfigurable_->get_property(ConfigKey::MeasuredQuantity));\n\n\t\tquantity_box_ = new ui::data::QuantityComboBox();\n\t\tquantity_box_->select_quantity(\n\t\t\tmq_prop->measured_quantity_value().first);\n\t\tlayout->addWidget(quantity_box_);\n\t\tquantity_flags_list_ = new ui::data::QuantityFlagsList();\n\t\tquantity_flags_list_->select_quantity_flags(\n\t\t\tmq_prop->measured_quantity_value().second);\n\t\tlayout->addWidget(quantity_flags_list_);\n\n\t\tset_button_ = new QPushButton();\n\t\tset_button_->setText(tr(\"Set\"));\n\t\tlayout->addWidget(set_button_, 0);\n\t}\n\n\tif (configurable_->has_get_config(ConfigKey::PatternMode) ||\n\t\tconfigurable_->has_set_config(ConfigKey::PatternMode)) {\n\n\t\tpattern_box_ = new ui::datatypes::StringComboBox(\n\t\t\tconfigurable_->get_property(ConfigKey::PatternMode), true, true);\n\t\tlayout->addWidget(pattern_box_);\n\t}\n\n\tQHBoxLayout *controls_layout = new QHBoxLayout();\n\n\tamplitude_control_ = new ui::datatypes::DoubleControl(\n\t\tconfigurable_->get_property(ConfigKey::Amplitude),\n\t\ttrue, true, tr(\"Amplitude\"));\n\tcontrols_layout->addWidget(amplitude_control_);\n\n\toffset_control_ = new ui::datatypes::DoubleControl(\n\t\tconfigurable_->get_property(ConfigKey::Offset),\n\t\ttrue, true, tr(\"Offset\"));\n\tcontrols_layout->addWidget(offset_control_);\n\n\tlayout->addLayout(controls_layout);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid DemoControlView::connect_signals()\n{\n\t// Control elements -> Device\n\tif (configurable_->has_get_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable_->has_set_config(ConfigKey::MeasuredQuantity)) {\n\n\t\tconnect(set_button_, &QPushButton::clicked,\n\t\t\tthis, &DemoControlView::on_quantity_set);\n\t}\n\n\t// Device -> control elements\n}\n\nvoid DemoControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid DemoControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nDemoControlView *DemoControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new DemoControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\nvoid DemoControlView::on_quantity_set()\n{\n\tsv::data::Quantity quantity = quantity_box_->selected_quantity();\n\tset<sv::data::QuantityFlag> quantity_flags =\n\t\tquantity_flags_list_->selected_quantity_flags();\n\n\tauto mq = make_pair(quantity, quantity_flags);\n\tauto prop = configurable_->get_property(ConfigKey::MeasuredQuantity);\n\tprop->change_value(QVariant::fromValue(mq));\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/democontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_DEMOCONTROLVIEW_HPP\n#define UI_VIEWS_DEMOCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QPushButton>\n#include <QSettings>\n#include <QString>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace data {\nclass QuantityComboBox;\nclass QuantityFlagsList;\n}\nnamespace datatypes {\nclass DoubleControl;\nclass StringComboBox;\n}\n\nnamespace views {\n\nclass DemoControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tDemoControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic DemoControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::data::QuantityComboBox *quantity_box_;\n\tui::data::QuantityFlagsList *quantity_flags_list_;\n\tQPushButton *set_button_;\n\tui::datatypes::StringComboBox *pattern_box_;\n\tui::datatypes::DoubleControl *amplitude_control_;\n\tui::datatypes::DoubleControl *offset_control_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\tvoid on_quantity_set();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_DEMOCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/devicesview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QAction>\n#include <QDebug>\n#include <QMessageBox>\n#include <QSettings>\n#include <QToolBar>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"devicesview.hpp\"\n#include \"src/devicemanager.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/session.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/hardwaredevice.hpp\"\n#include \"src/devices/userdevice.hpp\"\n#include \"src/ui/devices/devicetree/devicetreemodel.hpp\"\n#include \"src/ui/devices/devicetree/devicetreeview.hpp\"\n#include \"src/ui/devices/devicetree/treeitem.hpp\"\n#include \"src/ui/dialogs/connectdialog.hpp\"\n#include \"src/ui/tabs/devicetab.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing sv::ui::devices::devicetree::DeviceTreeModel;\nusing sv::ui::devices::devicetree::TreeItem;\nusing sv::ui::devices::devicetree::TreeItemType;\n\nQ_DECLARE_SMART_POINTER_METATYPE(std::shared_ptr)\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nDevicesView::DevicesView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\taction_add_device_(new QAction(this)),\n\taction_add_userdevice_(new QAction(this)),\n\taction_disconnect_device_(new QAction(this))\n{\n\tid_ = \"devices:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tsetup_toolbar();\n\tconnect_signals();\n}\n\nQString DevicesView::title() const\n{\n\treturn tr(\"Device Tree\");\n}\n\nvoid DevicesView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\tdevice_tree_ = new devices::devicetree::DeviceTreeView(session(),\n\t\tfalse, false, false, false, false, false, true, true);\n\tlayout->addWidget(device_tree_);\n\tlayout->setContentsMargins(2, 2, 2, 2);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid DevicesView::setup_toolbar()\n{\n\taction_add_device_->setText(tr(\"Add device\"));\n\taction_add_device_->setIcon(\n\t\tQIcon::fromTheme(\"document-new\",\n\t\tQIcon(\":/icons/document-new.png\")));\n\tconnect(action_add_device_, &QAction::triggered,\n\t\tthis, &DevicesView::on_action_add_device_triggered);\n\n\taction_add_userdevice_->setText(tr(\"Add virtual user device\"));\n\taction_add_userdevice_->setIcon(\n\t\tQIcon::fromTheme(\"tab-new-background\",\n\t\tQIcon(\":/icons/tab-new-background.png\")));\n\tconnect(action_add_userdevice_, &QAction::triggered,\n\t\tthis, &DevicesView::on_action_add_userdevice_triggered);\n\n\taction_disconnect_device_->setText(tr(\"Disconnect device\"));\n\taction_disconnect_device_->setIcon(\n\t\tQIcon::fromTheme(\"edit-delete\",\n\t\tQIcon(\":/icons/edit-delete.png\")));\n\tconnect(action_disconnect_device_, &QAction::triggered,\n\t\tthis, &DevicesView::on_action_disconnect_device_triggered);\n\n\ttoolbar_ = new QToolBar(\"Device Tree Toolbar\");\n\ttoolbar_->addAction(action_add_device_);\n\ttoolbar_->addAction(action_add_userdevice_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_disconnect_device_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid DevicesView::connect_signals()\n{\n}\n\nvoid DevicesView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\t(void)settings;\n\t(void)origin_device;\n}\n\nvoid DevicesView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\t(void)settings;\n\t(void)origin_device;\n}\n\nvoid DevicesView::on_action_add_device_triggered()\n{\n\tui::dialogs::ConnectDialog dlg(session().device_manager());\n\tif (dlg.exec()) {\n\t\tauto device = dlg.get_selected_device();\n\t\t// NOTE: add_device() must be called, before the device tab\n\t\t//       tries to access the device (device is not opend yet).\n\t\tsession().add_device(device);\n\t\tsession().main_window()->add_device_tab(device);\n\t}\n}\n\nvoid DevicesView::on_action_add_userdevice_triggered()\n{\n\t// NOTE: add_user_device() must be called, before the device tab\n\t//       tries to access the device (device is not opend yet).\n\tauto device = session().add_user_device();\n\tsession().main_window()->add_device_tab(device);\n}\n\nvoid DevicesView::on_action_disconnect_device_triggered()\n{\n\tTreeItem *item = device_tree_->selected_item();\n\tif (!item)\n\t\treturn;\n\n\tif (item->type() == (int)TreeItemType::DeviceItem) {\n\t\tauto device = item->data(DeviceTreeModel::DataRole).\n\t\t\tvalue<shared_ptr<sv::devices::BaseDevice>>();\n\n\t\tQMessageBox::StandardButton reply = QMessageBox::question(this,\n\t\t\ttr(\"Close device\"),\n\t\t\ttr(\"Closing the device \\\"%1\\\" will also delete all aquired data!\").\n\t\t\t\targ(device->short_name()),\n\t\t\tQMessageBox::Yes | QMessageBox::Cancel);\n\n\t\tif (reply == QMessageBox::Yes) {\n\t\t\tsession().main_window()->remove_tab(\n\t\t\t\tui::tabs::DeviceTab::TAB_ID_PREFIX + device->id());\n\t\t\tsession().remove_device(device);\n\t\t}\n\t}\n\telse if (item->type() == (int)TreeItemType::ChannelItem) {\n\t\t/* TODO\n\t\tauto channel = item->data(DeviceTreeModel::DataRole).\n\t\t\tvalue<shared_ptr<sv::channels::BaseChannel>>();\n\n\t\tQMessageBox::StandardButton reply = QMessageBox::question(this,\n\t\t\ttr(\"Delete signals from channel\"),\n\t\t\ttr(\"Deleting all signals from channel \\\"%1\\\" will also delete all aquired data!\").\n\t\t\t\targ(QString::fromStdString(channel->name())),\n\t\t\tQMessageBox::Yes | QMessageBox::Cancel);\n\n\t\tif (reply == QMessageBox::Yes) {\n\t\t\tchannel->clear_signals();\n\t\t}\n\t\t*/\n\t}\n\telse if (item->type() == (int)TreeItemType::SignalItem) {\n\t\tauto signal = item->data(DeviceTreeModel::DataRole).\n\t\t\tvalue<shared_ptr<sv::data::BaseSignal>>();\n\n\t\tQMessageBox::StandardButton reply = QMessageBox::question(this,\n\t\t\ttr(\"Delete signal\"),\n\t\t\ttr(\"Deleting the signal \\\"%1\\\" will also delete all aquired data!\").\n\t\t\t\targ(signal->display_name()),\n\t\t\tQMessageBox::Yes | QMessageBox::Cancel);\n\n\t\tif (reply == QMessageBox::Yes) {\n\t\t\tsignal->clear();\n\t\t}\n\t}\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/devicesview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_DEVICESVIEW_HPP\n#define UI_VIEWS_DEVICESVIEW_HPP\n\n#include <memory>\n\n#include <QAction>\n#include <QSettings>\n#include <QToolBar>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace devices {\nnamespace devicetree {\nclass DeviceTreeView;\n}\n}\n\nnamespace views {\n\nclass DevicesView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit DevicesView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tQAction *const action_add_device_;\n\tQAction *const action_add_userdevice_;\n\tQAction *const action_disconnect_device_;\n\tQToolBar *toolbar_;\n\tdevices::devicetree::DeviceTreeView  *device_tree_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid connect_signals();\n\nprivate Q_SLOTS:\n\tvoid on_action_add_device_triggered();\n\tvoid on_action_add_userdevice_triggered();\n\tvoid on_action_disconnect_device_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_DEVICESVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/genericcontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QFormLayout>\n#include <QSettings>\n#include <QString>\n#include <QUuid>\n#include <QVariant>\n#include <QWidget>\n\n#include \"genericcontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/datatypes/datatypehelper.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nGenericControlView::GenericControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"genericcontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tconnect_signals();\n}\n\nQString GenericControlView::title() const\n{\n\treturn tr(\"Control\") + \" \" + configurable_->display_name();\n}\n\nvoid GenericControlView::setup_ui()\n{\n\tQFormLayout *layout = new QFormLayout();\n\n\tfor (const auto &prop : configurable_->property_map()) {\n\t\tQString text = devices::deviceutil::format_config_key(prop.first);\n\t\tQWidget *dt_widget = datatypes::datatypehelper::get_widget_for_property(\n\t\t\tprop.second, true, true);\n\n\t\tlayout->addRow(text, dt_widget);\n\t}\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid GenericControlView::connect_signals()\n{\n\t// Control elements -> Device\n\n\t// Device -> control elements\n}\n\nvoid GenericControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid GenericControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nGenericControlView *GenericControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new GenericControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/genericcontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_GENERICCONTROLVIEW_HPP\n#define UI_VIEWS_GENERICCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QString>\n#include <QUuid>\n#include <QWidget>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\nnamespace views {\n\nclass GenericControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tGenericControlView(Session& session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic GenericControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tvoid setup_ui();\n\tvoid connect_signals();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_GENERICCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/measurementcontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QFormLayout>\n#include <QSettings>\n#include <QUuid>\n#include <QVariant>\n\n#include \"measurementcontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/datatypes/measuredquantitycombobox.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\nusing sv::devices::ConfigKey;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nMeasurementControlView::MeasurementControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"measurementcontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n}\n\nQString MeasurementControlView::title() const\n{\n\treturn tr(\"Control\") + \" \" + configurable_->display_name();\n}\n\nvoid MeasurementControlView::setup_ui()\n{\n\tQFormLayout *layout = new QFormLayout();\n\n\tmeasured_quantity_box_ = new ui::datatypes::MeasuredQuantityComboBox(\n\t\tconfigurable_->get_property(ConfigKey::MeasuredQuantity), true, true);\n\tlayout->addRow(tr(\"Quantity\"), measured_quantity_box_);\n\n\trange_box_ = new ui::datatypes::StringComboBox(\n\t\tconfigurable_->get_property(ConfigKey::Range), true, true);\n\tlayout->addRow(tr(\"Range\"), range_box_);\n\n\tdigits_box_ = new ui::datatypes::StringComboBox(\n\t\tconfigurable_->get_property(ConfigKey::Digits), true, true);\n\tlayout->addRow(tr(\"Digits\"), digits_box_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid MeasurementControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid MeasurementControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nMeasurementControlView *MeasurementControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new MeasurementControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/measurementcontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_MEASUREMENTCONTROLVIEW_HPP\n#define UI_VIEWS_MEASUREMENTCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace datatypes {\nclass MeasuredQuantityComboBox;\nclass StringComboBox;\n}\n\nnamespace views {\n\nclass MeasurementControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tMeasurementControlView(Session& session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic MeasurementControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::datatypes::MeasuredQuantityComboBox *measured_quantity_box_;\n\tui::datatypes::StringComboBox *range_box_;\n\tui::datatypes::StringComboBox *digits_box_;\n\n\tvoid setup_ui();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_MEASUREMENTCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/powerpanelview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QApplication>\n#include <QDateTime>\n#include <QDebug>\n#include <QSettings>\n#include <QTimer>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"powerpanelview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogbasesignal.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include \"src/ui/widgets/monofontdisplay.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::set;\nusing std::shared_ptr;\nusing sv::data::QuantityFlag;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nPowerPanelView::PowerPanelView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tvoltage_signal_(nullptr),\n\tcurrent_signal_(nullptr),\n\tvoltage_min_(std::numeric_limits<double>::max()),\n\tvoltage_max_(std::numeric_limits<double>::lowest()),\n\tcurrent_min_(std::numeric_limits<double>::max()),\n\tcurrent_max_(std::numeric_limits<double>::lowest()),\n\tresistance_min_(std::numeric_limits<double>::max()),\n\tresistance_max_(std::numeric_limits<double>::lowest()),\n\tpower_min_(std::numeric_limits<double>::max()),\n\tpower_max_(std::numeric_limits<double>::lowest()),\n\tactual_amp_hours_(0),\n\tactual_watt_hours_(0),\n\taction_reset_displays_(new QAction(this))\n{\n\tid_ = \"powerpanel:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tsetup_toolbar();\n\tconnect_signals();\n\treset_displays();\n\n\ttimer_ = new QTimer(this);\n\tinit_timer();\n}\n\nPowerPanelView::~PowerPanelView()\n{\n\tstop_timer();\n}\n\nQString PowerPanelView::title() const\n{\n\tQString title = tr(\"Power Panel\");\n\tif (voltage_signal_ && current_signal_)\n\t\ttitle = title.append(\" \").append(voltage_signal_->display_name()).\n\t\t\tappend(\" / \").append(current_signal_->display_name());\n\n\treturn title;\n}\n\nvoid PowerPanelView::set_signals(\n\tshared_ptr<sv::data::AnalogTimeSignal> voltage_signal,\n\tshared_ptr<sv::data::AnalogTimeSignal> current_signal)\n{\n\tassert(voltage_signal);\n\tassert(current_signal);\n\n\tdisconnect_signals();\n\tstop_timer();\n\tvoltage_signal_ = voltage_signal;\n\tcurrent_signal_ = current_signal;\n\tinit_timer();\n\tinit_displays();\n\tconnect_signals();\n\n\tQ_EMIT title_changed();\n}\n\nvoid PowerPanelView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\tQGridLayout *panel_layout = new QGridLayout();\n\n\tvoltage_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRangeWithSRDigits, \"\", \"\", \"\", false);\n\tvoltage_min_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Min), true);\n\tvoltage_max_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Max), true);\n\n\tcurrent_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRangeWithSRDigits, \"\", \"\", \"\", false);\n\tcurrent_min_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Min), true);\n\tcurrent_max_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Max), true);\n\n\tresistance_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Ohm), \"\", \"\", false);\n\tresistance_min_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Ohm), \"\",\n\t\tdata::datautil::format_quantity_flag(QuantityFlag::Min), true);\n\tresistance_max_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Ohm), \"\",\n\t\tdata::datautil::format_quantity_flag(QuantityFlag::Max), true);\n\n\tpower_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Watt), \"\", \"\", false);\n\tpower_min_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Watt), \"\",\n\t\tdata::datautil::format_quantity_flag(QuantityFlag::Min), true);\n\tpower_max_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::Watt), \"\",\n\t\tdata::datautil::format_quantity_flag(QuantityFlag::Max), true);\n\n\tamp_hour_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::AmpereHour), \"\", \"\", false);\n\twatt_hour_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange,\n\t\tdata::datautil::format_unit(data::Unit::WattHour), \"\", \"\", false);\n\n\tpanel_layout->addWidget(voltage_display_, 0, 0, 1, 2, Qt::AlignHCenter);\n\tpanel_layout->addWidget(voltage_min_display_, 1, 0, 1, 1, Qt::AlignHCenter);\n\tpanel_layout->addWidget(voltage_max_display_, 1, 1, 1, 1, Qt::AlignHCenter);\n\n\tpanel_layout->addWidget(current_display_, 2, 0, 1, 2, Qt::AlignHCenter);\n\tpanel_layout->addWidget(current_min_display_, 3, 0, 1, 1, Qt::AlignHCenter);\n\tpanel_layout->addWidget(current_max_display_, 3, 1, 1, 1, Qt::AlignHCenter);\n\n\tpanel_layout->addWidget(resistance_display_, 0, 2, 1, 2, Qt::AlignHCenter);\n\tpanel_layout->addWidget(resistance_min_display_, 1, 2, 1, 1, Qt::AlignHCenter);\n\tpanel_layout->addWidget(resistance_max_display_, 1, 3, 1, 1, Qt::AlignHCenter);\n\n\tpanel_layout->addWidget(power_display_, 2, 2, 1, 2, Qt::AlignHCenter);\n\tpanel_layout->addWidget(power_min_display_, 3, 2, 1, 1, Qt::AlignHCenter);\n\tpanel_layout->addWidget(power_max_display_, 3, 3, 1, 1, Qt::AlignHCenter);\n\n\tpanel_layout->addWidget(amp_hour_display_, 0, 4, 2, 1, Qt::AlignCenter);\n\tpanel_layout->addWidget(watt_hour_display_, 2, 4, 2, 1, Qt::AlignCenter);\n\n\tlayout->addLayout(panel_layout);\n\tlayout->addStretch(1);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid PowerPanelView::setup_toolbar()\n{\n\taction_reset_displays_->setText(tr(\"Reset displays\"));\n\taction_reset_displays_->setIcon(\n\t\tQIcon::fromTheme(\"view-refresh\",\n\t\tQIcon(\":/icons/view-refresh.png\")));\n\tconnect(action_reset_displays_, &QAction::triggered,\n\t\tthis, &PowerPanelView::on_action_reset_displays_triggered);\n\n\ttoolbar_ = new QToolBar(\"Power Panel Toolbar\");\n\ttoolbar_->addAction(action_reset_displays_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid PowerPanelView::init_displays()\n{\n\tQString voltage_unit_suffix(\"\");\n\tset<QuantityFlag> voltage_qfs = voltage_signal_->quantity_flags();\n\tif (voltage_qfs.count(QuantityFlag::AC) > 0) {\n\t\t//voltage_unit_suffix = QString::fromUtf8(\"\\u23E6\");\n\t\tvoltage_unit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tQuantityFlag::AC);\n\t\tvoltage_qfs.erase(QuantityFlag::AC);\n\t}\n\telse if (voltage_qfs.count(QuantityFlag::DC) > 0) {\n\t\t//voltage_unit_suffix = QString::fromUtf8(\"\\u2393\");\n\t\tvoltage_unit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tQuantityFlag::DC);\n\t\tvoltage_qfs.erase(QuantityFlag::DC);\n\t}\n\tset<QuantityFlag> voltage_qfs_min = voltage_qfs;\n\tvoltage_qfs_min.insert(QuantityFlag::Min);\n\tset<QuantityFlag> voltage_qfs_max = voltage_qfs;\n\tvoltage_qfs_max.insert(QuantityFlag::Max);\n\n\tvoltage_display_->set_unit(voltage_signal_->unit_name());\n\tvoltage_display_->set_unit_suffix(voltage_unit_suffix);\n\tvoltage_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(voltage_qfs, \"\\n\"));\n\tvoltage_display_->set_sr_digits(\n\t\tvoltage_signal_->total_digits(), voltage_signal_->sr_digits());\n\n\tvoltage_min_display_->set_unit(voltage_signal_->unit_name());\n\tvoltage_min_display_->set_unit_suffix(voltage_unit_suffix);\n\tvoltage_min_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(voltage_qfs_min, \"\\n\"));\n\tvoltage_min_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tvoltage_max_display_->set_unit(voltage_signal_->unit_name());\n\tvoltage_max_display_->set_unit_suffix(voltage_unit_suffix);\n\tvoltage_max_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(voltage_qfs_max, \"\\n\"));\n\tvoltage_max_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tQString current_unit_suffix(\"\");\n\tset<QuantityFlag> current_qfs = current_signal_->quantity_flags();\n\tif (current_qfs.count(QuantityFlag::AC) > 0) {\n\t\tcurrent_unit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tQuantityFlag::AC);\n\t\tcurrent_qfs.erase(QuantityFlag::AC);\n\t}\n\telse if (current_qfs.count(QuantityFlag::DC) > 0) {\n\t\tcurrent_unit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tQuantityFlag::DC);\n\t\tcurrent_qfs.erase(QuantityFlag::DC);\n\t}\n\tset<QuantityFlag> current_qfs_min = current_qfs;\n\tcurrent_qfs_min.insert(QuantityFlag::Min);\n\tset<QuantityFlag> current_qfs_max = current_qfs;\n\tcurrent_qfs_max.insert(QuantityFlag::Max);\n\n\tcurrent_display_->set_unit(current_signal_->unit_name());\n\tcurrent_display_->set_unit_suffix(current_unit_suffix);\n\tcurrent_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(current_qfs, \"\\n\"));\n\tcurrent_display_->set_sr_digits(\n\t\tcurrent_signal_->total_digits(), current_signal_->sr_digits());\n\n\tcurrent_min_display_->set_unit(current_signal_->unit_name());\n\tcurrent_min_display_->set_unit_suffix(current_unit_suffix);\n\tcurrent_min_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(current_qfs_min, \"\\n\"));\n\tcurrent_min_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tcurrent_max_display_->set_unit(current_signal_->unit_name());\n\tcurrent_max_display_->set_unit_suffix(current_unit_suffix);\n\tcurrent_max_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(current_qfs_max, \"\\n\"));\n\tcurrent_max_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tresistance_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\tresistance_min_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\tresistance_max_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tpower_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\tpower_min_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\tpower_max_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tamp_hour_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\twatt_hour_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n}\n\nvoid PowerPanelView::connect_signals()\n{\n\tif (!voltage_signal_ || !current_signal_)\n\t\treturn;\n\n\tconnect(voltage_signal_.get(), &data::AnalogBaseSignal::digits_changed,\n\t\tthis, &PowerPanelView::on_digits_changed);\n\tconnect(current_signal_.get(), &data::AnalogBaseSignal::digits_changed,\n\t\tthis, &PowerPanelView::on_digits_changed);\n}\n\nvoid PowerPanelView::disconnect_signals()\n{\n\tif (voltage_signal_) {\n\t\tdisconnect(\n\t\t\tvoltage_signal_.get(), &data::AnalogBaseSignal::digits_changed,\n\t\t\tthis, &PowerPanelView::on_digits_changed);\n\t}\n\tif (current_signal_) {\n\t\tdisconnect(\n\t\t\tcurrent_signal_.get(), &data::AnalogBaseSignal::digits_changed,\n\t\t\tthis, &PowerPanelView::on_digits_changed);\n\t}\n}\n\nvoid PowerPanelView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\n\tif (voltage_signal_)\n\t\tSettingsManager::save_signal(voltage_signal_, settings, origin_device, \"v_\");\n\tif (current_signal_)\n\t\tSettingsManager::save_signal(current_signal_, settings, origin_device, \"i_\");\n}\n\nvoid PowerPanelView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\n\tauto v_signal = SettingsManager::restore_signal(\n\t\tsession_, settings, origin_device, \"v_\");\n\tauto i_signal = SettingsManager::restore_signal(\n\t\tsession_, settings, origin_device, \"i_\");\n\tif (v_signal && i_signal) {\n\t\tset_signals(\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(v_signal),\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(i_signal));\n\t}\n}\n\nvoid PowerPanelView::reset_displays()\n{\n\tvoltage_display_->reset_value();\n\tvoltage_min_display_->reset_value();\n\tvoltage_max_display_->reset_value();\n\n\tcurrent_display_->reset_value();\n\tcurrent_min_display_->reset_value();\n\tcurrent_max_display_->reset_value();\n\n\tresistance_display_->reset_value();\n\tresistance_min_display_->reset_value();\n\tresistance_max_display_->reset_value();\n\n\tpower_display_->reset_value();\n\tpower_min_display_->reset_value();\n\tpower_max_display_->reset_value();\n\n\tamp_hour_display_->reset_value();\n\twatt_hour_display_->reset_value();\n}\n\nvoid PowerPanelView::init_timer()\n{\n\tstart_time_ = QDateTime::currentMSecsSinceEpoch();\n\tlast_time_ = start_time_;\n\n\tvoltage_min_ = std::numeric_limits<double>::max();\n\tvoltage_max_ = std::numeric_limits<double>::lowest();\n\tcurrent_min_ = std::numeric_limits<double>::max();\n\tcurrent_max_ = std::numeric_limits<double>::lowest();\n\tresistance_min_ = std::numeric_limits<double>::max();\n\tresistance_max_ = std::numeric_limits<double>::lowest();\n\tpower_min_ = std::numeric_limits<double>::max();\n\tpower_max_ = std::numeric_limits<double>::lowest();\n\tactual_amp_hours_ = 0;\n\tactual_watt_hours_ = 0;\n\n\tconnect(timer_, &QTimer::timeout, this, &PowerPanelView::on_update);\n\ttimer_->start(250);\n}\n\nvoid PowerPanelView::stop_timer()\n{\n\tif (!timer_->isActive())\n\t\treturn;\n\n\ttimer_->stop();\n\tdisconnect(timer_, &QTimer::timeout, this, &PowerPanelView::on_update);\n\n\treset_displays();\n}\n\nvoid PowerPanelView::on_update()\n{\n\tif (!voltage_signal_ || voltage_signal_->sample_count() == 0 ||\n\t\t\t!current_signal_ || current_signal_->sample_count() == 0)\n\t\treturn;\n\n\tqint64 now = QDateTime::currentMSecsSinceEpoch();\n\tdouble elapsed_time = (double)(now - last_time_) / (double)3600000; // / 1h\n\tlast_time_ = now;\n\n\tdouble voltage = voltage_signal_->last_value();\n\tif (voltage_min_ > voltage)\n\t\tvoltage_min_ = voltage;\n\tif (voltage_max_ < voltage)\n\t\tvoltage_max_ = voltage;\n\n\tdouble current = current_signal_->last_value();\n\tif (current_min_ > current)\n\t\tcurrent_min_ = current;\n\tif (current_max_ < current)\n\t\tcurrent_max_ = current;\n\n\tdouble resistance = current == 0. ?\n\t\tstd::numeric_limits<double>::max() : voltage / current;\n\tif (resistance_min_ > resistance)\n\t\tresistance_min_ = resistance;\n\tif (resistance_max_ < resistance)\n\t\tresistance_max_ = resistance;\n\n\tdouble power = voltage * current;\n\tif (power_min_ > power)\n\t\tpower_min_ = power;\n\tif (power_max_ < power)\n\t\tpower_max_ = power;\n\n\tactual_amp_hours_ = actual_amp_hours_ + (current * elapsed_time);\n\tactual_watt_hours_ = actual_watt_hours_ + (power * elapsed_time);\n\n\tvoltage_display_->set_value(voltage);\n\tvoltage_min_display_->set_value(voltage_min_);\n\tvoltage_max_display_->set_value(voltage_max_);\n\n\tcurrent_display_->set_value(current);\n\tcurrent_min_display_->set_value(current_min_);\n\tcurrent_max_display_->set_value(current_max_);\n\n\tresistance_display_->set_value(resistance);\n\tresistance_min_display_->set_value(resistance_min_);\n\tresistance_max_display_->set_value(resistance_max_);\n\n\tpower_display_->set_value(power);\n\tpower_min_display_->set_value(power_min_);\n\tpower_max_display_->set_value(power_max_);\n\n\tamp_hour_display_->set_value(actual_amp_hours_);\n\twatt_hour_display_->set_value(actual_watt_hours_);\n}\n\nvoid PowerPanelView::on_action_reset_displays_triggered()\n{\n\tstop_timer();\n\tinit_timer();\n}\n\nvoid PowerPanelView::on_digits_changed()\n{\n\tvoltage_display_->set_sr_digits(\n\t\tvoltage_signal_->total_digits(), voltage_signal_->sr_digits());\n\tcurrent_display_->set_sr_digits(\n\t\tcurrent_signal_->total_digits(), current_signal_->sr_digits());\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/powerpanelview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_POWERPANELVIEW_HPP\n#define UI_VIEWS_POWERPANELVIEW_HPP\n\n#include <memory>\n\n#include <QAction>\n#include <QSettings>\n#include <QTimer>\n#include <QToolBar>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace widgets {\nclass MonoFontDisplay;\n}\n\nnamespace views {\n\nclass PowerPanelView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit PowerPanelView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\t~PowerPanelView();\n\n\tQString title() const override;\n\tvoid set_signals(shared_ptr<sv::data::AnalogTimeSignal> voltage_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> current_signal);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tshared_ptr<sv::data::AnalogTimeSignal> voltage_signal_;\n\tshared_ptr<sv::data::AnalogTimeSignal> current_signal_;\n\n\tQTimer *timer_;\n\tqint64 start_time_;\n\tqint64 last_time_;\n\n\t// Min/max/actual values are stored here, so they can be reseted\n\tdouble voltage_min_;\n\tdouble voltage_max_;\n\tdouble current_min_;\n\tdouble current_max_;\n\tdouble resistance_min_;\n\tdouble resistance_max_;\n\tdouble power_min_;\n\tdouble power_max_;\n\tdouble actual_amp_hours_;\n\tdouble actual_watt_hours_;\n\n\tQAction *const action_reset_displays_;\n\tQToolBar *toolbar_;\n\twidgets::MonoFontDisplay *voltage_display_;\n\twidgets::MonoFontDisplay *voltage_min_display_;\n\twidgets::MonoFontDisplay *voltage_max_display_;\n\twidgets::MonoFontDisplay *current_display_;\n\twidgets::MonoFontDisplay *current_min_display_;\n\twidgets::MonoFontDisplay *current_max_display_;\n\twidgets::MonoFontDisplay *resistance_display_;\n\twidgets::MonoFontDisplay *resistance_min_display_;\n\twidgets::MonoFontDisplay *resistance_max_display_;\n\twidgets::MonoFontDisplay *power_display_;\n\twidgets::MonoFontDisplay *power_min_display_;\n\twidgets::MonoFontDisplay *power_max_display_;\n\twidgets::MonoFontDisplay *amp_hour_display_;\n\twidgets::MonoFontDisplay *watt_hour_display_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid init_displays();\n\tvoid connect_signals();\n\tvoid disconnect_signals();\n\tvoid reset_displays();\n\tvoid init_timer();\n\tvoid stop_timer();\n\nprivate Q_SLOTS:\n\tvoid on_update();\n\tvoid on_action_reset_displays_triggered();\n\tvoid on_digits_changed();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_POWERPANELVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/scopehorizontalcontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QFormLayout>\n#include <QSettings>\n#include <QUuid>\n\n#include \"scopehorizontalcontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/properties/baseproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/datatypes/boolcheckbox.hpp\"\n#include \"src/ui/datatypes/rationalcombobox.hpp\"\n#include \"src/ui/datatypes/uint64combobox.hpp\"\n#include \"src/ui/datatypes/uint64label.hpp\"\n#include \"src/ui/datatypes/uint64spinbox.hpp\"\n\nusing sv::devices::ConfigKey;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nScopeHorizontalControlView::ScopeHorizontalControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"scopehorizontalcontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n}\n\nQString ScopeHorizontalControlView::title() const\n{\n\treturn tr(\"Horizontal Control\") + \" \" + configurable_->display_name();\n}\n\nvoid ScopeHorizontalControlView::setup_ui()\n{\n\tQFormLayout *layout = new QFormLayout();\n\n\t// Samplerate\n\tsamplerate_label_ = new ui::datatypes::UInt64Label(\n\t\tconfigurable_->get_property(ConfigKey::Samplerate), true);\n\tlayout->addRow(tr(\"Samplerate\"), samplerate_label_);\n\n\t// Timebase\n\ttimebase_box_ = new ui::datatypes::RationalComboBox(\n\t\tconfigurable_->get_property(ConfigKey::TimeBase), true, true);\n\tlayout->addRow(tr(\"Timebase\"), timebase_box_);\n\n\t// Buffer\n\tbuffer_size_box_ = new ui::datatypes::UInt64ComboBox(\n\t\tconfigurable_->get_property(ConfigKey::BufferSize), true, true);\n\tlayout->addRow(tr(\"Buffer size\"), buffer_size_box_);\n\n\t// Average mode\n\taverage_check_ = new ui::datatypes::BoolCheckBox(\n\t\tconfigurable_->get_property(ConfigKey::Averaging), true, true);\n\tlayout->addRow(tr(\"Averaging\"), average_check_);\n\n\t// Average count\n\tauto avg_samples_prop = configurable_->get_property(ConfigKey::AvgSamples);\n\tif (avg_samples_prop->is_listable()) {\n\t\taverage_count_box_ = new ui::datatypes::UInt64ComboBox(\n\t\t\tavg_samples_prop, true, true);\n\t\tlayout->addRow(tr(\"Average count\"), average_count_box_);\n\t}\n\telse {\n\t\taverage_count_spin_ = new ui::datatypes::UInt64SpinBox(\n\t\t\tavg_samples_prop, true, true);\n\t\tlayout->addRow(tr(\"Average count\"), average_count_spin_);\n\t}\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid ScopeHorizontalControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid ScopeHorizontalControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nScopeHorizontalControlView *ScopeHorizontalControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new ScopeHorizontalControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/scopehorizontalcontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SCOPEHORIZONTALCONTROLVIEW_HPP\n#define UI_VIEWS_SCOPEHORIZONTALCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace datatypes {\nclass BoolCheckBox;\nclass RationalComboBox;\nclass UInt64ComboBox;\nclass UInt64Label;\nclass UInt64SpinBox;\n}\n\nnamespace views {\n\nclass ScopeHorizontalControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tScopeHorizontalControlView(Session& session,\n\t\tstd::shared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic ScopeHorizontalControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::datatypes::UInt64Label *samplerate_label_;\n\tui::datatypes::RationalComboBox *timebase_box_;\n\tui::datatypes::UInt64ComboBox *buffer_size_box_;\n\tui::datatypes::BoolCheckBox *average_check_;\n\tui::datatypes::UInt64ComboBox *average_count_box_;\n\tui::datatypes::UInt64SpinBox *average_count_spin_;\n\n\tvoid setup_ui();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SCOPEHORIZONTALCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/scopetriggercontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QFormLayout>\n#include <QSettings>\n#include <QUuid>\n\n#include \"scopetriggercontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n\nusing sv::devices::ConfigKey;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nScopeTriggerControlView::ScopeTriggerControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"scopetriggercontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n}\n\nQString ScopeTriggerControlView::title() const\n{\n\treturn tr(\"Trigger Control\") + \" \" + configurable_->display_name();\n}\n\nvoid ScopeTriggerControlView::setup_ui()\n{\n\tQFormLayout *layout = new QFormLayout();\n\n\t// Source\n\tsource_box_ = new ui::datatypes::StringComboBox(\n\t\tconfigurable_->get_property(ConfigKey::TriggerSource), true, true);\n\tlayout->addRow(tr(\"Source\"), source_box_);\n\n\t// Slope\n\tslope_box_ = new ui::datatypes::StringComboBox(\n\t\tconfigurable_->get_property(ConfigKey::TriggerSlope), true, true);\n\tlayout->addRow(tr(\"Slope\"), slope_box_);\n\n\t// Level\n\tlevel_spin_ = new ui::datatypes::DoubleSpinBox(\n\t\tconfigurable_->get_property(ConfigKey::TriggerLevel), true, true);\n\tlayout->addRow(tr(\"Level\"), level_spin_);\n\n\t// HPos\n\thpos_spin_ = new ui::datatypes::DoubleSpinBox(\n\t\tconfigurable_->get_property(ConfigKey::HorizTriggerPos), true, true);\n\tlayout->addRow(tr(\"Horiz. Pos\"), hpos_spin_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid ScopeTriggerControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid ScopeTriggerControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nScopeTriggerControlView *ScopeTriggerControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new ScopeTriggerControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/scopetriggercontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SCOPEHTRIGGERCONTROLVIEW_HPP\n#define UI_VIEWS_SCOPEHTRIGGERCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace datatypes {\nclass DoubleSpinBox;\nclass StringComboBox;\n}\n\nnamespace views {\n\nclass ScopeTriggerControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tScopeTriggerControlView(Session& session,\n\t\tstd::shared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic ScopeTriggerControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::datatypes::StringComboBox *source_box_;\n\tui::datatypes::StringComboBox *slope_box_;\n\tui::datatypes::DoubleSpinBox *level_spin_;\n\tui::datatypes::DoubleSpinBox *hpos_spin_;\n\n\tvoid setup_ui();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SCOPEHTRIGGERCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/scopeverticalcontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QFormLayout>\n#include <QSettings>\n#include <QUuid>\n\n#include \"scopeverticalcontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/ui/datatypes/boolcheckbox.hpp\"\n#include \"src/ui/datatypes/rationalcombobox.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n#include \"src/ui/datatypes/uint64combobox.hpp\"\n\nusing sv::devices::ConfigKey;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nScopeVerticalControlView::ScopeVerticalControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"scopeverticalcontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n}\n\nQString ScopeVerticalControlView::title() const\n{\n\treturn tr(\"Vertical Control\") + \" \" + configurable_->display_name();\n}\n\nvoid ScopeVerticalControlView::setup_ui()\n{\n\tQFormLayout *layout = new QFormLayout();\n\n\t// Enable channel\n\tenable_check_ = new ui::datatypes::BoolCheckBox(\n\t\tconfigurable_->get_property(ConfigKey::Enabled), true, true);\n\tlayout->addRow(tr(\"Enable\"), enable_check_);\n\n\t// VDiv\n\tvdiv_box_ = new ui::datatypes::RationalComboBox(\n\t\tconfigurable_->get_property(ConfigKey::VDiv), true, true);\n\tlayout->addRow(tr(\"VDiv\"), vdiv_box_);\n\n\t// Coupling\n\tcoupling_box_ = new ui::datatypes::StringComboBox(\n\t\tconfigurable_->get_property(ConfigKey::Coupling), true, true);\n\tlayout->addRow(tr(\"Coupling\"), coupling_box_);\n\n\t// Filter\n\tfilter_check_ = new ui::datatypes::BoolCheckBox(\n\t\tconfigurable_->get_property(ConfigKey::Filter), true, true);\n\tlayout->addRow(tr(\"Filter\"), filter_check_);\n\n\t// Probe factor\n\tprobe_factor_box_ = new ui::datatypes::UInt64ComboBox(\n\t\tconfigurable_->get_property(ConfigKey::ProbeFactor), true, true);\n\tlayout->addRow(tr(\"Probe\"), probe_factor_box_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid ScopeVerticalControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid ScopeVerticalControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nScopeVerticalControlView *ScopeVerticalControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (configurable)\n\t\treturn new ScopeVerticalControlView(session, configurable, uuid);\n\treturn nullptr;\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/scopeverticalcontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SCOPEVERTICALCONTROLVIEW_HPP\n#define UI_VIEWS_SCOPEVERTICALCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace datatypes {\nclass BoolCheckBox;\nclass RationalComboBox;\nclass StringComboBox;\nclass UInt64ComboBox;\n}\n\nnamespace views {\n\nclass ScopeVerticalControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tScopeVerticalControlView(Session& session,\n\t\tstd::shared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic ScopeVerticalControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::datatypes::BoolCheckBox *enable_check_;\n\tui::datatypes::RationalComboBox *vdiv_box_;\n\tui::datatypes::StringComboBox *coupling_box_;\n\tui::datatypes::BoolCheckBox *filter_check_;\n\tui::datatypes::UInt64ComboBox *probe_factor_box_;\n\n\tvoid setup_ui();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SCOPEVERTICALCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/sequenceoutputview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cmath>\n#include <fstream>\n#include <memory>\n#include <string>\n#include <vector>\n\n#include <QAction>\n#include <QCheckBox>\n#include <QDebug>\n#include <QDoubleSpinBox>\n#include <QFile>\n#include <QFileDialog>\n#include <QFormLayout>\n#include <QHBoxLayout>\n#include <QHeaderView>\n#include <QLabel>\n#include <QList>\n#include <QLocale>\n#include <QMessageBox>\n#include <QSettings>\n#include <QSpinBox>\n#include <QString>\n#include <QStringList>\n#include <QTableWidget>\n#include <QTableWidgetItem>\n#include <QTextStream>\n#include <QTimer>\n#include <QToolBar>\n#include <QUuid>\n#include <QVariant>\n#include <QVBoxLayout>\n\n#include \"sequenceoutputview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/properties/doubleproperty.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/datatypes/doublespinbox.hpp\"\n#include \"src/ui/dialogs/generatewaveformdialog.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nDoubleSpinBoxDelegate::DoubleSpinBoxDelegate(\n\t\tdouble min, double max, double step, int decimals, QObject *parent) :\n\tQStyledItemDelegate(parent),\n\tmin_(min),\n\tmax_(max),\n\tstep_(step),\n\tdecimals_(decimals)\n{\n}\n\nQWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\t(void)option;\n\t(void)index;\n\tQDoubleSpinBox *editor = new QDoubleSpinBox(parent);\n\teditor->setFrame(false);\n\teditor->setMinimum(min_);\n\teditor->setMaximum(max_);\n\teditor->setSingleStep(step_);\n\teditor->setDecimals(decimals_);\n\treturn editor;\n}\n\nQString DoubleSpinBoxDelegate::displayText(\n\tconst QVariant &value, const QLocale &locale) const\n{\n\t(void)locale;\n\treturn QString(\"%L1\").arg(value.toDouble(), 0, 'f', decimals_);\n}\n\nvoid DoubleSpinBoxDelegate::setEditorData(QWidget *editor,\n\tconst QModelIndex &index) const\n{\n\tdouble value = index.model()->data(index, Qt::EditRole).toDouble();\n\tQDoubleSpinBox *spin_box = qobject_cast<QDoubleSpinBox *>(editor);\n\tspin_box->setValue(value);\n}\n\nvoid DoubleSpinBoxDelegate::setModelData(QWidget *editor,\n\tQAbstractItemModel *model, const QModelIndex &index) const\n{\n\tQDoubleSpinBox *spin_box = qobject_cast<QDoubleSpinBox *>(editor);\n\tspin_box->interpretText();\n\tmodel->setData(index, QVariant(spin_box->value()), Qt::EditRole);\n}\n\nvoid DoubleSpinBoxDelegate::updateEditorGeometry(QWidget *editor,\n\tconst QStyleOptionViewItem &option, const QModelIndex &index) const\n{\n\t(void)index;\n\teditor->setGeometry(option.rect);\n}\n\n\nSequenceOutputView::SequenceOutputView(Session &session, QUuid uuid,\n\t\tQWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tproperty_(nullptr),\n\taction_run_(new QAction(this)),\n\taction_add_row_(new QAction(this)),\n\taction_delete_row_(new QAction(this)),\n\taction_delete_all_(new QAction(this)),\n\taction_load_from_file_(new QAction(this)),\n\taction_generate_waveform_(new QAction(this)),\n\tsequence_pos_(0)\n{\n\tid_ = \"sequenceoutput:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tsetup_toolbar();\n\n\ttimer_ = new QTimer(this);\n}\n\nSequenceOutputView::~SequenceOutputView()\n{\n\tstop_timer();\n}\n\nQString SequenceOutputView::title() const\n{\n\tQString title = tr(\"Sequence Output\");\n\tif (property_)\n\t\ttitle = title.append(\" \").append(property_->display_name());\n\treturn title;\n}\n\nvoid SequenceOutputView::set_property(\n\tshared_ptr<data::properties::DoubleProperty> property)\n{\n\tassert(property);\n\n\tstop_timer();\n\n\tproperty_ = property;\n\tsequence_table_->setItemDelegateForColumn(0,\n\t\tnew DoubleSpinBoxDelegate(property_->min(), property_->max(),\n\t\t\tproperty_->step(), property_->decimal_places()));\n\n\tQ_EMIT title_changed();\n}\n\nvoid SequenceOutputView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQHBoxLayout *repeat_layout = new QHBoxLayout();\n\trepeat_layout->addWidget(new QLabel(tr(\"Repeat\")));\n\trepeat_layout->addSpacing(8);\n\trepeat_infinite_box_ = new QCheckBox(tr(\"infinite\"));\n\trepeat_infinite_box_->setChecked(true);\n\tconnect(repeat_infinite_box_, &QCheckBox::stateChanged,\n\t\tthis, &SequenceOutputView::on_repeat_infinite_changed);\n\trepeat_layout->addWidget(repeat_infinite_box_);\n\trepeat_layout->addSpacing(8);\n\trepeat_count_box_ = new QSpinBox();\n\trepeat_count_box_->setValue(1);\n\trepeat_count_box_->setMinimum(1);\n\trepeat_count_box_->setMaximum(1000000);\n\trepeat_count_box_->setSuffix(tr(\" cycle(s)\"));\n\trepeat_count_box_->setDisabled(true);\n\trepeat_layout->addWidget(repeat_count_box_);\n\trepeat_layout->addStretch(1);\n\tlayout->addItem(repeat_layout);\n\n\tsequence_table_ = new QTableWidget();\n\tsequence_table_->setColumnCount(2);\n\tQTableWidgetItem *value_header_item = new QTableWidgetItem(tr(\"Value\"));\n\tsequence_table_->setHorizontalHeaderItem(0, value_header_item);\n\tsequence_table_->horizontalHeader()->setSectionResizeMode(\n\t\t0, QHeaderView::Stretch);\n\tQTableWidgetItem *delay_header_item = new QTableWidgetItem(tr(\"Delay [s]\"));\n\tsequence_table_->setHorizontalHeaderItem(1, delay_header_item);\n\tsequence_table_->horizontalHeader()->setSectionResizeMode(\n\t\t1, QHeaderView::Stretch);\n\tsequence_table_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);\n\n\tsequence_table_->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);\n\tsequence_table_->setItemDelegateForColumn(1,\n\t\tnew DoubleSpinBoxDelegate(0, 100000, 0.1, 3));\n\n\t//sequence_table_->setRowCount(1);\n\tlayout->addWidget(sequence_table_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid SequenceOutputView::setup_toolbar()\n{\n\taction_run_->setText(tr(\"Run generator\"));\n\taction_run_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\tQIcon(\":/icons/media-playback-start.png\")));\n\taction_run_->setCheckable(true);\n\taction_run_->setChecked(false);\n\tconnect(action_run_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_run_triggered);\n\n\taction_add_row_->setText(tr(\"Insert row\"));\n\taction_add_row_->setIcon(\n\t\tQIcon::fromTheme(\"edit-table-insert-row-under\",\n\t\tQIcon(\":/icons/edit-table-insert-row-under.png\")));\n\tconnect(action_add_row_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_add_row);\n\n\taction_delete_row_->setText(tr(\"Delete row\"));\n\taction_delete_row_->setIcon(\n\t\tQIcon::fromTheme(\"edit-table-delete-row\",\n\t\tQIcon(\":/icons/edit-table-delete-row.png\")));\n\tconnect(action_delete_row_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_delete_row);\n\n\taction_delete_all_->setText(tr(\"Delete all\"));\n\taction_delete_all_->setIcon(\n\t\tQIcon::fromTheme(\"edit-delete\",\n\t\tQIcon(\":/icons/edit-delete.png\")));\n\tconnect(action_delete_all_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_delete_all);\n\n\taction_load_from_file_->setText(tr(\"Load from file\"));\n\taction_load_from_file_->setIcon(\n\t\tQIcon::fromTheme(\"document-open\",\n\t\tQIcon(\":/icons/document-open.png\")));\n\tconnect(action_load_from_file_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_load_from_file_triggered);\n\n\taction_generate_waveform_->setText(tr(\"Run generator\"));\n\taction_generate_waveform_->setIcon(\n\t\tQIcon::fromTheme(\"office-chart-line\", // TODO: better icon\n\t\tQIcon(\":/icons/office-chart-line.png\")));\n\tconnect(action_generate_waveform_, &QAction::triggered,\n\t\tthis, &SequenceOutputView::on_action_generate_waveform_triggered);\n\n\ttoolbar_ = new QToolBar(\"Generator Toolbar\");\n\ttoolbar_->addAction(action_run_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_add_row_);\n\ttoolbar_->addAction(action_delete_row_);\n\ttoolbar_->addAction(action_delete_all_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_load_from_file_);\n\ttoolbar_->addAction(action_generate_waveform_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid SequenceOutputView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\n\tif (!property_)\n\t\treturn;\n\tSettingsManager::save_property(property_, settings, origin_device);\n\n\tsettings.setValue(\"repeat_infinite\",\n\t\tQVariant(repeat_infinite_box_->checkState()));\n\tsettings.setValue(\"repeat_count\", QVariant(repeat_count_box_->value()));\n\n\t// Save sequence\n\tint row_count = sequence_table_->rowCount();\n\tsettings.setValue(\"sequence_row_count\", QVariant(row_count));\n\tfor (int pos=0; pos<row_count; pos++) {\n\t\tQTableWidgetItem *value_item = sequence_table_->item(pos, 0);\n\t\tQTableWidgetItem *delay_item = sequence_table_->item(pos, 1);\n\t\tif (!value_item || !delay_item)\n\t\t\tcontinue;\n\n\t\tsettings.beginGroup(QString(\"sequence_\").append(QString::number(pos)));\n\t\tsettings.setValue(\"value\", value_item->data(0));\n\t\tsettings.setValue(\"delay\", delay_item->data(0));\n\t\tsettings.endGroup();\n\t}\n}\n\nvoid SequenceOutputView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\n\tauto property = SettingsManager::restore_property(\n\t\tsession_, settings, origin_device);\n\tif (!property)\n\t\treturn;\n\tset_property(\n\t\tdynamic_pointer_cast<sv::data::properties::DoubleProperty>(property));\n\n\tif (settings.contains(\"repeat_infinite\"))\n\t\trepeat_infinite_box_->setCheckState(\n\t\t\tsettings.value(\"repeat_infinite\").value<Qt::CheckState>());\n\tif (settings.contains(\"repeat_count\"))\n\t\trepeat_count_box_->setValue(settings.value(\"repeat_count\").toInt());\n\n\t// Restore sequence\n\tint row_count = settings.value(\"sequence_row_count\").toInt();\n\tfor (int pos=0; pos<row_count; pos++) {\n\t\tsettings.beginGroup(QString(\"sequence_\").append(QString::number(pos)));\n\t\tQVariant value = settings.value(\"value\");\n\t\tQVariant delay = settings.value(\"delay\");\n\t\tsequence_table_->insertRow(pos);\n\t\tQTableWidgetItem *value_item = new QTableWidgetItem(QString::number(\n\t\t\tvalue.toDouble(), 'f', 3));\n\t\tvalue_item->setData(0, value);\n\t\tsequence_table_->setItem(pos, 0, value_item);\n\t\tQTableWidgetItem *delay_item = new QTableWidgetItem(QString::number(\n\t\t\tdelay.toDouble(), 'f', property_->decimal_places()));\n\t\tdelay_item->setData(0, delay);\n\t\tsequence_table_->setItem(pos, 1, delay_item);\n\t\tsettings.endGroup();\n\t}\n}\n\nvoid SequenceOutputView::start_timer()\n{\n\tif (timer_->isActive()) {\n\t\ttimer_->stop();\n\t\tdisconnect(timer_, &QTimer::timeout,\n\t\t\tthis, &SequenceOutputView::on_timer_update);\n\t}\n\n\tsequence_pos_ = 0;\n\tsequence_reperat_count_ = 0;\n\tif (sequence_table_->rowCount() == 0)\n\t\treturn;\n\n\tconnect(timer_, &QTimer::timeout,\n\t\tthis, &SequenceOutputView::on_timer_update);\n\ttimer_->start();\n\n\taction_run_->setText(tr(\"Stop\"));\n\taction_run_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-stop\",\n\t\tQIcon(\":/icons/media-playback-stop.png\")));\n\taction_run_->setChecked(true);\n}\n\nvoid SequenceOutputView::stop_timer()\n{\n\taction_run_->setText(tr(\"Run\"));\n\taction_run_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\tQIcon(\":/icons/media-playback-start.png\")));\n\taction_run_->setChecked(false);\n\n\tif (!timer_->isActive())\n\t\treturn;\n\n\ttimer_->stop();\n\tdisconnect(timer_, &QTimer::timeout,\n\t\tthis, &SequenceOutputView::on_timer_update);\n\tsequence_pos_ = 0;\n\tsequence_reperat_count_ = 0;\n}\n\nvoid SequenceOutputView::insert_row(int row, double value, double delay)\n{\n\tif (!property_) {\n\t\tQMessageBox::warning(this, tr(\"No property assigned.\"),\n\t\t\ttr(\"Please assign a property to this sequence output view first.\"),\n\t\t\tQMessageBox::Ok);\n\t}\n\n\tsequence_table_->insertRow(row);\n\tQTableWidgetItem *value_item = new QTableWidgetItem(\n\t\tQString::number(value, 'f', 3));\n\tvalue_item->setData(0, QVariant(value));\n\tsequence_table_->setItem(row, 0, value_item);\n\tQTableWidgetItem *delay_item = new QTableWidgetItem(\n\t\tQString::number(delay, 'f', property_->decimal_places()));\n\tdelay_item->setData(0, QVariant(delay));\n\tsequence_table_->setItem(row, 1, delay_item);\n}\n\nvoid SequenceOutputView::on_timer_update()\n{\n\tif (!property_) {\n\t\tstop_timer();\n\t\treturn;\n\t}\n\n\tbool found_value = sequence_pos_ > 0;\n\tdouble value = .0;\n\tint delay_ms = 0;\n\t// Cycle through the row until a duration is found.\n\tdo {\n\t\tif (sequence_table_->rowCount() == 0) {\n\t\t\tstop_timer();\n\t\t\treturn;\n\t\t}\n\t\tif (sequence_pos_ >= sequence_table_->rowCount()) {\n\t\t\t// Jump up to the first row\n\t\t\tsequence_pos_ = 0;\n\t\t\tif (!found_value) {\n\t\t\t\tstop_timer();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!repeat_infinite_box_->isChecked()) {\n\t\t\t\tsequence_reperat_count_++;\n\t\t\t\tif (sequence_reperat_count_ >= repeat_count_box_->value()) {\n\t\t\t\t\tstop_timer();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tQTableWidgetItem *value_item = sequence_table_->item(sequence_pos_, 0);\n\t\tif (value_item)\n\t\t\tvalue = value_item->data(0).toDouble();\n\t\tQTableWidgetItem *delay_item = sequence_table_->item(sequence_pos_, 1);\n\t\tif (delay_item)\n\t\t\tdelay_ms = (int)std::round(delay_item->data(0).toDouble() * 1000);\n\n\t\tsequence_table_->selectRow(sequence_pos_);\n\t\tsequence_pos_++;\n\t}\n\twhile (delay_ms <= 0);\n\n\tproperty_->change_value(value);\n\ttimer_->setInterval(delay_ms);\n}\n\nvoid SequenceOutputView::on_repeat_infinite_changed()\n{\n\tif (repeat_infinite_box_->isChecked())\n\t\trepeat_count_box_->setDisabled(true);\n\telse\n\t\trepeat_count_box_->setDisabled(false);\n}\n\nvoid SequenceOutputView::on_action_run_triggered()\n{\n\tif (action_run_->isChecked())\n\t\tstart_timer();\n\telse\n\t\tstop_timer();\n}\n\nvoid SequenceOutputView::on_action_add_row()\n{\n\tint row = sequence_table_->currentRow() + 1;\n\tinsert_row(row, .0, .0);\n}\n\nvoid SequenceOutputView::on_action_delete_row()\n{\n\t// NOTE: If the cells are empty, there is no item to be returned by\n\t//       selectedItems() and selectedIndexes() is protected...\n\tconst auto items = sequence_table_->selectedItems();\n\tfor (const auto &item : items) {\n\t\tsequence_table_->removeRow(item->row());\n\t}\n}\n\nvoid SequenceOutputView::on_action_delete_all()\n{\n\tsequence_table_->setRowCount(0);\n}\n\nvoid SequenceOutputView::on_action_load_from_file_triggered()\n{\n\tQString file_name = QFileDialog::getOpenFileName(this,\n\t\ttr(\"Open Sequence-File\"), QDir::homePath(), tr(\"CSV Files (*.csv)\"));\n\tif (file_name.length() <= 0)\n\t\treturn;\n\n\tstd::ifstream file(file_name.toStdString());\n\tif (file.is_open()) {\n\t\tstring line;\n\t\tint row = 0;\n\t\twhile (std::getline(file, line)) {\n\t\t\tauto fields = sv::util::parse_csv_line(line);\n\n\t\t\t// TODO: Define CSV file format somehow/somewhere...\n\t\t\t// TODO: Parse header\n\t\t\tif (fields.size() < 2)\n\t\t\t\tcontinue;\n\t\t\tbool ok;\n\t\t\t// NOTE: QString::toDouble() to avoid locales and use the C locale\n\t\t\tdouble value = QString::fromStdString(fields[0]).toDouble(&ok);\n\t\t\tif (!ok)\n\t\t\t\tcontinue;\n\t\t\t// NOTE: QString::toDouble() to avoid locales and use the C locale\n\t\t\tdouble delay = QString::fromStdString(fields[1]).toDouble(&ok);\n\t\t\tif (!ok)\n\t\t\t\tcontinue;\n\n\t\t\tinsert_row(row, value, delay);\n\t\t\trow++;\n\t\t}\n\t}\n\tfile.close();\n}\n\nvoid SequenceOutputView::on_action_generate_waveform_triggered()\n{\n\tif (!property_) {\n\t\tQMessageBox::warning(this, tr(\"No property assigned.\"),\n\t\t\ttr(\"Please assign a property to this sequence output view first.\"),\n\t\t\tQMessageBox::Ok);\n\t}\n\n\tui::dialogs::GenerateWaveformDialog dlg(property_);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tvector<double> sequence_values = dlg.sequence_values();\n\tvector<double> sequence_delays = dlg.sequence_delays();\n\tfor (size_t i=0; i<sequence_values.size(); ++i) {\n\t\tinsert_row(static_cast<int>(i), sequence_values[i], sequence_delays[i]);\n\t}\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/sequenceoutputview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SEQUENCEOUTPUTVIEW_HPP\n#define UI_VIEWS_SEQUENCEOUTPUTVIEW_HPP\n\n#include <memory>\n\n#include <QAction>\n#include <QCheckBox>\n#include <QLocale>\n#include <QSettings>\n#include <QSpinBox>\n#include <QString>\n#include <QStringList>\n#include <QStyledItemDelegate>\n#include <QTableWidget>\n#include <QTimer>\n#include <QToolBar>\n#include <QUuid>\n#include <QVariant>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nnamespace properties {\nclass DoubleProperty;\n}\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass DoubleSpinBoxDelegate : public QStyledItemDelegate\n{\n\tQ_OBJECT\n\npublic:\n\tDoubleSpinBoxDelegate(double min, double max, double step, int decimals,\n\t\tQObject *parent = nullptr);\n\n\tQWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n\tQString displayText(const QVariant &value,\n\t\tconst QLocale &locale) const override;\n\tvoid setEditorData(QWidget *editor,\n\t\tconst QModelIndex &index) const override;\n\tvoid setModelData(QWidget *editor, QAbstractItemModel *model,\n\t\tconst QModelIndex &index) const override;\n\tvoid updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,\n\t\tconst QModelIndex &index) const override;\n\nprivate:\n\tdouble min_;\n\tdouble max_;\n\tdouble step_;\n\tint decimals_;\n\n};\n\nclass SequenceOutputView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SequenceOutputView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\t~SequenceOutputView();\n\n\tQString title() const override;\n\tvoid set_property(shared_ptr<sv::data::properties::DoubleProperty> property);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tshared_ptr<sv::data::properties::DoubleProperty> property_;\n\tQAction *const action_run_;\n\tQAction *const action_add_row_;\n\tQAction *const action_delete_row_;\n\tQAction *const action_delete_all_;\n\tQAction *const action_load_from_file_;\n\tQAction *const action_generate_waveform_;\n\tQToolBar *toolbar_;\n\tQTimer *timer_;\n\tQCheckBox *repeat_infinite_box_;\n\tQSpinBox *repeat_count_box_;\n\tQTableWidget *sequence_table_;\n\tint sequence_pos_;\n\tint sequence_reperat_count_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid start_timer();\n\tvoid stop_timer();\n\tvoid insert_row(int row, double value, double delay);\n\tQStringList parse_csv_line(QString line);\n\nprivate Q_SLOTS:\n\tvoid on_timer_update();\n\tvoid on_repeat_infinite_changed();\n\tvoid on_action_run_triggered();\n\tvoid on_action_add_row();\n\tvoid on_action_delete_row();\n\tvoid on_action_delete_all();\n\tvoid on_action_load_from_file_triggered();\n\tvoid on_action_generate_waveform_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SEQUENCEOUTPUTVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/smuscriptoutputview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QAction>\n#include <QBrush>\n#include <QDebug>\n#include <QFontDatabase>\n#include <QPlainTextEdit>\n#include <QScrollBar>\n#include <QSettings>\n#include <QString>\n#include <QTextCharFormat>\n#include <QToolBar>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"smuscriptoutputview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nSmuScriptOutputView::SmuScriptOutputView(Session &session,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tauto_scroll_(true),\n\taction_auto_scroll_(new QAction(this)),\n\taction_clear_output_(new QAction(this))\n{\n\t// The uuid is ignored here to give all SmuScriptOutputViews the same look,\n\t// when restored from the settings.\n\tid_ = \"smuscriptoutput:\";\n\n\tsetup_ui();\n\tsetup_toolbar();\n}\n\nQString SmuScriptOutputView::title() const\n{\n\treturn tr(\"SmuScript Output\");\n}\n\nvoid SmuScriptOutputView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\toutput_edit_ = new QPlainTextEdit();\n\toutput_edit_->setReadOnly(true);\n\t// Same as QCodeEditor::initFont()\n\tauto font = QFontDatabase::systemFont(QFontDatabase::FixedFont);\n\tfont.setFixedPitch(true);\n\tfont.setPointSize(10);\n\toutput_edit_->setFont(font);\n\n\tlayout->addWidget(output_edit_);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid SmuScriptOutputView::setup_toolbar()\n{\n\taction_auto_scroll_->setText(tr(\"Auto scroll\"));\n\taction_auto_scroll_->setIcon(\n\t\tQIcon::fromTheme(\"go-bottom\",\n\t\tQIcon(\":/icons/go-bottom.png\")));\n\taction_auto_scroll_->setCheckable(true);\n\taction_auto_scroll_->setChecked(auto_scroll_);\n\tconnect(action_auto_scroll_, &QAction::triggered,\n\t\tthis, &SmuScriptOutputView::on_action_auto_scroll_triggered);\n\n\taction_clear_output_->setText(tr(\"Clear output\"));\n\taction_clear_output_->setIcon(\n\t\tQIcon::fromTheme(\"edit-delete\",\n\t\tQIcon(\":/icons/edit-delete.png\")));\n\tconnect(action_clear_output_, &QAction::triggered,\n\t\tthis, &SmuScriptOutputView::on_action_clear_output_triggered);\n\n\ttoolbar_ = new QToolBar(\"SmuScript Output Toolbar\");\n\ttoolbar_->addAction(action_auto_scroll_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_clear_output_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid SmuScriptOutputView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n}\n\nvoid SmuScriptOutputView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nvoid SmuScriptOutputView::scroll_to_bottom()\n{\n\toutput_edit_->verticalScrollBar()->setValue(\n\t\toutput_edit_->verticalScrollBar()->maximum());\n}\n\nvoid SmuScriptOutputView::append_out_text(const std::string &text)\n{\n\toutput_edit_->appendPlainText(QString::fromStdString(text));\n\tif (auto_scroll_)\n\t\tscroll_to_bottom();\n}\n\nvoid SmuScriptOutputView::append_err_text(const std::string &text)\n{\n\tQTextCharFormat tcf = output_edit_->currentCharFormat();\n\tQBrush old_brush = tcf.foreground();\n\ttcf.setForeground(QBrush(Qt::red));\n\toutput_edit_->setCurrentCharFormat(tcf);\n\toutput_edit_->appendPlainText(QString::fromStdString(text));\n\ttcf.setForeground(old_brush);\n\toutput_edit_->setCurrentCharFormat(tcf);\n\tif (auto_scroll_)\n\t\tscroll_to_bottom();\n}\n\nvoid SmuScriptOutputView::on_action_auto_scroll_triggered()\n{\n\tauto_scroll_ = !auto_scroll_;\n\taction_auto_scroll_->setChecked(auto_scroll_);\n}\n\nvoid SmuScriptOutputView::on_action_clear_output_triggered()\n{\n\toutput_edit_->clear();\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/smuscriptoutputview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SMUSCRIPTOUTPUTVIEW_HPP\n#define UI_VIEWS_SMUSCRIPTOUTPUTVIEW_HPP\n\n#include <memory>\n#include <string>\n\n#include <QAction>\n#include <QPlainTextEdit>\n#include <QSettings>\n#include <QString>\n#include <QToolBar>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass SmuScriptOutputView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SmuScriptOutputView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tbool auto_scroll_;\n\tQAction *const action_auto_scroll_;\n\tQAction *const action_clear_output_;\n\tQToolBar *toolbar_;\n\tQPlainTextEdit *output_edit_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid scroll_to_bottom();\n\npublic Q_SLOTS:\n\tvoid append_out_text(const std::string &text);\n\tvoid append_err_text(const std::string &text);\n\nprivate Q_SLOTS:\n\tvoid on_action_auto_scroll_triggered();\n\tvoid on_action_clear_output_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SMUSCRIPTOUTPUTVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/smuscripttreeview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QAbstractItemView>\n#include <QAction>\n#include <QFileInfo>\n#include <QDebug>\n#include <QFileSystemModel>\n#include <QMessageBox>\n#include <QModelIndex>\n#include <QSettings>\n#include <QString>\n#include <QTimer>\n#include <QToolBar>\n#include <QTreeView>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"smuscripttreeview.hpp\"\n#include \"src/mainwindow.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nSmuScriptTreeView::SmuScriptTreeView(Session &session,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\taction_new_script_(new QAction(this)),\n\taction_open_script_(new QAction(this)),\n\taction_run_script_(new QAction(this))\n{\n\tid_ = \"smuscripttree:\" + util::format_uuid(uuid_);\n\n\tQSettings settings;\n\tif (SettingsManager::restore_settings() &&\n\t\t\tsettings.childGroups().contains(\"SmuScriptTree\")) {\n\t\tSmuScriptTreeView::restore_settings(settings);\n\t}\n\telse\n\t\tscript_dir_ = QDir::homePath();\n\n\tsetup_ui();\n\tsetup_toolbar();\n\tconnect_signals();\n}\n\nQString SmuScriptTreeView::title() const\n{\n\treturn tr(\"SmuScript\");\n}\n\nvoid SmuScriptTreeView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tfile_system_model_ = new QFileSystemModel();\n\tfile_system_model_->setRootPath(\"\");\n\tfile_system_tree_ = new QTreeView();\n\tfile_system_tree_->setModel(file_system_model_);\n\tfile_system_tree_->setAnimated(false);\n\tfile_system_tree_->setIndentation(20);\n\tfile_system_tree_->setSortingEnabled(true);\n\tfile_system_tree_->sortByColumn(0, Qt::SortOrder::AscendingOrder);\n\tlayout->addWidget(file_system_tree_);\n\n\tlayout->setContentsMargins(2, 2, 2, 2);\n\n\tthis->central_widget_->setLayout(layout);\n\n\tfile_system_tree_->setColumnWidth(0, file_system_tree_->width());\n\n\t// NOTE: QFileSystemModel::index() doesn't return the correct row the first\n\t//       time or when call a second time directly after the first.\n\t//       Therefore it is called via a timer the second time.\n\tQModelIndex script_path_index = file_system_model_->index(script_dir_);\n\tfile_system_tree_->expand(script_path_index);\n\tfile_system_tree_->setCurrentIndex(script_path_index);\n\tQTimer::singleShot(250, this, &SmuScriptTreeView::scroll_to_script_dir);\n}\n\nvoid SmuScriptTreeView::setup_toolbar()\n{\n\taction_new_script_->setText(tr(\"New script\"));\n\taction_new_script_->setIconText(tr(\"New script\"));\n\taction_new_script_->setIcon(\n\t\tQIcon::fromTheme(\"document-new\",\n\t\tQIcon(\":/icons/document-new.png\")));\n\tconnect(action_new_script_, &QAction::triggered,\n\t\tthis, &SmuScriptTreeView::on_action_new_script_triggered);\n\n\taction_open_script_->setText(tr(\"Open script\"));\n\taction_open_script_->setIconText(tr(\"Open script\"));\n\taction_open_script_->setIcon(\n\t\tQIcon::fromTheme(\"document-open\",\n\t\tQIcon(\":/icons/document-open.png\")));\n\tconnect(action_open_script_, &QAction::triggered,\n\t\tthis, &SmuScriptTreeView::on_action_open_script_triggered);\n\n\taction_run_script_->setText(tr(\"Run script\"));\n\taction_run_script_->setIconText(tr(\"Run script\"));\n\taction_run_script_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\tQIcon(\":/icons/media-playback-start.png\")));\n\taction_run_script_->setCheckable(true);\n\tconnect(action_run_script_, &QAction::triggered,\n\t\tthis, &SmuScriptTreeView::on_action_run_script_triggered);\n\tif (session_.smu_script_runner()->is_running())\n\t\taction_run_script_->setChecked(true);\n\telse\n\t\taction_run_script_->setChecked(false);\n\n\ttoolbar_ = new QToolBar(\"SmuScript Toolbar\");\n\ttoolbar_->addAction(action_new_script_);\n\ttoolbar_->addAction(action_open_script_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_run_script_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid SmuScriptTreeView::connect_signals()\n{\n\tconnect(file_system_tree_, &QTreeView::doubleClicked,\n\t\tthis, &SmuScriptTreeView::on_tree_double_clicked);\n\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::script_started,\n\t\tthis, &SmuScriptTreeView::on_script_started);\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::script_finished,\n\t\tthis, &SmuScriptTreeView::on_script_finished);\n}\n\nvoid SmuScriptTreeView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tsettings.beginGroup(\"SmuScriptTree\");\n\tsettings.remove(\"\");  // Remove all keys in this group\n\n\tBaseView::save_settings(settings, origin_device);\n\n\tQModelIndex index = file_system_tree_->selectionModel()->currentIndex();\n\tif (index.isValid()) {\n\t\tQFileInfo file_info = file_system_model_->fileInfo(index);\n\t\tif (file_info.isDir())\n\t\t\tsettings.setValue(\"directory\", file_info.canonicalFilePath());\n\t\telse\n\t\t\tsettings.setValue(\"directory\", file_info.canonicalPath());\n\t}\n\telse\n\t\tsettings.setValue(\"directory\", script_dir_);\n\n\tsettings.endGroup();\n}\n\nvoid SmuScriptTreeView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tsettings.beginGroup(\"SmuScriptTree\");\n\n\tBaseView::restore_settings(settings, origin_device);\n\n\tif (settings.contains(\"directory\")) {\n\t\tscript_dir_ = settings.value(\"directory\").toString();\n\t\tif (!QFileInfo::exists(script_dir_))\n\t\t\tscript_dir_ = QDir::homePath();\n\t}\n\telse\n\t\tscript_dir_ = QDir::homePath();\n\n\tsettings.endGroup();\n}\n\nvoid SmuScriptTreeView::scroll_to_script_dir()\n{\n\tQModelIndex script_path_index = file_system_model_->index(script_dir_);\n\tfile_system_tree_->scrollTo(script_path_index, QAbstractItemView::PositionAtTop);\n}\n\nvoid SmuScriptTreeView::open_script_file(const QModelIndex &index)\n{\n\tif (!index.isValid())\n\t\treturn;\n\n\tQFileInfo file_info = file_system_model_->fileInfo(index);\n\tif (!file_info.isFile())\n\t\treturn;\n\tif (!file_info.fileName().endsWith(\".py\"))\n\t\treturn;\n\n\tsession().main_window()->add_smuscript_tab(\n\t\tfile_info.filePath().toStdString());\n}\n\nvoid SmuScriptTreeView::on_action_new_script_triggered()\n{\n\tsession().main_window()->add_smuscript_tab(\"\");\n}\n\nvoid SmuScriptTreeView::on_action_open_script_triggered()\n{\n\tQModelIndex index = file_system_tree_->selectionModel()->currentIndex();\n\topen_script_file(index);\n}\n\nvoid SmuScriptTreeView::on_action_run_script_triggered()\n{\n\tif (action_run_script_->isChecked()) {\n\t\tQModelIndex index = file_system_tree_->selectionModel()->currentIndex();\n\t\tif (index.isValid())\n\t\t\tsession_.smu_script_runner()->run(\n\t\t\t\tfile_system_model_->filePath(index).toStdString());\n\t}\n\telse\n\t\tsession_.smu_script_runner()->stop();\n}\n\nvoid SmuScriptTreeView::on_tree_double_clicked(const QModelIndex& index)\n{\n\topen_script_file(index);\n}\n\nvoid SmuScriptTreeView::on_script_started()\n{\n\taction_run_script_->setText(tr(\"Stop\"));\n\taction_run_script_->setIconText(tr(\"Stop\"));\n\taction_run_script_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-stop\",\n\t\tQIcon(\":/icons/media-playback-stop.png\")));\n\taction_run_script_->setChecked(true);\n}\n\nvoid SmuScriptTreeView::on_script_finished()\n{\n\taction_run_script_->setText(tr(\"Run\"));\n\taction_run_script_->setIconText(tr(\"Run\"));\n\taction_run_script_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\tQIcon(\":/icons/media-playback-start.png\")));\n\taction_run_script_->setChecked(false);\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n"
  },
  {
    "path": "src/ui/views/smuscripttreeview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SMUSCRIPTTREEVIEW_HPP\n#define UI_VIEWS_SMUSCRIPTTREEVIEW_HPP\n\n#include <memory>\n\n#include <QAction>\n#include <QFileSystemModel>\n#include <QModelIndex>\n#include <QSettings>\n#include <QString>\n#include <QToolBar>\n#include <QTreeView>\n#include <QUuid>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass SmuScriptTreeView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SmuScriptTreeView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tQAction *const action_new_script_;\n\tQAction *const action_open_script_;\n\tQAction *const action_run_script_;\n\tQString script_dir_;\n\tQToolBar *toolbar_;\n\tQFileSystemModel *file_system_model_;\n\tQTreeView *file_system_tree_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid connect_signals();\n\tvoid scroll_to_script_dir();\n\tvoid open_script_file(const QModelIndex& index);\n\nprivate Q_SLOTS:\n\tvoid on_action_new_script_triggered();\n\tvoid on_action_open_script_triggered();\n\tvoid on_action_run_script_triggered();\n\tvoid on_tree_double_clicked(const QModelIndex& index);\n\tvoid on_script_started();\n\tvoid on_script_finished();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SMUSCRIPTTREEVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/smuscriptview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QAction>\n#include <QDebug>\n#include <QDir>\n#include <QFileDialog>\n#include <QMessageBox>\n#include <QSettings>\n#include <QString>\n#include <QTextOption>\n#include <QTextStream>\n#include <QToolBar>\n#include <QUuid>\n#include <QVBoxLayout>\n#include <QVector>\n\n#include <QCodeEditor>\n#include <QPythonCompleter>\n#include <QPythonHighlighter>\n#include <findreplacedialog.h>\n\n#include \"smuscriptview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/python/smuscriptrunner.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nSmuScriptView::SmuScriptView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\taction_open_(new QAction(this)),\n\taction_save_(new QAction(this)),\n\taction_save_as_(new QAction(this)),\n\taction_run_(new QAction(this)),\n\taction_find_(new QAction(this)),\n\ttext_changed_(false),\n\tstarted_from_here_(false)\n{\n\t// The uuid is ignored here to give all SmuScriptViews the same look, when\n\t// restored from the settings.\n\tid_ = \"smuscript:\";\n\n\tsetup_ui();\n\tsetup_toolbar();\n\tconnect_signals();\n}\n\nQString SmuScriptView::title() const\n{\n\tif (script_file_name_.empty())\n\t\treturn tr(\"Untitled\");\n\n\tstd::size_t found = script_file_name_.find_last_of(\"/\\\\\");\n\treturn QString::fromStdString(script_file_name_.substr(found+1));\n}\n\nvoid SmuScriptView::load_file(const string &file_name)\n{\n\tif (file_name.empty())\n\t\treturn;\n\n\tQFile file(QString::fromStdString(file_name));\n\tif (file.open(QFile::ReadOnly | QFile::Text)) {\n\t\teditor_->setPlainText(file.readAll());\n\t\tfile.close();\n\n\t\ttext_changed_ = false;\n\t\tQ_EMIT file_save_state_changed(false);\n\t}\n\n\t// Check if filename has changed\n\tif (script_file_name_ != file_name) {\n\t\tscript_file_name_ = file_name;\n\t\tQ_EMIT file_name_changed(QString::fromStdString(file_name));\n\t}\n}\n\nbool SmuScriptView::ask_to_save(const QString &title)\n{\n\tif (!text_changed_)\n\t\treturn true;\n\n\tQMessageBox::StandardButton reply = QMessageBox::warning(this, title,\n\t\ttr(\"The file \\\"%1\\\" has unsaved changes. Would you like to save them?\").\n\t\t\targ(QString::fromStdString(script_file_name_)),\n\t\tQMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);\n\n\tif (reply == QMessageBox::Yes) {\n\t\tif (!this->save(QString::fromStdString(script_file_name_)))\n\t\t\treturn false;\n\t}\n\telse if (reply == QMessageBox::Cancel)\n\t\treturn false;\n\n\treturn true;\n}\n\nvoid SmuScriptView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\teditor_ = new QCodeEditor();\n\t//editor_->setSyntaxStyle();\n\teditor_->setCompleter(new QPythonCompleter);\n\teditor_->setHighlighter(new QPythonHighlighter);\n\teditor_->setAutoIndentation(true);\n\teditor_->setWordWrapMode(QTextOption::WordWrap);\n\t// NOTE: The extra bottom margin will mess up the textChanged() signal!\n\teditor_->setExtraBottomMargin(false);\n\tlayout->addWidget(editor_);\n\n\tthis->central_widget_->setLayout(layout);\n\n\tfind_dialog_ = new FindReplaceDialog(this);\n\tfind_dialog_->setModal(false);\n\tfind_dialog_->setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint |\n\t\tQt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint);\n\tfind_dialog_->setTextEdit(editor_);\n}\n\nvoid SmuScriptView::setup_toolbar()\n{\n\taction_open_->setText(tr(\"&Open\"));\n\taction_open_->setIconText(tr(\"Open\"));\n\taction_open_->setIcon(\n\t\tQIcon::fromTheme(\"document-open\",\n\t\tQIcon(\":/icons/document-open.png\")));\n\taction_open_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_O));\n\tconnect(action_open_, &QAction::triggered,\n\t\tthis, &SmuScriptView::on_action_open_triggered);\n\n\taction_save_->setText(tr(\"&Save\"));\n\taction_save_->setIconText(tr(\"Save\"));\n\taction_save_->setIcon(\n\t\tQIcon::fromTheme(\"document-save\",\n\t\tQIcon(\":/icons/document-save.png\")));\n\taction_save_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));\n\tconnect(action_save_, &QAction::triggered,\n\t\tthis, &SmuScriptView::on_action_save_triggered);\n\n\taction_save_as_->setText(tr(\"Save &As\"));\n\taction_save_as_->setIconText(tr(\"Save As\"));\n\taction_save_as_->setIcon(\n\t\tQIcon::fromTheme(\"document-save-as\",\n\t\tQIcon(\":/icons/document-save-as.png\")));\n\tconnect(action_save_as_, &QAction::triggered,\n\t\tthis, &SmuScriptView::on_action_save_as_triggered);\n\n\taction_run_->setText(tr(\"Run\"));\n\taction_run_->setIconText(tr(\"Run\"));\n\taction_run_->setIcon(\n\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\tQIcon(\":/icons/media-playback-start.png\")));\n\taction_run_->setCheckable(true);\n\taction_run_->setChecked(false);\n\tconnect(action_run_, &QAction::triggered,\n\t\tthis, &SmuScriptView::on_action_run_triggered);\n\tif (session_.smu_script_runner()->is_running())\n\t\taction_run_->setDisabled(true);\n\n\taction_find_->setText(tr(\"&Find and Replace\"));\n\taction_find_->setIconText(tr(\"Find and Replace\"));\n\taction_find_->setIcon(\n\t\tQIcon::fromTheme(\"edit-find\",\n\t\tQIcon(\":/icons/edit-find.png\")));\n\taction_find_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F));\n\tconnect(action_find_, &QAction::triggered,\n\t\tthis, &SmuScriptView::on_action_find_triggered);\n\n\ttoolbar_ = new QToolBar(\"SmuScript Toolbar\");\n\ttoolbar_->addAction(action_open_);\n\ttoolbar_->addAction(action_save_);\n\ttoolbar_->addAction(action_save_as_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_run_);\n\ttoolbar_->addSeparator();\n\ttoolbar_->addAction(action_find_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid SmuScriptView::connect_signals()\n{\n\tconnect(editor_, &QCodeEditor::textChanged,\n\t\tthis, &SmuScriptView::on_text_changed);\n\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::script_started,\n\t\tthis, &SmuScriptView::on_script_started);\n\tconnect(session_.smu_script_runner().get(), &python::SmuScriptRunner::script_finished,\n\t\tthis, &SmuScriptView::on_script_finished);\n}\n\nvoid SmuScriptView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tfind_dialog_->writeSettings(settings);\n}\n\nvoid SmuScriptView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\tfind_dialog_->readSettings(settings);\n}\n\nbool SmuScriptView::save(QString file_name)\n{\n\tif (file_name.length() <= 0) {\n\t\tfile_name = QFileDialog::getSaveFileName(this,\n\t\t\ttr(\"Save SmuScript-File\"),\n\t\t\tQDir::homePath(), tr(\"Python Files (*.py)\"));\n\t\tif (file_name.length() <= 0)\n\t\t\treturn false;\n\t}\n\n\tQFile file(file_name);\n\tif (file.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) {\n\t\tQTextStream stream(&file);\n\t\tstream << editor_->toPlainText();\n\t\tstream.flush();\n\t\tfile.close();\n\n\t\ttext_changed_ = false;\n\t\tQ_EMIT file_save_state_changed(false);\n\t}\n\telse {\n\t\tQMessageBox::critical(this, tr(\"File error\"),\n\t\t\ttr(\"Could not save to file \\\"%1\\\".\").arg(file_name),\n\t\t\tQMessageBox::Ok);\n\t\treturn false;\n\t}\n\n\t// Check if filename has changed\n\tif (script_file_name_ != file_name.toStdString()) {\n\t\tscript_file_name_ = file_name.toStdString();\n\t\tQ_EMIT file_name_changed(file_name);\n\t}\n\n\treturn true;\n}\n\nvoid SmuScriptView::run_script()\n{\n\tif (action_run_->isChecked()) {\n\t\t// Already running!\n\t\treturn;\n\t}\n\n\taction_run_->activate(QAction::Trigger);\n}\n\nvoid SmuScriptView::stop_script()\n{\n\tif (!action_run_->isChecked()) {\n\t\t// Not running!\n\t\treturn;\n\t}\n\n\taction_run_->activate(QAction::Trigger);\n}\n\nvoid SmuScriptView::on_action_open_triggered()\n{\n\tif (!ask_to_save(tr(\"Open new script file\")))\n\t\treturn;\n\n\tQString file_name = QFileDialog::getOpenFileName(this,\n\t\ttr(\"Open SmuScript-File\"), QDir::homePath(), tr(\"Python Files (*.py)\"));\n\tload_file(file_name.toStdString());\n}\n\nvoid SmuScriptView::on_action_save_triggered()\n{\n\tthis->save(QString::fromStdString(script_file_name_));\n}\n\nvoid SmuScriptView::on_action_save_as_triggered()\n{\n\tthis->save(\"\");\n}\n\nvoid SmuScriptView::on_action_find_triggered()\n{\n\tfind_dialog_->showDialog(editor_->textCursor().selectedText());\n}\n\nvoid SmuScriptView::on_text_changed()\n{\n\ttext_changed_ = true;\n\tQ_EMIT file_save_state_changed(true);\n}\n\nvoid SmuScriptView::on_action_run_triggered()\n{\n\tif (action_run_->isChecked()) {\n\t\tif (!ask_to_save(tr(\"File changed\")))\n\t\t\treturn;\n\n\t\taction_run_->setText(tr(\"Stop\"));\n\t\taction_run_->setIconText(tr(\"Stop\"));\n\t\taction_run_->setIcon(\n\t\t\tQIcon::fromTheme(\"media-playback-stop\",\n\t\t\tQIcon(\":/icons/media-playback-stop.png\")));\n\n\t\tstarted_from_here_ = true;\n\t\tsession_.smu_script_runner()->run(script_file_name_);\n\t}\n\telse {\n\t\taction_run_->setText(tr(\"Run\"));\n\t\taction_run_->setIconText(tr(\"Run\"));\n\t\taction_run_->setIcon(\n\t\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\t\tQIcon(\":/icons/media-playback-start.png\")));\n\n\t\tstarted_from_here_ = false;\n\t\tsession_.smu_script_runner()->stop();\n\t}\n}\n\nvoid SmuScriptView::on_script_started()\n{\n\tif (started_from_here_)\n\t\tQ_EMIT script_started();\n\telse\n\t\taction_run_->setDisabled(true);\n}\n\nvoid SmuScriptView::on_script_finished()\n{\n\tif (started_from_here_) {\n\t\taction_run_->setText(tr(\"Run\"));\n\t\taction_run_->setIconText(tr(\"Run\"));\n\t\taction_run_->setIcon(\n\t\t\tQIcon::fromTheme(\"media-playback-start\",\n\t\t\tQIcon(\":/icons/media-playback-start.png\")));\n\t\taction_run_->setChecked(false);\n\t\tstarted_from_here_ = false;\n\n\t\tQ_EMIT script_finished();\n\t}\n\telse\n\t\taction_run_->setDisabled(false);\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/smuscriptview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SMUSCRIPTVIEW_HPP\n#define UI_VIEWS_SMUSCRIPTVIEW_HPP\n\n#include <memory>\n#include <string>\n\n#include <QAction>\n#include <QSettings>\n#include <QToolBar>\n#include <QUuid>\n\n#include <QCodeEditor>\n#include <findreplacedialog.h>\n\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass SmuScriptView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit SmuScriptView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\tvoid load_file(const string &file_name);\n\tbool ask_to_save(const QString &title);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tstring script_file_name_;\n\tQAction *const action_open_;\n\tQAction *const action_save_;\n\tQAction *const action_save_as_;\n\tQAction *const action_run_;\n\tQAction *const action_find_;\n\tQToolBar *toolbar_;\n\tQCodeEditor *editor_;\n\tFindReplaceDialog *find_dialog_;\n\tbool text_changed_;\n\tbool started_from_here_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid connect_signals();\n\tbool save(QString file_name);\n\npublic Q_SLOTS:\n\tvoid run_script();\n\tvoid stop_script();\n\nprivate Q_SLOTS:\n\tvoid on_action_open_triggered();\n\tvoid on_action_save_triggered();\n\tvoid on_action_save_as_triggered();\n\tvoid on_action_run_triggered();\n\tvoid on_action_find_triggered();\n\tvoid on_text_changed();\n\tvoid on_script_started();\n\tvoid on_script_finished();\n\nQ_SIGNALS:\n\tvoid file_name_changed(const QString &file_name);\n\tvoid file_save_state_changed(bool is_unsaved);\n\tvoid script_started();\n\tvoid script_finished();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SMUSCRIPTVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/sourcesinkcontrolview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <string>\n\n#include <QDebug>\n#include <QSettings>\n#include <QSizePolicy>\n#include <QHBoxLayout>\n#include <QUuid>\n#include <QVBoxLayout>\n\n#include \"sourcesinkcontrolview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/datatypes/boolbutton.hpp\"\n#include \"src/ui/datatypes/boolled.hpp\"\n#include \"src/ui/datatypes/doublecontrol.hpp\"\n#include \"src/ui/datatypes/stringcombobox.hpp\"\n#include \"src/ui/datatypes/stringled.hpp\"\n#include \"src/ui/datatypes/thresholdcontrol.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n\nusing std::shared_ptr;\nusing sv::devices::ConfigKey;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nSourceSinkControlView::SourceSinkControlView(Session &session,\n\t\tshared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tconfigurable_(configurable)\n{\n\tid_ = \"sourcesinkcontrol:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n}\n\nQString SourceSinkControlView::title() const\n{\n\treturn tr(\"Control\") + \" \" + configurable_->display_name();\n}\n\nvoid SourceSinkControlView::setup_ui()\n{\n\tQIcon red_icon(\":/icons/status-red.svg\");\n\tQIcon green_icon(\":/icons/status-green.svg\");\n\tQIcon grey_icon(\":/icons/status-grey.svg\");\n\n\tQVBoxLayout *layout = new QVBoxLayout();\n\n\tQGridLayout *info_layout = new QGridLayout();\n\n\t// Enable button\n\tenable_button_ = new ui::datatypes::BoolButton(\n\t\tconfigurable_->get_property(ConfigKey::Enabled), true, true);\n\t//info_layout->addWidget(enable_button_, 0, 0, 2, 1,  Qt::AlignLeft);\n\tinfo_layout->addWidget(enable_button_, 0, 0, Qt::AlignLeft);\n\n\t// Regulation selector (sinks) / range selector (power supplies)\n\tif (configurable_->device_type() == devices::DeviceType::ElectronicLoad) {\n\t\tregulation_box_ = new ui::datatypes::StringComboBox(\n\t\t\tconfigurable_->get_property(ConfigKey::Regulation), true, true);\n\t\tinfo_layout->addWidget(regulation_box_, 1, 0, Qt::AlignLeft);\n\t}\n\telse if (configurable_->device_type() == devices::DeviceType::PowerSupply &&\n\t\t(configurable_->has_get_config(ConfigKey::Range) ||\n\t\tconfigurable_->has_set_config(ConfigKey::Range) ||\n\t\tconfigurable_->has_list_config(ConfigKey::Range))) {\n\n\t\trange_box_ = new ui::datatypes::StringComboBox(\n\t\t\tconfigurable_->get_property(ConfigKey::Range), true, true);\n\t\tinfo_layout->addWidget(range_box_, 1, 0, Qt::AlignLeft);\n\t}\n\n\t// Regulation indicators for power supplies\n\tif (configurable_->device_type() == devices::DeviceType::PowerSupply) {\n\t\tcv_led_ = new ui::datatypes::StringLed(\n\t\t\tconfigurable_->get_property(ConfigKey::Regulation),\n\t\t\ttrue, green_icon, grey_icon, grey_icon,\n\t\t\t\"CV\", \"\", tr(\"CV\"));\n\t\tinfo_layout->addWidget(cv_led_, 0, 1, Qt::AlignLeft);\n\t\tcc_led_ = new ui::datatypes::StringLed(\n\t\t\tconfigurable_->get_property(ConfigKey::Regulation),\n\t\t\ttrue, red_icon, grey_icon, grey_icon,\n\t\t\t\"CC\", \"\", tr(\"CC\"));\n\t\tinfo_layout->addWidget(cc_led_, 1, 1, Qt::AlignLeft);\n\t}\n\n\t// Protection indicators\n\tovp_led_ = new ui::datatypes::BoolLed(\n\t\tconfigurable_->get_property(ConfigKey::OverVoltageProtectionActive),\n\t\ttrue, red_icon, grey_icon, grey_icon, tr(\"OVP\"));\n\tinfo_layout->addWidget(ovp_led_, 0, 2, Qt::AlignLeft);\n\tocp_led_ = new ui::datatypes::BoolLed(\n\t\tconfigurable_->get_property(ConfigKey::OverCurrentProtectionActive),\n\t\ttrue, red_icon, grey_icon, grey_icon, tr(\"OCP\"));\n\tinfo_layout->addWidget(ocp_led_, 1, 2, Qt::AlignLeft);\n\totp_led_ = new ui::datatypes::BoolLed(\n\t\tconfigurable_->get_property(ConfigKey::OverTemperatureProtectionActive),\n\t\ttrue, red_icon, grey_icon, grey_icon, tr(\"OTP\"));\n\tinfo_layout->addWidget(otp_led_, 0, 3, Qt::AlignLeft);\n\tuvc_led_ = new ui::datatypes::BoolLed(\n\t\tconfigurable_->get_property(ConfigKey::UnderVoltageConditionActive),\n\t\ttrue, red_icon, grey_icon, grey_icon, tr(\"UVC\"));\n\tinfo_layout->addWidget(uvc_led_, 1, 3, Qt::AlignLeft);\n\tinfo_layout->setColumnStretch(4, 1);\n\tlayout->addLayout(info_layout, 0);\n\n\tQHBoxLayout *ctrl_layout = new QHBoxLayout();\n\n\t// TODO: Change control when switching regulation mode for sinks\n\tif (configurable_->has_get_config(ConfigKey::VoltageTarget) ||\n\t\tconfigurable_->has_set_config(ConfigKey::VoltageTarget)) {\n\n\t\tvoltage_control_ = new ui::datatypes::DoubleControl(\n\t\t\tconfigurable_->get_property(ConfigKey::VoltageTarget),\n\t\t\ttrue, true, tr(\"Voltage\"));\n\t\tvoltage_control_->setSizePolicy(\n\t\t\tQSizePolicy::Fixed, QSizePolicy::MinimumExpanding);\n\t\tctrl_layout->addWidget(voltage_control_);\n\t}\n\n\t// TODO: Change control when switching regulation mode for sinks\n\tif (configurable_->has_get_config(ConfigKey::CurrentLimit) ||\n\t\tconfigurable_->has_set_config(ConfigKey::CurrentLimit)) {\n\n\t\tcurrent_control_ = new ui::datatypes::DoubleControl(\n\t\t\tconfigurable_->get_property(ConfigKey::CurrentLimit),\n\t\t\ttrue, true, tr(\"Current\"));\n\t\tcurrent_control_->setSizePolicy(\n\t\t\tQSizePolicy::Fixed, QSizePolicy::MinimumExpanding);\n\t\tctrl_layout->addWidget(current_control_, 1, Qt::AlignLeft);\n\t}\n\n\tlayout->addLayout(ctrl_layout, 0);\n\n\tQHBoxLayout *opt_ctrl_layout = new QHBoxLayout();\n\n\tovp_control_ = new ui::datatypes::ThresholdControl(\n\t\tconfigurable_->get_property(ConfigKey::OverVoltageProtectionThreshold),\n\t\tconfigurable_->get_property(ConfigKey::OverVoltageProtectionEnabled),\n\t\ttrue, true, tr(\"OVP\"));\n\topt_ctrl_layout->addWidget(ovp_control_);\n\n\tocp_control_ = new ui::datatypes::ThresholdControl(\n\t\tconfigurable_->get_property(ConfigKey::OverCurrentProtectionThreshold),\n\t\tconfigurable_->get_property(ConfigKey::OverCurrentProtectionEnabled),\n\t\ttrue, true, tr(\"OCP\"));\n\topt_ctrl_layout->addWidget(ocp_control_);\n\n\tuvc_control_ = new ui::datatypes::ThresholdControl(\n\t\tconfigurable_->get_property(ConfigKey::UnderVoltageConditionThreshold),\n\t\tconfigurable_->get_property(ConfigKey::UnderVoltageConditionEnabled),\n\t\ttrue, true, tr(\"UVC\"));\n\topt_ctrl_layout->addWidget(uvc_control_, 1, Qt::AlignLeft);\n\tlayout->addLayout(opt_ctrl_layout, 0);\n\tlayout->addStretch(1);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid SourceSinkControlView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\tSettingsManager::save_configurable(configurable_, settings, origin_device);\n}\n\nvoid SourceSinkControlView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n}\n\nSourceSinkControlView *SourceSinkControlView::init_from_settings(\n\tSession &session, QSettings &settings, QUuid uuid,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto configurable = SettingsManager::restore_configurable(\n\t\tsession, settings, origin_device);\n\tif (!configurable)\n\t\treturn nullptr;\n\treturn new SourceSinkControlView(session, configurable, uuid);\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/sourcesinkcontrolview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_SOURCESINKCONTROLVIEW_HPP\n#define UI_VIEWS_SOURCESINKCONTROLVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\nclass Configurable;\n}\n\nnamespace ui {\n\nnamespace datatypes {\nclass BoolButton;\nclass BoolLed;\nclass DoubleControl;\nclass StringComboBox;\nclass StringLed;\nclass ThresholdControl;\n}\n\nnamespace views {\n\nclass SourceSinkControlView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\tSourceSinkControlView(Session& session,\n\t\tstd::shared_ptr<sv::devices::Configurable> configurable,\n\t\tQUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\tstatic SourceSinkControlView *init_from_settings(\n\t\tSession &session, QSettings &settings, QUuid uuid,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::devices::Configurable> configurable_;\n\n\tui::datatypes::StringLed *cc_led_;\n\tui::datatypes::StringLed *cv_led_;\n\tui::datatypes::BoolLed *ovp_led_;\n\tui::datatypes::BoolLed *ocp_led_;\n\tui::datatypes::BoolLed *otp_led_;\n\tui::datatypes::BoolLed *uvc_led_;\n\tui::datatypes::BoolButton *enable_button_;\n\tui::datatypes::StringComboBox *regulation_box_;\n\tui::datatypes::StringComboBox *range_box_;\n\tui::datatypes::DoubleControl *voltage_control_;\n\tui::datatypes::DoubleControl *current_control_;\n\tui::datatypes::ThresholdControl *ovp_control_;\n\tui::datatypes::ThresholdControl *ocp_control_;\n\tui::datatypes::ThresholdControl *uvc_control_;\n\n\tvoid setup_ui();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_SOURCESINKCONTROLVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/timeplotview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <string>\n\n#include <QMessageBox>\n#include <QSettings>\n#include <QUuid>\n#include <QVariant>\n\n#include \"timeplotview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/dialogs/selectsignaldialog.hpp\"\n#include \"src/ui/views/baseplotview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include <src/ui/widgets/plot/curve.hpp>\n#include \"src/ui/widgets/plot/plot.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n#include \"src/ui/widgets/plot/timecurvedata.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::shared_ptr;\nusing std::static_pointer_cast;\nusing std::string;\n\nQ_DECLARE_METATYPE(sv::ui::widgets::plot::BaseCurveData *)\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nTimePlotView::TimePlotView(Session &session, QUuid uuid, QWidget *parent) :\n\tBasePlotView(session, uuid, parent),\n\tchannel_(nullptr)\n{\n\tid_ = \"timeplot:\" + util::format_uuid(uuid_);\n\tplot_type_ = PlotType::TimePlot;\n}\n\nQString TimePlotView::title() const\n{\n\tQString title;\n\n\tif (channel_)\n\t\ttitle = tr(\"Channel \").append(channel_->display_name());\n\telse {\n\t\ttitle = tr(\"Signal\");\n\t\tQString sep(\" \");\n\t\tfor (const auto &curve : plot_->curve_map()) {\n\t\t\ttitle = title.append(sep).append(curve.second->name());\n\t\t\tsep = \", \";\n\t\t}\n\t}\n\n\treturn title;\n}\n\nvoid TimePlotView::set_channel(shared_ptr<channels::BaseChannel> channel)\n{\n\tassert(channel);\n\n\tif (channel_) {\n\t\tdisconnect(channel_.get(), &channels::BaseChannel::signal_added,\n\t\t\tthis, &TimePlotView::on_signal_changed);\n\t\tdisconnect(channel_.get(), &channels::BaseChannel::signal_changed,\n\t\t\tthis, &TimePlotView::on_signal_changed);\n\t}\n\n\tplot_->remove_all_curves();\n\n\tchannel_ = channel;\n\n\tshared_ptr<data::AnalogTimeSignal> signal;\n\tif (channel_->actual_signal())\n\t\tsignal = static_pointer_cast<data::AnalogTimeSignal>(\n\t\t\tchannel_->actual_signal());\n\tif (signal)\n\t\tadd_signal(signal);\n\n\tconnect(channel_.get(), &channels::BaseChannel::signal_added,\n\t\tthis, &TimePlotView::on_signal_changed);\n\tconnect(channel_.get(), &channels::BaseChannel::signal_changed,\n\t\tthis, &TimePlotView::on_signal_changed);\n\n\tQ_EMIT title_changed();\n}\n\nstring TimePlotView::add_signal(shared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tassert(signal);\n\tstring id;\n\n\t// Check if new actual_signal is already added to this plot\n\tfor (const auto &curve : plot_->curve_map()) {\n\t\tauto *curve_data = qobject_cast<widgets::plot::TimeCurveData *>(\n\t\t\tcurve.second->curve_data());\n\t\tif (!curve_data)\n\t\t\tcontinue;\n\t\tif (curve_data->signal() == signal)\n\t\t\treturn id;\n\t}\n\n\tauto *curve = new widgets::plot::TimeCurveData(signal);\n\tid = plot_->add_curve(curve);\n\tif (!id.empty()) {\n\t\tQ_EMIT title_changed();\n\t}\n\telse {\n\t\tQMessageBox::warning(this,\n\t\t\ttr(\"Cannot add signal\"), tr(\"Cannot add time signal to plot!\"),\n\t\t\tQMessageBox::Ok);\n\t}\n\n\treturn id;\n}\n\nvoid TimePlotView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBasePlotView::save_settings(settings, origin_device);\n\n\t// TODO: Can the channel be saved inside the plot widget?\n\tbool save_curves = true;\n\tif (channel_) {\n\t\tSettingsManager::save_channel(channel_, settings, origin_device);\n\t\tsave_curves = false;\n\t}\n\tplot_->save_settings(settings, save_curves, origin_device);\n}\n\nvoid TimePlotView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBasePlotView::restore_settings(settings, origin_device);\n\n\t// TODO: Can the channel be restored inside the plot widget?\n\tbool restore_curves = true;\n\tauto channel = SettingsManager::restore_channel(\n\t\tsession_, settings, origin_device);\n\tif (channel) {\n\t\tset_channel(channel);\n\t\trestore_curves = false;\n\t}\n\tplot_->restore_settings(settings, restore_curves, origin_device);\n}\n\nvoid TimePlotView::on_action_add_curve_triggered()\n{\n\tshared_ptr<sv::devices::BaseDevice> selected_device;\n\tif (channel_)\n\t\tselected_device = channel_->parent_device();\n\n\tui::dialogs::SelectSignalDialog dlg(session(), selected_device);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tfor (const auto &signal : dlg.signals()) {\n\t\tadd_signal(dynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal));\n\t}\n}\n\nvoid TimePlotView::on_signal_changed()\n{\n\tif (!channel_)\n\t\treturn;\n\n\tshared_ptr<sv::data::AnalogTimeSignal> signal;\n\tif (channel_->actual_signal())\n\t\tsignal = dynamic_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\t\tchannel_->actual_signal());\n\tif (signal)\n\t\tadd_signal(signal);\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/timeplotview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_TIMEPLOTVIEW_HPP\n#define UI_VIEWS_TIMEPLOTVIEW_HPP\n\n#include <memory>\n#include <string>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseplotview.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass TimePlotView : public BasePlotView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit TimePlotView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\n\t/**\n\t * Add a new channel to the time plot.\n\t */\n\tvoid set_channel(shared_ptr<channels::BaseChannel> channel);\n\t/**\n\t * Add a new signal to the time plot and return the curve id.\n\t */\n\tstring add_signal(shared_ptr<sv::data::AnalogTimeSignal> signal);\n\nprivate:\n\tshared_ptr<channels::BaseChannel> channel_;\n\nprotected Q_SLOTS:\n\tvoid on_action_add_curve_triggered() override;\n\nprivate Q_SLOTS:\n\tvoid on_signal_changed();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_TIMEPLOTVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/valuepanelview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <string>\n#include <utility>\n\n#include <QApplication>\n#include <QDateTime>\n#include <QDebug>\n#include <QHBoxLayout>\n#include <QSettings>\n#include <QTimer>\n#include <QUuid>\n#include <QVariant>\n#include <QVBoxLayout>\n\n#include \"valuepanelview.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/channels/basechannel.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/basesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include \"src/ui/widgets/monofontdisplay.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nValuePanelView::ValuePanelView(Session &session, QUuid uuid, QWidget *parent) :\n\tBaseView(session, uuid, parent),\n\tchannel_(nullptr),\n\tsignal_(nullptr),\n\tvalue_min_(std::numeric_limits<double>::max()),\n\tvalue_max_(std::numeric_limits<double>::lowest()),\n\taction_reset_display_(new QAction(this))\n{\n\tid_ = \"valuepanel:\" + util::format_uuid(uuid_);\n\n\tsetup_ui();\n\tsetup_toolbar();\n\treset_display();\n\n\ttimer_ = new QTimer(this);\n\tinit_timer();\n}\n\nValuePanelView::~ValuePanelView()\n{\n\tstop_timer();\n}\n\nQString ValuePanelView::title() const\n{\n\tQString title;\n\n\tif (channel_)\n\t\ttitle = tr(\"Channel\");\n\telse\n\t\ttitle = tr(\"Signal\");\n\n\tif (channel_)\n\t\ttitle = title.append(\" \").append(channel_->display_name());\n\telse if (signal_)\n\t\ttitle = title.append(\" \").append(signal_->display_name());\n\n\treturn title;\n}\n\nvoid ValuePanelView::set_channel(shared_ptr<channels::BaseChannel> channel)\n{\n\tassert(channel);\n\n\tdisconnect_signals_channel();\n\tdisconnect_signals_signal();\n\n\tchannel_ = channel;\n\tsignal_ = dynamic_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\tchannel_->actual_signal());\n\tif (signal_) {\n\t\tinit_displays();\n\t\tconnect_signals_signal();\n\t}\n\n\tconnect_signals_channel();\n\n\tQ_EMIT title_changed();\n}\n\nvoid ValuePanelView::set_signal(shared_ptr<sv::data::AnalogTimeSignal> signal)\n{\n\tassert(signal);\n\n\tdisconnect_signals_channel();\n\tdisconnect_signals_signal();\n\n\tchannel_ = nullptr;\n\tsignal_ = signal;\n\tinit_displays();\n\n\tconnect_signals_signal();\n\n\tQ_EMIT title_changed();\n}\n\nvoid ValuePanelView::setup_ui()\n{\n\tQVBoxLayout *layout = new QVBoxLayout();\n\tQGridLayout *panel_layout = new QGridLayout();\n\n\tvalue_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRangeWithSRDigits, \"\", \"\", \"\", false);\n\tvalue_min_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Min), true);\n\tvalue_max_display_ = new widgets::MonoFontDisplay(\n\t\twidgets::MonoFontDisplayType::AutoRange, \"\", \"\",\n\t\tdata::datautil::format_quantity_flag(data::QuantityFlag::Max), true);\n\n\tpanel_layout->addWidget(value_display_, 0, 0, 1, 2, Qt::AlignHCenter);\n\tpanel_layout->addWidget(value_min_display_, 1, 0, 1, 1, Qt::AlignHCenter);\n\tpanel_layout->addWidget(value_max_display_, 1, 1, 1, 1, Qt::AlignHCenter);\n\tlayout->addLayout(panel_layout);\n\tlayout->addStretch(1);\n\n\tthis->central_widget_->setLayout(layout);\n}\n\nvoid ValuePanelView::setup_toolbar()\n{\n\taction_reset_display_->setText(tr(\"Reset display\"));\n\taction_reset_display_->setIcon(\n\t\tQIcon::fromTheme(\"view-refresh\",\n\t\tQIcon(\":/icons/view-refresh.png\")));\n\tconnect(action_reset_display_, &QAction::triggered,\n\t\tthis, &ValuePanelView::on_action_reset_display_triggered);\n\n\ttoolbar_ = new QToolBar(\"Panel Toolbar\");\n\ttoolbar_->addAction(action_reset_display_);\n\tthis->addToolBar(Qt::TopToolBarArea, toolbar_);\n}\n\nvoid ValuePanelView::init_displays()\n{\n\tQString unit = signal_->unit_name();\n\tQString unit_suffix;\n\tset<sv::data::QuantityFlag> quantity_flags = signal_->quantity_flags();\n\tint total_digits = signal_->total_digits();\n\tint sr_digits = signal_->sr_digits();\n\n\tif (quantity_flags.count(sv::data::QuantityFlag::AC) > 0) {\n\t\t//unit_suffix = QString::fromUtf8(\"\\u23E6\");\n\t\tunit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tsv::data::QuantityFlag::AC);\n\t\tquantity_flags.erase(sv::data::QuantityFlag::AC);\n\t}\n\telse if (quantity_flags.count(sv::data::QuantityFlag::DC) > 0) {\n\t\t//unit_suffix = QString::fromUtf8(\"\\u2393\");\n\t\tunit_suffix = sv::data::datautil::format_quantity_flag(\n\t\t\tsv::data::QuantityFlag::DC);\n\t\tquantity_flags.erase(sv::data::QuantityFlag::DC);\n\t}\n\tset<sv::data::QuantityFlag> quantity_flags_min = quantity_flags;\n\tquantity_flags_min.insert(sv::data::QuantityFlag::Min);\n\tset<sv::data::QuantityFlag> quantity_flags_max = quantity_flags;\n\tquantity_flags_max.insert(sv::data::QuantityFlag::Max);\n\n\tvalue_display_->set_unit(unit);\n\tvalue_display_->set_unit_suffix(unit_suffix);\n\tvalue_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(quantity_flags, \"\\n\"));\n\tvalue_display_->set_sr_digits(total_digits, sr_digits);\n\n\tvalue_min_display_->set_unit(unit);\n\tvalue_min_display_->set_unit_suffix(unit_suffix);\n\tvalue_min_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(quantity_flags_min, \"\\n\"));\n\tvalue_min_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n\n\tvalue_max_display_->set_unit(unit);\n\tvalue_max_display_->set_unit_suffix(unit_suffix);\n\tvalue_max_display_->set_extra_text(\n\t\tsv::data::datautil::format_quantity_flags(quantity_flags_max, \"\\n\"));\n\tvalue_max_display_->set_decimal_places(\n\t\tsv::data::DefaultTotalDigits, sv::data::DefaultDecimalPlaces);\n}\n\nvoid ValuePanelView::connect_signals_channel()\n{\n\tif (!channel_)\n\t\treturn;\n\n\tconnect(channel_.get(), &channels::BaseChannel::signal_added,\n\t\tthis, &ValuePanelView::on_signal_changed);\n\tconnect(channel_.get(), &channels::BaseChannel::signal_changed,\n\t\tthis, &ValuePanelView::on_signal_changed);\n}\n\nvoid ValuePanelView::disconnect_signals_channel()\n{\n\tif (!channel_)\n\t\treturn;\n\n\tdisconnect(channel_.get(), &channels::BaseChannel::signal_added,\n\t\tthis, &ValuePanelView::on_signal_changed);\n\tdisconnect(channel_.get(), &channels::BaseChannel::signal_changed,\n\t\tthis, &ValuePanelView::on_signal_changed);\n}\n\nvoid ValuePanelView::connect_signals_signal()\n{\n\tif (!signal_)\n\t\treturn;\n\n\t//connect(signal_.get(), SIGNAL(unit_changed(QString)),\n\t//\tvalue_display_, SLOT(set_unit(const String)));\n\tconnect(signal_.get(), &data::AnalogTimeSignal::digits_changed,\n\t\tvalue_display_, &widgets::MonoFontDisplay::set_sr_digits);\n}\n\nvoid ValuePanelView::disconnect_signals_signal()\n{\n\tif (!signal_)\n\t\treturn;\n\n\t//disconnect(signal_.get(), SIGNAL(unit_changed(QString)),\n\t//\tvalue_display_, SLOT(set_unit(QString)));\n\tdisconnect(signal_.get(), &data::AnalogTimeSignal::digits_changed,\n\t\tvalue_display_, &widgets::MonoFontDisplay::set_sr_digits);\n}\n\nvoid ValuePanelView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBaseView::save_settings(settings, origin_device);\n\n\tif (signal_)\n\t\tSettingsManager::save_signal(signal_, settings, origin_device);\n\telse\n\t\tSettingsManager::save_channel(channel_, settings, origin_device);\n}\n\nvoid ValuePanelView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBaseView::restore_settings(settings, origin_device);\n\n\tauto signal = SettingsManager::restore_signal(\n\t\tsession_, settings, origin_device);\n\tif (signal) {\n\t\tset_signal(\n\t\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(signal));\n\t\treturn;\n\t}\n\n\tauto channel = SettingsManager::restore_channel(\n\t\tsession_, settings, origin_device);\n\tif (channel)\n\t\tset_channel(channel);\n}\n\nvoid ValuePanelView::reset_display()\n{\n\tvalue_display_->reset_value();\n\tvalue_min_display_->reset_value();\n\tvalue_max_display_->reset_value();\n}\n\nvoid ValuePanelView::init_timer()\n{\n\tvalue_min_ = std::numeric_limits<double>::max();\n\tvalue_max_ = std::numeric_limits<double>::lowest();\n\n\tconnect(timer_, &QTimer::timeout, this, &ValuePanelView::on_update);\n\ttimer_->start(250);\n}\n\nvoid ValuePanelView::stop_timer()\n{\n\tif (!timer_->isActive())\n\t\treturn;\n\n\ttimer_->stop();\n\tdisconnect(timer_, &QTimer::timeout, this, &ValuePanelView::on_update);\n\n\treset_display();\n}\n\nvoid ValuePanelView::on_update()\n{\n\tif (!signal_ || signal_->sample_count() == 0)\n\t\treturn;\n\n\tdouble value = signal_->last_value();\n\tif (value_min_ > value)\n\t\tvalue_min_ = value;\n\tif (value_max_ < value)\n\t\tvalue_max_ = value;\n\n\tvalue_display_->set_value(value);\n\tvalue_min_display_->set_value(value_min_);\n\tvalue_max_display_->set_value(value_max_);\n}\n\nvoid ValuePanelView::on_signal_changed()\n{\n\t// When channel_ is not set, we have a fixed signal_ and nothing will change\n\tif (!channel_)\n\t\treturn;\n\n\tdisconnect_signals_signal();\n\n\tsignal_ = dynamic_pointer_cast<sv::data::AnalogTimeSignal>(\n\t\tchannel_->actual_signal());\n\tif (!signal_)\n\t\treturn;\n\tinit_displays();\n\n\tconnect_signals_signal();\n\n\tQ_EMIT title_changed();\n}\n\nvoid ValuePanelView::on_action_reset_display_triggered()\n{\n\tstop_timer();\n\tinit_timer();\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/valuepanelview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_VALUEPANELVIEW_HPP\n#define UI_VIEWS_VALUEPANELVIEW_HPP\n\n#include <memory>\n#include <set>\n\n#include <QAction>\n#include <QSettings>\n#include <QString>\n#include <QTimer>\n#include <QToolBar>\n#include <QUuid>\n\n#include \"src/data/datautil.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace channels {\nclass BaseChannel;\n}\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\n\nnamespace widgets {\nclass MonoFontDisplay;\n}\n\nnamespace views {\n\nclass ValuePanelView : public BaseView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ValuePanelView(Session& session, QUuid uuid = QUuid(),\n\t\tQWidget* parent = nullptr);\n\n\t~ValuePanelView();\n\n\tQString title() const override;\n\tvoid set_channel(shared_ptr<channels::BaseChannel> channel);\n\tvoid set_signal(shared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\nprivate:\n\tshared_ptr<channels::BaseChannel> channel_;\n\tshared_ptr<sv::data::AnalogTimeSignal> signal_;\n\n\tQTimer *timer_;\n\n\t// Min/max/actual values are stored here, so they can be reseted\n\tdouble value_min_;\n\tdouble value_max_;\n\n\tQAction *const action_reset_display_;\n\tQToolBar *toolbar_;\n\twidgets::MonoFontDisplay *value_display_;\n\twidgets::MonoFontDisplay *value_min_display_;\n\twidgets::MonoFontDisplay *value_max_display_;\n\n\tvoid setup_ui();\n\tvoid setup_toolbar();\n\tvoid init_displays();\n\tvoid connect_signals_channel();\n\tvoid disconnect_signals_channel();\n\tvoid connect_signals_signal();\n\tvoid disconnect_signals_signal();\n\tvoid reset_display();\n\tvoid init_timer();\n\tvoid stop_timer();\n\nprivate Q_SLOTS:\n\tvoid on_update();\n\tvoid on_signal_changed();\n\tvoid on_action_reset_display_triggered();\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_VALUEPANELVIEW_HPP\n"
  },
  {
    "path": "src/ui/views/viewhelper.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n#include <utility>\n#include <vector>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDebug>\n#include <QList>\n#include <QSettings>\n\n#include \"viewhelper.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/devices/configurable.hpp\"\n#include \"src/devices/deviceutil.hpp\"\n#include \"src/ui/views/dataview.hpp\"\n#include \"src/ui/views/baseview.hpp\"\n#include \"src/ui/views/democontrolview.hpp\"\n#include \"src/ui/views/genericcontrolview.hpp\"\n#include \"src/ui/views/measurementcontrolview.hpp\"\n#include \"src/ui/views/powerpanelview.hpp\"\n#include \"src/ui/views/scopehorizontalcontrolview.hpp\"\n#include \"src/ui/views/scopetriggercontrolview.hpp\"\n#include \"src/ui/views/scopeverticalcontrolview.hpp\"\n#include \"src/ui/views/sequenceoutputview.hpp\"\n#include \"src/ui/views/smuscriptoutputview.hpp\"\n#include \"src/ui/views/smuscriptview.hpp\"\n#include \"src/ui/views/sourcesinkcontrolview.hpp\"\n#include \"src/ui/views/timeplotview.hpp\"\n#include \"src/ui/views/valuepanelview.hpp\"\n#include \"src/ui/views/xyplotview.hpp\"\n\nusing std::shared_ptr;\nusing std::vector;\n\nusing sv::devices::ConfigKey;\nusing sv::devices::DeviceType;\n\nnamespace sv {\nnamespace ui {\nnamespace views {\nnamespace viewhelper {\n\nvector<BaseView *> get_views_for_configurable(Session &session,\n\tshared_ptr<sv::devices::Configurable> configurable)\n{\n\tvector<BaseView *> views;\n\n\tif (!configurable)\n\t\treturn views;\n\n\t// Power supplies or electronic loads control view\n\tif ((configurable->device_type() == DeviceType::PowerSupply ||\n\t\tconfigurable->device_type() == DeviceType::ElectronicLoad) &&\n\t\t(configurable->has_get_config(ConfigKey::Enabled) ||\n\t\tconfigurable->has_set_config(ConfigKey::Enabled) ||\n\t\tconfigurable->has_get_config(ConfigKey::Regulation) ||\n\t\tconfigurable->has_set_config(ConfigKey::Regulation) ||\n\t\tconfigurable->has_get_config(ConfigKey::VoltageTarget) ||\n\t\tconfigurable->has_set_config(ConfigKey::VoltageTarget) ||\n\t\tconfigurable->has_get_config(ConfigKey::CurrentLimit) ||\n\t\tconfigurable->has_set_config(ConfigKey::CurrentLimit) ||\n\t\tconfigurable->has_get_config(ConfigKey::OverVoltageProtectionEnabled) ||\n\t\tconfigurable->has_set_config(ConfigKey::OverVoltageProtectionEnabled) ||\n\t\tconfigurable->has_get_config(ConfigKey::OverVoltageProtectionThreshold) ||\n\t\tconfigurable->has_set_config(ConfigKey::OverVoltageProtectionThreshold) ||\n\t\tconfigurable->has_get_config(ConfigKey::OverCurrentProtectionEnabled) ||\n\t\tconfigurable->has_set_config(ConfigKey::OverCurrentProtectionEnabled) ||\n\t\tconfigurable->has_get_config(ConfigKey::OverCurrentProtectionThreshold) ||\n\t\tconfigurable->has_set_config(ConfigKey::OverCurrentProtectionThreshold) ||\n\t\tconfigurable->has_get_config(ConfigKey::UnderVoltageConditionEnabled) ||\n\t\tconfigurable->has_set_config(ConfigKey::UnderVoltageConditionEnabled) ||\n\t\tconfigurable->has_get_config(ConfigKey::UnderVoltageConditionThreshold) ||\n\t\tconfigurable->has_set_config(ConfigKey::UnderVoltageConditionThreshold))) {\n\n\t\tviews.push_back(new SourceSinkControlView(session, configurable));\n\t}\n\n\t// Vertical control for scopes\n\tif (configurable->device_type() == DeviceType::Oscilloscope &&\n\t\t(configurable->has_get_config(ConfigKey::Enabled) ||\n\t\tconfigurable->has_set_config(ConfigKey::Enabled) ||\n\t\tconfigurable->has_get_config(ConfigKey::VDiv) ||\n\t\tconfigurable->has_set_config(ConfigKey::VDiv) ||\n\t\tconfigurable->has_get_config(ConfigKey::Coupling) ||\n\t\tconfigurable->has_set_config(ConfigKey::Coupling) ||\n\t\tconfigurable->has_get_config(ConfigKey::Filter) ||\n\t\tconfigurable->has_set_config(ConfigKey::Filter))) {\n\n\t\tviews.push_back(new ScopeVerticalControlView(session, configurable));\n\t}\n\n\t// Trigger control for scopes\n\tif (configurable->device_type() == DeviceType::Oscilloscope &&\n\t\t(configurable->has_get_config(ConfigKey::TriggerSource) ||\n\t\tconfigurable->has_set_config(ConfigKey::TriggerSource) ||\n\t\tconfigurable->has_get_config(ConfigKey::TriggerSlope) ||\n\t\tconfigurable->has_set_config(ConfigKey::TriggerSlope) ||\n\t\tconfigurable->has_get_config(ConfigKey::TriggerLevel) ||\n\t\tconfigurable->has_set_config(ConfigKey::TriggerLevel))) {\n\n\t\tviews.push_back(new ScopeTriggerControlView(session, configurable));\n\t}\n\n\t// Horizontal control for scopes\n\tif (configurable->device_type() == DeviceType::Oscilloscope &&\n\t\t(configurable->has_get_config(ConfigKey::TimeBase) ||\n\t\tconfigurable->has_set_config(ConfigKey::TimeBase))) {\n\n\t\tviews.push_back(new ScopeHorizontalControlView(session, configurable));\n\t}\n\n\t// View for Demo Device\n\tif (configurable->device_type() == DeviceType::DemoDev &&\n\t\t(configurable->has_get_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable->has_set_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable->has_get_config(ConfigKey::Amplitude) ||\n\t\tconfigurable->has_set_config(ConfigKey::Amplitude) ||\n\t\tconfigurable->has_get_config(ConfigKey::Offset) ||\n\t\tconfigurable->has_set_config(ConfigKey::Offset))) {\n\n\t\tviews.push_back(new DemoControlView(session, configurable));\n\t}\n\n\t// Measurement devices like DMMs, scales, LCR meters, etc.\n\tif ((configurable->device_type() == DeviceType::Multimeter ||\n\t\tconfigurable->device_type() == DeviceType::SoundLevelMeter ||\n\t\tconfigurable->device_type() == DeviceType::Thermometer ||\n\t\tconfigurable->device_type() == DeviceType::Hygrometer ||\n\t\tconfigurable->device_type() == DeviceType::Energymeter ||\n\t\tconfigurable->device_type() == DeviceType::LcrMeter ||\n\t\tconfigurable->device_type() == DeviceType::Scale ||\n\t\tconfigurable->device_type() == DeviceType::Powermeter ||\n\t\t// TODO: Multiplexers doesn't really fit here\n\t\tconfigurable->device_type() == DeviceType::Multiplexer) &&\n\t\t(configurable->has_get_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable->has_set_config(ConfigKey::MeasuredQuantity) ||\n\t\tconfigurable->has_get_config(ConfigKey::Range) ||\n\t\tconfigurable->has_set_config(ConfigKey::Range))) {\n\n\t\tviews.push_back(new MeasurementControlView(session, configurable));\n\t}\n\n\t// TODO: SignalGenerators need their own view (waveforms, etc.)\n\n\t// Fallback: Generic control view if nothing else fits (e.g. signal\n\t// generators for now).\n\tif (views.empty() &&\n\t\t(!configurable->getable_configs().empty() ||\n\t\t!configurable->setable_configs().empty())) {\n\n\t\tviews.push_back(new GenericControlView(session, configurable));\n\t}\n\n\treturn views;\n}\n\nBaseView *get_view_from_settings(Session &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tQString id = settings.value(\"id\").toString();\n\tQUuid uuid = settings.value(\"uuid\").toUuid();\n\tQStringList id_list = id.split(':');\n\tQString type = id_list[0];\n\n\tBaseView *view = nullptr;\n\tif (type == \"data\") {\n\t\tview = new DataView(session, uuid);\n\t}\n\telse if (type == \"timeplot\") {\n\t\tview = new TimePlotView(session, uuid);\n\t}\n\telse if (type == \"xyplot\") {\n\t\tview = new XYPlotView(session, uuid);\n\t}\n\telse if (type == \"powerpanel\") {\n\t\tview = new PowerPanelView(session, uuid);\n\t}\n\telse if (type == \"valuepanel\") {\n\t\tview = new ValuePanelView(session, uuid);\n\t}\n\telse if (type == \"sequenceoutput\") {\n\t\tview = new SequenceOutputView(session, uuid);\n\t}\n\telse if (type == \"smuscriptoutput\") {\n\t\tview = new SmuScriptOutputView(session, uuid);\n\t}\n\telse if (type == \"smuscript\") {\n\t\tview = new SmuScriptView(session, uuid);\n\t}\n\telse if (type == \"democontrol\") {\n\t\tview = DemoControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"genericcontrol\") {\n\t\tview = GenericControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"measurementcontrol\") {\n\t\tview = MeasurementControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"scopehorizontalcontrol\") {\n\t\tview = ScopeHorizontalControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"scopetriggercontrol\") {\n\t\tview = ScopeTriggerControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"scopeverticalcontrol\") {\n\t\tview = ScopeVerticalControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\telse if (type == \"sourcesinkcontrol\") {\n\t\tview = SourceSinkControlView::init_from_settings(\n\t\t\tsession, settings, uuid, origin_device);\n\t}\n\n\tif (view)\n\t\tview->restore_settings(settings, origin_device);\n\n\treturn view;\n}\n\n} // namespace viewhelper\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/viewhelper.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_VIEWHELPER_HPP\n#define UI_VIEWS_VIEWHELPER_HPP\n\n#include <memory>\n#include <vector>\n\n#include <QSettings>\n\nusing std::shared_ptr;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass Configurable;\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass BaseView;\n\nnamespace viewhelper {\n\n/**\n * Returns the fitting control views for the given configurable, by checking for\n * get-/setable config keys and the device type.\n *\n * @param[in] session The reference to the actual SmuView session.\n * @param[in] configurable The Configurable.\n *\n * @return The control views for the configurable.\n */\nvector<BaseView *> get_views_for_configurable(Session &session,\n\tshared_ptr<sv::devices::Configurable> configurable);\n\n/**\n * Return the view defined in the actual settings group.\n *\n * @param[in] session The reference to the actual SmuView session.\n * @param[in] settings The settings.\n * @param[in] origin_device The origin device for this settings.\n *\n * @return The view defined by settings.\n */\nBaseView *get_view_from_settings(Session &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\n} // namespace viewhelper\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_VIEWHELPER_HPP\n"
  },
  {
    "path": "src/ui/views/xyplotview.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <memory>\n#include <string>\n\n#include <QMessageBox>\n#include <QSettings>\n#include <QUuid>\n\n#include \"xyplotview.hpp\"\n#include \"src/session.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/dialogs/selectxysignalsdialog.hpp\"\n#include \"src/ui/views/baseplotview.hpp\"\n#include \"src/ui/views/viewhelper.hpp\"\n#include <src/ui/widgets/plot/curve.hpp>\n#include \"src/ui/widgets/plot/plot.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n#include \"src/ui/widgets/plot/xycurvedata.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::shared_ptr;\nusing std::string;\n\nQ_DECLARE_METATYPE(sv::ui::widgets::plot::BaseCurveData *)\n\nnamespace sv {\nnamespace ui {\nnamespace views {\n\nXYPlotView::XYPlotView(Session &session, QUuid uuid, QWidget *parent) :\n\tBasePlotView(session, uuid, parent)\n{\n\tid_ = \"xyplot:\" + util::format_uuid(uuid_);\n\tplot_type_ = PlotType::XYPlot;\n}\n\n\nQString XYPlotView::title() const\n{\n\tQString title = tr(\"Signal\");\n\tQString sep(\" \");\n\tfor (const auto &curve : plot_->curve_map()) {\n\t\ttitle = title.append(sep).append(curve.second->name());\n\t\tsep = \", \";\n\t}\n\treturn title;\n}\n\nstring XYPlotView::add_signals(shared_ptr<sv::data::AnalogTimeSignal> x_signal,\n\tshared_ptr<sv::data::AnalogTimeSignal> y_signal)\n{\n\tauto *curve = new widgets::plot::XYCurveData(x_signal, y_signal);\n\tstring id = plot_->add_curve(curve);\n\tif (id.empty()) {\n\t\tQMessageBox::warning(this,\n\t\t\ttr(\"Cannot add signal\"), tr(\"Cannot add xy signal to plot!\"),\n\t\t\tQMessageBox::Ok);\n\t}\n\treturn id;\n}\n\nvoid XYPlotView::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tBasePlotView::save_settings(settings, origin_device);\n\tplot_->save_settings(settings, true, origin_device);\n}\n\nvoid XYPlotView::restore_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tBasePlotView::restore_settings(settings, origin_device);\n\tplot_->restore_settings(settings, true, origin_device);\n}\n\nvoid XYPlotView::on_action_add_curve_triggered()\n{\n\tui::dialogs::SelectXYSignalsDialog dlg(session(), nullptr);\n\tif (!dlg.exec())\n\t\treturn;\n\n\tadd_signals(\n\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(dlg.x_signal()),\n\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(dlg.y_signal()));\n}\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/views/xyplotview.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_VIEWS_XYPLOTVIEW_HPP\n#define UI_VIEWS_XYPLOTVIEW_HPP\n\n#include <memory>\n\n#include <QSettings>\n#include <QUuid>\n\n#include \"src/ui/views/baseplotview.hpp\"\n\nusing std::shared_ptr;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace views {\n\nclass XYPlotView : public BasePlotView\n{\n\tQ_OBJECT\n\npublic:\n\texplicit XYPlotView(Session &session, QUuid uuid = QUuid(),\n\t\tQWidget *parent = nullptr);\n\n\tQString title() const override;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) const override;\n\tvoid restore_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device = nullptr) override;\n\n\t/**\n\t * Add a new x/y curve to the xy plot. Return the curve id.\n\t */\n\tstring add_signals(shared_ptr<sv::data::AnalogTimeSignal> x_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> y_signal);\n\nprotected Q_SLOTS:\n\tvoid on_action_add_curve_triggered() override;\n\n};\n\n} // namespace views\n} // namespace ui\n} // namespace sv\n\n#endif // UI_VIEWS_XYPLOTVIEW_HPP\n"
  },
  {
    "path": "src/ui/widgets/clickablelabel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QLabel>\n#include <QMouseEvent>\n#include <QString>\n#include <QWidget>\n\n#include \"clickablelabel.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nClickableLabel::ClickableLabel(const QString &text, QWidget *parent) :\n\tQLabel(text, parent)\n{\n}\n\nClickableLabel::~ClickableLabel()\n{\n}\n\nvoid ClickableLabel::mousePressEvent(QMouseEvent* event)\n{\n\t(void)event;\n\tQ_EMIT clicked();\n}\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/clickablelabel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_CLICKABLELABEL_HPP\n#define UI_WIDGETS_CLICKABLELABEL_HPP\n\n#include <QLabel>\n#include <QMouseEvent>\n#include <QString>\n#include <QWidget>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nclass ClickableLabel : public QLabel\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ClickableLabel(const QString &text = \"\", QWidget *parent = nullptr);\n    ~ClickableLabel();\n\nprotected:\n    void mousePressEvent(QMouseEvent* event) override;\n\nQ_SIGNALS:\n    void clicked();\n\n};\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_CLICKABLELABEL_HPP\n"
  },
  {
    "path": "src/ui/widgets/colorbutton.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QApplication>\n#include <QBrush>\n#include <QColor>\n#include <QColorDialog>\n#include <QPainter>\n#include <QPaintEvent>\n#include <QPalette>\n#include <QPushButton>\n#include <QWidget>\n\n#include \"colorbutton.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nconst int ColorButton::SwatchMargin = 7;\n\nColorButton::ColorButton(QWidget *parent) :\n\tQPushButton(parent)\n{\n\tconnect(this, &ColorButton::clicked, this, &ColorButton::change_color);\n}\n\nvoid ColorButton::set_color(const QColor &color)\n{\n\tcolor_ = color;\n}\n\nconst QColor &ColorButton::color()\n{\n\treturn color_;\n}\n\nvoid ColorButton::change_color()\n{\n\tQColor new_color = QColorDialog::getColor(color_, parentWidget());\n\tif (new_color != color_)\n\t\tset_color(new_color);\n}\n\nvoid ColorButton::paintEvent(QPaintEvent *event)\n{\n\tQPushButton::paintEvent(event);\n\n\tconst QRect rect_adjusted = rect().adjusted(\n\t\tSwatchMargin, SwatchMargin, -SwatchMargin, -SwatchMargin);\n\n\tQPainter painter(this);\n\tpainter.setPen(QApplication::palette().color(QPalette::Dark));\n\tpainter.setBrush(QBrush(color_));\n\tpainter.drawRect(rect_adjusted);\n}\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/colorbutton.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_COLORBUTTON_HPP\n#define UI_WIDGETS_COLORBUTTON_HPP\n\n#include <QColor>\n#include <QPaintEvent>\n#include <QPushButton>\n#include <QWidget>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nclass ColorButton : public QPushButton\n{\n\tQ_OBJECT\n\npublic:\n\texplicit ColorButton(QWidget *parent = nullptr);\n\n\tvoid set_color(const QColor &color);\n\tconst QColor &color();\n\nprivate:\n\tstatic const int SwatchMargin;\n\tQColor color_;\n\nprivate:\n\tvoid paintEvent(QPaintEvent *event) override;\n\npublic Q_SLOTS:\n\tvoid change_color();\n\n};\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_COLORBUTTON_HPP\n"
  },
  {
    "path": "src/ui/widgets/monofontdisplay.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n\n#include <QDebug>\n#include <QFont>\n#include <QFrame>\n#include <QFontMetrics>\n#include <QGridLayout>\n#include <QSizePolicy>\n#include <QString>\n\n#include <QStandardPaths>\n\n#include \"monofontdisplay.hpp\"\n#include \"src/util.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nMonoFontDisplay::MonoFontDisplay(const MonoFontDisplayType display_type,\n\t\tconst QString &unit, const QString &unit_suffix,\n\t\tconst QString &extra_text, const bool small, QWidget *parent) :\n\tQFrame(parent),\n\tdisplay_type_(display_type),\n\ttotal_digits_(7),\n\ttotal_digits_changed_(true),\n\tsr_digits_(2),\n\tdecimal_places_(2),\n\textra_text_(extra_text),\n\textra_text_changed_(true),\n\tunit_(unit),\n\tunit_si_prefix_(\"\"),\n\tunit_suffix_(unit_suffix),\n\tunit_changed_(true),\n\tsmall_(small),\n\tvalue_(.0)\n{\n\tMonoFontDisplay::setup_ui();\n\treset_value();\n}\n\nvoid MonoFontDisplay::setup_ui()\n{\n\t// Use embedded mono space font\n\tQFont monospace_font = QFont(\"DejaVu Sans Mono\");\n\t// Get standard font sizes\n\tint monospace_font_size = monospace_font.pointSize();\n\tint std_font_size = QFont().pointSize();\n\n\tQFont value_font(monospace_font);\n\tQFont unit_font;\n\tint unit_spacer_size;\n\tif (!small_) {\n\t\tvalue_font.setPointSize(monospace_font_size + 12); // = 22\n\t\tvalue_font.setBold(true);\n\t\tvalue_font.setWeight(QFont::Bold);\n\t\tunit_font.setPointSize(std_font_size + 8); // = 18\n\t\textra_font_.setPointSize(std_font_size); // = 10\n\t\tunit_spacer_size = 5;\n\t}\n\telse {\n\t\tvalue_font.setPointSize(monospace_font_size + 4); // = 14\n\t\tunit_font.setPointSize(std_font_size); // = 10\n\t\textra_font_.setPointSize(std_font_size - 3); // = 7\n\t\tunit_spacer_size = 3;\n\t}\n\n\t// Qt::AlignBaseline is not working, so we have to calculate the\n\t// difference of the ascents for positioning the unit label.\n\tQFontMetrics value_font_metrics(value_font);\n\tQFontMetrics unit_font_metrics(unit_font);\n\tascent_diff_ = value_font_metrics.ascent() - unit_font_metrics.ascent();\n\n\n\t//this->setFrameShape(QFrame::Box);\n\tQSizePolicy layout_size_policy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tlayout_size_policy.setHorizontalStretch(0);\n\tlayout_size_policy.setVerticalStretch(0);\n\tthis->setSizePolicy(layout_size_policy);\n\n\tlayout_ = new QGridLayout();\n\t// Set the margin and spacing to 0, so we can position the value and\n\t// the unit by their baselines exactly.\n\tlayout_->setMargin(0);\n\tlayout_->setSpacing(0);\n\n\t// Value\n\tvalue_label_ = new QLabel();\n\tvalue_label_->setFont(value_font);\n\tvalue_label_->setAlignment(Qt::AlignRight);\n\tvalue_label_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\t//value_label_->setFrameShape(QFrame::Box);\n\tlayout_->addWidget(value_label_, 0, 0, 2, 1, Qt::AlignRight | Qt::AlignVCenter);\n\n\t// Spacer between the value and the unit labels.\n\tQSpacerItem *unit_spacer = new QSpacerItem(unit_spacer_size, 1,\n\t\tQSizePolicy::Fixed, QSizePolicy::Fixed);\n\tlayout_->addItem(unit_spacer, 0, 1, 2, 1, Qt::AlignCenter);\n\n\t// Extra spacer (used when extra text is empty to \"fake\" Qt::AlignBaseline)\n\textra_label_ = nullptr;\n\textra_spacer_ = new QSpacerItem(1, ascent_diff_,\n\t\tQSizePolicy::Fixed, QSizePolicy::Fixed);\n\tlayout_->addItem(extra_spacer_, 0, 2, 1, 1, Qt::AlignCenter);\n\n\t// Unit\n\tunit_label_ = new QLabel();\n\tunit_label_->setFont(unit_font);\n\t// Qt::AlignTop is not working!\n\tunit_label_->setAlignment(Qt::AlignRight | Qt::AlignVCenter);\n\tunit_label_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\t//unit_label_->setFrameShape(QFrame::Box);\n\tlayout_->addWidget(unit_label_, 1, 2, 1, 1, Qt::AlignHCenter | Qt::AlignTop);\n\tlayout_->setRowStretch(1, 1);\n\n\tthis->setLayout(layout_);\n}\n\nvoid MonoFontDisplay::update_value_widget_dimensions()\n{\n\t// Set the widget to a fixed width, so it doesn't jump around when the\n\t// length of the string is changing (e.g. minus sign).\n\t// TODO: Displays are too small (not wide enough) for neg. values, esp. for\n\t//       the power panel for W/Ah/Wh for the 6632B. B/c of the decimal\n\t//       point?\n\tQString str(\"\");\n\tsize_t str_len = total_digits_ + 2; // digits + decimal point + sign\n\tfor (size_t i=0; i<str_len; ++i) {\n\t\tstr += \"-\";\n\t}\n\tQFontMetrics metrics = value_label_->fontMetrics();\n#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)\n\tvalue_label_->setFixedWidth(metrics.horizontalAdvance(str));\n#else\n\tvalue_label_->setFixedWidth(metrics.width(str));\n#endif\n}\n\nvoid MonoFontDisplay::update_extra_widget_dimensions()\n{\n\t// Nothing to do here\n}\n\nvoid MonoFontDisplay::update_unit_widget_dimensions()\n{\n\t// Set the widget to a fixed width, so it doesn't jump around when the\n\t// SI prefix is changing.\n\tQString str;\n\tif (display_type_ == MonoFontDisplayType::AutoRangeWithSRDigits\n\t\t\t|| display_type_ == MonoFontDisplayType::AutoRange) {\n\t\t// 'm' is the widest character for non monospace fonts\n\t\tstr.append(\"m\");\n\t}\n\tstr.append(unit_);\n\tif (!unit_suffix_.isEmpty()) {\n\t\tstr.append(\" \").append(unit_suffix_);\n\t}\n\tQFontMetrics metrics = unit_label_->fontMetrics();\n#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)\n\tunit_label_->setFixedWidth(metrics.horizontalAdvance(str));\n#else\n\tunit_label_->setFixedWidth(metrics.width(str));\n#endif\n}\n\nvoid MonoFontDisplay::show_value(const QString &value)\n{\n\tvalue_label_->setText(value);\n}\n\nvoid MonoFontDisplay::show_extra_text(const QString &extra_text)\n{\n\tif (extra_text_.isEmpty() && !extra_spacer_) {\n\t\t// Remove label\n\t\tlayout_->removeWidget(extra_label_);\n\t\tdelete extra_label_;\n\t\textra_label_ = nullptr;\n\t\t// Insert spacer\n\t\textra_spacer_ = new QSpacerItem(1, ascent_diff_,\n\t\t\tQSizePolicy::Fixed, QSizePolicy::Fixed);\n\t\tlayout_->addItem(extra_spacer_, 0, 2, 1, 1, Qt::AlignCenter);\n\t}\n\telse if (!extra_text_.isEmpty()) {\n\t\tif (!extra_label_) {\n\t\t\t// Remove spacer\n\t\t\tlayout_->removeItem(extra_spacer_);\n\t\t\tdelete extra_spacer_;\n\t\t\textra_spacer_ = nullptr;\n\t\t\t// Insert label\n\t\t\textra_label_ = new QLabel();\n\t\t\textra_label_->setFont(extra_font_);\n\t\t\textra_label_->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);\n\t\t\textra_label_->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\t\t\t//extra_label_->setFrameShape(QFrame::Box);\n\t\t\tlayout_->addWidget(extra_label_, 0, 2, 1, 1, Qt::AlignCenter);\n\t\t}\n\t\textra_label_->setText(extra_text);\n\t}\n}\n\nvoid MonoFontDisplay::show_unit(const QString &unit)\n{\n\tunit_label_->setText(unit);\n}\n\ndouble MonoFontDisplay::value() const\n{\n\treturn value_;\n}\n\nvoid MonoFontDisplay::set_value(const double value)\n{\n\tvalue_ = value;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::set_extra_text(const QString &extra_text)\n{\n\textra_text_ = extra_text;\n\textra_text_changed_ = true;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::set_unit(const QString &unit)\n{\n\tunit_ = unit;\n\tunit_changed_ = true;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::set_unit_suffix(const QString &unit_suffix)\n{\n\tunit_suffix_ = unit_suffix;\n\tunit_changed_ = true;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::set_sr_digits(const int total_digits, const int sr_digits)\n{\n\tif (total_digits != total_digits_) {\n\t\ttotal_digits_ = total_digits;\n\t\ttotal_digits_changed_ = true;\n\t}\n\tsr_digits_ = sr_digits;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::set_decimal_places(const int total_digits, const int decimal_places)\n{\n\tif (total_digits != total_digits_) {\n\t\ttotal_digits_ = total_digits;\n\t\ttotal_digits_changed_ = true;\n\t}\n\tdecimal_places_ = decimal_places;\n\tupdate_display();\n}\n\nvoid MonoFontDisplay::reset_value()\n{\n\tQString init_value(\"\");\n\tfor (int i=0; i<total_digits_; i++)\n\t\tinit_value.append(\"-\");\n\tshow_value(init_value);\n}\n\nvoid MonoFontDisplay::update_display()\n{\n\tQString value_str(\"\");\n\tQString si_prefix(\"\");\n\n\tif (value_ >= std::numeric_limits<double>::max() ||\n\t\t\tvalue_ == std::numeric_limits<double>::infinity()) {\n\t\t// TODO: Replace with \"ol\" or \"overl\", depending on the avail. digits.\n\t\tvalue_str = QString(\"OL\");\n\t}\n\telse if (value_ <= std::numeric_limits<double>::lowest()) {\n\t\t// TODO: Replace with \"ul\" or \"underf\", depending on the avail. digits.\n\t\tvalue_str = QString(\"UL\");\n\t}\n\telse if (display_type_ == MonoFontDisplayType::FixedRange) {\n\t\t// Use actual locale (%L) for formating\n\t\tvalue_str = QString(\"%L1\").\n\t\t\targ(value_, total_digits_, 'f', decimal_places_, QChar(' '));\n\t}\n\telse if (display_type_ == MonoFontDisplayType::AutoRangeWithSRDigits) {\n\t\tutil::format_value_si(value_, total_digits_, sr_digits_, value_str,\n\t\t\tsi_prefix);\n\t}\n\telse if (display_type_ == MonoFontDisplayType::AutoRange) {\n\t\tutil::format_value_si_autoscale(value_, total_digits_, decimal_places_,\n\t\t\tvalue_str, si_prefix);\n\t}\n\tshow_value(value_str);\n\n\tif (total_digits_changed_) {\n\t\ttotal_digits_changed_ = false;\n\t\tthis->update_value_widget_dimensions();\n\t}\n\n\tif (extra_text_changed_) {\n\t\textra_text_changed_ = false;\n\t\tshow_extra_text(extra_text_);\n\t\tthis->update_extra_widget_dimensions();\n\t}\n\n\tif (si_prefix != unit_si_prefix_ || unit_changed_) {\n\t\tunit_si_prefix_ = si_prefix;\n\t\tQString unit_str = QString(\"%1%2\").arg(unit_si_prefix_, unit_);\n\t\tif (!unit_suffix_.isEmpty()) {\n\t\t\tunit_str.append(\" \").append(unit_suffix_);\n\t\t}\n\t\tshow_unit(unit_str);\n\t}\n\tif (unit_changed_) {\n\t\tunit_changed_ = false;\n\t\tthis->update_unit_widget_dimensions();\n\t}\n}\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/monofontdisplay.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_MONOFONTDISPLAY_HPP\n#define UI_WIDGETS_MONOFONTDISPLAY_HPP\n\n#include <QFont>\n#include <QFrame>\n#include <QGridLayout>\n#include <QLabel>\n#include <QSpacerItem>\n#include <QString>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nenum class MonoFontDisplayType {\n\tAutoRange,\n\tAutoRangeWithSRDigits,\n\tFixedRange\n};\n\nclass MonoFontDisplay : public QFrame\n{\n\tQ_OBJECT\n\npublic:\n\tMonoFontDisplay(const MonoFontDisplayType display_type,\n\t\tconst QString &unit, const QString &unit_suffix,\n\t\tconst QString &extra_text, const bool small, QWidget *parent = nullptr);\n\n\tdouble value() const;\n\nprivate:\n\tconst MonoFontDisplayType display_type_;\n\tint total_digits_;\n\tbool total_digits_changed_;\n\tint sr_digits_;\n\tint decimal_places_;\n\tQString extra_text_;\n\tbool extra_text_changed_;\n\tQString unit_;\n\tQString unit_si_prefix_;\n\tQString unit_suffix_;\n\tbool unit_changed_;\n\tconst bool small_;\n\tdouble value_;\n\tint ascent_diff_;\n\tQGridLayout *layout_;\n\tQLabel *value_label_;\n\tQFont extra_font_;\n\tQLabel *extra_label_;\n\tQSpacerItem *extra_spacer_;\n\tQLabel *unit_label_;\n\n\tvirtual void setup_ui();\n\tvoid update_value_widget_dimensions();\n\tvoid update_extra_widget_dimensions();\n\tvoid update_unit_widget_dimensions();\n\tvoid show_value(const QString &value);\n\tvoid show_extra_text(const QString &extra_text);\n\tvoid show_unit(const QString &unit);\n\npublic Q_SLOTS:\n\tvoid set_value(const double value);\n\tvoid set_extra_text(const QString &extra_text);\n\tvoid set_unit(const QString &unit);\n\tvoid set_unit_suffix(const QString &unit_suffix);\n\tvoid set_sr_digits(const int total_digits, const int sr_digits);\n\tvoid set_decimal_places(const int total_digits, const int decimal_places);\n\tvoid reset_value();\n\tvoid update_display();\n\n};\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_MONOFONTDISPLAY_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/axislocklabel.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QIcon>\n#include <QPixmap>\n#include <QSizePolicy>\n#include <QString>\n#include <QWidget>\n\n#include \"axislocklabel.hpp\"\n#include \"src/ui/widgets/clickablelabel.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nAxisLockLabel::AxisLockLabel(\n\t\tconst int axis_id, const AxisBoundary axis_boundary,\n\t\tconst QString &text, QWidget *parent) :\n\tClickableLabel(text, parent),\n\taxis_id_(axis_id),\n\taxis_boundary_(axis_boundary),\n\tlocked_(false)\n{\n\tQIcon unlocked_icon = QIcon::fromTheme(\"object-unlocked\",\n\t\tQIcon(\":/icons/object-unlocked.png\"));\n\tunlocked_pixmap_ = unlocked_icon.pixmap(QSize(16, 16));\n\n\tQIcon locked_icon = QIcon::fromTheme(\"object-locked\",\n\t\tQIcon(\":/icons/object-locked.png\"));\n\tlocked_pixmap_ = locked_icon.pixmap(QSize(16, 16));\n\n\tsetup_ui();\n}\n\nAxisLockLabel::~AxisLockLabel()\n{\n}\n\nvoid AxisLockLabel::setup_ui()\n{\n    this->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);\n\tset_locked(locked_);\n}\n\nint AxisLockLabel::get_axis_id() const\n{\n\treturn axis_id_;\n}\n\nAxisBoundary AxisLockLabel::get_axis_boundary() const\n{\n\treturn axis_boundary_;\n}\n\nbool AxisLockLabel::is_locked() const\n{\n\treturn locked_;\n}\n\nvoid AxisLockLabel::set_locked(bool locked)\n{\n\tlocked_ = locked;\n\tif (locked_)\n\t\tthis->setPixmap(locked_pixmap_);\n\telse\n\t\tthis->setPixmap(unlocked_pixmap_);\n}\n\nvoid AxisLockLabel::on_axis_lock_changed(const int axis_id,\n\tconst sv::ui::widgets::plot::AxisBoundary axis_boundary, bool locked)\n{\n\tif (axis_id != axis_id_ || axis_boundary != axis_boundary_)\n\t\treturn;\n\n\tset_locked(locked);\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/axislocklabel.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_AXISLOCKLABEL_HPP\n#define UI_WIDGETS_PLOT_AXISLOCKLABEL_HPP\n\n#include <QPixmap>\n#include <QString>\n#include <QWidget>\n\n#include \"src/ui/widgets/clickablelabel.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass AxisLockLabel : public ClickableLabel\n{\n\tQ_OBJECT\n\npublic:\n\texplicit AxisLockLabel(const int axis_id, const AxisBoundary axis_boundary,\n\t\tconst QString &text = \"\", QWidget *parent = nullptr);\n    ~AxisLockLabel();\n\n\tint get_axis_id() const;\n\tAxisBoundary get_axis_boundary() const;\n\tbool is_locked() const;\n\tvoid set_locked(bool locked);\n\npublic Q_SLOTS:\n\tvoid on_axis_lock_changed(const int axis_id,\n\t\tconst sv::ui::widgets::plot::AxisBoundary axis_boundary, bool locked);\nprivate:\n\tvoid setup_ui();\n\n\tconst int axis_id_;\n\tconst AxisBoundary axis_boundary_;\n\tQPixmap unlocked_pixmap_;\n\tQPixmap locked_pixmap_;\n\tbool locked_;\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_AXISLOCKLABEL_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/axispopup.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QCheckBox>\n#include <QDialogButtonBox>\n#include <QDoubleValidator>\n#include <QFormLayout>\n#include <QHBoxLayout>\n#include <QLabel>\n#include <QLineEdit>\n#include <QShowEvent>\n#include <QVBoxLayout>\n#include <QWidget>\n#include <qwt_scale_engine.h>\n\n#include \"axispopup.hpp\"\n#include \"src/ui/widgets/popup.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nAxisPopup::AxisPopup(Plot *plot, int axis_id, QWidget *parent) :\n\tPopup(parent),\n\tplot_(plot),\n\taxis_id_(axis_id)\n{\n\tsetup_ui();\n}\n\n\nvoid AxisPopup::setup_ui()\n{\n\tQFormLayout *form_layout = new QFormLayout;\n\n\t// Lower boundary\n\tdouble lower_value = plot_->axisScaleDiv(axis_id_).lowerBound();\n\taxis_lower_edit_ = new QLineEdit();\n\taxis_lower_edit_->setValidator(new QDoubleValidator());\n\taxis_lower_edit_->setText(QString(\"%1\").arg(lower_value, 0, 'f'));\n\tQString lower_label;\n\tif (axis_id_ == QwtPlot::xTop  || axis_id_ == QwtPlot::xBottom)\n\t\tlower_label = tr(\"Left boundary\");\n\telse\n\t\tlower_label = tr(\"Bottom boundary\");\n\tconnect(axis_lower_edit_, &QLineEdit::returnPressed,\n\t\tthis, &AxisPopup::on_accept);\n\n\taxis_lower_locked_check_ = new QCheckBox(tr(\"Locked\"));\n\taxis_lower_locked_check_->setChecked(plot_->is_axis_locked(\n\t\taxis_id_, AxisBoundary::LowerBoundary));\n\n\tQHBoxLayout *lower_layout = new QHBoxLayout;\n\tlower_layout->addWidget(axis_lower_edit_);\n\tlower_layout->addSpacing(15);\n\tlower_layout->addWidget(axis_lower_locked_check_);\n\tQWidget *lower_widget = new QWidget();\n\tlower_widget->setLayout(lower_layout);\n\n\t// Upper boundary\n\tdouble upper_value = plot_->axisScaleDiv(axis_id_).upperBound();\n\taxis_upper_edit_ = new QLineEdit();\n\taxis_upper_edit_->setValidator(new QDoubleValidator());\n\taxis_upper_edit_->setText(QString(\"%1\").arg(upper_value, 0, 'f'));\n\tQString upper_label;\n\tif (axis_id_ == QwtPlot::xTop  || axis_id_ == QwtPlot::xBottom)\n\t\tupper_label = tr(\"Right boundary\");\n\telse\n\t\tupper_label = tr(\"Top boundary\");\n\tconnect(axis_upper_edit_, &QLineEdit::returnPressed,\n\t\tthis, &AxisPopup::on_accept);\n\n\taxis_upper_locked_check_ = new QCheckBox(tr(\"Locked\"));\n\taxis_upper_locked_check_->setChecked(plot_->is_axis_locked(\n\t\taxis_id_, AxisBoundary::UpperBoundary));\n\n\tQHBoxLayout *upper_layout = new QHBoxLayout;\n\tupper_layout->addWidget(axis_upper_edit_);\n\tupper_layout->addSpacing(15);\n\tupper_layout->addWidget(axis_upper_locked_check_);\n\tQWidget *upper_widget = new QWidget();\n\tupper_widget->setLayout(upper_layout);\n\n\tif (axis_id_ == QwtPlot::xTop  || axis_id_ == QwtPlot::xBottom) {\n\t\tform_layout->addRow(lower_label, lower_widget);\n\t\tform_layout->addRow(upper_label, upper_widget);\n\t}\n\telse {\n\t\t// Reverse the display order for y axes\n\t\tform_layout->addRow(upper_label, upper_widget);\n\t\tform_layout->addRow(lower_label, lower_widget);\n\t}\n\n\tbool is_log_scale = false;\n\tif (dynamic_cast<QwtLogScaleEngine *>(plot_->axisScaleEngine(axis_id_)))\n\t\tis_log_scale = true;\n\taxis_log_check_ = new QCheckBox();\n\taxis_log_check_->setChecked(is_log_scale);\n\tform_layout->addRow(tr(\"Logarithmic scale\"), axis_log_check_);\n\n\tbutton_box_ = new QDialogButtonBox(\n\t\tQDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);\n\tform_layout->addWidget(button_box_);\n\tconnect(button_box_, &QDialogButtonBox::accepted,\n\t\tthis, &AxisPopup::on_accept);\n\tconnect(button_box_, &QDialogButtonBox::rejected,\n\t\tthis, &AxisPopup::close);\n\n\tthis->setLayout(form_layout);\n}\n\nvoid AxisPopup::showEvent(QShowEvent *event)\n{\n\twidgets::Popup::showEvent(event);\n}\n\nvoid AxisPopup::on_accept()\n{\n\tplot_->setAxisScale(axis_id_,\n\t\taxis_lower_edit_->text().toDouble(),\n\t\taxis_upper_edit_->text().toDouble());\n\n\tplot_->set_axis_locked(axis_id_, AxisBoundary::LowerBoundary,\n\t\taxis_lower_locked_check_->isChecked());\n\tplot_->set_axis_locked(axis_id_, AxisBoundary::UpperBoundary,\n\t\taxis_upper_locked_check_->isChecked());\n\n\tif (axis_log_check_->isChecked())\n\t\tplot_->setAxisScaleEngine(axis_id_, new QwtLogScaleEngine);\n\telse\n\t\tplot_->setAxisScaleEngine(axis_id_, new QwtLinearScaleEngine);\n\n\tplot_->replot();\n\tthis->close();\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/axispopup.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_AXISPOPUP_HPP\n#define UI_WIDGETS_PLOT_AXISPOPUP_HPP\n\n#include <QCheckBox>\n#include <QDialogButtonBox>\n#include <QLineEdit>\n#include <QShowEvent>\n#include <QWidget>\n\n#include \"src/ui/widgets/popup.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass AxisPopup : public widgets::Popup\n{\n\tQ_OBJECT\n\npublic:\n\tAxisPopup(Plot *plot, int axis_id, QWidget *parent);\n\nprivate:\n\tPlot *plot_;\n\tint axis_id_;\n\n\tQLineEdit *axis_lower_edit_;\n\tQCheckBox *axis_lower_locked_check_;\n\tQLineEdit *axis_upper_edit_;\n\tQCheckBox *axis_upper_locked_check_;\n\tQCheckBox *axis_log_check_;\n\tQDialogButtonBox *button_box_;\n\n\tvoid setup_ui();\n\tvoid showEvent(QShowEvent *event) override;\n\nprivate Q_SLOTS:\n\tvoid on_accept();\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_AXISPOPUP_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/basecurvedata.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <set>\n\n#include <QSettings>\n#include <QString>\n#include <QtGlobal>\n#include <QVariant>\n\n#include <qwt_series_data.h>\n\n#include \"basecurvedata.hpp\"\n#include \"src/data/datautil.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nBaseCurveData::BaseCurveData(CurveType curve_type) :\n\tQwtSeriesData<QPointF>(),\n\ttype_(curve_type),\n\trelative_time_(true)\n{\n}\n\nCurveType BaseCurveData::type() const\n{\n\treturn type_;\n}\n\nvoid BaseCurveData::set_relative_time(bool is_relative_time)\n{\n\trelative_time_ = is_relative_time;\n}\n\nbool BaseCurveData::is_relative_time() const\n{\n\treturn relative_time_;\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/basecurvedata.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_BASECURVEDATA_HPP\n#define UI_WIDGETS_PLOT_BASECURVEDATA_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QColor>\n#include <QObject>\n#include <QPointF>\n#include <QRectF>\n#include <QSettings>\n#include <QString>\n#include <qwt_series_data.h>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nenum class CurveType {\n\tTimeCurve,\n\tXYCurve\n};\n\nclass BaseCurveData : public QObject, public QwtSeriesData<QPointF>\n{\n\tQ_OBJECT\n\npublic:\n\texplicit BaseCurveData(CurveType curve_type);\n\tvirtual ~BaseCurveData() = default;\n\n\tCurveType type() const;\n\tvirtual QString name() const = 0;\n\tvirtual string id_prefix() const = 0;\n\tvoid set_relative_time(bool is_relative_time);\n\tbool is_relative_time() const;\n\n\tvirtual bool is_equal(const BaseCurveData *other) const = 0;\n\n\tvirtual QPointF sample(size_t i) const = 0;\n\tvirtual size_t size() const = 0;\n\tvirtual QRectF boundingRect() const = 0;\n\n\tvirtual QPointF closest_point(const QPointF &pos, double *dist) const = 0;\n\tvirtual sv::data::Quantity x_quantity() const = 0;\n\tvirtual set<sv::data::QuantityFlag> x_quantity_flags() const = 0;\n\tvirtual sv::data::Unit x_unit() const = 0;\n\tvirtual QString x_unit_str() const = 0;\n\tvirtual QString x_title() const = 0;\n\tvirtual sv::data::Quantity y_quantity() const = 0;\n\tvirtual set<sv::data::QuantityFlag> y_quantity_flags() const = 0;\n\tvirtual sv::data::Unit y_unit() const = 0;\n\tvirtual QString y_unit_str() const = 0;\n\tvirtual QString y_title() const = 0;\n\n\tvirtual void save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device) const = 0;\n\nprotected:\n\tconst CurveType type_;\n\tbool relative_time_;\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_BASECURVEDATA_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/curve.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n\n#include <QColor>\n#include <QDebug>\n#include <QObject>\n#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)\n#include <QRandomGenerator>\n#endif\n#include <QPen>\n#include <QSettings>\n#include <QUuid>\n#include <QVariant>\n#include <qwt_plot_curve.h>\n#include <qwt_plot_directpainter.h>\n#include <qwt_plot_marker.h>\n#include <qwt_symbol.h>\n#include <qwt_text.h>\n\n#include \"curve.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/util.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n#include \"src/ui/widgets/plot/timecurvedata.hpp\"\n#include \"src/ui/widgets/plot/xycurvedata.hpp\"\n\nusing std::shared_ptr;\n\nQ_DECLARE_METATYPE(QwtSymbol::Style)\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nCurve::Curve(BaseCurveData *curve_data, int x_axis_id, int y_axis_id,\n\t\tconst QString &custom_name, const QColor &custom_color) :\n\tcurve_data_(curve_data),\n\tplot_direct_painter_(new QwtPlotDirectPainter()),\n\tpainted_points_(0)\n{\n\tid_ = curve_data->id_prefix() + \":\" +\n\t\tutil::format_uuid(QUuid::createUuid());\n\n\tQPen pen;\n\t//pen.setColor(color_);\n\tpen.setWidthF(2.0);\n\tpen.setStyle(Qt::SolidLine);\n\tpen.setCosmetic(false);\n\n\tplot_curve_ = new QwtPlotCurve();\n\tplot_curve_->setYAxis(y_axis_id);\n\tplot_curve_->setXAxis(x_axis_id);\n\tplot_curve_->setStyle(QwtPlotCurve::Lines);\n\tplot_curve_->setPen(pen);\n\t// Set empty symbol, used in the PlotCurveConfigDialog.\n\tplot_curve_->setSymbol(new QwtSymbol(QwtSymbol::NoSymbol));\n\tplot_curve_->setRenderHint(QwtPlotItem::RenderAntialiased, true);\n\tplot_curve_->setPaintAttribute(QwtPlotCurve::ClipPolygons, false);\n\tplot_curve_->setData(curve_data_);\n\t//plot_curve_->setRawSamples(); // TODO: is this an option?\n\t// Curves have the lowest z order, everything else will be painted ontop.\n\tplot_curve_->setZ(1);\n\n\tset_name(custom_name);\n\tset_color(custom_color);\n}\n\nCurve::~Curve()\n{\n\tdelete plot_curve_;\n\tdelete plot_direct_painter_;\n}\n\n\nBaseCurveData *Curve::curve_data() const\n{\n\treturn curve_data_;\n}\n\nQwtPlotCurve *Curve::plot_curve() const\n{\n\treturn plot_curve_;\n}\n\nQwtPlotDirectPainter *Curve::plot_direct_painter() const\n{\n\treturn plot_direct_painter_;\n}\n\nvoid Curve::set_name(const QString &custom_name)\n{\n\tif (custom_name.size() > 0) {\n\t\thas_custom_name_ = true;\n\t\tname_ = custom_name;\n\t}\n\telse {\n\t\thas_custom_name_ = false;\n\t\tname_ = curve_data_->name();\n\t}\n\tplot_curve_->setTitle(name_);\n}\n\nQString Curve::name() const\n{\n\treturn name_;\n}\n\nstring Curve::id() const\n{\n\treturn id_;\n}\n\nint Curve::x_axis_id() const\n{\n\treturn plot_curve_->xAxis();\n}\n\nint Curve::y_axis_id() const\n{\n\treturn plot_curve_->yAxis();\n}\n\nvoid Curve::set_painted_points(size_t painted_points)\n{\n\tpainted_points_ = painted_points;\n}\n\nsize_t Curve::painted_points() const\n{\n\treturn painted_points_;\n}\n\nvoid Curve::set_color(const QColor &custom_color)\n{\n\tif (custom_color.isValid()) {\n\t\thas_custom_color_ = true;\n\t\tcolor_ = custom_color;\n\t}\n\telse {\n\t\thas_custom_color_ = false;\n\t\tcolor_ = Curve::default_color(\n\t\t\tcurve_data_->y_quantity(), curve_data_->y_quantity_flags());\n\t}\n\n\tQPen pen = plot_curve_->pen();\n\tpen.setColor(color_);\n\tplot_curve_->setPen(pen);\n}\n\nQColor Curve::color() const\n{\n\treturn color_;\n}\n\nvoid Curve::set_style(const Qt::PenStyle style)\n{\n\tQPen pen = plot_curve_->pen();\n\tpen.setStyle(style);\n\tplot_curve_->setPen(pen);\n}\n\nQt::PenStyle Curve::style() const\n{\n\treturn plot_curve_->pen().style();\n}\n\nvoid Curve::set_symbol(const QwtSymbol::Style style)\n{\n\tQwtSymbol *curve_symbol = new QwtSymbol(style);\n\tcurve_symbol->setBrush(QBrush(color_));\n\tcurve_symbol->setPen(color_, 2);\n\tif (style == QwtSymbol::XCross)\n\t\tcurve_symbol->setSize(QSize(8, 8));\n\telse\n\t\tcurve_symbol->setSize(QSize(4, 4));\n\tplot_curve_->setSymbol(curve_symbol);\n}\n\nQwtSymbol::Style Curve::symbol() const\n{\n\treturn plot_curve_->symbol()->style();\n}\n\nQwtPlotMarker *Curve::add_marker(const QString &name_postfix)\n{\n\tQwtSymbol *marker_symbol = new QwtSymbol(\n\t\tQwtSymbol::Diamond, QBrush(color_), QPen(color_), QSize(9, 9));\n\tQString marker_name = QString(\"M%1\").arg(name_postfix);\n\n\tQwtPlotMarker *marker = new QwtPlotMarker(marker_name);\n\tmarker->setSymbol(marker_symbol);\n\tmarker->setLineStyle(QwtPlotMarker::Cross);\n\tmarker->setLinePen(Qt::white, 1.0, Qt::DashLine);\n\tmarker->setXAxis(x_axis_id());\n\tmarker->setYAxis(y_axis_id());\n\t// Markers will be painted ontop of curves but below the markers label box.\n\tmarker->setZ(2);\n\n\t// Label\n\tQwtText marker_label = QwtText(marker_name);\n\tmarker_label.setColor(Qt::black);\n\tmarker_label.setPaintAttribute(QwtText::PaintBackground, true);\n\tQColor background(Qt::gray);\n\tbackground.setAlpha(200);\n\tmarker_label.setBackgroundBrush(background);\n\tQPen pen(Qt::black, 1.0, Qt::SolidLine);\n\tmarker_label.setBorderPen(pen);\n\tmarker_label.setBorderRadius(3);\n\tmarker->setLabel(marker_label);\n\tmarker->setLabelAlignment(Qt::AlignTop | Qt::AlignRight);\n\n\treturn marker;\n}\n\nvoid Curve::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tsettings.beginGroup(QString::fromStdString(id_));\n\tcurve_data_->save_settings(settings, origin_device);\n\tsettings.setValue(\"x_axis_id\", x_axis_id());\n\tsettings.setValue(\"y_axis_id\", y_axis_id());\n\tif (has_custom_name_)\n\t\tsettings.setValue(\"custom_name\", name_);\n\tif (has_custom_color_)\n\t\tsettings.setValue(\"custom_color\", color_);\n\t// Qt::PenSytle cannot be saved directly\n\tsettings.setValue(\"style\", QVariant(QPen(style())));\n\tsettings.setValue(\"symbol\", symbol());\n\n\tsettings.endGroup();\n}\n\nCurve *Curve::init_from_settings(\n\tSession &session, QSettings &settings, const QString &group,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tif (!group.startsWith(\"timecurve:\") && !group.startsWith(\"xycurve:\"))\n\t\treturn nullptr;\n\n\tsettings.beginGroup(group);\n\n\tBaseCurveData *curve_data = nullptr;\n\tif (group.startsWith(\"timecurve:\")) {\n\t\tcurve_data = TimeCurveData::init_from_settings(\n\t\t\tsession, settings, origin_device);\n\t}\n\telse if (group.startsWith(\"xycurve:\")) {\n\t\tcurve_data = XYCurveData::init_from_settings(\n\t\t\tsession, settings, origin_device);\n\t}\n\tif (!curve_data) {\n\t\tsettings.endGroup();\n\t\treturn nullptr;\n\t}\n\n\tint x_axis_id = settings.value(\"x_axis_id\").toInt();\n\tint y_axis_id = settings.value(\"y_axis_id\").toInt();\n\tQString custom_name = \"\";\n\tif (settings.contains(\"custom_name\"))\n\t\tcustom_name = settings.value(\"custom_name\").toString();\n\tQColor custom_color = QColor();\n\tif (settings.contains(\"custom_color\"))\n\t\tcustom_color = settings.value(\"custom_color\").value<QColor>();\n\n\tCurve *curve = new Curve(curve_data, x_axis_id, y_axis_id,\n\t\tcustom_name, custom_color);\n\n\tif (settings.contains(\"style\"))\n\t\tcurve->set_style(settings.value(\"style\").value<QPen>().style());\n\tif (settings.contains(\"symbol\"))\n\t\tcurve->set_symbol(settings.value(\"symbol\").value<QwtSymbol::Style>());\n\n\tsettings.endGroup();\n\n\treturn curve;\n}\n\nQColor Curve::default_color(sv::data::Quantity quantity,\n\tconst set<sv::data::QuantityFlag> &quantity_flags)\n{\n\t// First, try to get color from QSettings\n\tQColor curve_color = QColor();\n\tQSettings settings;\n\tif (SettingsManager::restore_settings() &&\n\t\t\tsettings.childGroups().contains(\"DefaultCurveColors\")) {\n\t\tsettings.beginGroup(\"DefaultCurveColors\");\n\t\tQString key = QString(\"%1_%2\").\n\t\t\targ(data::datautil::get_sr_quantity_id(quantity)).\n\t\t\targ(data::datautil::get_sr_quantity_flags_id(quantity_flags));\n\t\tif (settings.childKeys().contains(key))\n\t\t\tcurve_color = settings.value(key).value<QColor>();\n\t\tsettings.endGroup();\n\t}\n\tif (curve_color.isValid())\n\t\treturn curve_color;\n\n\t// Predefined colors\n\tif (quantity == sv::data::Quantity::Voltage &&\n\t\t\tquantity_flags.count(sv::data::QuantityFlag::DC) > 0)\n\t\treturn Qt::red;\n\tif (quantity == sv::data::Quantity::Voltage &&\n\t\t\tquantity_flags.count(sv::data::QuantityFlag::AC) > 0)\n\t\treturn Qt::darkRed;\n\tif (quantity == sv::data::Quantity::Voltage)\n\t\t// Fallback for Voltage without quantity flag\n\t\treturn Qt::red;\n\tif (quantity == sv::data::Quantity::Current &&\n\t\t\tquantity_flags.count(sv::data::QuantityFlag::DC) > 0)\n\t\treturn Qt::green;\n\tif (quantity == sv::data::Quantity::Current &&\n\t\t\tquantity_flags.count(sv::data::QuantityFlag::AC) > 0)\n\t\treturn Qt::darkGreen;\n\tif (quantity == sv::data::Quantity::Current)\n\t\t// Fallback for current without quantity flag\n\t\treturn Qt::green;\n\tif (quantity == sv::data::Quantity::Resistance)\n\t\treturn Qt::cyan;\n\tif (quantity == sv::data::Quantity::Power)\n\t\treturn Qt::yellow;\n\tif (quantity == sv::data::Quantity::Energy)\n\t\treturn Qt::darkYellow;\n\tif (quantity == sv::data::Quantity::Temperature)\n\t\treturn Qt::darkCyan;\n\tif (quantity == sv::data::Quantity::Capacitance)\n\t\treturn Qt::gray;\n\tif (quantity == sv::data::Quantity::Frequency)\n\t\treturn Qt::magenta;\n\tif (quantity == sv::data::Quantity::Time)\n\t\treturn Qt::darkMagenta;\n\tif (quantity == sv::data::Quantity::PowerFactor)\n\t\treturn Qt::lightGray;\n\tif (quantity == sv::data::Quantity::ElectricCharge)\n\t\treturn Qt::darkGray;\n\n\t// Random color for the rest\n#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)\n\treturn QColor::fromRgb(QRandomGenerator::global()->generate());\n#else\n\treturn QColor::fromRgb(qrand());\n#endif\n}\n\nvoid Curve::save_settings_default_color(sv::data::Quantity quantity,\n\tconst set<sv::data::QuantityFlag> &quantity_flags, const QColor &color)\n{\n\tQSettings settings;\n\tsettings.beginGroup(\"DefaultCurveColors\");\n\tQString key = QString(\"%1_%2\").\n\t\targ(data::datautil::get_sr_quantity_id(quantity)).\n\t\targ(data::datautil::get_sr_quantity_flags_id(quantity_flags));\n\tsettings.setValue(key, QVariant::fromValue(color));\n\tsettings.endGroup();\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/curve.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2020-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_CURVE_HPP\n#define UI_WIDGETS_PLOT_CURVE_HPP\n\n#include <memory>\n#include <string>\n#include <vector>\n\n#include <QColor>\n#include <QObject>\n#include <QSettings>\n#include <QString>\n#include <qwt_plot_curve.h>\n#include <qwt_plot_directpainter.h>\n#include <qwt_plot_marker.h>\n#include <qwt_symbol.h>\n\n#include \"src/data/datautil.hpp\"\n\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass BaseCurveData;\n\nclass Curve : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\tCurve(BaseCurveData *curve_data, int x_axis_id, int y_axis_id,\n\t\tconst QString &custom_name = \"\",\n\t\tconst QColor &custom_color = QColor());\n\t~Curve();\n\n\tstatic QColor default_color(sv::data::Quantity quantity,\n\t\tconst set<sv::data::QuantityFlag> &quantity_flags);\n\tstatic void save_settings_default_color(sv::data::Quantity quantity,\n\t\tconst set<sv::data::QuantityFlag> &quantity_flags, const QColor &color);\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device) const;\n\tstatic Curve *init_from_settings(\n\t\tSession &session, QSettings &settings, const QString &group,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\n\tBaseCurveData *curve_data() const;\n\tQwtPlotCurve *plot_curve() const;\n\tQwtPlotDirectPainter *plot_direct_painter() const;\n\tvoid set_name(const QString &custom_name);\n\tQString name() const;\n\tstring id() const;\n\tint x_axis_id() const;\n\tint y_axis_id() const;\n\tvoid set_painted_points(size_t painted_points);\n\tsize_t painted_points() const;\n\tvoid set_color(const QColor &custom_color);\n\tQColor color() const;\n\tvoid set_style(const Qt::PenStyle style);\n\tQt::PenStyle style() const;\n\tvoid set_symbol(const QwtSymbol::Style style);\n\tQwtSymbol::Style symbol() const;\n\tQwtPlotMarker *add_marker(const QString &name_postfix);\n\nprivate:\n\tBaseCurveData *curve_data_;\n\tQwtPlotCurve *plot_curve_;\n\tQwtPlotDirectPainter *plot_direct_painter_;\n\tbool has_custom_name_;\n\tQString name_;\n\tstring id_;\n\tsize_t painted_points_;\n\tbool has_custom_color_;\n\tQColor color_;\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_CURVE_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/plot.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n * This file is based on the QWT Oscilloscope Example.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cassert>\n#include <cmath>\n#include <memory>\n#include <string>\n#include <utility>\n\n#include <QtMath>\n#include <QBoxLayout>\n#include <QDateTime>\n#include <QDebug>\n#include <QEvent>\n#include <QHBoxLayout>\n#include <QPen>\n#include <QPoint>\n#include <QPointF>\n#include <QPushButton>\n#include <QRectF>\n#include <QSize>\n#include <QUuid>\n#include <QVariant>\n#include <QVBoxLayout>\n#include <qwt_curve_fitter.h>\n#include <qwt_date_scale_engine.h>\n#include <qwt_legend.h>\n#include <qwt_math.h>\n#include <qwt_painter.h>\n#include <qwt_picker_machine.h>\n#include <qwt_plot_canvas.h>\n#include <qwt_plot_curve.h>\n#include <qwt_plot_directpainter.h>\n#include <qwt_plot_grid.h>\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wdeprecated-declarations\"\n// This header uses deprecated declarations, disable checks.\n#include <qwt_plot_layout.h>\n#pragma GCC diagnostic pop\n#include <qwt_plot_textlabel.h>\n#include <qwt_plot_panner.h>\n#include <qwt_plot_picker.h>\n#include <qwt_scale_draw.h>\n#include <qwt_scale_map.h>\n#include <qwt_scale_widget.h>\n#include <qwt_symbol.h>\n\n#include \"plot.hpp\"\n#include \"src/session.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/dialogs/plotcurveconfigdialog.hpp\"\n#include \"src/ui/widgets/plot/axislocklabel.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n#include \"src/ui/widgets/plot/curve.hpp\"\n#include \"src/ui/widgets/plot/plotmagnifier.hpp\"\n#include \"src/ui/widgets/plot/plotscalepicker.hpp\"\n#include \"src/ui/widgets/plot/timecurvedata.hpp\"\n#include \"src/ui/widgets/plot/xycurvedata.hpp\"\n\nusing std::make_pair;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass Canvas : public QwtPlotCanvas\n{\npublic:\n\texplicit Canvas(QwtPlot *plot = nullptr) : QwtPlotCanvas(plot)\n\t{\n\t\t/*\n\t\t * NOTE:\n\t\t * The backing store is important, when working with widget overlays\n\t\t * (f.e rubberbands for zooming). Here we don't have them and the\n\t\t * internal backing store of QWidget is good enough.\n\t\t */\n\t\tsetPaintAttribute(QwtPlotCanvas::BackingStore, false);\n\t\t/*\n\t\t * NOTE:\n\t\t * ImmediatePaint is necessary so \"old\" curves will be deleted.\n\t\t * QwtPlot::repaint() in replot() will also work\n\t\t */\n\t\tsetPaintAttribute(QwtPlotCanvas::ImmediatePaint, true);\n\t\tsetBorderRadius(10);\n\n\t\tif (QwtPainter::isX11GraphicsSystem()) {\n\t\t\t/*\n\t\t\t * NOTE:\n\t\t\t * Disabling the backing store of Qt improves the performance for\n\t\t\t * the direct painter even more, but the canvas becomes a native\n\t\t\t * window of the window system, receiving paint events for resize\n\t\t\t * and expose operations. Those might be expensive when there are\n\t\t\t * many points and the backing store of the canvas is disabled. So\n\t\t\t * in this application we better don't disable both backing stores.\n\t\t\t */\n\t\t\tif (testPaintAttribute(QwtPlotCanvas::BackingStore)) {\n\t\t\t\tsetAttribute(Qt::WA_PaintOnScreen, true);\n\t\t\t\tsetAttribute(Qt::WA_NoSystemBackground, true);\n\t\t\t}\n\t\t}\n\n\t\tsetupPalette();\n\t}\n\nprivate:\n\tvoid setupPalette()\n\t{\n\t\tQPalette pal = palette();\n\n\t\tQLinearGradient gradient;\n\t\tgradient.setCoordinateMode(QGradient::StretchToDeviceMode);\n\t\tgradient.setColorAt(0.0, QColor(0, 49, 110));\n\t\tgradient.setColorAt(1.0, QColor(0, 87, 174));\n\n\t\tpal.setBrush(QPalette::Window, QBrush(gradient));\n\n\t\t// QPalette::WindowText is used for the curve color\n\t\tpal.setColor(QPalette::WindowText, Qt::green);\n\n\t\tsetPalette(pal);\n\t}\n};\n\nPlot::Plot(Session &session, QWidget *parent) : QwtPlot(parent),\n\tsession_(session),\n\tplot_interval_(200),\n\ttimer_id_(-1),\n\ttime_span_(120.),\n\tadd_time_(30.),\n\tactive_marker_(nullptr),\n\tmarkers_label_(nullptr),\n\tmarkers_label_alignment_(Qt::AlignBottom | Qt::AlignHCenter),\n\tmarker_select_picker_(nullptr),\n\tmarker_move_picker_(nullptr)\n{\n\tthis->setAutoReplot(false);\n\tthis->setCanvas(new Canvas());\n\n\t// This must be done, because when the QwtPlot widget is directly or\n\t// indirectly in a (Main)Window, therefor the minimum size is way to big.\n\tthis->setMinimumSize(250, 250);\n\t//qWarning() << \"Plot::Plot(): sizeHint() = \" << sizeHint() <<\n\t//\t\", minimumSizeHint() = \" << minimumSizeHint();\n\t//qWarning() << \"Plot::Plot(): size() = \" << size() <<\n\t//\t\", minimumSize() = \" << minimumSize();\n\n\tthis->plotLayout()->setAlignCanvasToScales(true);\n\n\tQwtLegend *legend = new QwtLegend;\n\tlegend->setDefaultItemMode(QwtLegendData::Clickable);\n\tthis->insertLegend(legend, QwtPlot::BottomLegend);\n\tconnect(legend, &QwtLegend::clicked, this, &Plot::on_legend_clicked);\n\n\tQwtPlotGrid *grid = new QwtPlotGrid();\n\tgrid->setPen(Qt::gray, 0.0, Qt::DotLine);\n\tgrid->enableX(true);\n\tgrid->enableXMin(true);\n\tgrid->enableY(true);\n\tgrid->enableYMin(false);\n\tgrid->attach(this);\n\n\t// Disable all x axis to have a known state for init_x_axis()\n\tthis->enableAxis(QwtPlot::xBottom, false);\n\tthis->enableAxis(QwtPlot::xTop, false);\n\t// Disable all y axis to have a known state for init_y_axis()\n\tthis->enableAxis(QwtPlot::yLeft, false);\n\tthis->enableAxis(QwtPlot::yRight, false);\n\n\t// Zooming and panning via the axes\n\t(void)new PlotScalePicker(this);\n\n\t// Panning via the canvas\n\tplot_panner_ = new QwtPlotPanner(this->canvas());\n\tconnect(plot_panner_, &QwtPlotPanner::panned, this, &Plot::lock_all_axis);\n\n\t// Zooming via the canvas\n\tplot_magnifier_ = new PlotMagnifier(this->canvas());\n\tconnect(plot_magnifier_, &PlotMagnifier::magnified,\n\t\tthis, &Plot::lock_all_axis);\n}\n\nPlot::~Plot()\n{\n\tthis->stop();\n\tfor (const auto &marker_pair : marker_curve_map_)\n\t\tdelete marker_pair.first;\n\tfor (const auto &curve_pair : curve_map_)\n\t\tdelete curve_pair.second;\n}\n\nvoid Plot::start()\n{\n\ttimer_id_ = startTimer(plot_interval_);\n}\n\nvoid Plot::stop()\n{\n\t//qWarning() << \"Plot::stop() for \" << curve_data_->name();\n\tkillTimer(timer_id_);\n}\n\nvoid Plot::replot()\n{\n\t//qWarning() << \"Plot::replot()\";\n\tfor (const auto &curve : curve_map_)\n\t\tcurve.second->set_painted_points(0);\n\n\tQwtPlot::replot();\n}\n\nstring Plot::add_curve(BaseCurveData *curve_data)\n{\n\tassert(curve_data);\n\n\t// Check y axis\n\tint y_axis_id = this->init_y_axis(curve_data);\n\tif (y_axis_id < 0)\n\t\treturn \"\";\n\n\t// Check x axis\n\tint x_axis_id = this->init_x_axis(curve_data);\n\tif (x_axis_id < 0)\n\t\treturn \"\";\n\n\tCurve *curve = new Curve(curve_data, x_axis_id, y_axis_id);\n\tcurve->plot_curve()->attach(this);\n\tcurve_map_.insert(make_pair(curve->id(), curve));\n\n\tQwtPlot::replot();\n\tQ_EMIT curve_added();\n\n\treturn curve->id();\n}\n\nbool Plot::add_curve(Curve *curve)\n{\n\tif (curve_map_.count(curve->id()) > 0)\n\t\treturn false;\n\n\t// Check y axis\n\tint y_axis_id = this->init_y_axis(curve->curve_data(), curve->y_axis_id());\n\tif (y_axis_id < 0)\n\t\treturn false;\n\n\t// Check x axis\n\tint x_axis_id = this->init_x_axis(curve->curve_data(), curve->x_axis_id());\n\tif (x_axis_id < 0)\n\t\treturn false;\n\n\tcurve->plot_curve()->attach(this);\n\tcurve_map_.insert(make_pair(curve->id(), curve));\n\n\tQwtPlot::replot();\n\tQ_EMIT curve_added();\n\n\treturn true;\n}\n\nvoid Plot::remove_curve(Curve *curve)\n{\n\t// Delete markers\n\tvector<QwtPlotMarker *> delete_markers;\n\tfor (const auto &mc_pair : marker_curve_map_) {\n\t\tif (mc_pair.second == curve)\n\t\t\tdelete_markers.push_back(mc_pair.first);\n\t}\n\tfor (const auto &marker : delete_markers) {\n\t\tremove_marker(marker);\n\t}\n\n\t// Delete curve\n\tcurve_map_.erase(curve->id());\n\tcurve->plot_curve()->detach();\n\tdelete curve;\n\n\tQ_EMIT curve_removed();\n}\n\nvoid Plot::remove_all_curves()\n{\n\tfor (const auto &curve_pair : curve_map_) {\n\t\tremove_curve(curve_pair.second);\n\t}\n}\n\nint Plot::init_x_axis(BaseCurveData *curve_data, int x_axis_id)\n{\n\tassert(curve_data);\n\n\tif (x_axis_id < 0) {\n\t\t// Check if there already is an axis with the same unit. This is done\n\t\t// via the strings to get potential AC/DC flags.\n\t\tfor (const auto &curve : curve_map_) {\n\t\t\tif (curve_data->x_unit_str() == curve.second->curve_data()->x_unit_str())\n\t\t\t\treturn curve.second->x_axis_id();\n\t\t}\n\t\t// No existing axis was found, try to use the bottom or top axis.\n\t\tif (!this->axisEnabled(QwtPlot::xBottom))\n\t\t\tx_axis_id = QwtPlot::xBottom;\n\t\telse if (!this->axisEnabled(QwtPlot::xTop))\n\t\t\tx_axis_id = QwtPlot::xTop;\n\t\telse\n\t\t\treturn -1;\n\t}\n\telse {\n\t\t// Check if the given axis id is already initialised with the proper\n\t\t// unit.\n\t\tfor (const auto &curve : curve_map_) {\n\t\t\tif (curve.second->x_axis_id() == x_axis_id &&\n\t\t\t\t\tcurve.second->curve_data()->x_unit_str() == curve_data->x_unit_str())\n\t\t\t\treturn x_axis_id;\n\t\t\telse if (curve.second->x_axis_id() == x_axis_id) // NOLINT\n\t\t\t\treturn -1;\n\t\t}\n\t}\n\n\tdouble min;\n\tdouble max;\n\tif (curve_data->type() == CurveType::TimeCurve &&\n\t\t\tcurve_data->is_relative_time()) {\n\t\tmin = 0.;\n\t\tmax = add_time_;\n\t}\n\telse if (curve_data->type() == CurveType::TimeCurve &&\n\t\t\t!curve_data->is_relative_time()) {\n\t\tmin = Session::session_start_timestamp;\n\t\tmax = min + add_time_;\n\t}\n\telse if (curve_data->type() == CurveType::XYCurve) {\n\t\t// Values +/- 10%\n\t\tmin = curve_data->boundingRect().left() -\n\t\t\t(std::fabs(curve_data->boundingRect().left()) * 0.1);\n\t\tmax = curve_data->boundingRect().right() +\n\t\t\t(std::fabs(curve_data->boundingRect().right()) * 0.1);\n\t}\n\telse {\n\t\tthrow std::runtime_error(\n\t\t\t\"Plot::init_x_axis(): Curve type not implemented!\");\n\t}\n\n\tthis->init_axis(x_axis_id, min, max, curve_data->x_title(), true);\n\n\tif (curve_data->type() == CurveType::TimeCurve &&\n\t\t\t!curve_data->is_relative_time())\n\t\tthis->setAxisScaleEngine(x_axis_id, new QwtDateScaleEngine());\n\n\treturn x_axis_id;\n}\n\nint Plot::init_y_axis(BaseCurveData *curve_data, int y_axis_id)\n{\n\tassert(curve_data);\n\n\tif (y_axis_id < 0) {\n\t\t// Check if there already is an axis with the same unit. This is done\n\t\t// via the strings to get potential AC/DC flags.\n\t\tfor (const auto &curve : curve_map_) {\n\t\t\tif (curve_data->y_unit_str() == curve.second->curve_data()->y_unit_str())\n\t\t\t\treturn curve.second->y_axis_id();\n\t\t}\n\t\t// No existing axis was found, try to use the left or right axis.\n\t\tif (!this->axisEnabled(QwtPlot::yLeft))\n\t\t\ty_axis_id = QwtPlot::yLeft;\n\t\telse if (!this->axisEnabled(QwtPlot::yRight))\n\t\t\ty_axis_id = QwtPlot::yRight;\n\t\telse\n\t\t\treturn -1;\n\t}\n\telse {\n\t\t// Check if the given axis id is already initialised with the proper\n\t\t// unit.\n\t\tfor (const auto &curve : curve_map_) {\n\t\t\tif (curve.second->y_axis_id() == y_axis_id &&\n\t\t\t\t\tcurve.second->curve_data()->y_unit_str() == curve_data->y_unit_str())\n\t\t\t\treturn y_axis_id;\n\t\t\telse if (curve.second->y_axis_id() == y_axis_id) // NOLINT\n\t\t\t\treturn -1;\n\t\t}\n\t}\n\n\t// Values +/- 10%\n\tdouble min = curve_data->boundingRect().bottom() -\n\t\t(std::fabs(curve_data->boundingRect().bottom()) * 0.1);\n\tdouble max = curve_data->boundingRect().top() +\n\t\t(std::fabs(curve_data->boundingRect().top()) * 0.1);\n\n\tthis->init_axis(y_axis_id, min, max, curve_data->y_title(), false);\n\n\treturn y_axis_id;\n}\n\nvoid Plot::init_axis(int axis_id, double min, double max, const QString &title,\n\tbool auto_scale)\n{\n\tmap<AxisBoundary, bool> locks;\n\tlocks.insert(make_pair<AxisBoundary, bool>(\n\t\tAxisBoundary::LowerBoundary, false));\n\tlocks.insert(make_pair<AxisBoundary, bool>(\n\t\tAxisBoundary::UpperBoundary, false));\n\taxis_lock_map_.insert(make_pair(axis_id, locks));\n\n\tthis->setAxisTitle(axis_id, title);\n\tthis->setAxisScale(axis_id, min, max);\n\tthis->setAxisAutoScale(axis_id, auto_scale); // TODO: Not working!?\n\tthis->enableAxis(axis_id);\n\tthis->add_axis_icons(axis_id);\n}\n\nvoid Plot::add_axis_icons(const int axis_id)\n{\n\tAxisLockLabel *upper_lock_label = new AxisLockLabel(\n\t\taxis_id, AxisBoundary::UpperBoundary, \"\");\n\tconnect(upper_lock_label, &AxisLockLabel::clicked,\n\t\tthis, &Plot::on_axis_lock_clicked);\n\tconnect(this, &Plot::axis_lock_changed,\n\t\tupper_lock_label, &AxisLockLabel::on_axis_lock_changed);\n\n\tAxisLockLabel *lower_lock_label = new AxisLockLabel(\n\t\taxis_id, AxisBoundary::LowerBoundary, \"\");\n\tconnect(lower_lock_label, &AxisLockLabel::clicked,\n\t\tthis, &Plot::on_axis_lock_clicked);\n\tconnect(this, &Plot::axis_lock_changed,\n\t\tlower_lock_label, &AxisLockLabel::on_axis_lock_changed);\n\n\tQBoxLayout *scale_layout;\n\tif (axis_id == QwtPlot::xTop || axis_id == QwtPlot::xBottom) {\n\t\tscale_layout = new QHBoxLayout();\n\t\tif (axis_id == QwtPlot::xTop)\n\t\t\tscale_layout->setAlignment(Qt::AlignTop);\n\t\telse\n\t\t\tscale_layout->setAlignment(Qt::AlignBottom);\n\t\tscale_layout->addWidget(lower_lock_label);\n\t\tscale_layout->addStretch(1);\n\t\tscale_layout->addWidget(upper_lock_label);\n\t\t// NOTE: setContentsMargins() places the locks more nicely in Windows.\n\t\tscale_layout->setContentsMargins(0, 2, 0, 2);\n\t}\n\telse {\n\t\tscale_layout = new QVBoxLayout();\n\t\tif (axis_id == QwtPlot::yLeft)\n\t\t\tscale_layout->setAlignment(Qt::AlignLeft);\n\t\telse\n\t\t\tscale_layout->setAlignment(Qt::AlignRight);\n\t\tscale_layout->addWidget(upper_lock_label);\n\t\tscale_layout->addStretch(1);\n\t\tscale_layout->addWidget(lower_lock_label);\n\t\t// NOTE: setContentsMargins() places the locks more nicely in Windows.\n\t\tscale_layout->setContentsMargins(2, 0, 2, 0);\n\t}\n\n\tQwtScaleWidget *scale_widget = this->axisWidget(axis_id);\n\tscale_widget->setLayout(scale_layout);\n}\n\nvoid Plot::set_axis_locked(int axis_id, AxisBoundary axis_boundary, bool locked)\n{\n\taxis_lock_map_[axis_id][axis_boundary] = locked;\n\tQ_EMIT axis_lock_changed(axis_id, axis_boundary, locked);\n}\n\nvoid Plot::set_all_axis_locked(bool locked)\n{\n\tfor (const auto &axis_lock : axis_lock_map_) {\n\t\tset_axis_locked(axis_lock.first, AxisBoundary::LowerBoundary, locked);\n\t\tset_axis_locked(axis_lock.first, AxisBoundary::UpperBoundary, locked);\n\t}\n}\n\nvoid Plot::lock_all_axis()\n{\n\tthis->set_all_axis_locked(true);\n}\n\nvoid Plot::on_axis_lock_clicked()\n{\n\tAxisLockLabel *lock_label = qobject_cast<AxisLockLabel *>(sender());\n\tif (lock_label) {\n\t\tbool locked = is_axis_locked(\n\t\t\tlock_label->get_axis_id(), lock_label->get_axis_boundary());\n\n\t\tlock_label->set_locked(!locked);\n\t\tset_axis_locked(lock_label->get_axis_id(),\n\t\t\tlock_label->get_axis_boundary(), !locked);\n\t}\n}\n\nvoid Plot::set_time_span(double time_span)\n{\n\ttime_span_ = time_span;\n\n\t// time_span_ is used in rolling mode and oscilloscope mode. Find the\n\t// last/highest x value/timestamp and use it to calculate the new\n\t// x axis interval.\n\tdouble last_timestamp = .0;\n\tfor (const auto &curve : curve_map_) {\n\t\tif (curve.second->curve_data()->boundingRect().right() > last_timestamp)\n\t\t\tlast_timestamp = curve.second->curve_data()->boundingRect().right();\n\t}\n\t// max must be set to the last timestamp to keep the manual calculation\n\t// of the scale divs for oscilloscope mode working.\n\tdouble max = last_timestamp;\n\tdouble min = max - time_span_;\n\tthis->setAxisScale(QwtPlot::xBottom, min, max);\n\tthis->replot();\n}\n\nvoid Plot::add_marker(sv::ui::widgets::plot::Curve *curve)\n{\n\tauto *marker = curve->add_marker(\n\t\tQString::number(marker_curve_map().size()+1));\n\n\t// Initial marker position is in the middle of the plot screen or\n\t// at the end of the curve.\n\tQwtInterval x_interval = this->axisInterval(curve->x_axis_id());\n\tdouble x_mid = (x_interval.minValue() + x_interval.maxValue()) / 2;\n\tQwtInterval y_interval = this->axisInterval(curve->y_axis_id());\n\tdouble y_mid = (y_interval.minValue() + y_interval.maxValue()) / 2;\n\tmarker->setValue(\n\t\tcurve->curve_data()->closest_point(QPointF(x_mid, y_mid), nullptr));\n\n\t// Attach to plot\n\tmarker->attach(this);\n\n\tmarker_curve_map_.insert(make_pair(marker, curve));\n\tactive_marker_ = marker;\n\n\t// Add pickers for _all_ markers, no matter of the axis\n\tif (!marker_select_picker_) {\n\t\t// Use QwtPlot::xBottom and QwtPlot::yLeft as axis. We calculate the\n\t\t// canvas positions for the markers in on_marker_selected()\n\t\tmarker_select_picker_ = new QwtPlotPicker(\n\t\t\tQwtPlot::xBottom, QwtPlot::yLeft, QwtPlotPicker::NoRubberBand,\n\t\t\tQwtPicker::AlwaysOff, this->canvas());\n\t\tmarker_select_picker_->setStateMachine(new QwtPickerClickPointMachine());\n\t\tconnect(\n\t\t\tmarker_select_picker_, QOverload<const QPointF &>::of(&QwtPlotPicker::selected),\n\t\t\tthis, &Plot::on_marker_selected);\n\t}\n\tif (!marker_move_picker_) {\n\t\t// Use QwtPlot::xBottom and QwtPlot::yLeft as axis. We calculate the\n\t\t// canvas positions for the markers in on_marker_moved()\n\t\tmarker_move_picker_ = new QwtPlotPicker(\n\t\t\tQwtPlot::xBottom, QwtPlot::yLeft,\n\t\t\tQwtPlotPicker::NoRubberBand, QwtPicker::AlwaysOff, this->canvas());\n\t\tmarker_move_picker_->setStateMachine(new QwtPickerDragPointMachine());\n\t\tconnect(marker_move_picker_, &QwtPlotPicker::moved,\n\t\t\tthis, &Plot::on_marker_moved);\n\t}\n\t/*\n\t * TODO: Maybe we could use a QwtPickerTrackerMachine for mouse movement.\n\t * This way we can avoid the mouse click event (problems with QwtPlotPanner)\n\t * and also highlight the marker that in the \"selectable range\" of the\n\t * mouse pointer. Maybe this would be a performance issue?\n\t */\n\n\tupdate_markers_label();\n\treplot();\n\tQ_EMIT marker_added();\n}\n\nvoid Plot::add_diff_marker(QwtPlotMarker *marker1, QwtPlotMarker *marker2)\n{\n\tif (!marker1 || !marker2)\n\t\treturn;\n\n\tdiff_markers_.push_back(make_pair(marker1, marker2));\n\n\tupdate_markers_label();\n\treplot();\n\tQ_EMIT marker_added();\n}\n\n// TODO: Implement GUI remove marker function\nvoid Plot::remove_marker(QwtPlotMarker *marker)\n{\n\t// Delete diff markers.\n\tfor (auto it = diff_markers_.begin(); it != diff_markers_.end(); ) {\n\t\tif (it->first == marker || it->second == marker)\n\t\t\tit = diff_markers_.erase(it);\n\t\telse\n\t\t\t++it;\n\t}\n\n\t// Delete marker.\n\tmarker_curve_map_.erase(marker);\n\tif (active_marker_ == marker)\n\t\tactive_marker_ = nullptr;\n\tmarker->detach();\n\tdelete marker;\n\n\tif (marker_curve_map_.empty()) {\n\t\t// No markers left.\n\t\tdisconnect(\n\t\t\tmarker_select_picker_, QOverload<const QPointF &>::of(&QwtPlotPicker::selected),\n\t\t\tthis, &Plot::on_marker_selected);\n\t\tdelete marker_select_picker_;\n\t\tmarker_select_picker_ = nullptr;\n\t\tdisconnect(marker_move_picker_, &QwtPlotPicker::moved,\n\t\t\tthis, &Plot::on_marker_moved);\n\t\tdelete marker_move_picker_;\n\t\tmarker_move_picker_ = nullptr;\n\t}\n\n\tupdate_markers_label();\n\treplot();\n\tQ_EMIT marker_removed();\n}\n\nvoid Plot::on_marker_selected(const QPointF mouse_pos)\n{\n\tif (marker_curve_map_.empty())\n\t\treturn;\n\n\t// Mouse canvas coordinates. Use QwtPlot::xBottom and QwtPlot::yLeft\n\t// as axis for marker_select_picker_.\n\tconst double mouse_canvas_x = transform(QwtPlot::xBottom, mouse_pos.x());\n\tconst double mouse_canvas_y = transform(QwtPlot::yLeft, mouse_pos.y());\n\n\t// Check if mouse pointer is near a marker\n\tdouble d_min = 15.; // Minimum distance to marker for selecting\n\tdouble d_lowest = 1.0e10;\n\tQwtPlotMarker *selected_marker = nullptr;\n\tfor (const auto &mc_pair : marker_curve_map_) {\n\t\t// Marker canvas coordinates. Use axis ids form plot.\n\t\tconst double marker_canvas_x =\n\t\t\ttransform(mc_pair.second->x_axis_id(), mc_pair.first->xValue());\n\t\tconst double marker_canvas_y =\n\t\t\ttransform(mc_pair.second->y_axis_id(), mc_pair.first->yValue());\n\n\t\tconst double d_x = marker_canvas_x - mouse_canvas_x;\n\t\tconst double d_y = marker_canvas_y - mouse_canvas_y;\n\t\tconst double d_actual = qSqrt(qwtSqr(d_x) + qwtSqr(d_y));\n\t\tif (d_actual <= d_min && d_actual < d_lowest) {\n\t\t\td_lowest = d_actual;\n\t\t\tselected_marker = mc_pair.first;\n\t\t}\n\t}\n\tif (selected_marker) {\n\t\tplot_panner_->setEnabled(false);\n\t\tactive_marker_ = selected_marker;\n\t}\n\telse {\n\t\t/*\n\t\t * TODO: Maybe activate the plot panner via a timer after 1s of no\n\t\t * marker move event. This would avoid the \"double\" click to deselect\n\t\t * the marker/enable the panner (1) and register a new panning event (2)\n\t\t */\n\t\tplot_panner_->setEnabled(true);\n\t\tactive_marker_ = nullptr;\n\t}\n\n\t// TODO: connect/disconnect marker_move_picker_\n}\n\nvoid Plot::on_marker_moved(const QPointF mouse_pos)\n{\n\tif (!active_marker_)\n\t\treturn;\n\n\tBaseCurveData *curve_data = marker_curve_map_[active_marker_]->curve_data();\n\tQPointF marker_pos = curve_data->closest_point(mouse_pos, nullptr);\n\tactive_marker_->setValue(marker_pos);\n\n\tupdate_markers_label();\n\treplot();\n}\n\nvoid Plot::on_legend_clicked(const QVariant &item_info, int index)\n{\n\t(void)index;\n\n\tQwtPlotItem *plot_item = infoToItem(item_info);\n\tif (!plot_item)\n\t\treturn;\n\tCurve *curve = get_curve_from_plot_curve(\n\t\tstatic_cast<QwtPlotCurve *>(plot_item));\n\tif (!curve)\n\t\treturn;\n\n\tui::dialogs::PlotCurveConfigDialog dlg(curve, this);\n\tdlg.exec();\n}\n\nvoid Plot::update_curves()\n{\n\tfor (const auto &curve : curve_map_) {\n\t\tconst size_t painted_points = curve.second->painted_points();\n\t\tconst size_t num_points = curve.second->curve_data()->size();\n\t\tif (num_points > painted_points) {\n\t\t\t//qWarning() << QString(\"Plot::updateCurve(): num_points = %1, painted_points = %2\").\n\t\t\t//\targ(num_points).arg(painted_points);\n\t\t\tconst bool clip = !canvas()->testAttribute(Qt::WA_PaintOnScreen);\n\t\t\tif (clip) {\n\t\t\t\t/*\n\t\t\t\t * NOTE:\n\t\t\t\t * Depending on the platform setting a clip might be an\n\t\t\t\t * important performance issue. F.e. for Qt Embedded this\n\t\t\t\t * reduces the part of the backing store that has to be copied\n\t\t\t\t * out - maybe to an unaccelerated frame buffer device.\n\t\t\t\t */\n\n\t\t\t\tconst QwtScaleMap x_map = canvasMap(curve.second->x_axis_id());\n\t\t\t\tconst QwtScaleMap y_map = canvasMap(curve.second->y_axis_id());\n\t\t\t\tQRectF br = qwtBoundingRect(*curve.second->plot_curve()->data(),\n\t\t\t\t\t(int)painted_points - 1, (int)num_points - 1);\n\n\t\t\t\tcurve.second->plot_direct_painter()->setClipRegion(\n\t\t\t\t\tQwtScaleMap::transform(x_map, y_map, br).toRect());\n\t\t\t}\n\t\t\tcurve.second->plot_direct_painter()->drawSeries(\n\t\t\t\tcurve.second->plot_curve(), (int)painted_points - 1,\n\t\t\t\t(int)num_points - 1);\n\t\t\tcurve.second->set_painted_points(num_points);\n\t\t}\n\n\t\t//replot();\n\t}\n}\n\nvoid Plot::update_intervals()\n{\n\tbool intervals_changed = false;\n\n\tfor (const auto &curve : curve_map_) {\n\t\tif (update_x_interval(curve.second))\n\t\t\tintervals_changed = true;\n\t\tif (update_y_interval(curve.second))\n\t\t\tintervals_changed = true;\n\t}\n\n\tif (intervals_changed)\n\t\treplot();\n}\n\nbool Plot::update_x_interval(Curve *curve)\n{\n\tif (axis_lock_map_[QwtPlot::xBottom][AxisBoundary::LowerBoundary] &&\n\t\taxis_lock_map_[QwtPlot::xBottom][AxisBoundary::UpperBoundary])\n\t\treturn false;\n\n\tbool interval_changed = false;\n\tQRectF boundaries = curve->curve_data()->boundingRect();\n\tQwtInterval x_interval = this->axisInterval(QwtPlot::xBottom);\n\tdouble min = x_interval.minValue();\n\tdouble max = x_interval.maxValue();\n\n\t// There are no plot modes when showing xy curves, just extend the intervals\n\tif (curve->curve_data()->type() == CurveType::XYCurve) {\n\t\tif (!axis_lock_map_[QwtPlot::xBottom][AxisBoundary::LowerBoundary] &&\n\t\t\t\tboundaries.left() < min) {\n\t\t\t// New value - 10%\n\t\t\tmin = boundaries.left() - (std::fabs(boundaries.left()) * 0.1);\n\t\t\tinterval_changed = true;\n\t\t}\n\t\tif (!axis_lock_map_[QwtPlot::xBottom][AxisBoundary::UpperBoundary] &&\n\t\t\t\tboundaries.right() > max) {\n\t\t\t// New value + 10%\n\t\t\tmax = boundaries.right() + (std::fabs(boundaries.right()) * 0.1);\n\t\t\tinterval_changed = true;\n\t\t}\n\n\t\tif (interval_changed)\n\t\t\tsetAxisScale(QwtPlot::xBottom, min, max);\n\t}\n\t// Handle the Additive plot mode\n\telse if (update_mode_ == PlotUpdateMode::Additive) {\n\t\tif (!axis_lock_map_[QwtPlot::xBottom][AxisBoundary::LowerBoundary] &&\n\t\t\t\tboundaries.left() < min) {\n\t\t\tmin = 0;\n\t\t\tinterval_changed = true;\n\t\t}\n\t\tif (!axis_lock_map_[QwtPlot::xBottom][AxisBoundary::UpperBoundary] &&\n\t\t\t\tboundaries.right() > max) {\n\t\t\tif (boundaries.right()+add_time_ > max)\n\t\t\t\tmax = boundaries.right() + add_time_;\n\t\t\telse\n\t\t\t\tmax = x_interval.maxValue() + add_time_;\n\t\t\tinterval_changed = true;\n\t\t}\n\n\t\tif (interval_changed)\n\t\t\tsetAxisScale(QwtPlot::xBottom, min, max);\n\t}\n\t// Handle the Rolling plot mode\n\telse if (update_mode_ == PlotUpdateMode::Rolling) {\n\t\t// TODO: axis locking. Lock/Unlock both upper and lower together!\n\t\tif (boundaries.right() <= max)\n\t\t\treturn false;\n\n\t\tif (boundaries.right() > max+time_span_)\n\t\t\tmin = boundaries.right();\n\t\telse\n\t\t\tmin += add_time_;\n\t\tmax = min + time_span_;\n\n\t\tinterval_changed = true;\n\t\tsetAxisScale(QwtPlot::xBottom, min, max);\n\t}\n\t// Handle the Oscilloscope plot mode\n\telse if (update_mode_ == PlotUpdateMode::Oscilloscope) {\n\t\t// TODO: axis locking. Lock/Unlock both upper and lower together?\n\t\tif (boundaries.right() <= max)\n\t\t\treturn false;\n\n\t\tif (boundaries.right() > max+time_span_)\n\t\t\tmin = boundaries.right();\n\t\telse\n\t\t\tmin += time_span_;\n\t\tmax = min + time_span_;\n\n\t\t/*\n\t\t * NOTE:\n\t\t * To avoid, that the grid is jumping, we disable the autocalculation\n\t\t * of the ticks and shift them manually instead.\n\t\t */\n\t\tQwtScaleDiv scaleDiv = axisScaleDiv(QwtPlot::xBottom);\n\t\tscaleDiv.setInterval(min, max);\n\t\tfor (int i = 0; i < QwtScaleDiv::NTickTypes; i++) {\n\t\t\tQList<double> ticks = scaleDiv.ticks(i);\n\t\t\tfor (int j = 0; j < ticks.size(); j++) {\n\t\t\t\tticks[j] += x_interval.width();\n\t\t\t}\n\t\t\tscaleDiv.setTicks(i, ticks);\n\t\t}\n\n\t\tinterval_changed = true;\n\t\tsetAxisScaleDiv(QwtPlot::xBottom, scaleDiv);\n\t\tcurve->set_painted_points(0);\n\t}\n\n\treturn interval_changed;\n}\n\nbool Plot::update_y_interval(const Curve *curve)\n{\n\tint y_axis_id = curve->y_axis_id();\n\tif (axis_lock_map_[y_axis_id][AxisBoundary::LowerBoundary] &&\n\t\t\taxis_lock_map_[y_axis_id][AxisBoundary::UpperBoundary])\n\t\treturn false;\n\n\tQRectF boundaries = curve->curve_data()->boundingRect();\n\tQwtInterval y_interval = this->axisInterval(y_axis_id);\n\tdouble min = y_interval.minValue();\n\tdouble max = y_interval.maxValue();\n\tbool interval_changed = false;\n\n\tif (!axis_lock_map_[y_axis_id][AxisBoundary::LowerBoundary] &&\n\t\t\tboundaries.bottom() < min) {\n\t\t// New value - 10%\n\t\tmin = boundaries.bottom() - (std::fabs(boundaries.bottom()) * 0.1);\n\t\tinterval_changed = true;\n\t}\n\tif (!axis_lock_map_[y_axis_id][AxisBoundary::UpperBoundary] &&\n\t\t\tboundaries.top() > max) {\n\t\t// New value + 10%\n\t\tmax = boundaries.top() + (std::fabs(boundaries.top()) * 0.1);\n\t\tinterval_changed = true;\n\t}\n\n\tif (interval_changed )\n\t\tsetAxisScale(y_axis_id, min, max);\n\treturn interval_changed;\n}\n\nvoid Plot::set_markers_label_alignment(int alignment)\n{\n\tmarkers_label_alignment_ = alignment;\n\tif (markers_label_) {\n\t\t// TODO: Maybe there is a better way to replot the label?\n\t\tmarkers_label_->detach();\n\t\tdelete markers_label_;\n\t\tmarkers_label_ = nullptr;\n\t\tupdate_markers_label();\n\t}\n}\n\nvoid Plot::update_markers_label()\n{\n\tif (!markers_label_) {\n\t\tmarkers_label_ = new QwtPlotTextLabel();\n\t\tmarkers_label_->setMargin(5);\n\t\t// The markers label will be painted ontop of curves.\n\t\tmarkers_label_->setZ(3);\n\t\tmarkers_label_->attach(this);\n\t}\n\n\tQString table(\"<table>\");\n\n\tfor (const auto &mc_pair : marker_curve_map_) {\n\t\ttable.append(\"<tr>\");\n\t\ttable.append(QString(\"<td width=\\\"50\\\" align=\\\"left\\\">%1:</td>\").\n\t\t\targ(mc_pair.first->title().text()));\n\t\ttable.append(QString(\"<td width=\\\"70\\\" align=\\\"right\\\">%2 %3</td>\").\n\t\t\targ(mc_pair.first->yValue()).\n\t\t\targ(mc_pair.second->curve_data()->y_unit_str()));\n\t\ttable.append(QString(\"<td width=\\\"70\\\" align=\\\"right\\\">%4 %5</td>\").\n\t\t\targ(mc_pair.first->xValue()).\n\t\t\targ(mc_pair.second->curve_data()->x_unit_str()));\n\t\ttable.append(\"</tr>\");\n\t}\n\n\tfor (const auto &marker_pair : diff_markers_) {\n\t\tdouble d_x = marker_pair.first->xValue() - marker_pair.second->xValue();\n\t\tdouble d_y = marker_pair.first->yValue() - marker_pair.second->yValue();\n\n\t\tQString x_unit(\"\");\n\t\tQString m1_x_unit =\n\t\t\tmarker_curve_map_[marker_pair.first]->curve_data()->x_unit_str();\n\t\tQString m2_x_unit =\n\t\t\tmarker_curve_map_[marker_pair.second]->curve_data()->x_unit_str();\n\t\tif (m1_x_unit == m2_x_unit)\n\t\t\tx_unit = m1_x_unit;\n\n\t\tQString y_unit(\"\");\n\t\tQString m1_y_unit =\n\t\t\tmarker_curve_map_[marker_pair.first]->curve_data()->y_unit_str();\n\t\tQString m2_y_unit =\n\t\t\tmarker_curve_map_[marker_pair.second]->curve_data()->y_unit_str();\n\t\tif (m1_y_unit == m2_y_unit)\n\t\t\ty_unit = m1_y_unit;\n\n\t\ttable.append(\"<tr>\");\n\t\ttable.append(QString(\"<td width=\\\"50\\\" align=\\\"left\\\">%1 - %2:</td>\").arg(\n\t\t\tmarker_pair.first->title().text(),\n\t\t\tmarker_pair.second->title().text()));\n\t\ttable.append(QString(\"<td width=\\\"70\\\" align=\\\"right\\\">%1 %2</td>\").\n\t\t\targ(d_y).arg(y_unit));\n\t\ttable.append(QString(\"<td width=\\\"70\\\" align=\\\"right\\\">%1 %2</td>\").\n\t\t\targ(d_x).arg(x_unit));\n\t\ttable.append(\"</tr>\");\n\t}\n\n\ttable.append(\"</table>\");\n\n\tQwtText text = QwtText(table);\n\ttext.setPaintAttribute(QwtText::PaintBackground, true);\n\tQColor background(Qt::gray);\n\tbackground.setAlpha(200);\n\ttext.setBackgroundBrush(background);\n\ttext.setBorderRadius(3);\n\tQPen pen;\n\tpen.setColor(Qt::black);\n\tpen.setWidthF(1.0);\n\tpen.setStyle(Qt::SolidLine);\n\ttext.setBorderPen(pen);\n\ttext.setRenderFlags(markers_label_alignment_);\n\tmarkers_label_->setText(text);\n}\n\nvoid Plot::timerEvent(QTimerEvent *event)\n{\n\tif (event->timerId() == timer_id_) {\n\t\tupdate_intervals();\n\t\tupdate_curves();\n\t\treturn;\n\t}\n\n\tQwtPlot::timerEvent(event);\n}\n\nvoid Plot::resizeEvent(QResizeEvent *event)\n{\n\tfor (const auto &curve : curve_map_) {\n\t\tcurve.second->plot_direct_painter()->reset();\n\t}\n\n\tQwtPlot::resizeEvent(event);\n}\n\nvoid Plot::showEvent(QShowEvent *event)\n{\n\t(void)event;\n\treplot();\n}\n\nbool Plot::eventFilter(QObject *object, QEvent *event)\n{\n\treturn QwtPlot::eventFilter(object, event);\n}\n\nvoid Plot::save_settings(QSettings &settings, bool save_curves,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\t// TODO: Use Q_ENUM_NS for PlotUpdateMode to add meta-object support (Qt >= 5.8)\n\tsettings.setValue(\"update_mode\", (int)update_mode());\n\tsettings.setValue(\"time_span\", time_span_);\n\tsettings.setValue(\"add_time\", add_time_);\n\n\tif (!save_curves)\n\t\treturn;\n\tfor (const auto &curve : curve_map_) {\n\t\tcurve.second->save_settings(settings, origin_device);\n\t}\n}\n\nvoid Plot::restore_settings(QSettings &settings, bool restore_curves,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tif (settings.contains(\"update_mode\"))\n\t\tupdate_mode_ = static_cast<PlotUpdateMode>(\n\t\t\tsettings.value(\"update_mode\").toInt());\n\tif (settings.contains(\"time_span\"))\n\t\ttime_span_ = settings.value(\"time_span\").toDouble();\n\tif (settings.contains(\"add_time\"))\n\t\tadd_time_ = settings.value(\"add_time\").toDouble();\n\n\tif (!restore_curves)\n\t\treturn;\n\tconst auto groups = settings.childGroups();\n\tfor (const auto &group : groups) {\n\t\tif (group.startsWith(\"timecurve:\") || group.startsWith(\"xycurve:\")) {\n\t\t\tCurve *curve = Curve::init_from_settings(\n\t\t\t\tsession_, settings, group, origin_device);\n\t\t\tif (curve)\n\t\t\t\tadd_curve(curve);\n\t\t}\n\t}\n}\n\nCurve *Plot::get_curve_from_plot_curve(const QwtPlotCurve *plot_curve) const\n{\n\tfor (const auto &curve : curve_map_) {\n\t\tif (curve.second->plot_curve() == plot_curve)\n\t\t\treturn curve.second;\n\t}\n\treturn nullptr;\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/plot.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n * This file is based on the QWT Oscilloscope Example.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_PLOT_HPP\n#define UI_WIDGETS_PLOT_PLOT_HPP\n\n#include <map>\n#include <memory>\n#include <string>\n#include <vector>\n\n#include <QSettings>\n#include <QString>\n#include <QVariant>\n\n#include <qwt_interval.h>\n#include <qwt_plot.h>\n#include <qwt_plot_curve.h>\n#include <qwt_plot_directpainter.h>\n#include <qwt_plot_marker.h>\n#include <qwt_plot_textlabel.h>\n#include <qwt_plot_panner.h>\n#include <qwt_plot_picker.h>\n#include <qwt_scale_engine.h>\n#include <qwt_symbol.h>\n#include <qwt_system_clock.h>\n#include <qwt_text.h>\n\nusing std::map;\nusing std::pair;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass BaseCurveData;\nclass Curve;\nclass PlotMagnifier;\n\nenum class AxisBoundary {\n\tLowerBoundary,\n\tUpperBoundary\n};\n\nenum class PlotUpdateMode {\n\tAdditive = 0,\n\tRolling,\n\tOscilloscope\n};\n\n// TODO: Use tr(), QCoreApplication::translate(), QT_TR_NOOP() or\n//       QT_TRANSLATE_NOOP() for translation.\n//       See: http://doc.qt.io/qt-5/i18n-source-translation.html\ntypedef map<PlotUpdateMode, QString> plot_update_mode_name_map_t;\nstatic plot_update_mode_name_map_t plot_update_mode_name_map = {\n\t{ sv::ui::widgets::plot::PlotUpdateMode::Additive, QString(\"Additive\") },\n\t{ sv::ui::widgets::plot::PlotUpdateMode::Rolling, QString(\"Rolling\") },\n\t{ sv::ui::widgets::plot::PlotUpdateMode::Oscilloscope, QString(\"Oscilloscope\") },\n};\n\nclass Plot : public QwtPlot\n{\n\tQ_OBJECT\n\npublic:\n\texplicit Plot(Session &session, QWidget *parent = nullptr);\n\tvirtual ~Plot();\n\n\tvirtual void replot() override;\n\tvirtual bool eventFilter(QObject * object, QEvent *event) override;\n\t/**\n\t * Return the id of the new curve. Empty string when curve couldn't be\n\t * added.\n\t */\n\tstring add_curve(BaseCurveData *curve_data);\n\tbool add_curve(Curve *curve);\n\tvoid remove_curve(Curve *curve);\n\tvoid remove_all_curves();\n\t/** Return a map of all curves. */\n\tmap<string, Curve *> curve_map() const { return curve_map_; }\n\tbool is_axis_locked(int axis_id, AxisBoundary axis_boundary) { return axis_lock_map_[axis_id][axis_boundary]; }\n\tvoid set_axis_locked(int axis_id, AxisBoundary axis_boundary, bool locked);\n\tvoid set_all_axis_locked(bool locked);\n\tvoid set_plot_interval(int plot_interval) { plot_interval_ = plot_interval; }\n\tvoid set_update_mode(PlotUpdateMode update_mode) { update_mode_ = update_mode; }\n\tPlotUpdateMode update_mode() const { return update_mode_; };\n\tvoid set_time_span(double time_span);\n\tdouble time_span() const { return time_span_; }\n\tvoid set_add_time(double add_time) { add_time_ = add_time; }\n\tdouble add_time() const { return add_time_; }\n\tmap<QwtPlotMarker *, Curve *> marker_curve_map() const { return marker_curve_map_; }\n\tvoid set_markers_label_alignment(int alignment);\n\tint markers_label_alignment() const { return markers_label_alignment_; }\n\n\tvoid save_settings(QSettings &settings, bool save_curves,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device) const;\n\tvoid restore_settings(QSettings &settings, bool restore_curves,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\npublic Q_SLOTS:\n\tvoid start();\n\tvoid stop();\n\tvoid add_axis_icons(const int axis_id);\n\tvoid lock_all_axis();\n\tvoid on_axis_lock_clicked();\n\tvoid add_marker(sv::ui::widgets::plot::Curve *curve);\n\tvoid add_diff_marker(QwtPlotMarker *marker1, QwtPlotMarker *marker2);\n\tvoid remove_marker(QwtPlotMarker *marker);\n\tvoid on_marker_selected(const QPointF mouse_pos);\n\tvoid on_marker_moved(const QPointF mouse_pos);\n\tvoid on_legend_clicked(const QVariant &item_info, int index);\n\nprotected:\n\tvirtual void showEvent(QShowEvent *event) override;\n\tvirtual void resizeEvent(QResizeEvent *event) override;\n\tvirtual void timerEvent(QTimerEvent *event) override;\n\nprivate:\n\tint init_x_axis(BaseCurveData *curve_data, int x_axis_id = -1);\n\tint init_y_axis(BaseCurveData *curve_data, int y_axis_id = -1);\n\tvoid init_axis(int axis_id, double min, double max, const QString &title,\n\t\tbool auto_scale);\n\tvoid update_curves();\n\tvoid update_intervals();\n\tbool update_x_interval(Curve *curve);\n\tbool update_y_interval(const Curve *curve);\n\tvoid update_markers_label();\n\tCurve *get_curve_from_plot_curve(const QwtPlotCurve *plot_curve) const;\n\n\tSession &session_;\n\tmap<string, Curve *> curve_map_;\n\tmap<int, map<AxisBoundary, bool>> axis_lock_map_; // map<axis_id, map<AxisBoundary, locked>>\n\tint plot_interval_;\n\tint timer_id_;\n\tPlotUpdateMode update_mode_;\n\tdouble time_span_;\n\tdouble add_time_;\n\n\tQwtPlotPanner *plot_panner_;\n\tPlotMagnifier *plot_magnifier_;\n\n\tmap<QwtPlotMarker *, Curve *> marker_curve_map_;\n\tvector<pair<QwtPlotMarker *, QwtPlotMarker *>> diff_markers_;\n\tQwtPlotMarker *active_marker_;\n\tQwtPlotTextLabel *markers_label_;\n\tint markers_label_alignment_;\n\tQwtPlotPicker *marker_select_picker_;\n\tQwtPlotPicker *marker_move_picker_;\n\nQ_SIGNALS:\n\tvoid axis_lock_changed(int axis_id,\n\t\tsv::ui::widgets::plot::AxisBoundary axis_boundary, bool locked);\n\tvoid curve_added();\n\tvoid curve_removed();\n\tvoid marker_added();\n\tvoid marker_removed();\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_PLOT_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/plotmagnifier.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <QWidget>\n#include <qwt_plot_magnifier.h>\n\n#include \"plotmagnifier.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nPlotMagnifier::PlotMagnifier(QWidget *canvas) :\n\tQwtPlotMagnifier(canvas)\n{\n}\n\nvoid PlotMagnifier::rescale(double factor)\n{\n\tQwtPlotMagnifier::rescale(factor);\n\tQ_EMIT magnified(factor);\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/plotmagnifier.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_PLOTMAGNIFIER_HPP\n#define UI_WIDGETS_PLOT_PLOTMAGNIFIER_HPP\n\n#include <QWidget>\n#include <qwt_plot_magnifier.h>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\n/**\n * QwtPlotMagnifier doesn't have signals, so we have to create them.\n *\n * TODO: Reimplement to zomm in/out at the mouse pointer position, not only\n * at the center of the canvas.\n */\nclass PlotMagnifier : public QwtPlotMagnifier\n{\n    Q_OBJECT\n\npublic:\n\texplicit PlotMagnifier(QWidget *canvas);\n\nprotected:\n\tvoid rescale(double factor) override;\n\nQ_SIGNALS:\n\tvoid magnified(double factor);\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_PLOTMAGNIFIER_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/plotscalepicker.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n * This file is based on the QWT EventFilter Example.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <cmath>\n\n#include <QEvent>\n#include <QDebug>\n#include <QMouseEvent>\n#include <QObject>\n#include <QPoint>\n#include <QPointF>\n#include <QWheelEvent>\n\n#include <qwt_scale_draw.h>\n#include <qwt_scale_map.h>\n#include <qwt_scale_widget.h>\n\n#include \"plotscalepicker.hpp\"\n#include \"src/ui/widgets/plot/axispopup.hpp\"\n#include \"src/ui/widgets/plot/plot.hpp\"\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nPlotScalePicker::PlotScalePicker(Plot *plot) :\n\tQObject(plot),\n\tplot_(plot),\n\tis_double_clicked(false),\n\twheel_factor_(0.9)\n{\n\tfor (int i = 0; i < QwtPlot::axisCnt; i++) {\n\t\tQwtScaleWidget *scale_widget = plot->axisWidget(i);\n\t\tif (scale_widget)\n\t\t\tscale_widget->installEventFilter(this);\n\t}\n}\n\nbool PlotScalePicker::eventFilter(QObject *object, QEvent *event)\n{\n\tif (event->type() == QEvent::MouseButtonPress) {\n\t\tQwtScaleWidget *scale_widget = qobject_cast<QwtScaleWidget *>(object);\n\t\tif (scale_widget) {\n\t\t\tQMouseEvent *mouse_event = static_cast<QMouseEvent *>(event);\n\t\t\tif ((mouse_event->buttons() & Qt::LeftButton) != 0) {\n\t\t\t\tQPoint pos = mouse_event->pos();\n\t\t\t\tswitch (scale_widget->alignment()) {\n\t\t\t\tcase QwtScaleDraw::LeftScale:\n\t\t\t\tcase QwtScaleDraw::RightScale:\n\t\t\t\t\tlast_pan_p_value_ = pos.y();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::BottomScale:\n\t\t\t\tcase QwtScaleDraw::TopScale:\n\t\t\t\t\tlast_pan_p_value_ = pos.x();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\telse if (event->type() == QEvent::MouseMove) {\n\t\tQwtScaleWidget *scale_widget = qobject_cast<QwtScaleWidget *>(object);\n\t\tif (scale_widget) {\n\t\t\tQMouseEvent *mouse_event = static_cast<QMouseEvent *>(event);\n\t\t\tif ((mouse_event->buttons() & Qt::LeftButton) != 0) {\n\t\t\t\tQPoint pos = mouse_event->pos();\n\t\t\t\tint axis_id = -1;\n\t\t\t\tint p_value = 0;\n\t\t\t\tswitch (scale_widget->alignment()) {\n\t\t\t\tcase QwtScaleDraw::LeftScale:\n\t\t\t\t\taxis_id = QwtPlot::yLeft;\n\t\t\t\t\tp_value = pos.y();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::RightScale:\n\t\t\t\t\taxis_id = QwtPlot::yRight;\n\t\t\t\t\tp_value = pos.y();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::BottomScale:\n\t\t\t\t\taxis_id = QwtPlot::xBottom;\n\t\t\t\t\tp_value = pos.x();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::TopScale:\n\t\t\t\t\taxis_id = QwtPlot::xTop;\n\t\t\t\t\tp_value = pos.x();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst bool auto_replot = plot_->autoReplot();\n\t\t\t\tplot_->setAutoReplot(false);\n\n\t\t\t\tconst QwtScaleMap scale_map =\n\t\t\t\t\tscale_widget->scaleDraw()->scaleMap();\n\t\t\t\tconst double p1 = scale_map.transform(\n\t\t\t\t\tplot_->axisScaleDiv(axis_id).lowerBound());\n\t\t\t\tconst double p2 = scale_map.transform(\n\t\t\t\t\tplot_->axisScaleDiv(axis_id).upperBound());\n\n\t\t\t\tint p_diff = p_value - last_pan_p_value_;\n\t\t\t\tdouble s1 = scale_map.invTransform(p1 - p_diff);\n\t\t\t\tdouble s2 = scale_map.invTransform(p2 - p_diff);\n\t\t\t\tlast_pan_p_value_ = p_value;\n\n\t\t\t\tplot_->set_axis_locked(\n\t\t\t\t\taxis_id, AxisBoundary::LowerBoundary, true);\n\t\t\t\tplot_->set_axis_locked(\n\t\t\t\t\taxis_id, AxisBoundary::UpperBoundary, true);\n\n\t\t\t\tplot_->setAxisScale(axis_id, s1, s2);\n\t\t\t\tplot_->setAutoReplot(auto_replot);\n\t\t\t\tplot_->replot();\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\telse if (event->type() == QEvent::Wheel) {\n\t\tQwtScaleWidget *scale_widget = qobject_cast<QwtScaleWidget *>(object);\n\t\tif (scale_widget) {\n\t\t\tQWheelEvent *wheel_event = static_cast<QWheelEvent *>(event);\n\t\t\tif (wheel_event) {\n\t\t\t\tdouble factor = std::pow(wheel_factor_,\n\t\t\t\t\tstd::fabs(wheel_event->angleDelta().y() / 120.0));\n\t\t\t\tif (wheel_event->angleDelta().y() > 0)\n\t\t\t\t\tfactor = 1 / factor;\n\t\t\t\tfactor = std::fabs(factor);\n\t\t\t\tif (factor == 1.0 || factor == 0.0)\n\t\t\t\t\treturn true;\n\n\t\t\t\tint axis_id = -1;\n\t\t\t\tdouble mouse_pos = -1; // Mouse position in the scale widget.\n\t\t\t\tswitch (scale_widget->alignment()) {\n\t\t\t\tcase QwtScaleDraw::LeftScale:\n\t\t\t\t\taxis_id = QwtPlot::yLeft;\n\t\t\t\t\tmouse_pos = get_wheel_pos(wheel_event).y();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::RightScale:\n\t\t\t\t\taxis_id = QwtPlot::yRight;\n\t\t\t\t\tmouse_pos = get_wheel_pos(wheel_event).y();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::BottomScale:\n\t\t\t\t\taxis_id = QwtPlot::xBottom;\n\t\t\t\t\tmouse_pos = get_wheel_pos(wheel_event).x();\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::TopScale:\n\t\t\t\t\taxis_id = QwtPlot::xTop;\n\t\t\t\t\tmouse_pos = get_wheel_pos(wheel_event).x();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tconst bool auto_replot = plot_->autoReplot();\n\t\t\t\tplot_->setAutoReplot(false);\n\n\t\t\t\tconst QwtScaleMap scale_map = plot_->canvasMap(axis_id);\n\t\t\t\tdouble v1 = scale_map.s1();\n\t\t\t\tdouble v2 = scale_map.s2();\n\t\t\t\tif (scale_map.transformation()) {\n\t\t\t\t\t// The coordinate system of the paint device is\n\t\t\t\t\t// always linear\n\t\t\t\t\tv1 = scale_map.transform(v1);\n\t\t\t\t\tv2 = scale_map.transform(v2);\n\t\t\t\t}\n\t\t\t\tconst double center = scale_map.invTransform(mouse_pos);\n\t\t\t\tconst double upper = (v2 - center) * factor;\n\t\t\t\tconst double lower = (center - v1) * factor;\n\t\t\t\tv1 = center - lower;\n\t\t\t\tv2 = center + upper;\n\t\t\t\tif (scale_map.transformation()) {\n\t\t\t\t\tv1 = scale_map.invTransform(v1);\n\t\t\t\t\tv2 = scale_map.invTransform(v2);\n\t\t\t\t}\n\n\t\t\t\tplot_->set_axis_locked(\n\t\t\t\t\taxis_id, AxisBoundary::LowerBoundary, true);\n\t\t\t\tplot_->set_axis_locked(\n\t\t\t\t\taxis_id, AxisBoundary::UpperBoundary, true);\n\n\t\t\t\tplot_->setAxisScale(axis_id, v1, v2);\n\t\t\t\tplot_->setAutoReplot(auto_replot);\n\t\t\t\tplot_->replot();\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\telse if (event->type() == QEvent::MouseButtonDblClick) {\n\t\tQwtScaleWidget *scale_widget = qobject_cast<QwtScaleWidget *>(object);\n\t\tif (scale_widget) {\n\t\t\tQMouseEvent *mouse_event = static_cast<QMouseEvent *>(event);\n\t\t\tif ((mouse_event->buttons() & Qt::LeftButton) != 0) {\n\t\t\t\tis_double_clicked = true;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tis_double_clicked = false;\n\t}\n\telse if (event->type() == QEvent::MouseButtonRelease) {\n\t\tQwtScaleWidget *scale_widget = qobject_cast<QwtScaleWidget *>(object);\n\t\tif (scale_widget) {\n\t\t\tQMouseEvent *mouse_event = static_cast<QMouseEvent *>(event);\n\t\t\tif (mouse_event->button() == Qt::LeftButton && is_double_clicked) {\n\t\t\t\tis_double_clicked = false;\n\n\t\t\t\tint axis_id = -1;\n\t\t\t\tPopupPosition popup_pos = PopupPosition::Right;\n\t\t\t\tswitch (scale_widget->alignment()) {\n\t\t\t\tcase QwtScaleDraw::LeftScale:\n\t\t\t\t\taxis_id = QwtPlot::yLeft;\n\t\t\t\t\tpopup_pos = PopupPosition::Right;\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::RightScale:\n\t\t\t\t\taxis_id = QwtPlot::yRight;\n\t\t\t\t\tpopup_pos = PopupPosition::Left;\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::BottomScale:\n\t\t\t\t\taxis_id = QwtPlot::xBottom;\n\t\t\t\t\tpopup_pos = PopupPosition::Top;\n\t\t\t\t\tbreak;\n\t\t\t\tcase QwtScaleDraw::TopScale:\n\t\t\t\t\taxis_id = QwtPlot::xTop;\n\t\t\t\t\tpopup_pos = PopupPosition::Bottom;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tAxisPopup *const axis_popup =\n\t\t\t\t\tnew AxisPopup(plot_, axis_id, scale_widget);\n\t\t\t\taxis_popup->set_position(scale_widget->mapToGlobal(\n\t\t\t\t\tmouse_event->pos()), popup_pos);\n\t\t\t\taxis_popup->show();\n\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn QObject::eventFilter(object, event);\n}\n\nQPointF PlotScalePicker::get_wheel_pos(QWheelEvent *wheel_event)\n{\n#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)\n\treturn wheel_event->position();\n#else\n\treturn wheel_event->posF();\n#endif\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/plotscalepicker.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n * This file is based on the QWT EventFilter Example.\n *\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_PLOTSCALEPICKER_HPP\n#define UI_WIDGETS_PLOT_PLOTSCALEPICKER_HPP\n\n#include <QEvent>\n#include <QObject>\n#include <QPointF>\n#include <QWheelEvent>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass Plot;\n\nclass PlotScalePicker : public QObject\n{\n\tQ_OBJECT\n\npublic:\n\texplicit PlotScalePicker(Plot *plot);\n\n\tvirtual bool eventFilter(QObject *object, QEvent *event);\n\nprivate:\n\tPlot *plot_;\n\tbool is_double_clicked;\n\tint last_pan_p_value_;\n\tdouble wheel_factor_;\n\n\tQPointF get_wheel_pos(QWheelEvent *wheel_event);\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_PLOTSCALEPICKER_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/timecurvedata.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <set>\n\n#include <QPointF>\n#include <QRectF>\n#include <QSettings>\n#include <QString>\n\n#include \"timecurvedata.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nTimeCurveData::TimeCurveData(shared_ptr<sv::data::AnalogTimeSignal> signal) :\n\tBaseCurveData(CurveType::TimeCurve),\n\tsignal_(signal)\n{\n}\n\nbool TimeCurveData::is_equal(const BaseCurveData *other) const\n{\n\tconst TimeCurveData *tcd = dynamic_cast<const TimeCurveData *>(other);\n\tif (tcd == nullptr)\n\t\treturn false;\n\n\treturn signal_ == tcd->signal();\n}\n\nQPointF TimeCurveData::sample(size_t index) const\n{\n\t//signal_data_->lock();\n\n\tauto sample = signal_->get_sample(index, relative_time_);\n\tQPointF sample_point(sample.first, sample.second);\n\n\t//signal_data_->.unlock();\n\n\treturn sample_point;\n}\n\nsize_t TimeCurveData::size() const\n{\n\t// TODO: Synchronize x/y sample data\n\treturn signal_->sample_count();\n}\n\nQRectF TimeCurveData::boundingRect() const\n{\n\t/*\n\tqWarning() << \"TimeCurveData::boundingRect(): min time = \"\n\t\t<< signal_->first_timestamp(relative_time_);\n\tqWarning() << \"TimeCurveData::boundingRect(): max time = \"\n\t\t<< signal_->last_timestamp(relative_time_);\n\tqWarning() << \"TimeCurveData::boundingRect(): min value = \"\n\t\t<< signal_->min_value();\n\tqWarning() << \"TimeCurveData::boundingRect(): max value = \"\n\t\t<< signal_->max_value();\n\t*/\n\n\t// top left, bottom right\n\treturn QRectF(\n\t\tQPointF(signal_->first_timestamp(relative_time_), signal_->max_value()),\n\t\tQPointF(signal_->last_timestamp(relative_time_), signal_->min_value()));\n}\n\nQPointF TimeCurveData::closest_point(const QPointF &pos, double *dist) const\n{\n\t(void)dist;\n\tconst double x_value = pos.x();\n\tconst int index_max = (int)size() - 1;\n\n\t// Corner cases\n\tif (index_max < 0)\n\t\treturn QPointF(0, 0);\n\tif (x_value <= sample(0).x())\n\t\treturn sample(0);\n\tif (x_value >= sample(index_max).x())\n\t\treturn sample(index_max);\n\n\tsize_t index_min = 0;\n\tsize_t index = index_max;\n\n\twhile (index > 0) {\n\t\tconst size_t half = index >> 1;\n\t\tconst size_t index_mid = index_min + half;\n\n\t\tif (x_value < sample(index_mid).x()) {\n\t\t\tindex = half;\n\t\t}\n\t\telse {\n\t\t\tindex_min = index_mid + 1;\n\t\t\tindex -= half + 1;\n\t\t}\n\t}\n\n\treturn sample(index_min);\n}\n\nQString TimeCurveData::name() const\n{\n\treturn signal_->display_name();\n}\n\nstring TimeCurveData::id_prefix() const\n{\n\treturn \"timecurve\";\n}\n\nsv::data::Quantity TimeCurveData::x_quantity() const\n{\n\treturn sv::data::Quantity::Time;\n}\n\nset<sv::data::QuantityFlag> TimeCurveData::x_quantity_flags() const\n{\n\treturn set<data::QuantityFlag>();\n}\n\nsv::data::Unit TimeCurveData::x_unit() const\n{\n\treturn sv::data::Unit::Second;\n}\n\nQString TimeCurveData::x_unit_str() const\n{\n\treturn data::datautil::format_unit(x_unit());\n}\n\nQString TimeCurveData::x_title() const\n{\n\treturn QString(\"%1 [%2]\").\n\t\targ(data::datautil::format_quantity(x_quantity()), x_unit_str());\n}\n\nsv::data::Quantity TimeCurveData::y_quantity() const\n{\n\treturn signal_->quantity();\n}\n\nset<sv::data::QuantityFlag> TimeCurveData::y_quantity_flags() const\n{\n\treturn signal_->quantity_flags();\n}\n\nsv::data::Unit TimeCurveData::y_unit() const\n{\n\treturn signal_->unit();\n}\n\nQString TimeCurveData::y_unit_str() const\n{\n\treturn data::datautil::format_unit(y_unit(), y_quantity_flags());\n}\n\nQString TimeCurveData::y_title() const\n{\n\t// Don't use only the unit, so we can add AC/DC to axis label.\n\treturn QString(\"%1 [%2]\").\n\t\targ(data::datautil::format_quantity(y_quantity()), y_unit_str());\n}\n\nshared_ptr<sv::data::AnalogTimeSignal> TimeCurveData::signal() const\n{\n\treturn signal_;\n}\n\nvoid TimeCurveData::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tSettingsManager::save_signal(signal_, settings, origin_device);\n}\n\nTimeCurveData *TimeCurveData::init_from_settings(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto data_signal = SettingsManager::restore_signal(\n\t\tsession, settings, origin_device);\n\tif (!data_signal)\n\t\treturn nullptr;\n\n\treturn new TimeCurveData(\n\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(data_signal));\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/timecurvedata.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_TIMECURVEDATA_HPP\n#define UI_WIDGETS_PLOT_TIMECURVEDATA_HPP\n\n#include <memory>\n#include <set>\n#include <string>\n\n#include <QPointF>\n#include <QRectF>\n#include <QSettings>\n#include <QString>\n\n#include \"src/data/datautil.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nclass TimeCurveData : public BaseCurveData\n{\n\tQ_OBJECT\n\npublic:\n\texplicit TimeCurveData(shared_ptr<sv::data::AnalogTimeSignal> signal);\n\n\tbool is_equal(const BaseCurveData *other) const override;\n\n\tQPointF sample(size_t index) const override;\n\tsize_t size() const override;\n\tQRectF boundingRect() const override;\n\n\tQPointF closest_point(const QPointF &pos, double *dist) const override;\n\tQString name() const override;\n\tstring id_prefix() const override;\n\tsv::data::Quantity x_quantity() const override;\n\tset<sv::data::QuantityFlag> x_quantity_flags() const override;\n\tsv::data::Unit x_unit() const override;\n\tQString x_unit_str() const override;\n\tQString x_title() const override;\n\tsv::data::Quantity y_quantity() const override;\n\tset<sv::data::QuantityFlag> y_quantity_flags() const override;\n\tsv::data::Unit y_unit() const override;\n\tQString y_unit_str() const override;\n\tQString y_title() const override;\n\n\tshared_ptr<sv::data::AnalogTimeSignal> signal() const;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device) const override;\n\tstatic TimeCurveData *init_from_settings(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::data::AnalogTimeSignal> signal_;\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_TIMECURVEDATA_HPP\n"
  },
  {
    "path": "src/ui/widgets/plot/xycurvedata.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <vector>\n\n#include <QtMath>\n#include <QPointF>\n#include <QRectF>\n#include <QSettings>\n#include <QString>\n#include <qwt_math.h>\n\n#include \"xycurvedata.hpp\"\n#include \"src/session.hpp\"\n#include \"src/settingsmanager.hpp\"\n#include \"src/data/analogtimesignal.hpp\"\n#include \"src/data/datautil.hpp\"\n#include \"src/devices/basedevice.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n\nusing std::dynamic_pointer_cast;\nusing std::lock_guard;\nusing std::make_shared;\nusing std::mutex;\nusing std::set;\nusing std::shared_ptr;\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\nXYCurveData::XYCurveData(shared_ptr<sv::data::AnalogTimeSignal> x_t_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> y_t_signal) :\n\tBaseCurveData(CurveType::XYCurve),\n\tx_t_signal_(x_t_signal),\n\ty_t_signal_(y_t_signal),\n\tx_t_signal_pos_(0),\n\ty_t_signal_pos_(0)\n{\n\tx_data_ = make_shared<vector<double>>();\n\ty_data_ = make_shared<vector<double>>();\n\n\t// Prefill data vectors\n\tthis->on_sample_appended();\n\n\tconnect(x_t_signal_.get(), &sv::data::AnalogTimeSignal::sample_appended,\n\t\tthis, &XYCurveData::on_sample_appended);\n\tconnect(y_t_signal_.get(), &sv::data::AnalogTimeSignal::sample_appended,\n\t\tthis, &XYCurveData::on_sample_appended);\n}\n\nbool XYCurveData::is_equal(const BaseCurveData *other) const\n{\n\tconst XYCurveData *xycd = dynamic_cast<const XYCurveData *>(other);\n\tif (xycd == nullptr)\n\t\treturn false;\n\n\treturn (x_t_signal_ == xycd->x_t_signal()) &&\n\t\t(y_t_signal_ == xycd->y_t_signal());\n}\n\nQPointF XYCurveData::sample(size_t index) const\n{\n\tQPointF sample_point(x_data_->at(index), y_data_->at(index));\n\treturn sample_point;\n}\n\nsize_t XYCurveData::size() const\n{\n\treturn x_data_->size();\n}\n\nQRectF XYCurveData::boundingRect() const\n{\n\t// top left, bottom right\n\treturn QRectF(\n\t\tQPointF(x_t_signal_->min_value(), y_t_signal_->max_value()),\n\t\tQPointF(x_t_signal_->max_value(), y_t_signal_->min_value()));\n}\n\nQPointF XYCurveData::closest_point(const QPointF &pos, double *dist) const\n{\n\tconst size_t num_samples = size();\n\tif (num_samples == 0)\n\t\treturn QPointF(0, 0); // TODO\n\n\tsize_t index = -1;\n\tdouble d_min = 1.0e10;\n\n\tfor (size_t i=0; i < num_samples; i++) {\n\t\tconst QPointF sample_point = sample(i);\n\t\tconst double d_x = sample_point.x() - pos.x();\n\t\tconst double d_y = sample_point.y() - pos.y();\n\t\tconst double d_actual = qwtSqr(d_x) + qwtSqr(d_y);\n\t\tif (d_actual < d_min) {\n\t\t\tindex = i;\n\t\t\td_min = d_actual;\n\t\t}\n\t}\n\tif (dist)\n\t\t*dist = qSqrt(d_min);\n\n\treturn sample(index);\n}\n\nQString XYCurveData::name() const\n{\n\treturn y_t_signal_->display_name().append(\" -> \").\n\t\tappend(x_t_signal_->display_name());\n}\n\nstring XYCurveData::id_prefix() const\n{\n\treturn \"xycurve\";\n}\n\nsv::data::Quantity XYCurveData::x_quantity() const\n{\n\treturn x_t_signal_->quantity();\n}\n\nset<sv::data::QuantityFlag> XYCurveData::x_quantity_flags() const\n{\n\treturn x_t_signal_->quantity_flags();\n}\n\nsv::data::Unit XYCurveData::x_unit() const\n{\n\treturn x_t_signal_->unit();\n}\n\nQString XYCurveData::x_unit_str() const\n{\n\treturn data::datautil::format_unit(x_unit(), x_quantity_flags());\n}\n\n\nQString XYCurveData::x_title() const\n{\n\t// Don't use only the unit, so we can add AC/DC to axis label.\n\treturn QString(\"%1 [%2]\").\n\t\targ(data::datautil::format_quantity(x_quantity()), x_unit_str());\n}\n\nsv::data::Quantity XYCurveData::y_quantity() const\n{\n\treturn y_t_signal_->quantity();\n}\n\nset<sv::data::QuantityFlag> XYCurveData::y_quantity_flags() const\n{\n\treturn y_t_signal_->quantity_flags();\n}\n\nsv::data::Unit XYCurveData::y_unit() const\n{\n\treturn y_t_signal_->unit();\n}\n\nQString XYCurveData::y_unit_str() const\n{\n\treturn data::datautil::format_unit(y_unit(), y_quantity_flags());\n}\n\nQString XYCurveData::y_title() const\n{\n\t// Don't use only the unit, so we can add AC/DC to axis label.\n\treturn QString(\"%1 [%2]\").\n\t\targ(data::datautil::format_quantity(y_quantity()), y_unit_str());\n}\n\nshared_ptr<sv::data::AnalogTimeSignal> XYCurveData::x_t_signal() const\n{\n\treturn x_t_signal_;\n}\n\nshared_ptr<sv::data::AnalogTimeSignal> XYCurveData::y_t_signal() const\n{\n\treturn y_t_signal_;\n}\n\nvoid XYCurveData::save_settings(QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device) const\n{\n\tSettingsManager::save_signal(x_t_signal_, settings, origin_device, \"x_\");\n\tSettingsManager::save_signal(y_t_signal_, settings, origin_device, \"y_\");\n}\n\nXYCurveData *XYCurveData::init_from_settings(\n\tSession &session, QSettings &settings,\n\tshared_ptr<sv::devices::BaseDevice> origin_device)\n{\n\tauto x_t_data_signal = SettingsManager::restore_signal(\n\t\tsession, settings, origin_device, \"x_\");\n\tauto y_t_data_signal = SettingsManager::restore_signal(\n\t\tsession, settings, origin_device, \"y_\");\n\tif (!x_t_data_signal || !y_t_data_signal)\n\t\treturn nullptr;\n\n\treturn new XYCurveData(\n\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(x_t_data_signal),\n\t\tdynamic_pointer_cast<sv::data::AnalogTimeSignal>(y_t_data_signal));\n}\n\nvoid XYCurveData::on_sample_appended()\n{\n\tlock_guard<mutex> lock(sample_append_mutex_);\n\n\tshared_ptr<vector<double>> time = make_shared<vector<double>>();\n\tsv::data::AnalogTimeSignal::combine_signals(\n\t\tx_t_signal_, x_t_signal_pos_,\n\t\ty_t_signal_, y_t_signal_pos_,\n\t\ttime, x_data_, y_data_);\n}\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/plot/xycurvedata.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2017-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_PLOT_XYCURVEDATA_HPP\n#define UI_WIDGETS_PLOT_XYCURVEDATA_HPP\n\n#include <memory>\n#include <mutex>\n#include <set>\n#include <string>\n#include <vector>\n\n#include <QPointF>\n#include <QRectF>\n#include <QSettings>\n#include <QString>\n\n#include \"src/data/datautil.hpp\"\n#include \"src/ui/widgets/plot/basecurvedata.hpp\"\n\nusing std::mutex;\nusing std::set;\nusing std::shared_ptr;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\n\nclass Session;\n\nnamespace data {\nclass AnalogTimeSignal;\n}\nnamespace devices {\nclass BaseDevice;\n}\n\nnamespace ui {\nnamespace widgets {\nnamespace plot {\n\n/*\n * NOTE: XYCurveData must also inherit QObject (Important: first QObject,\n *       then BaseCurvedata), to get signals/slots working!\n */\nclass XYCurveData : public BaseCurveData\n{\n\tQ_OBJECT\n\npublic:\n\tXYCurveData(shared_ptr<sv::data::AnalogTimeSignal> x_t_signal,\n\t\tshared_ptr<sv::data::AnalogTimeSignal> y_t_signal);\n\n\tbool is_equal(const BaseCurveData *other) const override;\n\n\tQPointF sample(size_t index) const override;\n\tsize_t size() const override;\n\tQRectF boundingRect() const override;\n\n\tQPointF closest_point(const QPointF &pos, double *dist) const override;\n\tQString name() const override;\n\tstring id_prefix() const override;\n\tsv::data::Quantity x_quantity() const override;\n\tset<sv::data::QuantityFlag> x_quantity_flags() const override;\n\tsv::data::Unit x_unit() const override;\n\tQString x_unit_str() const override;\n\tQString x_title() const override;\n\tsv::data::Quantity y_quantity() const override;\n\tset<sv::data::QuantityFlag> y_quantity_flags() const override;\n\tsv::data::Unit y_unit() const override;\n\tQString y_unit_str() const override;\n\tQString y_title() const override;\n\n\tshared_ptr<sv::data::AnalogTimeSignal> x_t_signal() const;\n\tshared_ptr<sv::data::AnalogTimeSignal> y_t_signal() const;\n\n\tvoid save_settings(QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device) const override;\n\tstatic XYCurveData *init_from_settings(\n\t\tSession &session, QSettings &settings,\n\t\tshared_ptr<sv::devices::BaseDevice> origin_device);\n\nprivate:\n\tshared_ptr<sv::data::AnalogTimeSignal> x_t_signal_;\n\tshared_ptr<sv::data::AnalogTimeSignal> y_t_signal_;\n\tsize_t x_t_signal_pos_;\n\tsize_t y_t_signal_pos_;\n\t// TODO: use some sort of AnalogSignal instead of 2 vectors?\n\tshared_ptr<vector<double>> x_data_;\n\tshared_ptr<vector<double>> y_data_;\n\tmutex sample_append_mutex_;\n\nprivate Q_SLOTS:\n\tvoid on_sample_appended();\n\n};\n\n} // namespace plot\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_PLOT_XYCURVEDATA_HPP\n"
  },
  {
    "path": "src/ui/widgets/popup.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n\n#include <QApplication>\n#include <QCloseEvent>\n#include <QDebug>\n#include <QDesktopWidget>\n#include <QEvent>\n#include <QLineEdit>\n#include <QMouseEvent>\n#include <QObject>\n#include <QPainter>\n#include <QPaintEvent>\n#include <QPoint>\n#include <QPolygon>\n#include <QRect>\n#include <QRegion>\n#include <QResizeEvent>\n#include <QScreen>\n#include <QShowEvent>\n#include <QWidget>\n\n#include \"popup.hpp\"\n\nusing std::max;\nusing std::min;\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nconst int Popup::ArrowLength = 10;\nconst int Popup::ArrowOverlap = 3;\nconst int Popup::MarginWidth = 6;\n\nPopup::Popup(QWidget *parent) :\n\tQWidget(parent, Qt::Popup | Qt::FramelessWindowHint),\n\tpos_(PopupPosition::Left),\n\tmouse_pressed_(false)\n{\n}\n\nconst QPoint& Popup::point() const\n{\n\treturn point_;\n}\n\nPopupPosition Popup::position() const\n{\n\treturn pos_;\n}\n\nvoid Popup::set_position(const QPoint point, PopupPosition pos)\n{\n\tpoint_ = point;\n\tpos_ = pos;\n\n\tsetContentsMargins(\n\t\tMarginWidth + ((pos == PopupPosition::Right) ? ArrowLength : 0),\n\t\tMarginWidth + ((pos == PopupPosition::Bottom) ? ArrowLength : 0),\n\t\tMarginWidth + ((pos == PopupPosition::Left) ? ArrowLength : 0),\n\t\tMarginWidth + ((pos == PopupPosition::Top) ? ArrowLength : 0));\n}\n\nbool Popup::eventFilter(QObject *obj, QEvent *event)\n{\n\t(void)obj;\n\t(void)event;\n\n\treturn false;\n\n\t/*\n\t * Deactivaded, because when catching key_Enter and _key_Return in here,\n\t * the retunPressed() signal in AxisPopup isn't working correctly.\n\n\tQKeyEvent *key_event;\n\n\t(void)obj;\n\n\tif (event->type() == QEvent::KeyPress) {\n\t\tkey_event = static_cast<QKeyEvent*>(event);\n\t\tif (key_event->key() == Qt::Key_Enter ||\n\t\t\t\tkey_event->key() == Qt::Key_Return) {\n\t\t\tclose();\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n\t*/\n}\n\nvoid Popup::show()\n{\n\tQWidget::show();\n\n\t// We want to close the popup when the Enter key was\n\t// pressed and the first editable widget had focus.\n\tQLineEdit *le = this->findChild<QLineEdit*>();\n\tif (le) {\n\t\t// For combo boxes we need to hook into the parent of\n\t\t// the line edit (i.e. the QComboBox). For edit boxes\n\t\t// we hook into the widget directly.\n\t\tif (le->parent()->metaObject()->className() ==\n\t\t\t\tthis->metaObject()->className())\n\t\t\tle->installEventFilter(this);\n\t\telse\n\t\t\tle->parent()->installEventFilter(this);\n\n\t\tle->selectAll();\n\t\tle->setFocus();\n\t}\n}\n\nbool Popup::space_for_arrow() const\n{\n\t// Check if there is room for the arrow\n\tswitch (pos_) {\n\tcase PopupPosition::Right:\n\t\treturn point_.x() <= x();\n\n\tcase PopupPosition::Bottom:\n\t\treturn point_.y() <= y();\n\n\tcase PopupPosition::Left:\n\t\treturn point_.x() >= (x() + width());\n\n\tcase PopupPosition::Top:\n\t\treturn point_.y() >= (y() + height());\n\t}\n\n\treturn true;\n}\n\nQPolygon Popup::arrow_polygon() const\n{\n\tQPolygon poly;\n\n\tconst QPoint widget_point = mapFromGlobal(point_);\n\tconst int total_len = ArrowLength + ArrowOverlap;\n\n\tswitch (pos_) {\n\tcase PopupPosition::Right:\n\t\tpoly << QPoint(widget_point.x() + total_len, widget_point.y() - total_len);\n\t\tbreak;\n\n\tcase PopupPosition::Bottom:\n\t\tpoly << QPoint(widget_point.x() - total_len, widget_point.y() + total_len);\n\t\tbreak;\n\n\tcase PopupPosition::Left:\n\tcase PopupPosition::Top:\n\t\tpoly << QPoint(widget_point.x() - total_len, widget_point.y() - total_len);\n\t\tbreak;\n\t}\n\n\tpoly << widget_point;\n\n\tswitch (pos_) {\n\tcase PopupPosition::Right:\n\tcase PopupPosition::Bottom:\n\t\tpoly << QPoint(widget_point.x() + total_len, widget_point.y() + total_len);\n\t\tbreak;\n\n\tcase PopupPosition::Left:\n\t\tpoly << QPoint(widget_point.x() - total_len, widget_point.y() + total_len);\n\t\tbreak;\n\n\tcase PopupPosition::Top:\n\t\tpoly << QPoint(widget_point.x() + total_len, widget_point.y() - total_len);\n\t\tbreak;\n\t}\n\n\treturn poly;\n}\n\nQRegion Popup::arrow_region() const\n{\n\treturn QRegion(arrow_polygon());\n}\n\nQRect Popup::bubble_rect() const\n{\n\treturn QRect(\n\t\tQPoint((pos_ == PopupPosition::Right) ? ArrowLength : 0,\n\t\t\t(pos_ == PopupPosition::Bottom) ? ArrowLength : 0),\n\t\tQSize(\n\t\t\twidth() -\n\t\t\t\t((pos_ == PopupPosition::Left || pos_ == PopupPosition::Right) ?\n\t\t\t\t\tArrowLength : 0),\n\t\t\theight() -\n\t\t\t\t((pos_ == PopupPosition::Top || pos_ == PopupPosition::Bottom) ?\n\t\t\t\t\tArrowLength : 0)));\n}\n\nQRegion Popup::bubble_region() const\n{\n\tconst QRect rect(bubble_rect());\n\n\tconst int radius = MarginWidth;\n\tconst int diameter = 2 * radius;\n\treturn QRegion(rect.adjusted(radius, 0, -radius, 0))\n\t\t.united(QRegion(rect.adjusted(0, radius, 0, -radius)))\n\t\t.united(QRegion(rect.left(), rect.top(), diameter, diameter,\n\t\t\tQRegion::Ellipse))\n\t\t.united(QRegion(rect.right() - diameter, rect.top(), diameter, diameter,\n\t\t\tQRegion::Ellipse))\n\t\t.united(QRegion(rect.left(), rect.bottom() - diameter, diameter, diameter,\n\t\t\tQRegion::Ellipse))\n\t\t.united(QRegion(rect.right() - diameter, rect.bottom() - diameter,\n\t\t\tdiameter, diameter, QRegion::Ellipse));\n}\n\nQRegion Popup::popup_region() const\n{\n\tif (space_for_arrow())\n\t\treturn arrow_region().united(bubble_region());\n\telse // NOLINT\n\t\treturn bubble_region();\n}\n\nvoid Popup::reposition_widget()\n{\n\tQPoint new_pos;\n#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)\n\tQScreen *screen = QGuiApplication::screenAt(point_);\n\tif(!screen)\n\t\treturn;\n\tconst QRect screen_rect = screen->availableGeometry();\n#else\n\tconst QRect screen_rect = QApplication::desktop()->availableGeometry(\n\t\tQApplication::desktop()->screenNumber(point_));\n#endif\n\n\tif (pos_ == PopupPosition::Right || pos_ == PopupPosition::Left)\n\t\tnew_pos.ry() = -height() / 2;\n\telse\n\t\tnew_pos.rx() = -width() / 2;\n\n\tif (pos_ == PopupPosition::Left)\n\t\tnew_pos.rx() = -width();\n\telse if (pos_ == PopupPosition::Top)\n\t\tnew_pos.ry() = -height();\n\n\tnew_pos += point_;\n\tmove(max(min(new_pos.x(), screen_rect.right() - width()), screen_rect.left()),\n\t\tmax(min(new_pos.y(), screen_rect.bottom() - height()), screen_rect.top()));\n}\n\nvoid Popup::closeEvent(QCloseEvent *event)\n{\n\t(void)event;\n\tQ_EMIT closed();\n}\n\nvoid Popup::paintEvent(QPaintEvent *event)\n{\n\t(void)event;\n\n\tQPainter painter(this);\n\tpainter.setRenderHint(QPainter::Antialiasing);\n\n\tconst QColor outline_color(QApplication::palette().color(\n\t\tQPalette::Dark));\n\n\t// Draw the bubble\n\tconst QRegion bubble = bubble_region();\n\tconst QRegion bubble_outline = QRegion(rect()).subtracted(\n\t\tbubble.translated(1, 0).intersected(bubble.translated(0, 1).intersected(\n\t\tbubble.translated(-1, 0).intersected(bubble.translated(0, -1)))));\n\n\tpainter.setPen(Qt::NoPen);\n\tpainter.setBrush(QApplication::palette().brush(QPalette::Window));\n\tpainter.drawRect(rect());\n\n\t// Draw the arrow\n\tif (!space_for_arrow())\n\t\treturn;\n\n\tconst QPoint ArrowOffsets[] = {\n\t\tQPoint(1, 0), QPoint(0, -1), QPoint(-1, 0), QPoint(0, 1)};\n\n\tconst QRegion arrow(arrow_region());\n\tconst QRegion arrow_outline = arrow.subtracted(\n\t\tarrow.translated(ArrowOffsets[static_cast<int>(pos_)]));\n\n\tpainter.setClipRegion(bubble_outline.subtracted(arrow).united(arrow_outline));\n\tpainter.setBrush(outline_color);\n\tpainter.drawRect(rect());\n}\n\nvoid Popup::resizeEvent(QResizeEvent *event)\n{\n\t(void)event;\n\treposition_widget();\n\tsetMask(popup_region());\n}\n\n\nvoid Popup::mousePressEvent(QMouseEvent *event)\n{\n\t(void)event;\n\tmouse_pressed_ = true;\n}\n\nvoid Popup::mouseReleaseEvent(QMouseEvent *event)\n{\n\tassert(event);\n\n\tif (!mouse_pressed_)\n\t\treturn;\n\n\tmouse_pressed_ = false;\n\n\t// We need our own out-of-bounds click handler because QWidget counts\n\t// the drop-shadow region as inside the widget\n\tif (!bubble_rect().contains(event->pos()))\n\t\tclose();\n}\n\nvoid Popup::showEvent(QShowEvent *event)\n{\n\t(void)event;\n\treposition_widget();\n}\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n"
  },
  {
    "path": "src/ui/widgets/popup.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2013 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2018-2021 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UI_WIDGETS_POPUP_HPP\n#define UI_WIDGETS_POPUP_HPP\n\n#include <QCloseEvent>\n#include <QEvent>\n#include <QMouseEvent>\n#include <QObject>\n#include <QPaintEvent>\n#include <QPoint>\n#include <QPolygon>\n#include <QRect>\n#include <QRegion>\n#include <QResizeEvent>\n#include <QShowEvent>\n#include <QWidget>\n\nnamespace sv {\nnamespace ui {\nnamespace widgets {\n\nenum class PopupPosition : int\n{\n\tRight,\n\tTop,\n\tLeft,\n\tBottom\n};\n\nclass Popup : public QWidget\n{\n\tQ_OBJECT\n\nprivate:\n\tstatic const int ArrowLength;\n\tstatic const int ArrowOverlap;\n\tstatic const int MarginWidth;\n\npublic:\n\texplicit Popup(QWidget *parent);\n\n\tconst QPoint &point() const;\n\tPopupPosition position() const;\n\tvoid set_position(const QPoint point, PopupPosition pos);\n\tbool eventFilter(QObject *obj, QEvent *event) override;\n\tvoid show();\n\nprivate:\n\tbool space_for_arrow() const;\n\tQPolygon arrow_polygon() const;\n\tQRegion arrow_region() const;\n\tQRect bubble_rect() const;\n\tQRegion bubble_region() const;\n\tQRegion popup_region() const;\n\tvoid reposition_widget();\n\n\tvoid closeEvent(QCloseEvent *event) override;\n\tvoid paintEvent(QPaintEvent *event) override;\n\tvoid resizeEvent(QResizeEvent *event) override;\n\tvoid mousePressEvent(QMouseEvent *event) override;\n\tvoid mouseReleaseEvent(QMouseEvent *event) override;\n\nprotected:\n\tvoid showEvent(QShowEvent *event) override;\n\nQ_SIGNALS:\n\tvoid closed();\n\nprivate:\n\tQPoint point_;\n\tPopupPosition pos_;\n\tbool mouse_pressed_;\n\n};\n\n} // namespace widgets\n} // namespace ui\n} // namespace sv\n\n#endif // UI_WIDGETS_POPUP_HPP\n"
  },
  {
    "path": "src/util.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <algorithm>\n#include <cassert>\n#include <limits>\n#include <math.h>\n#include <sstream>\n#include <vector>\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QDateTime>\n#include <QDebug>\n#include <QTextStream>\n#include <QUuid>\n\n#include \"extdef.h\"\n#include \"util.hpp\"\n\nusing std::fixed;\nusing std::max;\nusing std::ostringstream;\nusing std::setfill;\nusing std::setprecision;\nusing std::showpos;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace util {\n\nstatic QTextStream &operator<<(QTextStream &stream, SIPrefix prefix)\n{\n\tswitch (prefix) {\n\tcase SIPrefix::yocto: return stream << 'y';\n\tcase SIPrefix::zepto: return stream << 'z';\n\tcase SIPrefix::atto:  return stream << 'a';\n\tcase SIPrefix::femto: return stream << 'f';\n\tcase SIPrefix::pico:  return stream << 'p';\n\tcase SIPrefix::nano:  return stream << 'n';\n\tcase SIPrefix::micro: return stream << QChar(0x03BC);\n\tcase SIPrefix::milli: return stream << 'm';\n\tcase SIPrefix::kilo:  return stream << 'k';\n\tcase SIPrefix::mega:  return stream << 'M';\n\tcase SIPrefix::giga:  return stream << 'G';\n\tcase SIPrefix::tera:  return stream << 'T';\n\tcase SIPrefix::peta:  return stream << 'P';\n\tcase SIPrefix::exa:   return stream << 'E';\n\tcase SIPrefix::zetta: return stream << 'Z';\n\tcase SIPrefix::yotta: return stream << 'Y';\n\n\tdefault: return stream;\n\t}\n}\n\nint exponent(SIPrefix prefix)\n{\n\treturn 3 * (static_cast<int>(prefix) - static_cast<int>(SIPrefix::none));\n}\n\nstatic SIPrefix successor(SIPrefix prefix)\n{\n\tassert(prefix != SIPrefix::yotta);\n\treturn static_cast<SIPrefix>(static_cast<int>(prefix) + 1);\n}\n\nstatic int prefix_from_si_prefix(SIPrefix prefix)\n{\n\treturn static_cast<int>(prefix) - static_cast<int>(SIPrefix::none);\n}\n\nstatic SIPrefix si_prefix_from_prefix(int prefix)\n{\n\treturn static_cast<SIPrefix>(static_cast<int>(SIPrefix::none) + prefix);\n}\n\n// Insert the timestamp value into the stream in fixed-point notation\n// (and honor the precision)\nstatic QTextStream &operator<<(QTextStream &stream, const Timestamp &timestamp)\n{\n\t// The multiprecision types already have a function and a stream insertion\n\t// operator to convert them to a string, however these functions abuse a\n\t// precision value of zero to print all available decimal places instead of\n\t// none, and the boost authors refuse to fix this because they don't want\n\t// to break buggy code that relies on this bug.\n\t// (https://svn.boost.org/trac/boost/ticket/10103)\n\t// Therefore we have to work around the case where precision is zero.\n\n\tint precision = stream.realNumberPrecision();\n\n\tostringstream ss;\n\tss << fixed;\n\n\tif ((stream.numberFlags() & QTextStream::ForceSign) != 0)\n\t\tss << showpos;\n\n\tif (0 == precision)\n\t\tss << setprecision(1) << round(timestamp);\n\telse\n\t\tss << setprecision(precision) << timestamp;\n\n\tstring str(ss.str());\n\tif (0 == precision) {\n\t\t// remove the separator and the unwanted decimal place\n\t\tstr.resize(str.size() - 2);\n\t}\n\n\treturn stream << QString::fromStdString(str);\n}\n\nint prefix_from_value(const double value, const int sr_digits)\n{\n\tdouble logval = log10(fabs(value));\n\tint prefix = static_cast<int>((logval / 3) - static_cast<int>(logval < 1));\n\n\tif (value == 0 || value == NAN ||\n\t\t\tvalue == std::numeric_limits<double>::infinity() ||\n\t\t\tvalue >= std::numeric_limits<double>::max() ||\n\t\t\tvalue <= std::numeric_limits<double>::lowest()) {\n\t\tprefix = prefix_from_si_prefix(SIPrefix::none);\n\t}\n\telse if (prefix < prefix_from_si_prefix(SIPrefix::yocto))\n\t\tprefix = prefix_from_si_prefix(SIPrefix::yocto);\n\telse if (prefix > prefix_from_si_prefix(SIPrefix::yotta))\n\t\tprefix = prefix_from_si_prefix(SIPrefix::yotta);\n\telse if (3 * prefix < -sr_digits)\n\t\tprefix = (-sr_digits + 2 * static_cast<int>(sr_digits < 0)) / 3;\n\n\treturn prefix;\n}\n\nint decimal_places_from_prefix(const int prefix, const int sr_digits)\n{\n\tint decimal_places = sr_digits + (3 * prefix);\n\tdecimal_places = decimal_places < 0 ? 0 : decimal_places;\n\n\treturn decimal_places;\n}\n\nvoid format_value_si(\n\tconst double value, const int total_digits, const int sr_digits,\n\tQString &value_str, QString &si_prefix_str, const bool use_locale)\n{\n\tint prefix = prefix_from_value(value, sr_digits);\n\tSIPrefix si_prefix = si_prefix_from_prefix(prefix);\n\tassert(si_prefix >= SIPrefix::yocto);\n\tassert(si_prefix <= SIPrefix::yotta);\n\n\tint decimal_places = decimal_places_from_prefix(prefix, sr_digits);\n\n\tdouble new_value = value * pow(10, -3 * prefix);\n\n\t// Check if, use current locale (%L) for formating.\n\tQString format_string = use_locale ? \"%L1\" : \"%1\";\n\tvalue_str = QString(format_string)\n\t\t.arg(new_value, total_digits, 'f', decimal_places, QChar(' '));\n\n\tQTextStream si_prefix_stream(&si_prefix_str);\n\tsi_prefix_stream << si_prefix;\n}\n\nvoid format_value_si_autoscale(\n\tconst double value, const int total_digits, const int decimal_places,\n\tQString &value_str, QString &si_prefix_str, const bool use_locale)\n{\n\tSIPrefix si_prefix;\n\tif (value == 0 || value == NAN ||\n\t\t\tvalue == std::numeric_limits<double>::infinity() ||\n\t\t\tvalue >= std::numeric_limits<double>::max() ||\n\t\t\tvalue <= std::numeric_limits<double>::lowest()) {\n\t\tsi_prefix = SIPrefix::none;\n\t}\n\telse {\n\t\tint exp = exponent(SIPrefix::yotta);\n\t\tsi_prefix = SIPrefix::yocto;\n\t\twhile ((fabs(value) * pow(10, exp)) > 999 &&\n\t\t\t\tsi_prefix < SIPrefix::yotta) {\n\t\t\tsi_prefix = successor(si_prefix);\n\t\t\texp -= 3;\n\t\t}\n\t}\n\tassert(si_prefix >= SIPrefix::yocto);\n\tassert(si_prefix <= SIPrefix::yotta);\n\n\tconst double multiplier = pow(10, -exponent(si_prefix));\n\n\t// Check if, use current locale (%L) for formating.\n\tQString format_string = use_locale ? \"%L1\" : \"%1\";\n\tvalue_str = QString(format_string).\n\t\targ(value * multiplier, total_digits, 'f', decimal_places, QChar(' '));\n\n\tQTextStream si_prefix_stream(&si_prefix_str);\n\tsi_prefix_stream << si_prefix;\n}\n\nQString format_time_si(const Timestamp &timestamp, SIPrefix prefix,\n\tunsigned int precision, const QString &unit, bool sign)\n{\n\tif (prefix == SIPrefix::unspecified) {\n\t\t// No prefix given, calculate it\n\n\t\tif (timestamp.is_zero()) {\n\t\t\tprefix = SIPrefix::none;\n\t\t}\n\t\telse {\n\t\t\tint exp = exponent(SIPrefix::yotta);\n\t\t\tprefix = SIPrefix::yocto;\n\t\t\twhile ((fabs(timestamp) * pow(Timestamp(10), exp)) > 999 &&\n\t\t\t\t\tprefix < SIPrefix::yotta) {\n\t\t\t\tprefix = successor(prefix);\n\t\t\t\texp -= 3;\n\t\t\t}\n\t\t}\n\t}\n\n\tassert(prefix >= SIPrefix::yocto);\n\tassert(prefix <= SIPrefix::yotta);\n\n\tconst Timestamp multiplier = pow(Timestamp(10), -exponent(prefix));\n\n\tQString str;\n\tQTextStream ts(&str);\n\tif (sign && !timestamp.is_zero())\n\t\tts.setNumberFlags(ts.numberFlags() | QTextStream::ForceSign);\n\tts << qSetRealNumberPrecision((int)precision) << (timestamp * multiplier)\n\t\t<< ' ' << prefix << unit;\n\n\treturn str;\n}\n\nQString format_time_si_adjusted(const Timestamp &timestamp, SIPrefix prefix,\n\tunsigned precision, const QString &unit, bool sign)\n{\n\t// The precision is always given without taking the prefix into account\n\t// so we need to deduct the number of decimals the prefix might imply\n\tconst int prefix_order = -exponent(prefix);\n\n\tconst unsigned int relative_prec = (prefix >= SIPrefix::none) ?\n\t\tprecision : max((int)(precision - prefix_order), 0);\n\n\treturn format_time_si(timestamp, prefix, relative_prec, unit, sign);\n}\n\n// Helper for 'format_time_minutes()'.\nstatic QString pad_number(unsigned int number, int length)\n{\n\treturn QString(\"%1\").arg(number, length, 10, QChar('0'));\n}\n\nQString format_time_minutes(const Timestamp &timestamp, signed precision,\n\tbool sign)\n{\n\tconst Timestamp whole_seconds = floor(abs(timestamp));\n\tconst Timestamp days = floor(whole_seconds / (60 * 60 * 24));\n\tconst unsigned int hours = fmod(whole_seconds / (60 * 60), 24).convert_to<uint>();\n\tconst unsigned int minutes = fmod(whole_seconds / 60, 60).convert_to<uint>();\n\tconst unsigned int seconds = fmod(whole_seconds, 60).convert_to<uint>();\n\n\tQString str;\n\tQTextStream ts(&str);\n\n\tif (timestamp < 0)\n\t\tts << \"-\";\n\telse if (sign)\n\t\tts << \"+\";\n\n\tbool use_padding = false;\n\n\t// DD\n\tif (days) {\n\t\tts << days.str().c_str() << \":\";\n\t\tuse_padding = true;\n\t}\n\n\t// HH\n\tif (hours || days) {\n\t\tts << pad_number(hours, use_padding ? 2 : 0) << \":\";\n\t\tuse_padding = true;\n\t}\n\n\t// MM\n\tts << pad_number(minutes, use_padding ? 2 : 0);\n\n\tts << \":\";\n\n\t// SS\n\tts << pad_number(seconds, 2);\n\n\tif (precision) {\n\t\tts << \".\";\n\n\t\tconst Timestamp fraction = fabs(timestamp) - whole_seconds;\n\n\t\tostringstream ss;\n\t\tss << fixed << setprecision(precision) << setfill('0') << fraction;\n\t\tstring fs = ss.str();\n\n\t\t// Copy all digits, inserting spaces as unit separators\n\t\tfor (int i = 1; i <= precision; i++) {\n\t\t\t// Start at index 2 to skip the \"0.\" at the beginning\n\t\t\tts << fs.at(1 + i);\n\n\t\t\tif ((i > 0) && (i % 3 == 0) && (i != precision))\n\t\t\t\tts << \" \";\n\t\t}\n\t}\n\n\treturn str;\n}\n\nQString format_time_date(double timestamp)\n{\n\tQDateTime date;\n\tdate.setMSecsSinceEpoch(static_cast<qint64>(timestamp * 1000));\n\treturn date.toString(\"yyyy.MM.dd hh:mm:ss.zzz\");\n}\n\nstring format_uuid(QUuid uuid)\n{\n#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)\n\treturn uuid.toString(QUuid::WithoutBraces).toStdString();\n#else\n\treturn uuid.toString().replace(\"{\", \"\").replace(\"}\", \"\").toStdString();\n#endif\n}\n\nvector<string> split_string(string text, const string &separator)\n{\n\tvector<string> result;\n\tsize_t pos;\n\n\twhile ((pos = text.find(separator)) != std::string::npos) {\n\t\tresult.push_back(text.substr(0, pos));\n\t\ttext = text.substr(pos + separator.length());\n\t}\n\tresult.push_back(text);\n\n\treturn result;\n}\n\nbool starts_with(const string &str, const string &start_str)\n{\n\treturn start_str.length() <= str.length() &&\n\t\tstd::equal(start_str.begin(), start_str.end(), str.begin());\n}\n\nint count_int_digits(int number)\n{\n\tif (number == 0)\n\t\treturn 0;\n\tint abs_number = abs(number);\n\tint digits = 1;\n\twhile (abs_number >= 10) {\n\t\tabs_number /= 10;\n\t\tdigits++;\n\t}\n\treturn digits;\n}\n\nint count_double_digits(double max_value, double step)\n{\n\tint count_int = util::count_int_digits((int)floor(max_value));\n\tint count_frac = util::count_decimal_places(fmod(max_value, 1.0));\n\tint count_step = util::count_decimal_places(step);\n\treturn count_int + (count_frac > count_step ? count_frac : count_step);\n}\n\nint count_decimal_places(double step)\n{\n\tdouble frac_part = fmod(step, 1.0);\n\tif (frac_part == 0)\n\t\treturn 0;\n\n\tstd::stringstream stream;\n\tstream << frac_part;\n\tstd::string frac_str = stream.str();\n\n\t// Check for exponential notation\n\tsize_t e_pos = frac_str.find('e');\n\tif (e_pos != std::string::npos) {\n\t\tstd::string exponent_str = frac_str.substr(e_pos + 1);\n\t\treturn -(std::stoi(exponent_str));\n\t}\n\n\t// Check for the decimal point\n\tsize_t point_pos = frac_str.find('.');\n\tif (point_pos != std::string::npos) {\n\t\treturn static_cast<int>(frac_str.length() - point_pos - 1);\n\t}\n\n\treturn 0;\n\n\t/*\n\t* Old implementation, didn't worked for e.g. `0.111`\n\tdouble frac_part = fmod(step, 1.0);\n\tif (frac_part == 0)\n\t\t\treturn 0;\n\tint decimal = (int)floor(1/frac_part) - 1;\n\treturn util::count_int_digits(decimal);\n\t*/\n}\n\nint get_sr_digits(double step)\n{\n\tif (step == 0)\n\t\treturn 0;\n\n\tint count_frac = util::count_decimal_places(fmod(step, 1.0));\n\tif (count_frac > 0)\n\t\treturn count_frac;\n\n\t// Count the zeros at the end of the integer part\n\tstd::stringstream stream;\n\tstream << static_cast<int>(floor(step));\n\tstd::string int_str = stream.str();\n\n\tint int_count = 0;\n\tsize_t int_str_pos = int_str.length();\n\twhile (int_str_pos > 0) {\n\t\tint_str_pos--;\n\t\tif (int_str[int_str_pos] != '0')\n\t\t\tbreak;\n\t\tint_count++;\n\t}\n\n\treturn -int_count;\n}\n\n/*\n * Based on https://stackoverflow.com/a/30338543\n */\nvector<string> parse_csv_line(const string &line)\n{\n\tenum State { UnquotedField, QuotedField, QuotedQuote } state = UnquotedField;\n\tstd::vector<std::string> fields{\"\"};\n\n\tsize_t index = 0; // index of the current field\n\tfor (char chr : line) {\n\t\tswitch (state) {\n\t\tcase State::UnquotedField:\n\t\t\tswitch (chr) {\n\t\t\tcase ',':\n\t\t\t\t// end of field\n\t\t\t\tfields.push_back(\"\");\n\t\t\t\tindex++;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\tstate = State::QuotedField;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tfields[index].push_back(chr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase State::QuotedField:\n\t\t\tswitch (chr) {\n\t\t\tcase '\"':\n\t\t\t\tstate = State::QuotedQuote;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tfields[index].push_back(chr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase State::QuotedQuote:\n\t\t\tswitch (chr) {\n\t\t\tcase ',':\n\t\t\t\t// , after closing quote\n\t\t\t\tfields.push_back(\"\");\n\t\t\t\tindex++;\n\t\t\t\tstate = State::UnquotedField;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\t// \"\" -> \"\n\t\t\t\tfields[index].push_back('\"');\n\t\t\t\tstate = State::QuotedField;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// end of quote\n\t\t\t\tstate = State::UnquotedField;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn fields;\n}\n\n} // namespace util\n} // namespace sv\n"
  },
  {
    "path": "src/util.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n * Copyright (C) 2017-2022 Frank Stettner <frank-stettner@gmx.net>\n *\n * This program is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program.  If not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef UTIL_HPP\n#define UTIL_HPP\n\n#include <cmath>\n#include <map>\n#include <set>\n#include <string>\n#include <vector>\n\n#ifndef Q_MOC_RUN\n#include <boost/serialization/nvp.hpp>\n#include <boost/multiprecision/cpp_dec_float.hpp>\n#endif\n\n#include <libsigrokcxx/libsigrokcxx.hpp>\n\n#include <QMetaType>\n#include <QString>\n#include <QUuid>\n\nusing std::map;\nusing std::set;\nusing std::string;\nusing std::vector;\n\nnamespace sv {\nnamespace util {\n\nenum class TimeUnit {\n\tTime = 1,\n\tSamples = 2\n};\n\nenum class SIPrefix {\n\tunspecified = -1,\n\tyocto, zepto,\n\tatto, femto, pico,\n\tnano, micro, milli,\n\tnone,\n\tkilo, mega, giga,\n\ttera, peta, exa,\n\tzetta, yotta\n};\n\n/// Returns the exponent that corresponds to a given prefix.\nint exponent(SIPrefix prefix);\n\n/// Timestamp type providing yoctosecond resolution.\ntypedef boost::multiprecision::number<\n\tboost::multiprecision::cpp_dec_float<24>,\n\tboost::multiprecision::et_off> Timestamp;\n\n/**\n * Returns the SI prefix as `int` based on the `value` and the sigrok digits.\n *\n * @param value The value.\n * @param sr_digits The digits from the sigrok analog payload. Something like\n *                  exponent with reversed polarity.\n *\n * TODO: move to data\n */\nint prefix_from_value(const double value, const int sr_digits);\n\n/**\n * Returns the number of decimal places based on the `prefix` and the sigrok digits.\n *\n * @param prefix The SI prefix as an `int`.\n * @param sr_digits The digits from the sigrok analog payload. Something like\n *                  exponent with reversed polarity.\n *\n * TODO: move to data\n */\nint decimal_places_from_prefix(const int prefix, const int sr_digits);\n\n/**\n * Formats and rescales a given double value and stores the results in\n * `value_str` and `si_prefix`.\n *\n * @param value The value to format.\n * @param total_digits The number of total digits (incl. the decimal places)\n *                     for `value_str`. This is directly passed to\n *                     `QString.arg()` as `fieldWidth`.\n * @param sr_digits The digits from the sigrok analog payload. Something like\n *                  exponent with reversed polarity.\n * @param value_str A reference to a `QString` to stre the digits to.\n * @param si_prefix A reference to a `QString` to store the SI prefix to.\n * @param use_locale Format `value_str` by using the locale settings, otherwise\n *                   the \"C\" locale will be used.\n *\n * TODO: move to data\n */\nvoid format_value_si(\n\tconst double value, const int total_digits, const int sr_digits,\n\tQString &value_str, QString &si_prefix_str, const bool use_locale = true);\n\nvoid format_value_si_autoscale(\n\tconst double value, const int total_digits, const int decimal_places,\n\tQString &value_str, QString &si_prefix_str, const bool use_locale = true);\n\n/**\n * Formats a given timestamp with the specified SI prefix.\n *\n * If 'prefix' is left 'unspecified', the function chooses a prefix so that\n * the value in front of the decimal point is between 1 and 999.\n *\n * The default value \"s\" for the unit argument makes the most sense when\n * formatting time values, but a different value can be given if the function\n * is reused to format a value of another quantity.\n *\n * @param timestamp The value to format.\n * @param prefix The SI prefix to use.\n * @param precision The number of digits after the decimal separator.\n * @param unit The unit of quantity.\n * @param sign Whether or not to add a sign also for positive numbers.\n *\n * @return The formatted value.\n *\n * TODO: move to data\n */\nQString format_time_si(const Timestamp& timestamp,\n\tSIPrefix prefix = SIPrefix::unspecified, unsigned precision = 0,\n\tconst QString &unit = \"s\", bool sign = true);\n\n/**\n * Wrapper around 'format_time_si()' that interprets the given 'precision'\n * value as the number of decimal places if the timestamp would be formatted\n * without a SI prefix (using 'SIPrefix::none') and adjusts the precision to\n * match the given 'prefix'\n *\n * @param timestamp The value to format.\n * @param prefix The SI prefix to use.\n * @param precision The number of digits after the decimal separator if the\n *        'prefix' would be 'SIPrefix::none', see above for more information.\n * @param unit The unit of quantity.\n * @param sign Whether or not to add a sign also for positive numbers.\n *\n * @return The formatted value.\n *\n * TODO: move to data\n */\nQString format_time_si_adjusted(const Timestamp& timestamp, SIPrefix prefix,\n\tunsigned precision = 0, const QString &unit = \"s\", bool sign = true);\n\n/**\n * Formats the given timestamp using \"[+-]DD:HH:MM:SS.mmm uuu nnn ppp...\" format.\n *\n * \"DD\" and \"HH\" are left out if they would be \"00\" (but if \"DD\" is generated,\n * \"HH\" is also always generated. The \"MM:SS\" part is always produced, the\n * number of subsecond digits can be influenced using the 'precision' parameter.\n *\n * @param timestamp The value to format.\n * @param precision The number of digits after the decimal separator.\n * @param sign Whether or not to add a sign also for positive numbers.\n *\n * @return The formatted value.\n *\n * TODO: move to data\n */\nQString format_time_minutes(const Timestamp& timestamp, signed precision = 0,\n\tbool sign = true);\n\n/**\n * Formats the given timestamp as a date using\n * \"yyyy.MM.dd hh:mm:ss.zzz\" QDateTime.toString() format.\n *\n * The number of subsecond digits can be influenced using the\n * 'precision' parameter.\n *\n * @param timestamp The value to format.\n * @param precision The number of digits after the decimal separator.\n *\n * @return The formatted date.\n *\n * TODO: move to data\n */\nQString format_time_date(double timestamp);\n\n/**\n * Format the given UUID as a string without braches.\n *\n * @param uuid The UUID to format.\n *\n * @return The formated UUID.\n */\nstring format_uuid(QUuid uuid);\n\n/**\n * Split a string into tokens at occurences of the separator.\n *\n * @param[in] text The input string to split.\n * @param[in] separator The delimiter between tokens.\n *\n * @return A vector of broken down tokens.\n */\nvector<string> split_string(string text, const string &separator);\n\n/**\n * Check if a string 'str' starts with the string 'start_str'.\n *\n * @param[in] str The string to check.\n * @param[in] start_str The start string.\n *\n * @return True if string str starts with string start_str.\n */\nbool starts_with(const string &str, const string &start_str);\n\n/**\n * Counts the number of digits for the given integer.\n *\n * @param[in] int The integers digits to count.\n *\n * @return Number of total digits.\n */\nint count_int_digits(int number);\n\n/**\n * Get the number of digits for the given double.\n *\n * @param[in] value The value of the double.\n * @param[in] step Step size of the double.\n *\n * @return Number of total digits\n */\nint count_double_digits(double value, double step);\n\n/**\n * Count the number of decimal places (number of digits after the decimal point)\n *\n * @param[in] step The step size from which to calculate the decimal places\n *\n * @return Number of decimal places\n */\nint count_decimal_places(double step);\n\n\n/**\n * Get the sr_digits as used in the analog payload from the step size.\n *\n * @param[in] step The step size from which to calculate the decimal places\n *\n * @return The sr_digits\n */\nint get_sr_digits(double step);\n\n/**\n * Parse a single CSV line.\n * Based on https://stackoverflow.com/a/30338543\n *\n * @param[in] line The CSV line to parse.\n *\n * @return A vector of the values.\n */\nvector<string> parse_csv_line(const string &line);\n\n} // namespace util\n} // namespace sv\n\nQ_DECLARE_METATYPE(sv::util::Timestamp)\n\n#endif // UTIL_HPP\n"
  },
  {
    "path": "stuff/gstreamer.txt",
    "content": "Docs\n====\n\n- https://code.launchpad.net/~richwareham/firtree/gstreamer-integration\n\n\nPipeline editors\n================\n\n- https://github.com/virinext/pipeviz\n- https://github.com/emdash/gst-editor\n- https://github.com/metratec/gst-editor\n  - https://code.google.com/archive/p/gst-editor/\n- https://code.launchpad.net/firtree\n  - https://code.launchpad.net/~richwareham/firtree/pipeline-editor\n  - https://code.launchpad.net/~richwareham/firtree/gstreamer-integration\n\n\nNode editors\n============\n\n- https://github.com/paceholder/nodeeditor\n"
  },
  {
    "path": "stuff/linuxgpib_build.txt",
    "content": "https://xdevs.com/guide/agilent_gpib_rpi/\nhttps://gist.github.com/turingbirds/6eb05c9267a6437183a9567700e8581a\nhttps://www.linuxquestions.org/questions/linux-software-2/how-to-enable-agilent-82357a-usb-gpib-dongle-and-remain-sane-4175498814/\nhttps://www.linuxquestions.org/questions/linux-software-2/how-to-enable-hp-82357b-usb-gpib-dongle-and-remain-sane-4175485218/\n\n\nMy Way (Debian Testing, Clone Agilent 82357B):\n==============================================\n\nAfter each Kernel update:\n\n- Install Kernel Headers (linux-headers-4.XX.X-X-all)\n- Install fxload (fxload)\n- Download last linux-gpib (https://sourceforge.net/projects/linux-gpib/files/)\n- Download last firmware (http://linux-gpib.sourceforge.net/firmware/)\n\nSince linux-gpib 4.2.0 there are two seperated builds (kernel modules + user space programms)\n\n# tar -xvzf linux-gpib-4.2.0.tar.gz\n# cd linux-gpib-4.2.0\n\n# tar -xvzf linux-gpib-kernel-4.2.0.tar.gz\n# cd linux-gpib-kernel-4.2.0\n# ./configure # No longer needed?\n# make\n# sudo make install\n# sudo ldconfig\n\n# cd ..\n# tar -xvzf linux-gpib-user-4.2.0.tar.gz\n# cd linux-gpib-user-4.2.0\n# ./configure --sysconfdir=/etc\n# make\n# sudo make install\n\n- Copy firmware to /usr/local/share/usb (old: /usr/share/usb) (e.g. agilent_82357a -> /usr/local/share/usb)\n  as root (see udev rules in /etc/udev/rules.d which scripts/directories are used!)\n- Edit file /etc/gpib.conf:\n\n/***********************************************************************\n                 GPIB.CONF IEEE488 library config file\n                             -------------------\n\n   copyright            : (C) 2002 by Frank Mori Hess\n                          (C) 1994 by C.Schroeter\n   email                : fmhess@users.sourceforge.net\n ***************************************************************************/\n/***************************************************************************\n *\n *   Syntax:\n *\n *         interface { ... } starts new interface board section\n *         device {...} device configuration\n *\n ***************************************************************************/\n\n/* This section configures the configurable driver characteristics\n * for an interface board, such as board address, and interrupt level.\n * minor = 0 configures /dev/gpib0, minor = 1 configures /dev/gpib1, etc.\n */\n\ninterface {\n        minor = 0       /* board index, minor = 0 uses /dev/gpib0, minor = 1 uses /dev/gpib1, etc. */\n        board_type = \"agilent_82357a\"   /* type of interface board being used */\n        name = \"agi\"    /* optional name, allows you to get a board descriptor using ibfind() */\n        pad = 0 /* primary address of interface             */\n        sad = 0 /* secondary address of interface           */\n        timeout = T3s   /* timeout for commands */\n\n        eos = 0x0a      /* EOS Byte, 0xa is newline and 0xd is carriage return */\n        set-reos = yes  /* Terminate read if EOS */\n        set-bin = no    /* Compare EOS 8-bit */\n        set-xeos = no   /* Assert EOI whenever EOS byte is sent */\n        set-eot = yes   /* Assert EOI with last byte on writes */\n\n/* settings for boards that lack plug-n-play capability */\n        base = 0        /* Base io ADDRESS                  */\n        irq  = 0        /* Interrupt request level */\n        dma  = 0        /* DMA channel (zero disables)      */\n\n/* pci_bus and pci_slot can be used to distinguish two pci boards supported by the same driver */\n/*      pci_bus = 0 */\n/*      pci_slot = 7 */\n\n        master = yes    /* interface board is system controller */\n}\n\n/* This is how you might set up a pcIIa board on /dev/gpib1, uncomment to use. */\n/*******************\ninterface {\n        minor = 1\n        board_type = \"pcIIa\"\n        pad = 0\n        sad = 0\n        timeout = T3s\n\n        eos = 0x0a\n        set-reos = yes\n        set-bin = no\n\n        base = 0x2e1\n        irq  = 7\n        dma  = 1\n\n        master = yes\n}\n*********************/\n\n/* Now the device sections define the device characteristics for each device.\n * These are only used if you want to open the device using ibfind() (instead\n * of ibdev() )\n */\n\ndevice {\n        minor = 0       /* minor number for interface board this device is connected to */\n        name = \"hp3478a\"        /* device mnemonic */\n        pad = 24        /* The Primary Address */\n        sad = 0 /* Secondary Address */\n\n        eos = 0xa       /* EOS Byte */\n        set-reos = no /* Terminate read if EOS */\n        set-bin = no /* Compare EOS 8-bit */\n}\n\ndevice {\n        minor = 0       /* minor number for interface board this device is connected to */\n        name = \"voltmeter\"      /* device mnemonic */\n        pad = 7 /* The Primary Address */\n        sad = 0 /* Secondary Address */\n\n        eos = 0xa       /* EOS Byte */\n        set-reos = no /* Terminate read if EOS */\n        set-bin = no /* Compare EOS 8-bit */\n}\n\ndevice {\n        minor = 0\n        name = \"scope\"\n        pad = 8\n        sad = 0\n}\n\n- add users to group \"gpib\" (/etc/group)\n- load config:\n# sudo gpib_config\n\nCHECK:\n======\n\n# lsmod\nagilent_82357a         24576  0\ngpib_common            36864  1 agilent_82357a\n\n\n# dmesg\nLinux-GPIB 4.1.0 Driver\nagilent_82357a_gpib driver loading\nusbcore: registered new interface driver agilent_82357a_gpib\ngpib: registered agilent_82357a interface\n\n# ls -l /dev/gpib*\ncrw-rw----  1 root gpib    160,   1 Okt 31 17:25 gpib0\n...\ncrw-rw----  1 root gpib    160,   9 Okt 31 17:25 gpib9\n\n# ibtest -d 24\n"
  },
  {
    "path": "stuff/loads.txt",
    "content": "Re:load Pro\n===========\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_ELECTRONIC_LOAD,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n};\n\nstatic const uint32_t devopts_cg[] = {\n\tSR_CONF_ENABLED | SR_CONF_SET,\n\tSR_CONF_REGULATION | SR_CONF_GET,\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET,\n\tSR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET,\n\tSR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET,\n\tSR_CONF_UNDER_VOLTAGE_CONDITION | SR_CONF_GET,\n\tSR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE | SR_CONF_GET,\n\tSR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n};\n\n\nM97\n===\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_ELECTRONIC_LOAD,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n};\n\nstatic const uint32_t devopts_cg[] = {\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_REGULATION | SR_CONF_GET,\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET,\n\tSR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE | SR_CONF_GET,\n\tSR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ACTIVE | SR_CONF_GET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET,\n\tSR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET,\n};\n\n\n\n\nGeneral\n=======\n\n\nSR_CONF_CONTINUOUS,\nSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n\nSR_CONF_ENABLED | SR_CONF_SET | SR_CONF_SET,\nSR_CONF_REGULATION | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_VOLTAGE | SR_CONF_GET,\nSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_CURRENT | SR_CONF_GET,\nSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET,\nSR_CONF_OVER_CURRENT_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET,\nSR_CONF_OVER_TEMPERATURE_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_UNDER_VOLTAGE_CONDITION | SR_CONF_GET,\nSR_CONF_UNDER_VOLTAGE_CONDITION_ACTIVE | SR_CONF_GET,\nSR_CONF_UNDER_VOLTAGE_CONDITION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\n"
  },
  {
    "path": "stuff/mxe.txt",
    "content": "make MXE_TARGETS=i686-w64-mingw32.static.posix gcc glib libzip libusb1 libftdi1 glibmm qt5 boost check\n\n\n\ngit clone https://github.com/mxe/mxe.git mxe-git\ncd mxe-git\npatch -p1 < mxe_fixes.patch\nls -l\npatch -p1 < ~/Projekte/elektronik/sigrok/sigrok-util/cross-compile/mingw/mxe_fixes.patch\nmake MXE_TARGETS=i686-w64-mingw32.static.posix gcc glib libzip libusb1    libftdi1 glibmm qt5 boost check\n\n\n\n\nmake MXE_TARGETS=i686-w64-mingw32.static.posix \\\n   MXE_PLUGIN_DIRS=plugins/examples/qt5-freeze \\\n   gcc glib libzip libusb1 libftdi1 glibmm qtbase qtimageformats qtsvg \\\n   boost check gendef qtbase_CONFIGURE_OPTS='-no-sql-mysql'\n\n\n\n\n\ngit clone https://github.com/mxe/mxe.git mxe-git-qt5_10\ncd mxe-git-qt5_10\npatch -p1 < ~/Projekte/elektronik/sigrok/sigrok-util/cross-compile/mingw/mxe_fixes.patch\nmake MXE_TARGETS=i686-w64-mingw32.static.posix gcc glib libzip libusb1 libftdi1 glibmm qt5 qwt boost check gendef\n\nmake MXE_TARGETS=i686-w64-mingw32.static.posix gcc glib libzip libusb1 libftdi1 glibmm qt5 qwt boost check gendef MXE_CONFIGURE_OPTS='--with-default-msvcrt=msvcr100' mingw-w64_SOURCE_TREE=/home/frank/mingw-w64\n\n\n\n\n\ngit clone https://github.com/mxe/mxe.git mxe-git-std\ncd mxe-git-std\npatch -p1 < ~/Projekte/elektronik/sigrok/sigrok-util/cross-compile/mingw/mxe_fixes.patch\nmake MXE_TARGETS=i686-w64-mingw32.static.posix MXE_PLUGIN_DIRS=plugins/examples/qt5-freeze gcc glib libzip libusb1 libftdi1 glibmm qtbase qtimageformats qtsvg qwt boost check gendef qtbase_CONFIGURE_OPTS='-no-sql-mysql'\n\nmake MXE_TARGETS=i686-w64-mingw32.static.posix MXE_PLUGIN_DIRS=plugins/examples/qt5-freeze gcc glib libzip libusb1 libftdi1 glibmm qtbase qtimageformats qtsvg qwt boost check gendef qtbase_CONFIGURE_OPTS='-no-sql-mysql' mingw-w64_SOURCE_TREE=/home/frank/mingw-w64 mingw-w64_CONFIGURE_OPTS='--with-default-msvcrt=msvcr100'\n"
  },
  {
    "path": "stuff/parameter.txt",
    "content": "\n--driver peaktech-4390a:conn=/dev/ttyUSB2 -l 5\n--driver hp-3478a:conn=libgpib/hp3478a -l 5\n--driver eevblog-121gw:conn=bt/ble122/88-6B-0F-81-AA-C3\n--driver arachnid-labs-re-load-pro:conn=/dev/ttyUSB0 -l 5\n--driver conrad-digi-35-cpu:conn=/dev/ttyUSB1 -l 5\n--driver scpi-pps:conn=libgpib/hp6632b -l 5\n--driver hp-59306a:conn=libgpib/hp59306a -l 5\n--driver icstation:conn=/dev/ttyUSB0 -l 5\n--driver zketech-ebd-usb:conn=/dev/ttyUSB0 -l 5\n\n--driver conrad-digi-35-cpu:conn=/dev/ttyUSB2 --driver arachnid-labs-re-load-pro:conn=/dev/ttyUSB0 -l 5\n--driver conrad-digi-35-cpu:conn=/dev/ttyUSB2 --driver peaktech-4390a:conn=/dev/ttyUSB1 -l 5\n--driver conrad-digi-35-cpu:conn=/dev/ttyUSB2 --driver hp-3478a:conn=libgpib/hp3478a -l 5\n\n--driver arachnid-labs-re-load-pro:conn=/dev/ttyUSB0 --driver hp-3478a:conn=libgpib/hp3478a -l 5\n"
  },
  {
    "path": "stuff/pps.txt",
    "content": "conrad-digi-35-cpu\n==================\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_SET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_SET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_SET,\n};\n\n\nkorad-kaxxxxp\n=============\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_REGULATION | SR_CONF_GET,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\n\nmanson-hcs-3xxx\n===============\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\n\nmotech-lps-30x\n==============\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n\tSR_CONF_CHANNEL_CONFIG | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n};\n\n/** Hardware capabilities channel 1, 2. */\nstatic const uint32_t devopts_cg_ch12[] = {\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\n/** Hardware capabilities channel 3 (LPS-304/305 only). */\nstatic const uint32_t devopts_cg_ch3[] = {\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\n\natten-pps3xxx\n=============\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const uint32_t devopts[] = {\n\tSR_CONF_CONTINUOUS,\n\tSR_CONF_CHANNEL_CONFIG | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\nstatic const uint32_t devopts_cg[] = {\n\tSR_CONF_VOLTAGE | SR_CONF_GET,\n\tSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_CURRENT | SR_CONF_GET,\n\tSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\n\tSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\n};\n\n\nscpi-pps\n========\n\nstatic const uint32_t drvopts[] = {\n\tSR_CONF_POWER_SUPPLY,\n};\n\nstatic const struct pps_channel_instance pci[] = {\n\t{ SR_MQ_VOLTAGE, SCPI_CMD_GET_MEAS_VOLTAGE, \"V\" },\n\t{ SR_MQ_CURRENT, SCPI_CMD_GET_MEAS_CURRENT, \"I\" },\n\t{ SR_MQ_POWER, SCPI_CMD_GET_MEAS_POWER, \"P\" },\n\t{ SR_MQ_FREQUENCY, SCPI_CMD_GET_MEAS_FREQUENCY, \"F\" },\n};\n\nSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_VOLTAGE | SR_CONF_GET,\nSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET,\nSR_CONF_OUTPUT_FREQUENCY_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_CURRENT | SR_CONF_GET,\nSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_CURRENT_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_REGULATION | SR_CONF_GET\n\n\nTODO:\n=====\n\n- atten-pps3xxx missing SR_CONF_LIMIT_SAMPLES and SR_CONF_LIMIT_MSEC\n\n\nGeneral\n=======\n\nSR_CONF_CONTINUOUS,\nSR_CONF_LIMIT_SAMPLES | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_LIMIT_MSEC | SR_CONF_GET | SR_CONF_SET,\n\nSR_CONF_CHANNEL_CONFIG | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_VOLTAGE | SR_CONF_GET,\nSR_CONF_VOLTAGE_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_CURRENT | SR_CONF_GET,\nSR_CONF_CURRENT_LIMIT | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OUTPUT_FREQUENCY | SR_CONF_GET,\nSR_CONF_OUTPUT_FREQUENCY_TARGET | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_REGULATION | SR_CONF_GET,\nSR_CONF_OVER_CURRENT_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_CURRENT_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_CURRENT_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ENABLED | SR_CONF_GET | SR_CONF_SET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_ACTIVE | SR_CONF_GET,\nSR_CONF_OVER_VOLTAGE_PROTECTION_THRESHOLD | SR_CONF_GET | SR_CONF_SET | SR_CONF_LIST,\nSR_CONF_OVER_TEMPERATURE_PROTECTION | SR_CONF_GET | SR_CONF_SET,\n\n\n\n\nSCPI-PPS\n========\n\nAgilent N5763A\n--------------\nMulti Commands: Agilent-N5700.pdf -> p.59\n\nChroma 61604\n------------\nMulti Commands: Chroma-61500.pdf -> p.8-4\n\nChroma 62000 series\n-------------------\nMulti Commands: Chroma-62000H.pdf -> chpt 5.3.5.8\n\nHP 6633A\n--------\nMulti Commands: NOT working! Returns only last requested value!\n\nHP 6632B\n--------\nMulti Commands: Working! Return: ret1;ret2\n\nRigol DP800 series\n------------------\n(DP821A, DP831A, DP832, DP832A)\n\nMulti Commands: Rigol-DP800_Prog.pdf -> ??? nothing found\n\nPhilips/Fluke PM2800 series\n---------------------------\nMulti Commands: Philips-PM2800_Ref.pdf -> p.1-68, p.1-84\n\nRohde & Schwarz HMC8043\n-----------------------\nMulti Commands:\n\n"
  },
  {
    "path": "stuff/python.txt",
    "content": "C++, Python, boost::python, ...\n===============================\n\nIntroduction\n------------\n\n\nPassing C++ class instances to python\n-------------------------------------\n\nhttps://stackoverflow.com/questions/5055443/boost-python-how-to-pass-a-c-class-instance-to-a-python-class\nhttps://stackoverflow.com/questions/8225934/exposing-a-c-class-instance-to-a-python-embedded-interpreter\nhttps://stackoverflow.com/questions/9062152/pass-c-object-to-python-function-by-boostpython\n\n\nExamples\n--------\n\nhttps://github.com/TNG/boost-python-examples/tree/master/10-Embedding\nhttps://github.com/wynemo/boost-python-embed\n\nstd::shard_ptr\n--------------\n\nhttps://stackoverflow.com/questions/13986581/using-boost-python-stdshared-ptr\nhttps://wiki.python.org/moin/boost.python/PointersAndSmartPointers\nhttps://www.boost.org/doc/libs/1_45_0/libs/python/doc/v2/register_ptr_to_python.html\nhttp://yyc.solvcon.net/writing/2016/resource/\nhttps://codereview.stackexchange.com/questions/130044/same-pyobject-for-a-shared-ptr-c-object\n"
  },
  {
    "path": "stuff/relays/relays.txt",
    "content": "Finder\n======\n\n55.34.9.012.5040 (AgNi + Au plated)\n55.34.9.006.0040 (AgNi)\n\n\nA 7A medium power relay with AgNi contacts has a minimum switching specification of 5 V / 5 mA / 300 mW.\nThis relay is also available with gold plated contacts; when the revised values become 5 V / 2 mA / 50 mW.\n\nIf a much lower voltage must be reliably switched, consider two contacts in parallel. This dramatically\nlowers the minimum switching load - two parallel gold contacts make it possible to handle loads down to\n0.1 V / 1 mA / 1 mW. It may be useful to appreciate that statistically the unreliability of two contacts\nin parallel is equal to the unreliability of the single contact raised to the power of two. So, just to\nillustrate the maths, a 1% unreliable switching circuit becomes 0.01% unreliable - i.e. a 100x improvement\nin reliability. And for three contacts in parallel the unreliability would be raised to the power of\nthree – a 10,000x improvement in reliability!\n(https://www.findernet.com/en/unitedkingdom/news/relay-contact-materials-does-it-matter)\n\n\nMinimum switching load:\nThe minimum values of power, voltage and current that a contact can reliably switch. For example, if\nminimum values are 300 mW, 5 V / 5 mA:\n- with 5 V the current must be at least 60 mA;\n- with 24 V the current must be at least 12.5 mA;\n- with 5 mA the voltage must be at least 60 V;\nFor gold contact variants, loads no less than 50 mW, 5 V / 2 mA are suggested.\nWith 2 gold contacts in parallel, it is possible to switch 1 mW, 0.1 V / 1 mA.\n(https://www.finder-relais.net/en/Finder-general-technical-information-en.pdf)\n"
  },
  {
    "path": "stuff/release.txt",
    "content": "Prepare a virtual machine (Ubuntuy Xenial 16.04 LTS) for the AppImage build process\n===================================================================================\n\nInstall a Ubuntu 16.04.6 64bit or 32bit Server VM with hostname ubuntu[32|64].\nThen update and install some base packets:\n $ sudo apt update && sudo apt -y upgrade\n $ sudo apt -y install gpm vim apt-file\n\nAfter the base installation take a snapshot of the VM.\n\n---------------\n\nInstall packages for libserialport:\n $ sudo apt -y install git wget unzip gcc make autoconf automake libtool\n\nInstall packages for libsigrok:\n $ sudo apt -y install g++ autoconf-archive pkg-config libglib2.0-dev libglibmm-2.4-dev libzip-dev libusb-1.0-0-dev libftdi1-dev libhidapi-dev libbluetooth-dev libvisa-dev nettle-dev libavahi-client-dev libieee1284-3-dev check doxygen python3-numpy python3-dev python-gi-dev python3-setuptools swig\n\nSet python3 as the default python version\n $ sudo update-alternatives --install /usr/bin/python python /usr/bin/python2.7 1\n $ sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2\n $ sudo update-alternatives --set python /usr/bin/python3\n\nInstall packages for smuview:\n $ sudo apt -y install libboost-all-dev\n\nFor QCodeEditor and (modified) pybind11 you need cmake >= 3.6:\n $ wget -O - https://apt.kitware.com/keys/kitware-archive-latest.asc 2>/dev/null | sudo apt-key add -\n $ sudo apt-add-repository 'deb https://apt.kitware.com/ubuntu/ xenial main'\n $ sudo apt update\n $ sudo apt -y install kitware-archive-keyring\n $ sudo apt-key --keyring /etc/apt/trusted.gpg del C1F34CDD40CD72DA\n $ sudo apt -y install cmake\n\nInstall Qt 5.12.9 (LTS) (SmuView needs Qt >= 5.7 but Ubuntu 16.04 comes with 5.5)\n $ sudo add-apt-repository -y ppa:beineri/opt-qt-5.12.9-xenial\n $ sudo apt update\n $ sudo apt -y install qt512base qt512-meta-full\n $ source /opt/qt512/bin/qt512-env.sh\n\nInstall newest Qwt 6.1.4:\n $ sudo apt -y install mesa-common-dev libgl1-mesa-dev\n $ wget https://sourceforge.net/projects/qwt/files/qwt/6.1.4/qwt-6.1.4.tar.bz2\n $ tar xf qwt-6.1.4.tar.bz2\n $ cd qwt-6.1.4\n $ qmake qwt.pro\n $ make\nNow change the QWT_INSTALL_PREFIX in qwtconfig.pri to /usr and then install:\n $ sudo make install\n\nInstall shellcheck for i686 (The x86_64 appimagecraft AppImage comes with an actual shellcheck, but i686 not). Only v0.5.0 builds with Ubuntu 16.04:\n $ sudo apt -y install cabal-install\n $ sudo cabal update\n $ wget https://github.com/koalaman/shellcheck/archive/v0.5.0.tar.gz\n $ tar xf v0.5.0.tar.gz\n $ cd shellcheck-0.5.0\n $ sudo cabal install --prefix=/usr\n\nAfter the advanced installation take a snapshot of the VM.\n\n\nBuild the SmuView release\n=========================\n\n $ source /opt/qt512/bin/qt512-env.sh\n $ sudo ldconfig\n $ cd\n\n $ wget https://github.com/TheAssassin/appimagecraft/releases/download/continuous/appimagecraft-x86_64.AppImage\n $ chmod ug+x appimagecraft-x86_64.AppImage\nor\n $ wget https://github.com/TheAssassin/appimagecraft/releases/download/continuous/appimagecraft-i386.AppImage\n $ chmod ug+x appimagecraft-i386.AppImage\n\n $ git clone https://github.com/knarfS/smuview.git\n $ cd smuview\n $ ../appimagecraft-x86_64.AppImage genscripts -d build/ # TODO: Single command\n $ cd build                                              # TODO\n $ ./build.sh                                            # TODO\n\n---------------\n\nThe alternative to linuxdeployqt is the sigrok AppImageKit script (not tested in a long time!):\n $ cd\n $ sudo apt-get -y install desktop-file-utils libcairo2-dev libfuse-dev zsync\n $ git clone --single-branch --recursive https://github.com/AppImage/AppImageKit\n $ cd AppImageKit\n $ sudo apt -y install zsync git libarchive-dev autoconf libtool make gcc g++ libtool libfuse-dev liblzma-dev libglib2.0-dev libssl-dev libinotifytools0-dev liblz4-dev libcairo-dev desktop-file-utils\n $ patch -p1 < ../sigrok-util/cross-compile/appimage/chdir.patch\n $ ./build.sh\n $ mkdir -p build/lib/appimagekit\n $ cp build/out/mksquashfs build/lib/appimagekit\n\n\nMisc\n====\n\nTo debug the SmuView AppImage:\n $ export QT_DEBUG_PLUGINS=1\n $ LD_DEBUG=libs ./SmuView.AppImage\n"
  },
  {
    "path": "stuff/scpi-use.txt",
    "content": "static int parse_strict_bool(const char *str, gboolean *ret)\nstatic struct sr_dev_inst *sr_scpi_scan_resource(struct drv_context *drvc, const char *resource, const char *serialcomm, struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))\n\nSR_PRIV GSList *sr_scpi_scan(struct drv_context *drvc, GSList *options, struct sr_dev_inst *(*probe_device)(struct sr_scpi_dev_inst *scpi))\n\thardware/rohde-schwarz-sme-0x/api.c\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV struct sr_scpi_dev_inst *scpi_dev_inst_new(struct drv_context *drvc, const char *resource, const char *serialcomm)\n\nSR_PRIV int sr_scpi_open(struct sr_scpi_dev_inst *scpi)\n\thardware/rohde-schwarz-sme-0x/api.c\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV int sr_scpi_source_add(struct sr_session *session, struct sr_scpi_dev_inst *scpi, int events, int timeout, sr_receive_data_callback cb, void *cb_data)\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV int sr_scpi_source_remove(struct sr_session *session, struct sr_scpi_dev_inst *scpi)\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV int sr_scpi_send(struct sr_scpi_dev_inst *scpi, const char *format, ...)\n\tscpi/helpers.c\n\thardware/rohde-schwarz-sme-0x/protocol.c\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/lecroy-xstream/api.c\n\thardware/gwinstek-gds-800/protocol.c\n\thardware/hp-3457a/protocol.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/protocol_wrappers.c\n\nSR_PRIV int sr_scpi_send_variadic(struct sr_scpi_dev_inst *scpi, const char *format, va_list args)\n\tscpi/helpers.c\n\thardware/rigol-ds/protocol.c\n\nSR_PRIV int sr_scpi_read_begin(struct sr_scpi_dev_inst *scpi)\n\thardware/rigol-ds/protocol.c\n\thardware/gwinstek-gds-800/protocol.c\n\thardware/yokogawa-dlm/protocol.c\n\nSR_PRIV int sr_scpi_read_data(struct sr_scpi_dev_inst *scpi, char *buf, int maxlen)\n\thardware/rigol-ds/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/gwinstek-gds-800/protocol.c\n\thardware/yokogawa-dlm/protocol.c\n\nSR_PRIV int sr_scpi_write_data(struct sr_scpi_dev_inst *scpi, char *buf, int maxlen)\n\nSR_PRIV int sr_scpi_read_complete(struct sr_scpi_dev_inst *scpi)\n\thardware/rigol-ds/protocol.c\n\thardware/gwinstek-gds-800/protocol.c\n\thardware/yokogawa-dlm/protocol.c\n\nSR_PRIV int sr_scpi_close(struct sr_scpi_dev_inst *scpi)\n\thardware/rohde-schwarz-sme-0x/api.c\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV void sr_scpi_free(struct sr_scpi_dev_inst *scpi)\n\tstd.c\n\nSR_PRIV int sr_scpi_get_string(struct sr_scpi_dev_inst *scpi, const char *command, char **scpi_response)\n\tscpi/helpers.c\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/protocol.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/protocol_wrappers.c\n\nSR_PRIV int sr_scpi_read_response(struct sr_scpi_dev_inst *scpi, GString *response, gint64 abs_timeout_us)\n\nSR_PRIV int sr_scpi_get_data(struct sr_scpi_dev_inst *scpi, const char *command, GString **scpi_response)\n\nSR_PRIV int sr_scpi_get_bool(struct sr_scpi_dev_inst *scpi, const char *command, gboolean *scpi_response)\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/yokogawa-dlm/protocol_wrappers.c\n\nSR_PRIV int sr_scpi_get_int(struct sr_scpi_dev_inst *scpi, const char *command, int *scpi_response)\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/protocol.c\n\thardware/yokogawa-dlm/protocol_wrappers.c\n\nSR_PRIV int sr_scpi_get_float(struct sr_scpi_dev_inst *scpi, const char *command, float *scpi_response)\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/hp-3457a/protocol.c\n\thardware/hp-3457a/api.c\n\thardware/yokogawa-dlm/protocol_wrappers.c\n\nSR_PRIV int sr_scpi_get_double(struct sr_scpi_dev_inst *scpi, const char *command, double *scpi_response)\n\tscpi/helpers.c\n\thardware/rohde-schwarz-sme-0x/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/scpi-pps/protocol.c\n\thardware/scpi-pps/api.c\n\thardware/hp-3457a/protocol.c\n\nSR_PRIV int sr_scpi_get_opc(struct sr_scpi_dev_inst *scpi)\n\thardware/rigol-ds/protocol.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/protocol.c\n\thardware/lecroy-xstream/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV int sr_scpi_get_floatv(struct sr_scpi_dev_inst *scpi, const char *command, GArray **scpi_response)\n\thardware/hp-3457a/api.c\n\nSR_PRIV int sr_scpi_get_uint8v(struct sr_scpi_dev_inst *scpi, const char *command, GArray **scpi_response)\n\nSR_PRIV int sr_scpi_get_block(struct sr_scpi_dev_inst *scpi, const char *command, GByteArray **scpi_response)\n\thardware/hameg-hmo/protocol.c\n\thardware/lecroy-xstream/protocol.c\n\nSR_PRIV int sr_scpi_get_hw_id(struct sr_scpi_dev_inst *scpi, struct sr_scpi_hw_info **scpi_response)\n\thardware/rohde-schwarz-sme-0x/api.c\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/yokogawa-dlm/api.c\n\nSR_PRIV void sr_scpi_hw_info_free(struct sr_scpi_hw_info *hw_info)\n\thardware/rohde-schwarz-sme-0x/api.c\n\thardware/rigol-ds/api.c\n\thardware/hameg-hmo/api.c\n\thardware/lecroy-xstream/api.c\n\thardware/scpi-pps/api.c\n\thardware/gwinstek-gds-800/api.c\n\thardware/yokogawa-dlm/api.c\n"
  },
  {
    "path": "stuff/snippets.txt",
    "content": "Thread ID\n=========\n\n#define _GNU_SOURCE         /* See feature_test_macros(7) */\n#include <sys/types.h>\n#include <unistd.h>\n#include <sys/syscall.h>   /* For SYS_xxx definitions */\n\n//pid_t tid = gettid();\npid_t tid = syscall(__NR_gettid);\nsr_spew(\"ThreadId = %i\", tid);\n\n\n\nCall Stack\n==========\n\n#include <execinfo.h>\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid some_function() {\n\tvoid* callstack[128];\n\tint i, frames;\n\tchar** strs;\n\n\tframes = backtrace(callstack, 128);\n\tstrs = backtrace_symbols(callstack, frames);\n\tfor (i = 0; i < frames; ++i) {\n\t\tprintf(\"%s\\n\", strs[i]);\n\t}\n\tfree(strs);\n}\n\n\n\nCMake\n=====\n\nOutput file in Docker:\n----------------------\n\nfile(READ /home/runner/work/smuview/smuview/build/cmake-build/CMakeFiles/CMakeOutput.log OUT_LOG)\nmessage(WARNING \"CMakeOutput.log: ${OUT_LOG}\")\n\n\nSee https://stackoverflow.com/questions/9298278/cmake-print-out-all-accessible-variables-in-a-script\n----------------------------------------------------------------------------------------------------\n\nUsing the get_cmake_property function, the following loop will print out all CMake variables defined and their values:\n\nget_cmake_property(_variableNames VARIABLES)\nlist (SORT _variableNames)\nforeach (_variableName ${_variableNames})\n    message(STATUS \"${_variableName}=${${_variableName}}\")\nendforeach()\n\n\nThis can also be embedded in a convenience function which can optionally use a regular expression to print only a subset of variables with matching names\n\nfunction(dump_cmake_variables)\n    get_cmake_property(_variableNames VARIABLES)\n    list (SORT _variableNames)\n    foreach (_variableName ${_variableNames})\n        if (ARGV0)\n            unset(MATCHED)\n            string(REGEX MATCH ${ARGV0} MATCHED ${_variableName})\n            if (NOT MATCHED)\n                continue()\n            endif()\n        endif()\n        message(STATUS \"${_variableName}=${${_variableName}}\")\n    endforeach()\nendfunction()\n\n\nTo print environment variables, use CMake's command mode:\n---------------------------------------------------------\n\nexecute_process(COMMAND \"${CMAKE_COMMAND}\" \"-E\" \"environment\")\n\n\nTo print all defined properties of a target:\n--------------------------------------------\n\n# Get all propreties that cmake supports\nexecute_process(COMMAND cmake --help-property-list OUTPUT_VARIABLE CMAKE_PROPERTY_LIST)`\n\n# Convert command output into a CMake list\nSTRING(REGEX REPLACE \";\" \"\\\\\\\\;\" CMAKE_PROPERTY_LIST \"${CMAKE_PROPERTY_LIST}\")\nSTRING(REGEX REPLACE \"\\n\" \";\" CMAKE_PROPERTY_LIST \"${CMAKE_PROPERTY_LIST}\")\n# Fix https://stackoverflow.com/questions/32197663/how-can-i-remove-the-the-location-property-may-not-be-read-from-target-error-i\nlist(FILTER CMAKE_PROPERTY_LIST EXCLUDE REGEX \"^LOCATION$|^LOCATION_|_LOCATION$\")\n# For some reason, \"TYPE\" shows up twice - others might too?\nlist(REMOVE_DUPLICATES CMAKE_PROPERTY_LIST)\n\n# build whitelist by filtering down from CMAKE_PROPERTY_LIST in case cmake is\n# a different version, and one of our hardcoded whitelisted properties\n# doesn't exist!\nunset(CMAKE_WHITELISTED_PROPERTY_LIST)\n\nforeach(prop ${CMAKE_PROPERTY_LIST})\n    if(prop MATCHES \"^(INTERFACE|[_a-z]|IMPORTED_LIBNAME_|MAP_IMPORTED_CONFIG_)|^(COMPATIBLE_INTERFACE_(BOOL|NUMBER_MAX|NUMBER_MIN|STRING)|EXPORT_NAME|IMPORTED(_GLOBAL|_CONFIGURATIONS|_LIBNAME)?|NAME|TYPE|NO_SYSTEM_FROM_IMPORTED)$\")\n        list(APPEND CMAKE_WHITELISTED_PROPERTY_LIST ${prop})\n    endif()\nendforeach(prop)\n\nfunction(print_target_properties tgt)\n    if(NOT TARGET ${tgt})\n        message(\"There is no target named '${tgt}'\")\n        return()\n    endif()\n\n    get_target_property(target_type ${tgt} TYPE)\n    if(target_type STREQUAL \"INTERFACE_LIBRARY\")\n        set(PROP_LIST ${CMAKE_WHITELISTED_PROPERTY_LIST})\n    else()\n        set(PROP_LIST ${CMAKE_PROPERTY_LIST})\n    endif()\n\n    foreach (prop ${PROP_LIST})\n        string(REPLACE \"<CONFIG>\" \"${CMAKE_BUILD_TYPE}\" prop ${prop})\n        # message (\"Checking ${prop}\")\n        get_property(propval TARGET ${tgt} PROPERTY ${prop} SET)\n        if (propval)\n            get_target_property(propval ${tgt} ${prop})\n            message (\"${tgt} ${prop} = ${propval}\")\n        endif()\n    endforeach(prop)\nendfunction(print_target_properties)\n\n\n32bit build on 64bit:\n---------------------\n\nexport C=\"--host=i686-linux-gnu --build=i686-linux-gnu\"\nexport CC=\"gcc -m32\"\nexport CXX=\"g++ -m32\"\nexport CFLAGS=\"-O2 -march=i686\"\nexport CXXFLAGS=\"-O2 -march=i686\"\nexport LD=\"ld -melf_i386\"\nexport LDFLAGS=\"-m32\"\n\n\nQt for Ubuntu\n=============\n\nhttps://launchpad.net/~beineri/\n\nInstead for sourcing the env file:\n\nexport QTDIR=/opt/qt512\nexport PATH=/opt/qt512/bin:$PATH\nexport LD_LIBRARY_PATH=/opt/qt512/lib/i386-linux-gnu:/opt/qt512/lib:$LD_LIBRARY_PATH\nexport PKG_CONFIG_PATH=/opt/qt512/lib/pkgconfig:$PKG_CONFIG_PATH\nsudo ldconfig\n"
  },
  {
    "path": "test/CMakeLists.txt",
    "content": "##\n## This file is part of the SmuView project.\n##\n## Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n## Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>\n## Copyright (C) 2022 Frank Stettner <frank-stettner@gmx.net>\n##\n## This program is free software: you can redistribute it and/or modify\n## it under the terms of the GNU General Public License as published by\n## the Free Software Foundation, either version 2 of the License, or\n## (at your option) any later version.\n##\n## This program is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n## GNU General Public License for more details.\n##\n## You should have received a copy of the GNU General Public License\n## along with this program.  If not, see <http://www.gnu.org/licenses/>.\n##\n\nset(smuview_TEST_SOURCES\n\t${PROJECT_SOURCE_DIR}/src/util.cpp\n\ttest.cpp\n\tutil.cpp\n)\n\n# On MinGW we need to use static linking.\nif(NOT WIN32)\n\tadd_definitions(-DBOOST_TEST_DYN_LINK)\nendif()\n\nadd_executable(smuview-test\n\t${smuview_TEST_SOURCES}\n)\n\ntarget_link_libraries(smuview-test ${SMUVIEW_LINK_LIBS})\n"
  },
  {
    "path": "test/test.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, see <http://www.gnu.org/licenses/>.\n */\n\n#define BOOST_TEST_MAIN\n#include \"test/test.hpp\"\n#include <boost/test/unit_test.hpp>\n\nusing std::ostream;\n\nostream& operator<<(ostream& stream, const QString& str)\n{\n\treturn stream << str.toUtf8().data();\n}\n"
  },
  {
    "path": "test/test.hpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Jens Steinhauser <jens.steinhauser@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, see <http://www.gnu.org/licenses/>.\n */\n\n#ifndef SMUVIEW_TEST_TEST_HPP\n#define SMUVIEW_TEST_TEST_HPP\n\n#include <QString>\n\nusing std::ostream;\n\nostream& operator<<(ostream& stream, const QString& str);\n\n#endif // SMUVIEW_TEST_TEST_HPP\n"
  },
  {
    "path": "test/util.cpp",
    "content": "/*\n * This file is part of the SmuView project.\n *\n * Copyright (C) 2015 Jens Steinhauser <jens.steinhauser@gmail.com>\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation; either version 2 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program; if not, see <http://www.gnu.org/licenses/>.\n */\n\n#include <limits>\n#include <math.h>\n#include <boost/test/unit_test.hpp>\n\n#include \"src/util.hpp\"\n#include \"test/test.hpp\"\n\nusing namespace sv::util;\nusing ts = sv::util::Timestamp;\n\nusing std::bind;\n\nnamespace {\n\tQChar mu = QChar(0x03BC);\n\n\tsv::util::SIPrefix unspecified = sv::util::SIPrefix::unspecified;\n\tsv::util::SIPrefix yocto       = sv::util::SIPrefix::yocto;\n\tsv::util::SIPrefix nano        = sv::util::SIPrefix::nano;\n/*\tsv::util::SIPrefix micro       = sv::util::SIPrefix::micro; // Not currently used */\n\tsv::util::SIPrefix milli       = sv::util::SIPrefix::milli;\n\tsv::util::SIPrefix none        = sv::util::SIPrefix::none;\n\tsv::util::SIPrefix kilo        = sv::util::SIPrefix::kilo;\n\tsv::util::SIPrefix yotta       = sv::util::SIPrefix::yotta;\n\n/*\tsv::util::TimeUnit Time = sv::util::TimeUnit::Time; // Not currently used */\n}  // namespace\n\nBOOST_AUTO_TEST_SUITE(UtilTest)\n\nBOOST_AUTO_TEST_CASE(exponent_test)\n{\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::yocto), -24);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::zepto), -21);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::atto),  -18);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::femto), -15);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::pico),  -12);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::nano),   -9);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::micro),  -6);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::milli),  -3);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::none),    0);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::kilo),    3);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::mega),    6);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::giga),    9);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::tera),   12);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::peta),   15);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::exa),    18);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::zetta),  21);\n\tBOOST_CHECK_EQUAL(exponent(SIPrefix::yotta),  24);\n}\n\nBOOST_AUTO_TEST_CASE(format_value_si_test)\n{\n\tQString value_str(\"\");\n\tQString si_prefix_str(\"\");\n\n\t/* Common values for DMMs */\n\n\tformat_value_si(4635000000.           , -1, -6, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"G\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si( 463500000.           , -1, -5, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(  46350000.           , -1, -4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(   4635000.           , -1, -3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(    463500.           , -1, -2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(     46350.           , -1, -1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(      4635.           , -1,  0, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(       463.5           , -1,  1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(        46.35          , -1,  2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         4.635         , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .4635        , -1,  4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .04635       , -1,  5, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .004635      , -1,  6, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .0004635     , -1,  7, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .00004635    , -1,  8, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .000004635   , -1,  9, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .0000004635  , -1, 10, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.5\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .00000004635 , -1, 11, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.35\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(          .000000004635, -1, 12, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\t/* Common values for power supplies */\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(       123.456         , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.456\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(       123.4567        , -1,  4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4567\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t/* Edge cases */\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(1234e25, -1,  -25, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"12340\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"Y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(1234e23, -1, -23, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"Y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(.4635e-23, -1, 27, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(.4635e-26, -1, 30, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.004635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(0, -1,  4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.0000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(0, -1,  1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.0\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t// si_prefix_str = \"\";\n\t// format_value_si(NAN, -1,  4, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"nan\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(std::numeric_limits<double>::infinity(), -1,  4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"inf\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(std::numeric_limits<double>::max(), -1,  4, value_str, si_prefix_str, false);\n\t//BOOST_CHECK_EQUAL(value_str, \"0.0000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(std::numeric_limits<double>::lowest(), -1,  4, value_str, si_prefix_str, false);\n\t//BOOST_CHECK_EQUAL(value_str, \"0.0000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t/* Some more values from the libsigrok tests */\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(        12.0           , -1,  1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"12.0\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(        12.0           , -1, -1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.01\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(      1024.0           , -1,  0, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1.024\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(      1024.0           , -1, -1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1.02\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(      1024.0           , -1, -3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(        12.0e5         , -1, 0, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1.200000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 0, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.1\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.12\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 5, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.45\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 6, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.456\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.123456      , -1, 7, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4560\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.0123        , -1, 4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"12.3\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.00123       , -1, 5, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1.23\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.000123      , -1, 4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.1\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.000123      , -1, 5, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.12\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.000123      , -1, 6, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.000123      , -1, 7, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.0\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si(         0.0001      , -1, 4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.1\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n}\n\nBOOST_AUTO_TEST_CASE(format_value_si_autoscale_test)\n{\n\tQString value_str(\"\");\n\tQString si_prefix_str(\"\");\n\n\t/* Common values for DMMs */\n\n\tformat_value_si_autoscale(4635000000.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"G\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale( 463500000.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(  46350000.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(   4635000.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(    463500.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(     46350.           , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(      4635.           , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(       463.5           , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(        46.35          , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         4.635         , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .4635        , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .04635       , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .004635      , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .0004635     , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .00004635    , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .000004635   , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .0000004635  , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"463.500\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .00000004635 , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"46.350\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(          .000000004635, -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"n\");\n\n\t/* Common values for power supplies */\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(       123.456         , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.456\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(       123.4567        , -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.456\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t/* Edge cases */\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(1234e25, -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"12340.000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"Y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(1234e23, -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.400\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"Y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(.4635e-23, -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"4.635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(.4635e-26, -1, 6, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.004635\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"y\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(0, -1,  2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.00\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(0, -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"0.000\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t// si_prefix_str = \"\";\n\t// format_value_si(NAN, -1,  3, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"nan\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(std::numeric_limits<double>::infinity(), -1,  3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"inf\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\n\t/* Some more values from the libsigrok tests */\n\n\t// si_prefix_str = \"\";\n\t// format_value_si(        12.0           , -1,  1, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"12.0\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"\");\n\t//\n\t// si_prefix_str = \"\";\n\t// format_value_si(        12.0           , -1, -1, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"0.01\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\t//\n\t// si_prefix_str = \"\";\n\t// format_value_si(      1024.0           , -1,  0, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"1.024\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\t//\n\t// si_prefix_str = \"\";\n\t// format_value_si(      1024.0           , -1, -1, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"1.02\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\t//\n\t// si_prefix_str = \"\";\n\t// format_value_si(      1024.0           , -1, -3, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"1\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"k\");\n\t//\n\t// si_prefix_str = \"\";\n\t// format_value_si(        12.0e5         , -1, 0, value_str, si_prefix_str, false);\n\t// BOOST_CHECK_EQUAL(value_str, \"1.200000\");\n\t// BOOST_CHECK_EQUAL(si_prefix_str, \"M\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.123456      , -1, 0, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.123456      , -1, 1, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.123456      , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.45\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.123456      , -1, 3, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.456\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.123456      , -1, 4, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.4560\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.0123        , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"12.30\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.00123       , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"1.23\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, \"m\");\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.000123      , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"123.00\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n\n\tsi_prefix_str = \"\";\n\tformat_value_si_autoscale(         0.0001      , -1, 2, value_str, si_prefix_str, false);\n\tBOOST_CHECK_EQUAL(value_str, \"100.00\");\n\tBOOST_CHECK_EQUAL(si_prefix_str, mu);\n}\n\nBOOST_AUTO_TEST_CASE(format_time_si_test)\n{\n\t// check prefix calculation\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"0\")), \"0 s\");\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-24\")),    \"+1 ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-23\")),   \"+10 ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-22\")),  \"+100 ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-21\")),    \"+1 zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-20\")),   \"+10 zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-19\")),  \"+100 zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-18\")),    \"+1 as\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-17\")),   \"+10 as\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-16\")),  \"+100 as\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-15\")),    \"+1 fs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-14\")),   \"+10 fs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-13\")),  \"+100 fs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-12\")),    \"+1 ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-11\")),   \"+10 ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-10\")),  \"+100 ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-9\")),     \"+1 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-8\")),    \"+10 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-7\")),   \"+100 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-6\")),    QString(\"+1 \") + mu + \"s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-5\")),   QString(\"+10 \") + mu + \"s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-4\")),  QString(\"+100 \") + mu + \"s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-3\")),     \"+1 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-2\")),    \"+10 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-1\")),   \"+100 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e0\")),       \"+1 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e1\")),      \"+10 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e2\")),     \"+100 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e3\")),      \"+1 ks\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e4\")),     \"+10 ks\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e5\")),    \"+100 ks\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e6\")),      \"+1 Ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e7\")),     \"+10 Ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e8\")),    \"+100 Ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e9\")),      \"+1 Gs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e10\")),    \"+10 Gs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e11\")),   \"+100 Gs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e12\")),     \"+1 Ts\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e13\")),    \"+10 Ts\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e14\")),   \"+100 Ts\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e15\")),     \"+1 Ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e16\")),    \"+10 Ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e17\")),   \"+100 Ps\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e18\")),     \"+1 Es\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e19\")),    \"+10 Es\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e20\")),   \"+100 Es\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e21\")),     \"+1 Zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e22\")),    \"+10 Zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e23\")),   \"+100 Zs\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e24\")),     \"+1 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e25\")),    \"+10 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e26\")),   \"+100 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e27\")),  \"+1000 Ys\");\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1234\")),              \"+1 ks\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1234\"), kilo, 3), \"+1.234 ks\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1234.5678\")),         \"+1 ks\");\n\n\t// check prefix\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-24\"), yocto),    \"+1 ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-21\"), yocto), \"+1000 ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"0\"), yocto),         \"0 ys\");\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-4\"), milli),         \"+0 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-4\"), milli, 1),     \"+0.1 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1000\"), milli),    \"+1000000 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"0\"), milli),              \"0 ms\");\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-1\"), none),       \"+0 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-1\"), none, 1),  \"+0.1 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e-1\"), none, 2), \"+0.10 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1\"), none),          \"+1 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e1\"), none),       \"+10 s\");\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e23\"), yotta),       \"+0 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e23\"), yotta, 1),  \"+0.1 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1e27\"), yotta),    \"+1000 Ys\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"0\"), yotta),           \"0 Ys\");\n\n\t// check precision, rounding\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2345678\")),                         \"+1 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.4\")),                               \"+1 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.5\")),                               \"+2 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.9\")),                               \"+2 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2345678\"), unspecified, 2),      \"+1.23 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2345678\"), unspecified, 3),     \"+1.235 s\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2345678\"), milli, 3),       \"+1234.568 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2345678\"), milli, 0),           \"+1235 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1.2\"), unspecified, 3),           \"+1.200 s\");\n\n\t// check unit and sign\n\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"-1\"), none, 0, \"V\", true),  \"-1 V\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"-1\"), none, 0, \"V\", false), \"-1 V\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1\"), none, 0, \"V\", true),   \"+1 V\");\n\tBOOST_CHECK_EQUAL(format_time_si(ts(\"1\"), none, 0, \"V\", false),   \"1 V\");\n}\n\nBOOST_AUTO_TEST_CASE(format_time_si_adjusted_test)\n{\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts(\"-1.5\"), milli), \"-1500 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts(\"-1.0\"), milli), \"-1000 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts(\"-0.2\"), milli),  \"-200 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts(\"-0.1\"), milli),  \"-100 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.0\"), milli),     \"0 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.1\"), milli),  \"+100 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.2\"), milli),  \"+200 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.3\"), milli),  \"+300 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.4\"), milli),  \"+400 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.5\"), milli),  \"+500 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.6\"), milli),  \"+600 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.7\"), milli),  \"+700 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.8\"), milli),  \"+800 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"0.9\"), milli),  \"+900 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.0\"), milli), \"+1000 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.1\"), milli), \"+1100 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.2\"), milli), \"+1200 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.3\"), milli), \"+1300 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.4\"), milli), \"+1400 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), milli), \"+1500 ms\");\n\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), milli, 6), \"+1500.000 ms\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), nano,  6), \"+1500000000 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), nano,  8), \"+1500000000 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), nano,  9), \"+1500000000 ns\");\n\tBOOST_CHECK_EQUAL(format_time_si_adjusted(ts( \"1.5\"), nano, 10), \"+1500000000.0 ns\");\n}\n\nBOOST_AUTO_TEST_CASE(format_time_minutes_test)\n{\n\tusing namespace std::placeholders;\n\n\tauto fmt = bind(format_time_minutes, _1, _2, true);\n\n\tBOOST_CHECK_EQUAL(fmt(ts(    0), 0),    \"+0:00\");\n\tBOOST_CHECK_EQUAL(fmt(ts(    1), 0),    \"+0:01\");\n\tBOOST_CHECK_EQUAL(fmt(ts(   59), 0),    \"+0:59\");\n\tBOOST_CHECK_EQUAL(fmt(ts(   60), 0),    \"+1:00\");\n\tBOOST_CHECK_EQUAL(fmt(ts(   -1), 0),    \"-0:01\");\n\tBOOST_CHECK_EQUAL(fmt(ts(  -59), 0),    \"-0:59\");\n\tBOOST_CHECK_EQUAL(fmt(ts(  -60), 0),    \"-1:00\");\n\tBOOST_CHECK_EQUAL(fmt(ts(  100), 0),    \"+1:40\");\n\tBOOST_CHECK_EQUAL(fmt(ts( -100), 0),    \"-1:40\");\n\tBOOST_CHECK_EQUAL(fmt(ts( 4000), 0), \"+1:06:40\");\n\tBOOST_CHECK_EQUAL(fmt(ts(-4000), 0), \"-1:06:40\");\n\tBOOST_CHECK_EQUAL(fmt(ts(12000), 0), \"+3:20:00\");\n\tBOOST_CHECK_EQUAL(fmt(ts(15000), 0), \"+4:10:00\");\n\tBOOST_CHECK_EQUAL(fmt(ts(20000), 0), \"+5:33:20\");\n\tBOOST_CHECK_EQUAL(fmt(ts(25000), 0), \"+6:56:40\");\n\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 0), \"+123:04:05:06\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 1), \"+123:04:05:06.0\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 2), \"+123:04:05:06.01\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 3), \"+123:04:05:06.007\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 4), \"+123:04:05:06.007 0\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 5), \"+123:04:05:06.007 01\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 6), \"+123:04:05:06.007 008\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 7), \"+123:04:05:06.007 008 0\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 8), \"+123:04:05:06.007 008 01\");\n\tBOOST_CHECK_EQUAL(fmt(ts(\"10641906.007008009\"), 9), \"+123:04:05:06.007 008 009\");\n\n\tBOOST_CHECK_EQUAL(format_time_minutes(ts(   0), 0, false),  \"0:00\");\n\tBOOST_CHECK_EQUAL(format_time_minutes(ts( 100), 0, false),  \"1:40\");\n\tBOOST_CHECK_EQUAL(format_time_minutes(ts(-100), 0, false), \"-1:40\");\n}\n\nBOOST_AUTO_TEST_CASE(count_int_digits_test)\n{\n\tBOOST_CHECK_EQUAL(count_int_digits( 101), 3);\n\tBOOST_CHECK_EQUAL(count_int_digits( 100), 3);\n\tBOOST_CHECK_EQUAL(count_int_digits(  99), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits(  11), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits(  10), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits(   9), 1);\n\tBOOST_CHECK_EQUAL(count_int_digits(   1), 1);\n\tBOOST_CHECK_EQUAL(count_int_digits(   0), 0);\n\tBOOST_CHECK_EQUAL(count_int_digits(  -1), 1);\n\tBOOST_CHECK_EQUAL(count_int_digits(  -9), 1);\n\tBOOST_CHECK_EQUAL(count_int_digits( -10), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits( -11), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits( -99), 2);\n\tBOOST_CHECK_EQUAL(count_int_digits(-100), 3);\n\tBOOST_CHECK_EQUAL(count_int_digits(-101), 3);\n}\n\nBOOST_AUTO_TEST_CASE(count_double_digits_test)\n{\n\tBOOST_CHECK_EQUAL(count_double_digits( 100.   , 1. ),  3);\n\tBOOST_CHECK_EQUAL(count_double_digits(  10.   , 1. ),  2);\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.   , 1. ),  1);\n\tBOOST_CHECK_EQUAL(count_double_digits(   0.   , 1.  ), 0);\n\tBOOST_CHECK_EQUAL(count_double_digits( 100.   ,  .1),  4);\n\tBOOST_CHECK_EQUAL(count_double_digits(  10.   ,  .1),  3);\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.   ,  .1),  2);\n\tBOOST_CHECK_EQUAL(count_double_digits(   0.   ,  .1 ), 1);\n\tBOOST_CHECK_EQUAL(count_double_digits( 100.   ,  .01), 5);\n\tBOOST_CHECK_EQUAL(count_double_digits(  10.   ,  .01), 4);\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.   ,  .01), 3);\n\tBOOST_CHECK_EQUAL(count_double_digits(   0.   ,  .01), 2);\n\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.1  ,  .01), 3);\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.01 ,  .01), 3);\n\tBOOST_CHECK_EQUAL(count_double_digits(   1.001,  .01), 4);\n}\n\nBOOST_AUTO_TEST_CASE(count_decimal_places_test)\n{\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00001), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .0001),  4);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .001),   3);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .01),    2);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .1),     1);\n\tBOOST_CHECK_EQUAL(count_decimal_places(  0.),      0);\n\tBOOST_CHECK_EQUAL(count_decimal_places(  1.),      0);\n\tBOOST_CHECK_EQUAL(count_decimal_places( 10.),      0);\n\tBOOST_CHECK_EQUAL(count_decimal_places(100.),      0);\n\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00002), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00003), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00004), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00005), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00006), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00007), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00008), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00009), 5);\n\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .11   ), 2);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .111  ), 3);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .1111 ), 4);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .9999 ), 4);\n\n\tBOOST_CHECK_EQUAL(count_decimal_places(  1.001  ), 3);\n\tBOOST_CHECK_EQUAL(count_decimal_places(  1.00001), 5);\n\tBOOST_CHECK_EQUAL(count_decimal_places(   .00007), 5);\n}\n\nBOOST_AUTO_TEST_CASE(get_sr_digits_test)\n{\n\tBOOST_CHECK_EQUAL(get_sr_digits(1000000.       ), -6);\n\tBOOST_CHECK_EQUAL(get_sr_digits( 100000.       ), -5);\n\tBOOST_CHECK_EQUAL(get_sr_digits(  10000.       ), -4);\n\tBOOST_CHECK_EQUAL(get_sr_digits(   1000.       ), -3);\n\tBOOST_CHECK_EQUAL(get_sr_digits(    100.       ), -2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(     10.       ), -1);\n\tBOOST_CHECK_EQUAL(get_sr_digits(      1.       ),  0);\n\tBOOST_CHECK_EQUAL(get_sr_digits(      0.       ),  0);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .1      ),  1);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .01     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .001    ),  3);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .0001   ),  4);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .00001  ),  5);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .000001 ),  6);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .0000001),  7);\n\n\tBOOST_CHECK_EQUAL(get_sr_digits(1100000.       ), -5);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1110000.       ), -4);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111000.       ), -3);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111100.       ), -2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111110.       ), -1);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111111.       ),  0);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111111.1      ),  1);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111111.11     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(1111111.111    ),  3);\n\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .02     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .03     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .04     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .05     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .06     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .07     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .08     ),  2);\n\tBOOST_CHECK_EQUAL(get_sr_digits(       .09     ),  2);\n}\n\nBOOST_AUTO_TEST_SUITE_END()\n"
  }
]