diff --git a/.gersemirc b/.gersemirc index c682c6bb5..b67911cf9 100644 --- a/.gersemirc +++ b/.gersemirc @@ -1,4 +1,4 @@ -definitions: [./CMakeLists.txt,./cmake-module,./cmake-external,./bindings,./include] -line_length: 80 +definitions: [./CMakeLists.txt, ./test] +line_length: 100 indent: 2 warn_about_unknown_commands: false diff --git a/.github/workflows/ci-arch.yml b/.github/workflows/ci-arch.yml deleted file mode 100644 index 07df38fdc..000000000 --- a/.github/workflows/ci-arch.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: CI - ArchLinux - -on: - push: - branches: devel - pull_request: - paths-ignore: - - CHANGELOG.md - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-with-arch: - runs-on: "ubuntu-latest" - container: - image: archlinux/archlinux:base-devel - steps: - - run: pacman -Syu --noconfirm cmake eigen git libmatio python-scipy simde - - - uses: actions/checkout@v6 - with: - submodules: recursive - - - run: cmake -B build -S . -DBUILD_PYTHON_INTERFACE=ON - - run: cmake --build build - - run: cmake --build build -t test diff --git a/.github/workflows/ci-linux-osx-win-conda.yml b/.github/workflows/ci-linux-osx-win-conda.yml deleted file mode 100644 index 487790dcc..000000000 --- a/.github/workflows/ci-linux-osx-win-conda.yml +++ /dev/null @@ -1,221 +0,0 @@ -name: CI - Linux/OSX/Windows - Conda - -on: - push: - branches: devel - pull_request: - paths-ignore: - - CHANGELOG.md - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - build-with-conda: - name: '[conda:${{ matrix.os }}:${{ matrix.build_type }}:c++${{ matrix.cxx_std }}]' - runs-on: ${{ matrix.os }} - - strategy: - fail-fast: false - matrix: - build_type: [Release, Debug] - name: [ubuntu-latest, macos-latest, windows-latest-clang-cl, windows-latest, macos-15-intel] - cxx_std: [17, 20] - continue_on_error: [false] - - include: - - name: ubuntu-latest - os: ubuntu-latest - - name: macos-latest - os: macos-latest - - name: macos-15-intel - os: macos-15-intel - - name: windows-latest-clang-cl - os: windows-latest - compiler: clang-cl - - name: windows-latest - os: windows-latest - compiler: cl - - name: macos-latest - os: macos-latest - build_type: Debug - cxx_std: 17 - continue_on_error: true - - name: macos-latest - os: macos-latest - build_type: Debug - cxx_std: 20 - continue_on_error: true - - exclude: - - name: macos-latest - build_type: Debug - cxx_std: 17 - continue_on_error: false - - name: macos-latest - build_type: Debug - cxx_std: 20 - continue_on_error: false - - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - - uses: conda-incubator/setup-miniconda@v3 - with: - activate-environment: proxsuite - environment-file: .github/workflows/conda/environment.yml - auto-activate-base: false - auto-update-conda: true - - - name: Install dependencies [Conda/Windows-latest] - if: contains(matrix.os, 'windows-latest') - shell: bash -l {0} - run: | - # Use VS2022 on Windows-latest - conda install vs2022_win-64 - - - name: Install julia [Linux] - if: contains(matrix.os, 'ubuntu') - shell: bash -l {0} - run: | - conda install julia - - - name: Activate ccache [Conda] - uses: hendrikmuhs/ccache-action@v1.2 - with: - key: ${{ matrix.os }}-${{ matrix.type }}-${{ matrix.cxx_std }} - max-size: 1G - - - name: Print environment [Conda] - shell: bash -l {0} - run: | - conda info - conda list - env - - - name: Configure [Conda/Linux&macOS] - if: contains(matrix.os, 'macos-') || contains(matrix.os, 'ubuntu') - shell: bash -l {0} - run: | - echo $(whereis ccache) - echo $(which ccache) - git submodule update --init - mkdir build - cd build - cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=OFF -DOpenMP_ROOT=$CONDA_PREFIX - - - name: Configure [Conda/macOS-debug/CheckMalloc] - if: contains(matrix.os, 'macos-latest') && contains(matrix.build_type, 'Debug') - shell: bash -l {0} - run: | - echo $(whereis ccache) - echo $(which ccache) - cd build - cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCHECK_RUNTIME_MALLOC:BOOL=ON -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DTEST_JULIA_INTERFACE:BOOL=OFF -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DOpenMP_ROOT=$CONDA_PREFIX - - - name: Configure [Conda/Windows] - if: contains(matrix.os, 'windows-') - # It's better to use CMD to have all VS variables setup - shell: cmd /C CALL {0} - run: | - git submodule update --init - mkdir build - cd build - set CC=${{ matrix.compiler }} - set CXX=${{ matrix.compiler }} - cmake .. -GNinja -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -DCMAKE_INSTALL_PREFIX=%CONDA_PREFIX%/Library -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_CXX_STANDARD=${{ matrix.cxx_std }} -DBUILD_PYTHON_INTERFACE:BOOL=ON -DPYTHON_SITELIB=%CONDA_PREFIX%/Lib/site-packages -DPYTHON_EXECUTABLE=%CONDA_PREFIX%/python.exe -DOpenMP_ROOT=%CONDA_PREFIX% -DBUILD_WITH_OPENMP_SUPPORT:BOOL=ON -DLINK_PYTHON_INTERFACE_TO_OPENMP:BOOL=ON -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON - - - name: Build [Conda/Linux&macOS] - if: contains(matrix.os, 'macos-') || contains(matrix.os, 'ubuntu') - shell: bash -l {0} - run: | - cd build - cmake --build . --config ${{ matrix.build_type }} -v -j 1 - - - name: Build [Conda/Windows] - if: contains(matrix.os, 'windows-') - # It's better to use CMD to have all VS variables setup - shell: cmd /C CALL {0} - run: | - cd build - cmake --build . --config ${{ matrix.build_type }} -v -j 1 - - - name: Build documentation [Conda] - shell: bash -l {0} - run: | - cd build - cmake --build . --config ${{ matrix.build_type }} --target doc - - - name: Install [Conda] - shell: bash -l {0} - run: | - cd build - cmake --install . --config ${{ matrix.build_type }} - - - name: Test [Conda] - continue-on-error: ${{ matrix.continue_on_error }} - shell: bash -l {0} - run: | - find $CONDA_PREFIX -name proxsuite* - python -c "import proxsuite" - cd build - ctest --output-on-failure -C ${{ matrix.build_type }} - # - name: Test pkg-config [Conda] - # shell: bash -l {0} - # run: | - # cd build - # export PKG_CONFIG_PATH=$CONDA_PREFIX/lib/pkgconfig - # pkg-config --cflags proxsuite - # g++ -std=c++17 examples/cpp/overview-simple.cpp -o overview-simple $(pkg-config --cflags proxsuite) - # ./overview-simple - - - name: Test FetchContent packaging [Conda/Linux&macOS] - if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') - shell: bash -l {0} - run: | - cd test/packaging/external - mkdir build && cd build - export PROXSUITE_GIT_REPOSITORY="file://"$GITHUB_WORKSPACE - export PROXSUITE_GIT_TAG="test-external-"$(git rev-parse --short HEAD) - git tag $PROXSUITE_GIT_TAG - cmake .. -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} - cmake --build . --config ${{ matrix.build_type }} --target all - ./run-proxqp - - - name: Test CMake packaging [Conda/Linux&macOS] - if: contains(matrix.os, 'macos') || contains(matrix.os, 'ubuntu') - shell: bash -l {0} - run: | - cd test/packaging/cmake - mkdir build && cd build - cmake .. -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DPACKAGE_PREFIX_DIR=${CONDA_PREFIX} - cmake --build . --config ${{ matrix.build_type }} --target all - ./run-proxqp - - - name: Uninstall [Conda] - shell: bash -l {0} - run: | - cd build - cmake --build . --config ${{ matrix.build_type }} --target uninstall - - - name: Display ccache statistics [Conda] - shell: bash -l {0} - run: | - echo $(ccache -s) - - check: - if: always() - name: check-ci-linux-osx-win-conda - - needs: - - build-with-conda - - runs-on: Ubuntu-latest - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/ci-linux-ros.yml b/.github/workflows/ci-linux-ros.yml deleted file mode 100644 index 3908082de..000000000 --- a/.github/workflows/ci-linux-ros.yml +++ /dev/null @@ -1,57 +0,0 @@ -name: CI - Linux - ROS -on: - push: - branches: devel - pull_request: - paths-ignore: - - CHANGELOG.md - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -jobs: - CI: - strategy: - matrix: - env: - # ROS2 Jazzy Jalisco (May 2024 - May 2029) - - {name: "Jazzy / Debug", ROS_DISTRO: jazzy, CMAKE_BUILD_TYPE: Debug, VECTORIZATION_SUPPORT: OFF} - - {name: "Jazzy / Release", ROS_DISTRO: jazzy, CMAKE_BUILD_TYPE: Release, VECTORIZATION_SUPPORT: OFF} - - {name: "Jazzy / Debug / Vectorization", ROS_DISTRO: jazzy, CMAKE_BUILD_TYPE: Debug, VECTORIZATION_SUPPORT: ON} - - {name: "Jazzy / Release / Vectorization", ROS_DISTRO: jazzy, CMAKE_BUILD_TYPE: Release, VECTORIZATION_SUPPORT: ON} - # ROS2 Humble Hawksbill (May 2022 - May 2027) - - {name: "Humble / Debug / Vectorization", ROS_DISTRO: humble, CMAKE_BUILD_TYPE: Debug, VECTORIZATION_SUPPORT: ON} - - {name: "Humble / Release / Vectorization", ROS_DISTRO: humble, CMAKE_BUILD_TYPE: Release, VECTORIZATION_SUPPORT: ON} - # - {name: "Humble / Pre-Release", ROS_DISTRO: humble, PRERELEASE: true} - # ROS2 Rolling Ridley - - {name: "Rolling / Debug / Vectorization", ROS_DISTRO: rolling, CMAKE_BUILD_TYPE: Debug, VECTORIZATION_SUPPORT: ON} - - {name: "Rolling / Release / Vectorization", ROS_DISTRO: rolling, CMAKE_BUILD_TYPE: Release, VECTORIZATION_SUPPORT: ON} - # - {name: "Rolling / Pre-Release", ROS_DISTRO: rolling, PRERELEASE: true} - # - {name: "Rolling / TSID-Downstream", ROS_DISTRO: rolling, CMAKE_BUILD_TYPE: Release, VECTORIZATION_SUPPORT: ON, DOWNSTREAM_WORKSPACE: "github:stack-of-tasks/tsid#devel github:stack-of-tasks/eiquadprog#devel", DOWNSTREAM_CMAKE_ARGS: -DBUILD_WITH_PROXQP=ON} - name: ${{ matrix.env.name }} - env: - CMAKE_ARGS: -DBUILD_WITH_VECTORIZATION_SUPPORT=${{ matrix.env.VECTORIZATION_SUPPORT }} # Simde is available since humble - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - # Run industrial_ci - - uses: 'ros-industrial/industrial_ci@master' - env: ${{ matrix.env }} - - - check: - if: always() - name: check-ci-linux-ros - - needs: - - CI - - runs-on: Ubuntu-latest - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml new file mode 100644 index 000000000..5a3484244 --- /dev/null +++ b/.github/workflows/ci-linux.yml @@ -0,0 +1,90 @@ +name: CI - Linux + +on: + push: + branches: + - devel + pull_request: + paths-ignore: + - CHANGELOG.md + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ubuntu: + name: CI - ${{ matrix.os }} - ${{ matrix.build_type }} (APT) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-22.04, ubuntu-24.04] + build_type: [Release, Debug] + env: + CCACHE_BASEDIR: ${{ github.workspace }} + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_COMPRESS: true + CCACHE_COMPRESSLEVEL: 6 + CMAKE_C_COMPILER_LAUNCHER: ccache + CMAKE_CXX_COMPILER_LAUNCHER: ccache + steps: + - uses: actions/checkout@v6 + - name: Setup ccache + uses: actions/cache@v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ runner.os }}-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-${{ runner.os }}-${{ matrix.os }}- + + - name: Update APT repositories + run: sudo apt-get update + + - name: Install dependencies via APT + run: sudo apt-get install -y cmake ninja-build ccache graphviz libmatio-dev doxygen catch2 libeigen3-dev python3-numpy python3-dev python3-scipy + + - name: Clear ccache stats + run: ccache --show-stats --zero-stats --verbose + + - name: CMake Configure + run: /usr/bin/cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DBUILD_PYTHON_INTERFACE=ON -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_DOCUMENTATION=ON -DBUILD_BENCHMARKS=ON + + - name: CMake Build + run: /usr/bin/cmake --build build --verbose --parallel 2 + + - name: Show ccache stats + run: ccache --show-stats --verbose + + - name: CTest + run: /usr/bin/ctest --test-dir build --output-on-failure + + - name: CMake Install + run: /usr/bin/cmake --install build --prefix install + + archlinux: + name: CI - ArchLinux + runs-on: ubuntu-latest + container: + image: archlinux/archlinux:base-devel + steps: + - run: pacman -Syu --noconfirm cmake ninja catch2 git eigen cereal libmatio doxygen graphviz nanobind python-scipy simde + - uses: actions/checkout@v6 + - run: cmake -G Ninja -B build -S . -DBUILD_PYTHON_INTERFACE=ON + - run: cmake --build build + - run: ctest --test-dir build --output-on-failure + + check: + if: always() + name: check-linux + + needs: + - ubuntu + - archlinux + + runs-on: ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/nix.yml b/.github/workflows/ci-nix.yml similarity index 71% rename from .github/workflows/nix.yml rename to .github/workflows/ci-nix.yml index 3ce3d1a31..c413eec56 100644 --- a/.github/workflows/nix.yml +++ b/.github/workflows/ci-nix.yml @@ -1,4 +1,4 @@ -name: "CI - Nix" +name: CI - Nix on: push: @@ -10,6 +10,9 @@ on: jobs: nix: + # ⚠️ temporarly disable the Nix job for https://github.com/Simple-Robotics/nanoeigenpy/pull/40 ⚠️ + if: false + runs-on: "${{ matrix.os }}" strategy: matrix: @@ -25,13 +28,16 @@ jobs: - run: nix build -L .#proxsuite${{ matrix.eigen }} check: - if: always() + # ⚠️ temporarly disable the Nix job for https://github.com/Simple-Robotics/nanoeigenpy/pull/40 ⚠️ + if: false + # if: always() + name: check-macos-linux-nix needs: - nix - runs-on: Ubuntu-latest + runs-on: ubuntu-latest steps: - name: Decide whether the needed jobs succeeded or failed diff --git a/.github/workflows/ci-pixi.yml b/.github/workflows/ci-pixi.yml new file mode 100644 index 000000000..c4a13c43d --- /dev/null +++ b/.github/workflows/ci-pixi.yml @@ -0,0 +1,121 @@ +name: CI - Pixi - Windows/Linux/macOS + +on: + push: + branches: + - devel + pull_request: + paths-ignore: + - CHANGELOG.md + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pixi: + name: Pixi CI - ${{ matrix.os }} - ${{ matrix.build_type }} - C++${{ matrix.cxx_std }} + runs-on: ${{ matrix.os }} + env: + CCACHE_BASEDIR: ${{ github.workspace }} + CCACHE_DIR: ${{ github.workspace }}/.ccache + CCACHE_COMPRESS: true + CCACHE_COMPRESSLEVEL: 6 + # Since pixi will install a compiler, the compiler mtime will be changed. + # This can invalidate the cache (https://ccache.dev/manual/latest.html#config_compiler_check) + CCACHE_COMPILERCHECK: content + CMAKE_BUILD_TYPE: ${{ matrix.build_type }} + PROXSUITE_CXX_STANDARD: ${{ matrix.cxx_std }} + strategy: + fail-fast: false + matrix: + build_type: [Release, Debug] + cxx_std: [17, 20] + pixi_environment: [default] + os: [ubuntu-24.04, macos-15-intel, macos-26, windows-2025] + + steps: + - uses: actions/checkout@v6 + - uses: actions/cache@v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-pixi-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_std }}-${{ github.sha }} + restore-keys: ccache-pixi-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.cxx_std }}- + + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.9.3 + with: + environments: default + + - name: Configure + run: pixi run -e default configure --fresh --log-level=DEBUG + + - name: Build + run: pixi run -e default build --verbose --parallel 1 + + - name: Install + run: pixi run -e default install + + - name: Test Python import + run: pixi run -e default test-import-python + + - name: Run C++ tests + if: ${{ !(startsWith(matrix.os, 'windows-') && matrix.build_type == 'Debug') }} + run: pixi run -e default test + + - name: Run packaging tests + run: pixi run -e default test-packaging + + - name: Uninstall + run: pixi run -e default uninstall + + # pixi-build: + # name: Pixi Build CI + # strategy: + # fail-fast: false + # matrix: + # os: [ubuntu-24.04, macos-15-intel, macos-26, windows-2025] + # runs-on: ${{ matrix.os }} + # steps: + # - uses: actions/checkout@v6 + + # - name: Install Pixi + # uses: prefix-dev/setup-pixi@v0.9.3 + # with: + # cache: false + # environments: test-pixi-build + + # - name: Run Pixi build test + # run: pixi run -e test-pixi-build test + + prek: + name: Prek CI + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.9.3 + with: + environments: prek + + - name: Run Prek + run: pixi run -e prek prek + + check: + if: always() + name: check-linux + + needs: + - prek + - pixi + # - pixi-build + + runs-on: ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} + diff --git a/.github/workflows/ci-ros.yml b/.github/workflows/ci-ros.yml new file mode 100644 index 000000000..765fe4e5b --- /dev/null +++ b/.github/workflows/ci-ros.yml @@ -0,0 +1,65 @@ +name: CI - ROS - Linux +on: + push: + branches: + - devel + pull_request: + paths-ignore: + - CHANGELOG.md + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + ros: + name: ROS ${{ matrix.ROS_DISTRO }} - ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + # ROS2 Humble Hawksbill (May 2022 - May 2027) + - ROS_DISTRO: humble + os: Ubuntu 22.04 (Jammy) + + # ROS2 Jazzy Jalisco (May 2024 - May 2029) + - ROS_DISTRO: jazzy + os: Ubuntu 24.04 (Noble) + + # ROS2 Kilted Kayu (May 2025 - December 2026) + - ROS_DISTRO: kilted + os: Ubuntu 24.04 (Noble) + + # ROS2 Rolling Ridley + - ROS_DISTRO: rolling + os: Ubuntu 24.04 (Noble) + env: + CCACHE_DIR: ${{ github.workspace }}/.ccache + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/cache@v5 + with: + path: ${{ env.CCACHE_DIR }} + key: ccache-${{ matrix.ROS_DISTRO }}-${{github.run_id}} + restore-keys: ccache-${{ matrix.ROS_DISTRO }}- + - uses: ros-industrial/industrial_ci@ba2a3d0f830f8051b356711a8df2fedfc5d256cf + env: + CMAKE_ARGS: -DBUILD_WITH_VECTORIZATION_SUPPORT=ON -DBUILD_WITH_SERIALIZATION=ON -DBUILD_PYTHON_INTERFACE=ON -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BENCHMARKS=ON + VERBOSE_OUTPUT: true + VERBOSE_TESTS: true + ROS_DISTRO: ${{ matrix.ROS_DISTRO }} + + check: + if: always() + name: check-ci-linux-ros + + needs: + - ros + + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/conda/environment.yml b/.github/workflows/conda/environment.yml deleted file mode 100644 index 787d71b36..000000000 --- a/.github/workflows/conda/environment.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: proxsuite -channels: - - conda-forge - - nodefaults -dependencies: - - python-gil - - cmake - - compilers - - make - - pkg-config - - doxygen - - ninja - - graphviz - - typing_extensions - - llvm-openmp - - clang - - eigen - - simde - - libmatio - - numpy - - scipy diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml index f15b16a7d..63edc4152 100644 --- a/.github/workflows/gh-pages.yml +++ b/.github/workflows/gh-pages.yml @@ -1,63 +1,33 @@ -name: gh-pages +name: Github Pages Deployment on: release: types: - published jobs: - build: + build_doc: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - with: - submodules: recursive - - - uses: conda-incubator/setup-miniconda@v3 - with: - miniforge-version: latest - activate-environment: doc - channels: conda-forge - conda-remove-defaults: "true" - - - name: Dependencies - shell: bash -l {0} - run: | - # Compilation related dependencies - conda install cmake make pkg-config doxygen graphviz - # Main dependencies - conda install eigen - - - name: Print environment - shell: bash -l {0} - run: | - conda info - conda list - env - - - name: Configure - shell: bash -l {0} - run: | - git submodule update --init - mkdir build - cd build - cmake .. -DCMAKE_INSTALL_PREFIX=${CONDA_PREFIX} -DCMAKE_BUILD_TYPE=Release -DBUILD_PYTHON_INTERFACE:BOOL=OFF -DPYTHON_EXECUTABLE=$(which python3) -DBUILD_DOCUMENTATION:BOOL=ON -DINSTALL_DOCUMENTATION:BOOL=ON -DBUILD_TESTING:BOOL=OFF -DBUILD_WITH_VECTORIZATION_SUPPORT:BOOL=OFF + - name: Install Pixi + uses: prefix-dev/setup-pixi@v0.9.3 - name: Build documentation - shell: bash -l {0} - run: | - cd build - cmake --build . --config Release --target doc + run: pixi run build_documentation + + - name: Install documentation + run: pixi run install_documentation - name: Archive artifacts uses: actions/upload-artifact@v7 with: name: site - path: build/doc/doxygen-html + path: build/doc/html deploy: - runs-on: ubuntu-22.04 - needs: [build] + runs-on: ubuntu-latest + needs: [build_doc] steps: - name: Download artifacts uses: actions/download-artifact@v8 @@ -68,3 +38,19 @@ jobs: uses: JamesIves/github-pages-deploy-action@v4.8.0 with: folder: site + + check: + if: always() + name: check-linux + + needs: + - build_doc + - deploy + + runs-on: ubuntu-latest + + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} \ No newline at end of file diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml deleted file mode 100644 index 37869fc2e..000000000 --- a/.github/workflows/release-linux.yml +++ /dev/null @@ -1,142 +0,0 @@ -name: Release on PyPI [Linux] - -on: - pull_request: - paths-ignore: - - CHANGELOG.md - release: - types: - - published - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - # Only cancel workflow on new push if we are not releasing - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-wheel: - name: "Build ${{ matrix.build }} wheels on ${{ matrix.arch }}" - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - arch: ["x86_64", "aarch64"] - build: ["cp39-*", "cp310-*", "cp311-*", "cp312-*", "cp313-*"] - include: - - arch: "x86_64" - os: ubuntu-latest - - arch: "aarch64" - os: ubuntu-24.04-arm - - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - run: python -m pip install -U pip - - run: python -m pip install cibuildwheel - - run: touch setup.py - if: matrix.arch == 'aarch64' - - run: python -m cibuildwheel --output-dir dist - env: - CIBW_BUILD: ${{ matrix.build }} - CIBW_ARCHS: ${{ matrix.arch }} - CIBW_MANYLINUX_X86_64_IMAGE: "quay.io/pypa/manylinux2014_x86_64" - CIBW_MANYLINUX_AARCH64_IMAGE: "quay.io/pypa/manylinux_2_28_aarch64" - CIBW_REPAIR_WHEEL_COMMAND: "" - CIBW_ENVIRONMENT: "CMEEL_JOBS=2 CMEEL_RUN_TESTS=OFF CMEEL_CMAKE_ARGS=-DBUILD_WITH_OPENMP_SUPPORT=ON" - - - run: echo "ARTIFACT_NAME=dist-${{ matrix.arch }}-${{ matrix.build }}" | sed 's/\*/_/g' >> $GITHUB_ENV - - - uses: actions/upload-artifact@v7 - with: - name: ${{ env.ARTIFACT_NAME }} - path: dist - - test: - name: "Test ${{ matrix.python-version }} wheels on ${{ matrix.os }}" - needs: "build-wheel" - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [ubuntu-latest, ubuntu-24.04-arm] - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - steps: - - uses: actions/setup-python@v6 - with: - python-version: ${{ matrix.python-version }} - - uses: actions/download-artifact@v8 - with: - pattern: dist-* - merge-multiple: true - path: /tmp/dist - - name: setup and install wheel - run: | - python -m pip install -U pip - python -m pip install wheel simpleindex - # Since it's dangerous to use --extra-index-url we use simpleindex - # to mirror PyPI but use the local proxsuite packages - cat < configuration.toml - # Serve local files for packages with prefix "proxsuite". - [routes."proxsuite"] - source = "path" - to = "/tmp/dist" - - # Otherwise use PyPI. - [routes."{project}"] - source = "http" - to = "https://pypi.org/simple/{project}/" - - [server] - host = "127.0.0.1" - port = 8000 - EOF - python -m simpleindex ./configuration.toml & - # Wait for simpleindex server - curl --head -X GET --retry 5 --retry-connrefused --retry-delay 1 http://127.0.0.1:8000 - python -m pip install -i http://127.0.0.1:8000 proxsuite - - name: test module - run: python -c "import proxsuite" - env: - PYTHONWARNINGS: error - - release: - needs: "test" - runs-on: ubuntu-latest - permissions: - id-token: write - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - uses: actions/download-artifact@v8 - with: - pattern: dist-* - merge-multiple: true - path: dist - - - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - if: | - github.repository == 'Simple-Robotics/proxsuite' && - (github.event_name == 'release' && github.event.action == 'published') - - check: - if: always() - name: check-release-linux - - needs: - - build-wheel - - test - - release - - runs-on: ubuntu-latest - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/release-osx-win.yml b/.github/workflows/release-osx-win.yml deleted file mode 100644 index c28bfb15d..000000000 --- a/.github/workflows/release-osx-win.yml +++ /dev/null @@ -1,132 +0,0 @@ -name: Release on PyPI [Windows, Mac] - -on: - pull_request: - paths-ignore: - - CHANGELOG.md - release: - types: - - published - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - # Only cancel workflow on new push if we are not releasing - cancel-in-progress: ${{ github.event_name == 'pull_request' }} - -jobs: - build-wheel: - runs-on: ${{ matrix.os }} - name: Build ${{ matrix.os }} ${{ matrix.python-version }} - strategy: - fail-fast: false - matrix: - python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] - os: [macos-15-intel, macos-14, windows-2022] - include: - - os: windows-2022 - toolset: v143 - - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - - - name: Set ownership - run: | - # Workaround for https://github.com/actions/runner/issues/2033 - # this is to fix GIT not liking owner of the checkout dir - chown -R $(id -u):$(id -g) $PWD - git submodule update - - - name: Setup conda - uses: conda-incubator/setup-miniconda@v3 - with: - miniforge-version: 25.11.0-1 - python-version: ${{ matrix.python-version }} - activate-environment: proxsuite - channels: conda-forge - conda-remove-defaults: "true" - - - name: Install dependencies [Conda] - if: contains(matrix.os, 'macos') || contains(matrix.os, 'windows') - shell: bash -l {0} - run: | - conda install doxygen graphviz eigen simde cmake compilers typing_extensions - - - name: Print environment [Conda] - shell: bash -l {0} - run: | - conda info - conda list - env - - - name: Build wheel - if: contains(matrix.os, 'macos') - shell: bash -l {0} - run: | - pip wheel . -w dist - - - name: Build wheel on windows - if: contains(matrix.os, 'windows') - shell: bash -l {0} - env : - CMEEL_CMAKE_ARGS: "-T${{ matrix.toolset }} -DBUILD_PYTHON_INTERFACE=ON -DBUILD_WITH_VECTORIZATION_SUPPORT=ON -DINSTALL_DOCUMENTATION=OFF" - CMEEL_RUN_TESTS: False - CMEEL_JOBS: 1 - CMEEL_LOG_LEVEL: Debug - run: | - pip wheel . -w dist - - - name: Move proxsuite to specific dist folder - shell: bash -l {0} - run: | - mkdir -p dist_proxsuite - mv dist/proxsuite*.whl dist_proxsuite - - - name: Archive artifacts - uses: actions/upload-artifact@v7 - with: - name: dist-${{ matrix.os }}-${{ matrix.python-version }} - path: dist_proxsuite - - release: - needs: "build-wheel" - runs-on: ubuntu-latest - permissions: - id-token: write - steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 - with: - python-version: "3.12" - - uses: actions/download-artifact@v8 - with: - pattern: dist-* - merge-multiple: true - path: dist - - - name: Check package with twine - run: | - pip install twine - # checks if files can be unzipped and if metadata is correct - twine check --strict dist/* - - - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - if: | - github.repository == 'Simple-Robotics/proxsuite' && - (github.event_name == 'release' && github.event.action == 'published') - - check: - if: always() - name: release-osx-win - - needs: - - build-wheel - - runs-on: Ubuntu-latest - steps: - - name: Decide whether the needed jobs succeeded or failed - uses: re-actors/alls-green@release/v1 - with: - jobs: ${{ toJSON(needs) }} diff --git a/.gitignore b/.gitignore index 50e5b7617..1f8cb67e4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,17 @@ -build* +build*/ +install*/ +.pytest_cache/ +.cache/ +.pixi/ +__pycache__/ Xcode* *.pyc -.vscode* \ No newline at end of file +*~ +*.egg-info +.ruff_cache +.DS_Store +compile_commands.json +cmake-profiling.json +*.whl +dist/ +*.conda diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 2867bf33b..000000000 --- a/.gitmodules +++ /dev/null @@ -1,9 +0,0 @@ -[submodule "bindings/python/external/nanobind"] - path = bindings/python/external/nanobind - url = https://github.com/wjakob/nanobind -[submodule "cmake-module"] - path = cmake-module - url = https://github.com/jrl-umi3218/jrl-cmakemodules.git -[submodule "external/cereal"] - path = external/cereal - url = https://github.com/USCiLab/cereal.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e69089932..d308c452e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -11,7 +11,7 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.10 hooks: - - id: ruff + - id: ruff-check args: - --fix - --exit-non-zero-on-fix diff --git a/CHANGELOG.md b/CHANGELOG.md index a1fdb73cc..7c3b20ec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - replace `std::numeric_limits::infinity()` by `std::numeric_limits::max()` ([#413](https://github.com/Simple-Robotics/proxsuite/pull/413)) - Upgraded nanobind dependency version (submodule) to v2.9.2 ([#418](https://github.com/Simple-Robotics/proxsuite/pull/418)) - Better dynamic module handling ([#419](https://github.com/Simple-Robotics/proxsuite/pull/419)) +- Switch to [JRL CMake modules v2](https://github.com/jrl-umi3218/jrl-cmakemodules/pull/798) ([#28](https://github.com/Simple-Robotics/nanoeigenpy/pull/28)) ### Fixed - Correction of the status update for `PROXQP_SOLVED_CLOSEST_PRIMAL_FEASIBLE` ([#432](https://github.com/Simple-Robotics/proxsuite/pull/432)) diff --git a/CMakeLists.txt b/CMakeLists.txt index a91b58935..8675a3a9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,259 +1,374 @@ -# -# Copyright (c) 2022-2023 INRIA -# +# Copyright (c) 2022-2026 Inria cmake_minimum_required(VERSION 3.22) -if(DEFINED PROJECT_NAME AND NOT PROJECT_WORKSPACE) - set(PROXSUITE_AS_SUBPROJECT ON) +project( + proxsuite + VERSION 0.7.2 + DESCRIPTION "The Advanced Proximal Optimization Toolbox" + HOMEPAGE_URL "https://github.com/Simple-Robotics/proxsuite" +) + +include(cmake/get-jrl-cmakemodules.cmake) + +jrl_configure_defaults() + +# Requires macOS >=10.14 SDK (fixes build issues on macos-15-intel) +# ref: https://github.com/wjakob/nanobind_example/blob/master/pyproject.toml#L43 +set( + CMAKE_OSX_DEPLOYMENT_TARGET + "10.14" + CACHE STRING + "Minimum macOS version supported by proxsuite" + FORCE +) + +set(PROXSUITE_CXX_STANDARD 17 CACHE STRING "C++ standard to be used by proxsuite") +if(PROXSUITE_CXX_STANDARD LESS 17) + message( + FATAL_ERROR + "[proxsuite] PROXSUITE_CXX_STANDARD must be at least 17. + Current value: ${PROXSUITE_CXX_STANDARD}" + ) +elseif(NOT PROXSUITE_CXX_STANDARD) + message( + DEBUG + "[proxsuite] PROXSUITE_CXX_STANDARD passed in the cmd line, but set to nothing. + Defaulting to C++17." + ) + set(PROXSUITE_CXX_STANDARD 17) endif() +message(STATUS "[proxsuite] PROXSUITE_CXX_STANDARD set to '${PROXSUITE_CXX_STANDARD}'") + +jrl_option(PROXSUITE_EXPORT_PACKAGE "Generate the CMake export files" ${PROJECT_IS_TOP_LEVEL}) +jrl_option(BUILD_TESTING "Build the tests" OFF) +jrl_option(BUILD_EXAMPLES "Build the examples" OFF) +jrl_option(BUILD_BENCHMARKS "Build the benchmarks" OFF) +jrl_option(BUILD_DOCUMENTATION "Build the documentation" OFF) +jrl_option(BUILD_MAROS_MESZAROS_TESTS "Build the Maros-Meszaros tests, needs matio library" OFF) +jrl_option(ENABLE_WARNINGS "Enable warnings during compilation" OFF) +jrl_option(ENABLE_WARNINGS_AS_ERRORS "Treat all warnings as errors" OFF) +jrl_option(BUILD_PYTHON_INTERFACE "Build the Python bindings" OFF) +jrl_option(INSTALL_DOCUMENTATION "Install the documentation" OFF) +jrl_option(INITIALIZE_EIGEN_WITH_NAN "Initialize Eigen objects with NAN values" OFF) +jrl_option(CHECK_RUNTIME_MALLOC "Check if some memory allocations are performed at runtime" OFF) +jrl_option(SUFFIX_SO_VERSION "Suffix library name with its version" ON) +jrl_option(BUILD_WITH_VECTORIZATION_SUPPORT "Build the library with the support of modern SIMD instructions" OFF) +jrl_option(BUILD_BINDINGS_WITH_AVX2_SUPPORT "Build the bindings with AVX2 support" ON CONDITION "BUILD_WITH_VECTORIZATION_SUPPORT" FALLBACK OFF) +jrl_option(BUILD_BINDINGS_WITH_AVX512_SUPPORT "Build the bindings with AVX512 support" ON CONDITION "BUILD_WITH_VECTORIZATION_SUPPORT" FALLBACK OFF) +jrl_option(TEST_JULIA_INTERFACE "Run the julia examples as unittest" OFF) +jrl_option(BUILD_WITH_OPENMP_SUPPORT "Build the library with the OpenMP support" OFF) +jrl_option(LINK_PYTHON_INTERFACE_TO_OPENMP "Link OpenMP to the Python interface" ON CONDITION "BUILD_WITH_OPENMP_SUPPORT" FALLBACK OFF) +jrl_option(BUILD_WITH_SERIALIZATION "Build with serialization support" ON CONDITION "BUILD_PYTHON_INTERFACE" FALLBACK OFF) +jrl_option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) -set(PROJECT_NAME proxsuite) -set(PROJECT_DESCRIPTION "The Advanced Proximal Optimization Toolbox") -set(PROJECT_URL "http://github.com/Simple-Robotics/proxsuite") -set(PROJECT_CUSTOM_HEADER_EXTENSION "hpp") -set(PROJECT_USE_CMAKE_EXPORT TRUE) -set(PROJECT_USE_KEYWORD_LINK_LIBRARIES TRUE) -# To enable jrl-cmakemodules compatibility with workspace we must define the two -# following lines -set(PROJECT_AUTO_RUN_FINALIZE FALSE) -set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}) - -# Check if the submodule cmake have been initialized -set(JRL_CMAKE_MODULES "${CMAKE_CURRENT_LIST_DIR}/cmake-module") -if(EXISTS "${JRL_CMAKE_MODULES}/base.cmake") - message(STATUS "JRL cmakemodules found in 'cmake/' git submodule") -else() - find_package(jrl-cmakemodules QUIET CONFIG) - if(jrl-cmakemodules_FOUND) - get_property( - JRL_CMAKE_MODULES - TARGET jrl-cmakemodules::jrl-cmakemodules - PROPERTY INTERFACE_INCLUDE_DIRECTORIES +############################################################ + +# Eigen3 +jrl_find_package(Eigen3 CONFIG REQUIRED) + +# Catch2 +# NOTE: We have to keep the FetchContent support because: +# - pixi does not have debug symbols for Catch2 on Windows. +# - Ubuntu 22.04 LTS ships Catch2 v2 which is incompatible with our tests. +if(BUILD_TESTING) + if(WIN32) + set(Catch2_USE_FETCHCONTENT ON) + endif() + + if(NOT Catch2_USE_FETCHCONTENT) + jrl_find_package(Catch2 3.0 CONFIG QUIET) + if(Catch2_FOUND) + include(Catch) + else() + message( + WARNING + "[proxsuite] Catch2 version >= 3.0 is required for testing. + Falling back to FetchContent to get Catch2 v3.12.0" + ) + set(Catch2_USE_FETCHCONTENT ON) + endif() + endif() + + if(Catch2_USE_FETCHCONTENT) + include(FetchContent) + FetchContent_Declare( + catch2 + URL https://github.com/catchorg/Catch2/archive/refs/tags/v3.12.0.zip + URL_HASH MD5=f04aa334408d47e37aac534e34d1c861 + EXCLUDE_FROM_ALL ) - message(STATUS "JRL cmakemodules found on system at ${JRL_CMAKE_MODULES}") - elseif(${CMAKE_VERSION} VERSION_LESS "3.14.0") + FetchContent_MakeAvailable(catch2) + include(${catch2_SOURCE_DIR}/extras/Catch.cmake) + endif() +endif() + +# cereal (Serialization) +# NOTE: We have to keep the FetchContent support because: +# - Cereal is not available via CMeel +if(BUILD_WITH_SERIALIZATION) + jrl_find_package(cereal CONFIG QUIET) + if(NOT cereal_FOUND) message( - FATAL_ERROR - "\nCan't find jrl-cmakemodules. Please either:\n" - " - use git submodule: 'git submodule update --init'\n" - " - or install https://github.com/jrl-umi3218/jrl-cmakemodules\n" - " - or upgrade your CMake version to >= 3.14 to allow automatic fetching\n" + WARNING + "[proxsuite] cereal library not found. Falling back to FetchContent to get cereal v1.3.2" ) - else() - message(STATUS "JRL cmakemodules not found. Let's fetch it.") include(FetchContent) FetchContent_Declare( - "jrl-cmakemodules" - GIT_REPOSITORY "https://github.com/jrl-umi3218/jrl-cmakemodules.git" + cereal + URL https://github.com/USCiLab/cereal/archive/refs/tags/v1.3.2.zip + URL_HASH MD5=953a872cd3d78abf2e29212987a0ba71 + SOURCE_SUBDIR + download_only + EXCLUDE_FROM_ALL ) - FetchContent_MakeAvailable("jrl-cmakemodules") - FetchContent_GetProperties("jrl-cmakemodules" SOURCE_DIR JRL_CMAKE_MODULES) + FetchContent_MakeAvailable(cereal) + add_library(cereal::cereal INTERFACE IMPORTED) + target_include_directories(cereal::cereal SYSTEM INTERFACE ${cereal_SOURCE_DIR}/include) endif() endif() -# Disable -Werror on Unix for now. -set(CXX_DISABLE_WERROR True) -set(CMAKE_VERBOSE_MAKEFILE True) - -# Set CMake Policies -if(POLICY CMP0068) - cmake_policy(SET CMP0068 NEW) -endif(POLICY CMP0068) - -# ---------------------------------------------------- -# --- OPTIONS --------------------------------------- -# Need to be set before including base.cmake -# ---------------------------------------------------- -option(BUILD_DOCUMENTATION "Build the documentation." OFF) -option(BUILD_BENCHMARK "Build the benchmarks" OFF) -option(INSTALL_DOCUMENTATION "Install the documentation" OFF) -option(BUILD_PYTHON_INTERFACE "Build the Python bindings" OFF) -set(DOXYGEN_USE_MATHJAX YES) -set(DOXYGEN_USE_TEMPLATE_CSS YES) - -# install() DESTINATION paths are normalized (to remove in 3.31) (copied over -# from Pinocchio) -if(POLICY CMP0177) - cmake_policy(SET CMP0177 NEW) - set(CMAKE_POLICY_DEFAULT_CMP0177 NEW) +# nanobind (Python bindings) +# NOTE: We have to keep the FetchContent support because: +# - Ubuntu 24.04 ships an incompatible 1.9.2 version of nanobind via apt-get. +# - Ubuntu 22.04 does not ship nanobind at all via apt-get. +if(BUILD_PYTHON_INTERFACE) + jrl_find_python(3.10 REQUIRED COMPONENTS Interpreter Development.Module) + jrl_find_nanobind(2.5.0 CONFIG QUIET) + if(NOT nanobind_FOUND) + message( + WARNING + "[proxsuite] nanobind library not found. Falling back to FetchContent to get nanobind v2.11.0" + ) + include(FetchContent) + FetchContent_Declare( + nanobind + GIT_REPOSITORY https://github.com/wjakob/nanobind.git + GIT_TAG v2.11.0 + EXCLUDE_FROM_ALL + ) + FetchContent_MakeAvailable(nanobind) + endif() endif() -include(${JRL_CMAKE_MODULES}/base.cmake) -COMPUTE_PROJECT_ARGS(PROJECT_ARGS LANGUAGES CXX) -project(${PROJECT_NAME} ${PROJECT_ARGS}) - -include(${JRL_CMAKE_MODULES}/ide.cmake) -include(${JRL_CMAKE_MODULES}/apple.cmake) - -if(NOT ${CMAKE_VERSION} VERSION_GREATER "3.26.0" OR WIN32) - set( - CMAKE_MODULE_PATH - ${JRL_CMAKE_MODULES}/find-external/OpenMP - ${CMAKE_MODULE_PATH} - ) + +# simde +if(BUILD_WITH_VECTORIZATION_SUPPORT) + jrl_find_package(simde REQUIRED) endif() -include(${JRL_CMAKE_MODULES}/julia.cmake) -include(CMakeDependentOption) - -# If needed, set CMake policy for APPLE systems -APPLY_DEFAULT_APPLE_CONFIGURATION() -SET_DEFAULT_CMAKE_BUILD_TYPE(Release) - -option(INITIALIZE_EIGEN_WITH_NAN "Initialize Eigen objects with NAN values" OFF) -option( - CHECK_RUNTIME_MALLOC - "Check if some memory allocations are performed at runtime" - OFF -) -option(SUFFIX_SO_VERSION "Suffix library name with its version" ON) -option( - BUILD_WITH_VECTORIZATION_SUPPORT - "Build the library with the support of modern SIMD instructions." - ON -) -option( - BUILD_BINDINGS_WITH_AVX2_SUPPORT - "Build the bindings with AVX2 support." - ON -) -option( - BUILD_BINDINGS_WITH_AVX512_SUPPORT - "Build the bindings with AVX512 support." - ON -) -option(TEST_JULIA_INTERFACE "Run the julia examples as unittest" OFF) -option( - BUILD_WITH_OPENMP_SUPPORT - "Build the library with the OpenMP support" - OFF -) -cmake_dependent_option( - LINK_PYTHON_INTERFACE_TO_OPENMP - "Link OpenMP to the Python interface" - ON - BUILD_WITH_OPENMP_SUPPORT - OFF -) +# matio +if(BUILD_TESTING AND BUILD_MAROS_MESZAROS_TESTS) + jrl_find_package(matio REQUIRED) +endif() +# OpenMP if(BUILD_WITH_OPENMP_SUPPORT) - find_package(OpenMP REQUIRED) - separate_arguments(OpenMP_CXX_FLAGS UNIX_COMMAND "${OpenMP_CXX_FLAGS}") -endif(BUILD_WITH_OPENMP_SUPPORT) - -set( - CMAKE_MODULE_PATH - "${JRL_CMAKE_MODULES}/find-external/Julia" - ${CMAKE_MODULE_PATH} -) -set( - CMAKE_MODULE_PATH - "${CMAKE_CURRENT_LIST_DIR}/cmake-external" - ${CMAKE_MODULE_PATH} -) - -message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}") -if(INITIALIZE_EIGEN_WITH_NAN) - add_definitions(-DEIGEN_INITIALIZE_MATRICES_BY_NAN) -endif(INITIALIZE_EIGEN_WITH_NAN) -if(CHECK_RUNTIME_MALLOC) - message(STATUS "Check if some memory allocations are performed at runtime.") - add_definitions(-DPROXSUITE_EIGEN_CHECK_MALLOC) - add_definitions(-DEIGEN_RUNTIME_NO_MALLOC) -endif(CHECK_RUNTIME_MALLOC) - -# set CXX standard -if(DEFINED CMAKE_CXX_STANDARD) - CHECK_MINIMAL_CXX_STANDARD(14 ENFORCE) -else() - set(CMAKE_CXX_STANDARD 17) + jrl_find_package(OpenMP REQUIRED) endif() -message(STATUS "[Proxsuite] Using C++ standard: ${CMAKE_CXX_STANDARD}") -# Handle Windows context -if(MSVC) - # add_definitions(-D_USE_MATH_DEFINES) - add_definitions(-DNOMINMAX) +# Doxygen + Graphviz (dot) +if(BUILD_DOCUMENTATION) + jrl_find_package(Doxygen REQUIRED COMPONENTS dot) endif() -# Look for dependencies -ADD_PROJECT_DEPENDENCY(Eigen3 REQUIRED PKG_CONFIG_REQUIRES "eigen3 >= 3.0.5") +############################################################ -set( - SIMDE_HINT_FAILURE - "Set BUILD_WITH_VECTORIZATION_SUPPORT=OFF or install Simde on your system.\n If Simde is already installed, ensure that the CMake variable CMAKE_MODULE_PATH correctly points toward the location of FindSimde.cmake file." +add_library(proxsuite INTERFACE) +add_library(proxsuite::proxsuite ALIAS proxsuite) +target_compile_features(proxsuite INTERFACE cxx_std_${PROXSUITE_CXX_STANDARD}) +jrl_target_enforce_msvc_conformance(proxsuite INTERFACE) + +target_include_directories( + proxsuite + INTERFACE + $ + $ ) -if(BUILD_WITH_VECTORIZATION_SUPPORT) - ADD_PROJECT_DEPENDENCY( - Simde - REQUIRED - FIND_EXTERNAL "Simde" - PKG_CONFIG_REQUIRES "simde" - ) + +jrl_target_generate_config_header(proxsuite INTERFACE VERSION ${PROJECT_VERSION}) + +if(ENABLE_WARNINGS) + jrl_target_set_default_compile_options(proxsuite INTERFACE) endif() -# Build the main library -file(GLOB_RECURSE ${PROJECT_NAME}_HEADERS ${PROJECT_SOURCE_DIR}/include/*.hpp) +if(ENABLE_WARNINGS_AS_ERRORS) + jrl_target_treat_all_warnings_as_errors(proxsuite INTERFACE) +endif() -add_library(proxsuite INTERFACE) -if(MSVC) - target_compile_options(proxsuite INTERFACE /permissive-) - target_compile_options(proxsuite INTERFACE $<$:/bigobj>) -endif(MSVC) -target_link_libraries(proxsuite PUBLIC INTERFACE Eigen3::Eigen) -target_include_directories( +target_compile_definitions( proxsuite INTERFACE - "$" - "$" + $<$:EIGEN_INITIALIZE_MATRICES_BY_NAN> + $<$:EIGEN_RUNTIME_NO_MALLOC> + $<$:PROXSUITE_EIGEN_CHECK_MALLOC> + $<$:PROXSUITE_PYTHON_INTERFACE_WITH_OPENMP> ) -target_include_directories( + +target_link_libraries( proxsuite - INTERFACE "$" + INTERFACE + Eigen3::Eigen + $<$:OpenMP::OpenMP_CXX> + $<$:cereal::cereal> ) -set(EXPORTED_TARGETS_LIST proxsuite) -ADD_HEADER_GROUP(${PROJECT_NAME}_HEADERS) +if(BUILD_PYTHON_INTERFACE) + add_subdirectory(bindings/python) +endif() if(BUILD_WITH_VECTORIZATION_SUPPORT) add_library(proxsuite-vectorized INTERFACE) - target_link_libraries(proxsuite-vectorized PUBLIC INTERFACE proxsuite) - target_link_libraries(proxsuite-vectorized PUBLIC INTERFACE simde) + add_library(proxsuite::proxsuite-vectorized ALIAS proxsuite-vectorized) + target_link_libraries( + proxsuite-vectorized + INTERFACE proxsuite simde::simde $<$:cereal::cereal> + ) target_compile_definitions(proxsuite-vectorized INTERFACE PROXSUITE_VECTORIZE) - list(APPEND EXPORTED_TARGETS_LIST proxsuite-vectorized) endif() -if(BUILD_TESTING OR BUILD_PYTHON_INTERFACE) - # Download cereal for pything bindings and unittests - find_package(cereal QUIET CONFIG) - if(NOT cereal_FOUND) - set(cereal_dir ${PROJECT_SOURCE_DIR}/external/cereal) - set(cereal ${cereal_dir}/README.md) - find_package(Git REQUIRED) - if(NOT EXISTS ${cereal}) - execute_process( - COMMAND ${GIT_EXECUTABLE} submodule update --init ${cereal_dir} - WORKING_DIRECTORY ${cereal_dir} - COMMAND_ERROR_IS_FATAL ANY - ) - endif() - endif() +if(BUILD_TESTING) + message(STATUS "[proxsuite] Building tests") + enable_testing() + add_subdirectory(test) endif() -install( - TARGETS ${EXPORTED_TARGETS_LIST} - EXPORT ${TARGETS_EXPORT_NAME} - LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} +if(BUILD_EXAMPLES) + message(STATUS "[proxsuite] Building examples") + add_subdirectory(examples) +endif() + +if(BUILD_BENCHMARKS) + message(STATUS "[proxsuite] Building benchmarks") + add_subdirectory(benchmark) +endif() + +if(BUILD_DOCUMENTATION) + message(STATUS "[proxsuite] Building documentation") + add_subdirectory(doc) +endif() + +jrl_target_headers(proxsuite INTERFACE + HEADERS + include/proxsuite/helpers/common.hpp + include/proxsuite/helpers/instruction-set.hpp + include/proxsuite/helpers/optional.hpp + include/proxsuite/helpers/version.hpp + include/proxsuite/linalg/dense/core.hpp + include/proxsuite/linalg/dense/factorize.hpp + include/proxsuite/linalg/dense/ldlt.hpp + include/proxsuite/linalg/dense/modify.hpp + include/proxsuite/linalg/dense/solve.hpp + include/proxsuite/linalg/dense/update.hpp + include/proxsuite/linalg/sparse/core.hpp + include/proxsuite/linalg/sparse/factorize.hpp + include/proxsuite/linalg/sparse/rowmod.hpp + include/proxsuite/linalg/sparse/update.hpp + include/proxsuite/linalg/veg/internal/external/hedley.ext.hpp + include/proxsuite/linalg/veg/internal/external/unhedley.ext.hpp + include/proxsuite/linalg/veg/internal/assert_impl.hpp + include/proxsuite/linalg/veg/internal/collection_algo.hpp + include/proxsuite/linalg/veg/internal/dbg.hpp + include/proxsuite/linalg/veg/internal/delete_special_members.hpp + include/proxsuite/linalg/veg/internal/dyn_index.hpp + include/proxsuite/linalg/veg/internal/epilogue.hpp + include/proxsuite/linalg/veg/internal/fix_index.hpp + include/proxsuite/linalg/veg/internal/has_asan.hpp + include/proxsuite/linalg/veg/internal/integer_seq.hpp + include/proxsuite/linalg/veg/internal/macros.hpp + include/proxsuite/linalg/veg/internal/narrow.hpp + include/proxsuite/linalg/veg/internal/preprocessor.hpp + include/proxsuite/linalg/veg/internal/prologue.hpp + include/proxsuite/linalg/veg/internal/std.hpp + include/proxsuite/linalg/veg/internal/terminate.hpp + include/proxsuite/linalg/veg/internal/typedefs.hpp + include/proxsuite/linalg/veg/memory/address.hpp + include/proxsuite/linalg/veg/memory/alloc.hpp + include/proxsuite/linalg/veg/memory/dynamic_stack.hpp + include/proxsuite/linalg/veg/memory/placement.hpp + include/proxsuite/linalg/veg/memory/stack_alloc.hpp + include/proxsuite/linalg/veg/type_traits/alloc.hpp + include/proxsuite/linalg/veg/type_traits/assignable.hpp + include/proxsuite/linalg/veg/type_traits/constructible.hpp + include/proxsuite/linalg/veg/type_traits/core.hpp + include/proxsuite/linalg/veg/type_traits/invocable.hpp + include/proxsuite/linalg/veg/type_traits/primitives.hpp + include/proxsuite/linalg/veg/type_traits/tags.hpp + include/proxsuite/linalg/veg/util/assert.hpp + include/proxsuite/linalg/veg/util/dbg.hpp + include/proxsuite/linalg/veg/util/defer.hpp + include/proxsuite/linalg/veg/util/dynstack_alloc.hpp + include/proxsuite/linalg/veg/util/get.hpp + include/proxsuite/linalg/veg/util/index.hpp + include/proxsuite/linalg/veg/util/unreachable.hpp + include/proxsuite/linalg/veg/ref.hpp + include/proxsuite/linalg/veg/slice.hpp + include/proxsuite/linalg/veg/tuple.hpp + include/proxsuite/linalg/veg/vec.hpp + include/proxsuite/proxqp/dense/preconditioner/identity.hpp + include/proxsuite/proxqp/dense/preconditioner/ruiz.hpp + include/proxsuite/proxqp/dense/backward_data.hpp + include/proxsuite/proxqp/dense/compute_ECJ.hpp + include/proxsuite/proxqp/dense/dense.hpp + include/proxsuite/proxqp/dense/fwd.hpp + include/proxsuite/proxqp/dense/helpers.hpp + include/proxsuite/proxqp/dense/linesearch.hpp + include/proxsuite/proxqp/dense/model.hpp + include/proxsuite/proxqp/dense/solver.hpp + include/proxsuite/proxqp/dense/utils.hpp + include/proxsuite/proxqp/dense/views.hpp + include/proxsuite/proxqp/dense/workspace.hpp + include/proxsuite/proxqp/dense/wrapper.hpp + include/proxsuite/proxqp/parallel/omp.hpp + include/proxsuite/proxqp/parallel/qp_solve.hpp + include/proxsuite/proxqp/sparse/preconditioner/identity.hpp + include/proxsuite/proxqp/sparse/preconditioner/ruiz.hpp + include/proxsuite/proxqp/sparse/fwd.hpp + include/proxsuite/proxqp/sparse/helpers.hpp + include/proxsuite/proxqp/sparse/model.hpp + include/proxsuite/proxqp/sparse/solver.hpp + include/proxsuite/proxqp/sparse/sparse.hpp + include/proxsuite/proxqp/sparse/utils.hpp + include/proxsuite/proxqp/sparse/views.hpp + include/proxsuite/proxqp/sparse/workspace.hpp + include/proxsuite/proxqp/sparse/wrapper.hpp + include/proxsuite/proxqp/utils/prints.hpp + include/proxsuite/proxqp/utils/random_qp_problems.hpp + include/proxsuite/proxqp/utils/uint128_msvc.hpp + include/proxsuite/proxqp/results.hpp + include/proxsuite/proxqp/settings.hpp + include/proxsuite/proxqp/status.hpp + include/proxsuite/proxqp/timings.hpp + include/proxsuite/fwd.hpp + BASE_DIRS include ) -add_subdirectory(bindings) -if(BUILD_TESTING AND NOT PROXSUITE_AS_SUBPROJECT) - add_subdirectory(test) - add_subdirectory(examples) +if(BUILD_WITH_SERIALIZATION) + jrl_target_headers(proxsuite INTERFACE + HEADERS + include/proxsuite/serialization/archive.hpp + include/proxsuite/serialization/eigen.hpp + include/proxsuite/serialization/model.hpp + include/proxsuite/serialization/results.hpp + include/proxsuite/serialization/ruiz.hpp + include/proxsuite/serialization/settings.hpp + include/proxsuite/serialization/workspace.hpp + include/proxsuite/serialization/wrapper.hpp + BASE_DIRS include + ) +endif() + +jrl_add_export_component(NAME proxsuite TARGETS proxsuite) + +if(BUILD_WITH_VECTORIZATION_SUPPORT) + jrl_add_export_component(NAME vectorized TARGETS proxsuite-vectorized) endif() -add_subdirectory(benchmark) +jrl_export_package() + +jrl_generate_ros2_package_files( + INSTALL_CPP_PACKAGE_FILES [[NOT BUILD_STANDALONE_PYTHON_INTERFACE]] + INSTALL_PYTHON_PACKAGE_FILES [[BUILD_PYTHON_INTERFACE]] +) -SETUP_PROJECT_FINALIZE() +jrl_print_dependencies_summary() +jrl_print_options_summary() diff --git a/README.md b/README.md index 271cfc1b9..65639d8d9 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,23 @@ This approach is available on Linux, Windows and Mac OS X. ``` This approach is available on Linux and Mac OS X. +### Develop with `pixi`: + +Install [pixi](https://pixi.prefix.dev/latest), then build with: + +```bash +pixi run build +``` + +To run the tests: + +```bash +pixi run test +``` + +This approach is available on Linux, Windows, and MacOS (Intel and Apple Silicon). + + ### Alternative approaches Installation from source is presented [here](https://github.com/Simple-Robotics/proxsuite/blob/devel/doc/5-installation.md). diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 6f6ea47ef..1249fbb47 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -1,26 +1,18 @@ -add_custom_target(${PROJECT_NAME}_bench) - -macro(proxsuite_benchmark bench_name) - if(BUILD_BENCHMARK) - add_executable(${bench_name} ${bench_name}.cpp) - else(BUILD_BENCHMARK) - add_executable(${bench_name} EXCLUDE_FROM_ALL ${bench_name}.cpp) - endif(BUILD_BENCHMARK) +function(proxsuite_add_benchmark name) + add_executable(proxsuite-benchmark-${name} ${name}.cpp) + target_link_libraries(proxsuite-benchmark-${name} PRIVATE proxsuite) if(BUILD_WITH_VECTORIZATION_SUPPORT) - target_link_libraries(${bench_name} PUBLIC proxsuite-vectorized) - else() - target_link_libraries(${bench_name} PUBLIC proxsuite) + add_executable(proxsuite-vectorized-benchmark-${name} ${name}.cpp) + target_link_libraries(proxsuite-vectorized-benchmark-${name} PRIVATE proxsuite-vectorized) endif() - add_dependencies(${PROJECT_NAME}_bench ${bench_name}) -endmacro(proxsuite_benchmark) +endfunction() -proxsuite_benchmark(timings-lp) -proxsuite_benchmark(timings-box-constraints) -proxsuite_benchmark(timings-dense-backend) -proxsuite_benchmark(timings-diagonal-hessian) +proxsuite_add_benchmark(timings-box-constraints) +proxsuite_add_benchmark(timings-dense-backend) +proxsuite_add_benchmark(timings-diagonal-hessian) +proxsuite_add_benchmark(timings-lp) if(BUILD_WITH_OPENMP_SUPPORT) - proxsuite_benchmark(timings-parallel) - target_link_libraries(timings-parallel PRIVATE OpenMP::OpenMP_CXX) -endif(BUILD_WITH_OPENMP_SUPPORT) + proxsuite_add_benchmark(timings-parallel) +endif() diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt deleted file mode 100644 index 284d3386b..000000000 --- a/bindings/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -if(BUILD_PYTHON_INTERFACE) - add_subdirectory(python) -endif() diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt index cf55a9d47..7145a9849 100644 --- a/bindings/python/CMakeLists.txt +++ b/bindings/python/CMakeLists.txt @@ -1,313 +1,157 @@ -if(UNIX) - set(PYTHON_COMPONENTS Interpreter Development.Module) +set( + proxsuite_pywrap_HEADERS + src/algorithms.hpp + src/expose-backward.hpp + src/expose-helpers.hpp + src/expose-model.hpp + src/expose-qpobject.hpp + src/expose-qpvector.hpp + src/expose-results.hpp + src/expose-settings.hpp + src/expose-solve.hpp + src/expose-workspace.hpp + src/optional-eigen-fix.hpp +) +if(BUILD_WITH_OPENMP_SUPPORT) + list(APPEND proxsuite_pywrap_HEADERS src/expose-parallel.hpp) endif() -include(${JRL_CMAKE_MODULES}/python.cmake) -include(${JRL_CMAKE_MODULES}/python-helpers.cmake) +set(proxsuite_pywrap_SOURCES src/expose-all.cpp) -option(GENERATE_PYTHON_STUBS "Generate Python stubs" OFF) +function(create_python_target target_name) + set(options) + set(oneValueArgs) + set(multiValueArgs COMPILE_OPTIONS LINK_LIBRARIES) + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) -FINDPYTHON(REQUIRED) -set(Python_INCLUDE_DIRS ${Python3_INCLUDE_DIRS}) -set(Python_VERSION ${Python3_VERSION}) -# Nanobind expects these targets instead of Python3::* -# https://github.com/jrl-umi3218/jrl-cmakemodules/issues/708 -add_library(Python::Module ALIAS Python3::Module) -add_executable(Python::Interpreter ALIAS Python3::Interpreter) + nanobind_add_module(${target_name} NB_STATIC LTO NB_SUPPRESS_WARNINGS ${proxsuite_pywrap_SOURCES} ${proxsuite_pywrap_HEADERS}) + jrl_check_python_module_name(${target_name}) -if(IS_ABSOLUTE ${PYTHON_SITELIB}) - set(${PYWRAP}_INSTALL_DIR ${PYTHON_SITELIB}/${PROJECT_NAME}) -else() - set( - ${PYWRAP}_INSTALL_DIR - ${CMAKE_INSTALL_PREFIX}/${PYTHON_SITELIB}/${PROJECT_NAME} - ) -endif() + target_link_libraries(${target_name} PRIVATE ${arg_LINK_LIBRARIES}) + target_compile_options(${target_name} PRIVATE ${arg_COMPILE_OPTIONS}) + target_compile_definitions(${target_name} PRIVATE PYTHON_MODULE_NAME=${target_name}) + jrl_target_set_output_directory(${target_name} OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib/site-packages/${PROJECT_NAME}) +endfunction() -cmake_policy(PUSH) -cmake_policy(SET CMP0074 NEW) -# Detect the installed nanobind package and import it into CMake -execute_process( - COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE nanobind_ROOT -) -find_package(nanobind CONFIG) -cmake_policy(POP) -if(NOT nanobind_FOUND) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind) - add_subdirectory( - external/nanobind - ${CMAKE_CURRENT_BINARY_DIR}/external/nanobind - ) - message(STATUS "Will use nanobind submodule.") -else() - message(STATUS "Found installed nanobind.") +# copy __init_.py and torch files into the build directory (so we can import proxsuite) +file(COPY proxsuite DESTINATION ${CMAKE_BINARY_DIR}/lib/site-packages) + +# The main python binding target +create_python_target(proxsuite_pywrap LINK_LIBRARIES proxsuite) + +if(LINK_PYTHON_INTERFACE_TO_OPENMP) + message(STATUS "[proxsuite] Linking python bindings to OpenMP") + target_link_libraries(proxsuite_pywrap PRIVATE OpenMP::OpenMP_CXX) endif() -add_custom_target(${PROJECT_NAME}_python) +# Vectorized python binding targets +if(BUILD_WITH_VECTORIZATION_SUPPORT) + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(AVX_COMPILE_OPTION "/arch:AVX") + set(AVX2_COMPILE_OPTION "/arch:AVX2") + set(FMA_COMPILE_OPTION "/fp:fast") + set(AVX512_COMPILE_OPTION "/arch:AVX512") + else() + set(AVX_COMPILE_OPTION "-mavx") + set(AVX2_COMPILE_OPTION "-mavx2") + set(FMA_COMPILE_OPTION "-mfma") + set(AVX512_COMPILE_OPTION "-mavx512f") + endif() + + if(BUILD_BINDINGS_WITH_AVX2_SUPPORT) + message(STATUS "[proxsuite] Building python bindings with AVX2 support") + create_python_target( + proxsuite_pywrap_avx2 + COMPILE_OPTIONS + "${AVX2_COMPILE_OPTION}" + "${FMA_COMPILE_OPTION}" + LINK_LIBRARIES proxsuite-vectorized + ) + endif() -# Collect files -file(GLOB_RECURSE PYWRAP_HEADERS ${CMAKE_CURRENT_LIST_DIR}/src/*.hpp) -file(GLOB_RECURSE PYWRAP_SOURCES ${CMAKE_CURRENT_LIST_DIR}/src/*.cpp) + if(BUILD_BINDINGS_WITH_AVX512_SUPPORT) + message(STATUS "[proxsuite] Building python bindings with AVX512 support") + create_python_target( + proxsuite_pywrap_avx512 + COMPILE_OPTIONS + "${AVX512_COMPILE_OPTION}" + "${FMA_COMPILE_OPTION}" + LINK_LIBRARIES proxsuite-vectorized + ) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND Eigen3_VERSION VERSION_GREATER_EQUAL 5.0) + # BUG: Eigen5 introduced a new AVX512 GEMM kernel that causes extremely long compilation times on MSVC. + # Disabling it for now. ref: libeigen/eigen#3066 + target_compile_definitions(proxsuite_pywrap_avx512 PRIVATE EIGEN_USE_AVX512_GEMM_KERNELS=0) + endif() + endif() + else() + message( + WARNING + "[proxsuite] AVX2 and AVX512 python bindings are only supported on x86_64. Current architecture is '${CMAKE_SYSTEM_PROCESSOR}'" + ) + endif() +endif() # Add simd feature detectors for current intel CPU if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)") - nanobind_add_module(instructionset helpers/instruction-set.cpp) - add_dependencies(${PROJECT_NAME}_python instructionset) + nanobind_add_module(instructionset NB_STATIC LTO NB_SUPPRESS_WARNINGS helpers/instruction-set.cpp) target_link_libraries(instructionset PRIVATE proxsuite) - set_target_properties( + jrl_target_set_output_directory( instructionset - PROPERTIES - OUTPUT_NAME instructionset - LIBRARY_OUTPUT_DIRECTORY - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - LIBRARY_OUTPUT_DIRECTORY_RELEASE - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - LIBRARY_OUTPUT_DIRECTORY_DEBUG - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - # On Windows, shared library are treat as binary - RUNTIME_OUTPUT_DIRECTORY - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - RUNTIME_OUTPUT_DIRECTORY_RELEASE - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - RUNTIME_OUTPUT_DIRECTORY_DEBUG - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - ) - if(UNIX AND NOT APPLE) - set_target_properties( - instructionset - PROPERTIES INSTALL_RPATH "\$ORIGIN/../../.." - ) - endif() - install( - TARGETS instructionset - EXPORT ${TARGETS_EXPORT_NAME} - DESTINATION ${${PYWRAP}_INSTALL_DIR} + OUTPUT_DIRECTORY + ${CMAKE_BINARY_DIR}/lib/site-packages/${PROJECT_NAME} ) if(GENERATE_PYTHON_STUBS) nanobind_add_stub( instructionset_stub MODULE instructionset - OUTPUT instructionset.pyi + OUTPUT ${CMAKE_BINARY_DIR}/lib/site-packages/${PROJECT_NAME}/instructionset.pyi PYTHON_PATH $ DEPENDS instructionset ) - install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/instructionset.pyi - DESTINATION ${${PYWRAP}_INSTALL_DIR} - ) endif() endif() -function(list_filter list regular_expression dest_list) - foreach(elt ${list}) - if(${elt} MATCHES ${regular_expression}) - list(REMOVE_ITEM list ${elt}) - endif() - endforeach(elt ${list}) - set(${dest_list} ${list} PARENT_SCOPE) -endfunction(list_filter) - -function( - create_python_target - target_name - compile_options - dependencies - generate_stubs -) - nanobind_add_module(${target_name} ${PYWRAP_SOURCES} ${PYWRAP_HEADERS}) - add_dependencies(${PROJECT_NAME}_python ${target_name}) - - target_link_libraries(${target_name} PUBLIC ${dependencies}) - target_compile_options(${target_name} PRIVATE ${compile_options}) - target_link_libraries(${target_name} PRIVATE proxsuite) - target_compile_definitions( - ${target_name} - PRIVATE PYTHON_MODULE_NAME=${target_name} - ) - - if(BUILD_WITH_OPENMP_SUPPORT) - target_compile_options(${target_name} PRIVATE ${OpenMP_CXX_FLAGS}) - target_compile_definitions( - ${target_name} - PRIVATE -DPROXSUITE_PYTHON_INTERFACE_WITH_OPENMP - ) - target_include_directories( - ${target_name} - SYSTEM - PRIVATE ${OpenMP_CXX_INCLUDE_DIR} - ) - if(LINK_PYTHON_INTERFACE_TO_OPENMP) - target_link_libraries(${target_name} PRIVATE ${OpenMP_CXX_LIBRARIES}) - endif(LINK_PYTHON_INTERFACE_TO_OPENMP) - else() - list_filter("${PYWRAP_HEADERS}" "expose-parallel" PYWRAP_HEADERS) - endif(BUILD_WITH_OPENMP_SUPPORT) - - if(cereal_FOUND) - target_link_libraries(${target_name} PRIVATE cereal::cereal) - else() - target_include_directories( - ${target_name} - SYSTEM - PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include - ) - endif() - set_target_properties( - ${target_name} - PROPERTIES - OUTPUT_NAME ${target_name} - LIBRARY_OUTPUT_DIRECTORY - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - LIBRARY_OUTPUT_DIRECTORY_RELEASE - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - LIBRARY_OUTPUT_DIRECTORY_DEBUG - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - # On Windows, shared library are treat as binary - RUNTIME_OUTPUT_DIRECTORY - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - RUNTIME_OUTPUT_DIRECTORY_RELEASE - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - RUNTIME_OUTPUT_DIRECTORY_DEBUG - "${PROJECT_BINARY_DIR}/bindings/python/${PROJECT_NAME}" - ) - - if(UNIX AND NOT APPLE) - set_target_properties( - ${target_name} - PROPERTIES INSTALL_RPATH "\$ORIGIN/../../.." - ) +if(GENERATE_PYTHON_STUBS) + if(TARGET proxsuite_pywrap_avx2) + set(avx2_lib proxsuite_pywrap_avx2) endif() - - install(TARGETS ${target_name} DESTINATION ${${PYWRAP}_INSTALL_DIR}) - if(${generate_stubs}) - set( - stub_outputs - ${target_name}/__init__.pyi - ${target_name}/helpers.pyi - ${target_name}/proxqp/__init__.pyi - ${target_name}/proxqp/dense.pyi - ${target_name}/proxqp/sparse.pyi - ) - nanobind_add_stub( - ${target_name}_stub - MODULE ${target_name} - OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} - OUTPUT ${stub_outputs} - RECURSIVE - PYTHON_PATH $ - DEPENDS ${target_name} - ) - install( - DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${target_name} - DESTINATION ${${PYWRAP}_INSTALL_DIR} - ) + if(TARGET proxsuite_pywrap_avx512) + set(avx512_lib proxsuite_pywrap_avx512) endif() -endfunction() -if(CMAKE_CXX_COMPILER_ID MATCHES MSVC) - set(AVX_COMPILE_OPTION "/arch:AVX") - set(AVX2_COMPILE_OPTION "/arch:AVX2") - set(FMA_COMPILE_OPTION "/fp:fast,") - set(AVX512_COMPILE_OPTION "/arch:AVX512") -else() - set(AVX_COMPILE_OPTION "-mavx") - set(AVX2_COMPILE_OPTION "-mavx2") - set(FMA_COMPILE_OPTION "-mfma") - set(AVX512_COMPILE_OPTION "-mavx512f") + nanobind_add_stub( + proxsuite_pywrap_stub + MODULE proxsuite + VERBOSE + OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib/site-packages/${PROJECT_NAME} + OUTPUT + __init__.pyi + helpers.pyi + proxqp/__init__.pyi + proxqp/dense.pyi + proxqp/sparse.pyi + RECURSIVE + PYTHON_PATH ${CMAKE_BINARY_DIR}/lib/site-packages + DEPENDS proxsuite_pywrap ${avx2_lib} ${avx512_lib} + ) endif() -create_python_target(proxsuite_pywrap "" proxsuite ${GENERATE_PYTHON_STUBS}) -if( - BUILD_WITH_VECTORIZATION_SUPPORT - AND ${CMAKE_SYSTEM_PROCESSOR} MATCHES "(x86)|(X86)|(amd64)|(AMD64)" +jrl_python_compile_all( + DIRECTORY ${CMAKE_BINARY_DIR}/lib/site-packages ) - if(BUILD_BINDINGS_WITH_AVX2_SUPPORT) - create_python_target( - proxsuite_pywrap_avx2 - "${AVX2_COMPILE_OPTION};${FMA_COMPILE_OPTION}" - proxsuite-vectorized - FALSE - ) - endif(BUILD_BINDINGS_WITH_AVX2_SUPPORT) - if(BUILD_BINDINGS_WITH_AVX512_SUPPORT) - create_python_target( - proxsuite_pywrap_avx512 - "${AVX512_COMPILE_OPTION};${FMA_COMPILE_OPTION}" - proxsuite-vectorized - FALSE - ) - endif(BUILD_BINDINGS_WITH_AVX512_SUPPORT) -endif() -ADD_HEADER_GROUP(PYWRAP_HEADERS) -ADD_SOURCE_GROUP(PYWRAP_SOURCES) -# --- INSTALL SCRIPTS - -# On Windows, we need to enforce the environment variable KMP_DUPLICATE_LIB_OK -# to True to to allow the program to continue to execute with OpenMP support -if( - WIN32 - AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - AND BUILD_WITH_OPENMP_SUPPORT +# Install the whole python package directory +jrl_python_compute_install_dir(python_install_dir) +install( + DIRECTORY ${CMAKE_BINARY_DIR}/lib/site-packages/${PROJECT_NAME} + DESTINATION ${python_install_dir} + FILES_MATCHING + PATTERN "*.py" + PATTERN "*.pyc" + PATTERN "*.pyi" + PATTERN "*.typed" + PATTERN "*.so" + PATTERN "*.pyd" ) - set( - OPENMP_KMP_DUPLICATE_LIB_OK_SCRIPT - "import os\n" - "os.environ[\"KMP_DUPLICATE_LIB_OK\"] = \"1\"\n\n" - ) - - if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode") - set(PYTHON_MODULE_DIR "${CMAKE_CURRENT_BINARY_DIR}/proxsuite/$") - else() - set(PYTHON_MODULE_DIR "${CMAKE_CURRENT_BINARY_DIR}/proxsuite") - endif() - - set(original_init_dot_py_file ${CMAKE_CURRENT_LIST_DIR}/proxsuite/__init__.py) - set( - generated_init_dot_py_file - ${CMAKE_CURRENT_BINARY_DIR}/proxsuite/__init__.py - ) - set(generated_init_dot_pyc_file ${PYTHON_MODULE_DIR}/__init__.pyc) - - # Copy content of the __init__.py file - file(READ ${original_init_dot_py_file} INIT_CONTENT) - # Create a new __init__.py file containing both the content of __init__.py - # prepended with the OPENMP_KMP_DUPLICATE_LIB_OK_SCRIPT content - file( - WRITE ${generated_init_dot_py_file} - ${OPENMP_KMP_DUPLICATE_LIB_OK_SCRIPT} - ) - file(APPEND ${generated_init_dot_py_file} ${INIT_CONTENT}) - - PYTHON_BUILD_FILE( - ${generated_init_dot_py_file} - ${generated_init_dot_pyc_file} - ) - install( - FILES "${generated_init_dot_py_file}" - DESTINATION ${${PYWRAP}_INSTALL_DIR} - ) -else() - PYTHON_BUILD(${PROJECT_NAME} __init__.py) - install( - FILES "${CMAKE_CURRENT_SOURCE_DIR}/proxsuite/__init__.py" - DESTINATION ${${PYWRAP}_INSTALL_DIR} - ) -endif() - -PYTHON_BUILD_GET_TARGET(compile_pyc) -add_dependencies(${PROJECT_NAME}_python ${compile_pyc}) - -set(PYTHON_FILES torch/__init__.py torch/qplayer.py torch/utils.py) - -file(MAKE_DIRECTORY ${${PYWRAP}_INSTALL_DIR}/torch) - -foreach(python ${PYTHON_FILES}) - PYTHON_BUILD(${PROJECT_NAME} ${python}) - get_filename_component(pysubmodule ${python} PATH) - get_filename_component(pyname ${python} NAME) - set(MODULE_NAME ${PROJECT_NAME}/${pysubmodule}) - PYTHON_INSTALL_ON_SITE(${MODULE_NAME} ${pyname}) -endforeach(python) diff --git a/bindings/python/external/nanobind b/bindings/python/external/nanobind deleted file mode 160000 index 22acf11a2..000000000 --- a/bindings/python/external/nanobind +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 22acf11a2dac212e857f0d06ce80f808cac8fdad diff --git a/bindings/python/proxsuite/__init__.py b/bindings/python/proxsuite/__init__.py index 22e535961..eb79e4acb 100644 --- a/bindings/python/proxsuite/__init__.py +++ b/bindings/python/proxsuite/__init__.py @@ -8,6 +8,12 @@ if TYPE_CHECKING: from .proxsuite_pywrap import * # noqa F403 +import os + +os.environ["KMP_DUPLICATE_LIB_OK"] = ( + "True" # to avoid issues with OpenMP in some environments +) + def _load_main_module(): import platform diff --git a/bindings/python/proxsuite/torch/qplayer.py b/bindings/python/proxsuite/torch/qplayer.py index 4d407de5a..86bf8af06 100644 --- a/bindings/python/proxsuite/torch/qplayer.py +++ b/bindings/python/proxsuite/torch/qplayer.py @@ -18,7 +18,7 @@ def QPFunction( omp_parallel=False, structural_feasibility=True, ): - """! + r"""! Solve a batch of Quadratic Programming (QP) problems. This function solves QP problems of the form: diff --git a/cmake-external/FindMatio.cmake b/cmake-external/FindMatio.cmake deleted file mode 100644 index 935aad504..000000000 --- a/cmake-external/FindMatio.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# ============================================================================= -# SPDX-FileCopyrightText: 2021 Stefan Gerlach -# -# SPDX-License-Identifier: BSD-3-Clause -# ============================================================================= - -find_library(MATIO_LIBRARIES NAMES matio libmatio) - -find_path(MATIO_INCLUDE_DIR matio.h) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - Matio - FOUND_VAR MATIO_FOUND - REQUIRED_VARS MATIO_LIBRARIES MATIO_INCLUDE_DIR -) - -if(MATIO_FOUND) - add_library(matio UNKNOWN IMPORTED) - set_target_properties( - matio - PROPERTIES - IMPORTED_LOCATION "${MATIO_LIBRARIES}" - INTERFACE_INCLUDE_DIRECTORIES "${MATIO_INCLUDE_DIR}" - ) -else() - set(MATIO_LIBRARIES "") -endif() - -mark_as_advanced(MATIO_LIBRARIES MATIO_INCLUDE_DIR) - -include(FeatureSummary) -set_package_properties( - Matio - PROPERTIES - DESCRIPTION "Reading and writing binary MATLAB MAT files" - URL "https://github.com/tbeu/matio" -) diff --git a/cmake-external/FindSphinx.cmake b/cmake-external/FindSphinx.cmake deleted file mode 100644 index c00f3720d..000000000 --- a/cmake-external/FindSphinx.cmake +++ /dev/null @@ -1,14 +0,0 @@ -# Look for an executable called sphinx-build -find_program( - SPHINX_EXECUTABLE - NAMES sphinx-build - DOC "Path to sphinx-build executable" -) - -include(FindPackageHandleStandardArgs) -# Handle standard arguments to find_package like REQUIRED and QUIET -find_package_handle_standard_args( - Sphinx - "Failed to find sphinx-build executable" - SPHINX_EXECUTABLE -) diff --git a/cmake-external/compiler_warnings.cmake b/cmake-external/compiler_warnings.cmake deleted file mode 100644 index da63eaf57..000000000 --- a/cmake-external/compiler_warnings.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# from here: -# -# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Avai -# lable.md - -function(set_project_warnings project_name) - option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF) - - set( - MSVC_WARNINGS - /W4 # Baseline reasonable warnings - /w14242 # 'identfier': conversion from 'type1' to 'type1', possible loss - # of data - /w14254 # 'operator': conversion from 'type1:field_bits' to - # 'type2:field_bits', possible loss of data - /w14263 # 'function': member function does not override any base class - # virtual member function - /w14265 # 'classname': class has virtual functions, but destructor is not - # virtual instances of this class may not be destructed correctly - /w14287 # 'operator': unsigned/negative constant mismatch - /we4289 # nonstandard extension used: 'variable': loop control variable - # declared in the for-loop is used outside the for-loop scope - /w14296 # 'operator': expression is always 'boolean_value' - /w14311 # 'variable': pointer truncation from 'type1' to 'type2' - /w14545 # expression before comma evaluates to a function which is missing - # an argument list - /w14546 # function call before comma missing argument list - /w14547 # 'operator': operator before comma has no effect; expected - # operator with side-effect - /w14549 # 'operator': operator before comma has no effect; did you intend - # 'operator'? - /w14555 # expression has no effect; expected expression with side- effect - /w14619 # pragma warning: there is no warning number 'number' - /w14640 # Enable warning on thread un-safe static member initialization - /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may - # cause unexpected runtime behavior. - /w14905 # wide string literal cast to 'LPSTR' - /w14906 # string literal cast to 'LPWSTR' - /w14928 # illegal copy-initialization; more than one user-defined - # conversion has been implicitly applied - ) - - set( - CLANG_WARNINGS - -Wall - -Wextra # reasonable and standard - -Wshadow # warn the user if a variable declaration shadows one from a - # parent context - -Wnon-virtual-dtor # warn the user if a class with virtual functions has a - # non-virtual destructor. This helps catch hard to - # track down memory errors - -Wold-style-cast # warn for c-style casts - -Wcast-align # warn for potential performance problem casts - -Wunused # warn on anything being unused - -Woverloaded-virtual # warn if you overload (not override) a virtual - # function - -Wpedantic # warn if non-standard C++ is used - -Wconversion # warn on type conversions that may lose data - -Wsign-conversion # warn on sign conversions - -Wnull-dereference # warn if a null dereference is detected - -Wdouble-promotion # warn if float is implicit promoted to double - -Wformat=2 # warn on security issues around functions that format output - # (ie printf) - ) - - if(WARNINGS_AS_ERRORS) - set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror) - set(MSVC_WARNINGS ${MSVC_WARNINGS} /WX) - endif() - - set( - GCC_WARNINGS - ${CLANG_WARNINGS} - -Wmisleading-indentation # warn if identation implies blocks where blocks - # do not exist - -Wduplicated-cond # warn if if / else chain has duplicated conditions - -Wduplicated-branches # warn if if / else branches have duplicated code - -Wlogical-op # warn about logical operations being used where bitwise were - # probably wanted - ) - - if(MSVC) - set(PROJECT_WARNINGS ${MSVC_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set(PROJECT_WARNINGS ${CLANG_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(PROJECT_WARNINGS ${GCC_WARNINGS}) - endif() - - target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) -endfunction() diff --git a/cmake-external/doctest.cmake b/cmake-external/doctest.cmake deleted file mode 100644 index 6e10cd31a..000000000 --- a/cmake-external/doctest.cmake +++ /dev/null @@ -1,178 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -#[=======================================================================[.rst: -doctest ------ - -This module defines a function to help use the doctest test framework. - -The :command:`doctest_discover_tests` discovers tests by asking the compiled test -executable to enumerate its tests. This does not require CMake to be re-run -when tests change. However, it may not work in a cross-compiling environment, -and setting test properties is less convenient. - -This command is intended to replace use of :command:`add_test` to register -tests, and will create a separate CTest test for each doctest test case. Note -that this is in some cases less efficient, as common set-up and tear-down logic -cannot be shared by multiple test cases executing in the same instance. -However, it provides more fine-grained pass/fail information to CTest, which is -usually considered as more beneficial. By default, the CTest test name is the -same as the doctest name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``. - -.. command:: doctest_discover_tests - - Automatically add tests with CTest by querying the compiled test executable - for available tests:: - - doctest_discover_tests(target - [TEST_SPEC arg1...] - [EXTRA_ARGS arg1...] - [WORKING_DIRECTORY dir] - [TEST_PREFIX prefix] - [TEST_SUFFIX suffix] - [PROPERTIES name1 value1...] - [TEST_LIST var] - ) - - ``doctest_discover_tests`` sets up a post-build command on the test executable - that generates the list of tests by parsing the output from running the test - with the ``--list-test-cases`` argument. This ensures that the full - list of tests is obtained. Since test discovery occurs at build time, it is - not necessary to re-run CMake when the list of tests changes. - However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set - in order to function in a cross-compiling environment. - - Additionally, setting properties on tests is somewhat less convenient, since - the tests are not available at CMake time. Additional test properties may be - assigned to the set of tests as a whole using the ``PROPERTIES`` option. If - more fine-grained test control is needed, custom content may be provided - through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES` - directory property. The set of discovered tests is made accessible to such a - script via the ``_TESTS`` variable. - - The options are: - - ``target`` - Specifies the doctest executable, which must be a known CMake executable - target. CMake will substitute the location of the built executable when - running the test. - - ``TEST_SPEC arg1...`` - Specifies test cases, wildcarded test cases, tags and tag expressions to - pass to the doctest executable with the ``--list-test-cases`` argument. - - ``EXTRA_ARGS arg1...`` - Any extra arguments to pass on the command line to each test case. - - ``WORKING_DIRECTORY dir`` - Specifies the directory in which to run the discovered test cases. If this - option is not provided, the current binary directory is used. - - ``TEST_PREFIX prefix`` - Specifies a ``prefix`` to be prepended to the name of each discovered test - case. This can be useful when the same test executable is being used in - multiple calls to ``doctest_discover_tests()`` but with different - ``TEST_SPEC`` or ``EXTRA_ARGS``. - - ``TEST_SUFFIX suffix`` - Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of - every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may - be specified. - - ``PROPERTIES name1 value1...`` - Specifies additional properties to be set on all tests discovered by this - invocation of ``doctest_discover_tests``. - - ``TEST_LIST var`` - Make the list of tests available in the variable ``var``, rather than the - default ``_TESTS``. This can be useful when the same test - executable is being used in multiple calls to ``doctest_discover_tests()``. - Note that this variable is only available in CTest. - -#]=======================================================================] - -# ------------------------------------------------------------------------------ -function(doctest_discover_tests TARGET) - cmake_parse_arguments( - "" - "" - "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" - "TEST_SPEC;EXTRA_ARGS;PROPERTIES" - ${ARGN} - ) - - if(NOT _WORKING_DIRECTORY) - set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - endif() - if(NOT _TEST_LIST) - set(_TEST_LIST ${TARGET}_TESTS) - endif() - - # Generate a unique name based on the extra arguments - string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}") - string(SUBSTRING ${args_hash} 0 7 args_hash) - - # Define rule to generate test list for aforementioned test executable - set( - ctest_include_file - "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake" - ) - set( - ctest_tests_file - "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake" - ) - get_property( - crosscompiling_emulator - TARGET ${TARGET} - PROPERTY CROSSCOMPILING_EMULATOR - ) - add_custom_command( - TARGET ${TARGET} - POST_BUILD - BYPRODUCTS "${ctest_tests_file}" - COMMAND - "${CMAKE_COMMAND}" -D "TEST_TARGET=${TARGET}" -D - "TEST_EXECUTABLE=$" -D - "TEST_EXECUTOR=${crosscompiling_emulator}" -D - "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" -D "TEST_SPEC=${_TEST_SPEC}" -D - "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" -D "TEST_PROPERTIES=${_PROPERTIES}" -D - "TEST_PREFIX=${_TEST_PREFIX}" -D "TEST_SUFFIX=${_TEST_SUFFIX}" -D - "TEST_LIST=${_TEST_LIST}" -D "CTEST_FILE=${ctest_tests_file}" -P - "${_DOCTEST_DISCOVER_TESTS_SCRIPT}" - VERBATIM - ) - - file( - WRITE "${ctest_include_file}" - "if(EXISTS \"${ctest_tests_file}\")\n" - " include(\"${ctest_tests_file}\")\n" - "else()\n" - " add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" - "endif()\n" - ) - - if(NOT CMAKE_VERSION VERSION_LESS 3.10) - # Add discovered tests to directory TEST_INCLUDE_FILES - set_property( - DIRECTORY - APPEND - PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}" - ) - else() - # Add discovered tests as directory TEST_INCLUDE_FILE if possible - get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET) - if(NOT ${test_include_file_set}) - set_property(DIRECTORY PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}") - else() - message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE") - endif() - endif() -endfunction() - -# ############################################################################## - -set( - _DOCTEST_DISCOVER_TESTS_SCRIPT - ${CMAKE_CURRENT_LIST_DIR}/doctestAddTests.cmake -) diff --git a/cmake-external/doctestAddTests.cmake b/cmake-external/doctestAddTests.cmake deleted file mode 100644 index 689ec75de..000000000 --- a/cmake-external/doctestAddTests.cmake +++ /dev/null @@ -1,91 +0,0 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. - -set(prefix "${TEST_PREFIX}") -set(suffix "${TEST_SUFFIX}") -set(spec ${TEST_SPEC}) -set(extra_args ${TEST_EXTRA_ARGS}) -set(properties ${TEST_PROPERTIES}) -set(script) -set(suite) -set(tests) - -function(add_command NAME) - set(_args "") - foreach(_arg ${ARGN}) - if(_arg MATCHES "[^-./:a-zA-Z0-9_]") - set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument - else() - set(_args "${_args} ${_arg}") - endif() - endforeach() - set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE) -endfunction() - -# Run test executable to get list of available tests -if(NOT EXISTS "${TEST_EXECUTABLE}") - message( - FATAL_ERROR - "Specified test executable '${TEST_EXECUTABLE}' does not exist" - ) -endif() - -if("${spec}" MATCHES .) - set(spec "--test-case=${spec}") -endif() - -execute_process( - COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-cases - OUTPUT_VARIABLE output - RESULT_VARIABLE result -) -if(NOT ${result} EQUAL 0) - message( - FATAL_ERROR - "Error running test executable '${TEST_EXECUTABLE}':\n" - " Result: ${result}\n" - " Output: ${output}\n" - ) -endif() - -string(REPLACE "\n" ";" output "${output}") - -# Parse output -foreach(line ${output}) - if( - "${line}" - STREQUAL - "===============================================================================" - OR "${line}" MATCHES [==[^\[doctest\] ]==] - ) - continue() - endif() - set(test ${line}) - # use escape commas to handle properly test cases with commas inside the name - string(REPLACE "," "\\," test_name ${test}) - # ...and add to script - add_command( - add_test - "${prefix}${test}${suffix}" - ${TEST_EXECUTOR} - "${TEST_EXECUTABLE}" - "--test-case=${test_name}" - ${extra_args} - ) - add_command( - set_tests_properties - "${prefix}${test}${suffix}" - PROPERTIES - WORKING_DIRECTORY - "${TEST_WORKING_DIR}" - ${properties} - ) - list(APPEND tests "${prefix}${test}${suffix}") -endforeach() - -# Create a list of all discovered tests, which users may use to e.g. set -# properties on the tests -add_command(set ${TEST_LIST} ${tests}) - -# Write CTest script -file(WRITE "${CTEST_FILE}" "${script}") diff --git a/cmake-external/extra_local_settings.cmake b/cmake-external/extra_local_settings.cmake deleted file mode 100644 index 7e1687e4f..000000000 --- a/cmake-external/extra_local_settings.cmake +++ /dev/null @@ -1,58 +0,0 @@ -option( - ENABLE_IPO - "Enable Iterprocedural Optimization, aka Link Time Optimization (LTO)" - OFF -) -option(ARCH_NATIVE "Build with -march=native" OFF) -option(USE_LIBCXX "Use the libc++ STL" OFF) - -option( - ENABLE_BUILD_WITH_TIME_TRACE - "Enable -ftime-trace to generate time tracing .json files on clang" - OFF -) -if(ENABLE_BUILD_WITH_TIME_TRACE AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - add_compile_options("-ftime-trace") -endif() - -if(USE_LLD) - add_link_options("-fuse-ld=lld") -elseif(USE_GOLD) - add_link_options("-fuse-ld=gold") -endif() - -if(USE_LIBCXX) - if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - add_compile_options("-stdlib=libc++") - add_link_options("-stdlib=libc++ -lc++abi") - else() - message(SEND_ERROR "libc++ only available with clang") - endif() -endif() - -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - message(STATUS "Setting build type to 'Debug' as none was specified.") - set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) - set_property( - CACHE CMAKE_BUILD_TYPE - PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" - ) -endif() - -if(ENABLE_IPO) - include(CheckIPOSupported) - check_ipo_supported(RESULT result OUTPUT output) - if(result) - set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) - else() - message(SEND_ERROR "IPO is not supported: ${output}") - endif() -endif() - -include(CheckCXXCompilerFlag) -if(ARCH_NATIVE) - check_cxx_compiler_flag("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE) - if(COMPILER_SUPPORTS_MARCH_NATIVE) - add_compile_options("-march=native") - endif() -endif() diff --git a/cmake-external/sanitizers.cmake b/cmake-external/sanitizers.cmake deleted file mode 100644 index 7c54c8eb4..000000000 --- a/cmake-external/sanitizers.cmake +++ /dev/null @@ -1,76 +0,0 @@ -function(enable_sanitizers project_name) - if( - CMAKE_CXX_COMPILER_ID STREQUAL "GNU" - OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" - ) - option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) - - if(ENABLE_COVERAGE) - target_compile_options(${project_name} INTERFACE --coverage -O0 -g) - target_link_libraries(${project_name} INTERFACE --coverage) - endif() - - set(SANITIZERS "") - - option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF) - if(ENABLE_SANITIZER_ADDRESS) - list(APPEND SANITIZERS "address") - target_compile_options( - ${project_name} - INTERFACE -fsanitize-address-use-after-scope - ) - target_link_libraries( - ${project_name} - INTERFACE -fsanitize-address-use-after-scope - ) - endif() - - option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF) - if(ENABLE_SANITIZER_MEMORY) - list(APPEND SANITIZERS "memory") - target_compile_options( - ${project_name} - INTERFACE -fsanitize-memory-track-origins=2 - ) - target_link_libraries( - ${project_name} - INTERFACE -fsanitize-memory-track-origins=2 - ) - endif() - - option( - ENABLE_SANITIZER_UNDEFINED_BEHAVIOR - "Enable undefined behavior sanitizer" - OFF - ) - if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) - list(APPEND SANITIZERS "undefined") - endif() - - option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF) - if(ENABLE_SANITIZER_THREAD) - list(APPEND SANITIZERS "thread") - endif() - - list(JOIN SANITIZERS "," LIST_OF_SANITIZERS) - endif() - - if(LIST_OF_SANITIZERS) - if(NOT "${LIST_OF_SANITIZERS}" STREQUAL "") - target_compile_options( - ${project_name} - INTERFACE - -fsanitize=${LIST_OF_SANITIZERS} - -fno-omit-frame-pointer - -fno-optimize-sibling-calls - ) - target_link_libraries( - ${project_name} - INTERFACE - -fsanitize=${LIST_OF_SANITIZERS} - -fno-omit-frame-pointer - -fno-optimize-sibling-calls - ) - endif() - endif() -endfunction() diff --git a/cmake-external/static_analyzers.cmake b/cmake-external/static_analyzers.cmake deleted file mode 100644 index 255478f11..000000000 --- a/cmake-external/static_analyzers.cmake +++ /dev/null @@ -1,33 +0,0 @@ -option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) -option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) -if(ENABLE_CPPCHECK) - find_program(CPPCHECK cppcheck) - if(CPPCHECK) - set( - CMAKE_CXX_CPPCHECK - ${CPPCHECK} - --suppress=missingInclude - --enable=all - --inconclusive - -i - ${CMAKE_SOURCE_DIR}/imgui/lib - ) - else() - message(SEND_ERROR "cppcheck requested but executable not found") - endif() -endif() - -if(ENABLE_CLANG_TIDY AND (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")) - find_program(CLANGTIDY clang-tidy) - find_program(UNBUFFER unbuffer) - if(CLANGTIDY) - if(UNBUFFER) - set(CMAKE_CXX_CLANG_TIDY unbuffer ${CLANGTIDY}) - else() - message(WARNING "unbuffer not found") - set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY}) - endif() - else() - message(SEND_ERROR "clang-tidy requested but executable not found") - endif() -endif() diff --git a/cmake-module b/cmake-module deleted file mode 160000 index 307951909..000000000 --- a/cmake-module +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 30795190916d0297092e37bc1f7b50f5d76fc09c diff --git a/cmake/get-jrl-cmakemodules.cmake b/cmake/get-jrl-cmakemodules.cmake new file mode 100644 index 000000000..c23f6b728 --- /dev/null +++ b/cmake/get-jrl-cmakemodules.cmake @@ -0,0 +1,49 @@ +# Get jrl-cmakemodules package + +# Option 1: pass -DJRL_CMAKEMODULES_SOURCE_DIR=... to cmake command line +if(JRL_CMAKEMODULES_SOURCE_DIR) + message( + DEBUG + "JRL_CMAKEMODULES_SOURCE_DIR variable set, adding jrl-cmakemodules from source directory: ${JRL_CMAKEMODULES_SOURCE_DIR}" + ) + add_subdirectory(${JRL_CMAKEMODULES_SOURCE_DIR} jrl-cmakemodules) + return() +endif() + +# Option 2: use JRL_CMAKEMODULES_SOURCE_DIR environment variable (pixi might unset it, prefer option 1) +if(ENV{JRL_CMAKEMODULES_SOURCE_DIR}) + message( + DEBUG + "JRL_CMAKEMODULES_SOURCE_DIR environement variable set, adding jrl-cmakemodules from source directory: ${JRL_CMAKEMODULES_SOURCE_DIR}" + ) + add_subdirectory(${JRL_CMAKEMODULES_SOURCE_DIR} jrl-cmakemodules) + return() +endif() + +# Try to look for the installed package +message(DEBUG "Looking for jrl-cmakemodules using find_package().") +find_package(jrl-cmakemodules 1.2.0 CONFIG QUIET) + +# If we have the package, we are done. +if(jrl-cmakemodules_FOUND) + message(DEBUG "Found jrl-cmakemodules package via find_package().") + return() +else() + message(DEBUG "jrl-cmakemodules package not found using find_package().") +endif() + +# Fallback to FetchContent if not found +set(JRL_GIT_REPOSITORY "https://github.com/ahoarau/jrl-cmakemodules.git") +set(JRL_GIT_TAG "jrl-next") + +message( + DEBUG + "Fetching jrl-cmakemodules using FetchContent: + GIT_REPOSITORY: ${JRL_GIT_REPOSITORY} + GIT_TAG : ${JRL_GIT_TAG} +" +) + +include(FetchContent) +FetchContent_Declare(jrl-cmakemodules GIT_REPOSITORY ${JRL_GIT_REPOSITORY} GIT_TAG ${JRL_GIT_TAG}) +FetchContent_MakeAvailable(jrl-cmakemodules) diff --git a/doc/2-ProxQP_api.md b/doc/2-ProxQP_api.md index c909ba29b..599c893b7 100644 --- a/doc/2-ProxQP_api.md +++ b/doc/2-ProxQP_api.md @@ -698,11 +698,11 @@ It is important to notice that some other solvers API have made different choice \subsection OverviewArchitectureOptions Architecture options when compiling ProxSuite -We highly encourage you to enable the vectorization of the underlying linear algebra for the best performance. You just need to activate the cmake option `BUILD_WITH_SIMD_SUPPORT=ON`, like: +We highly encourage you to enable the vectorization of the underlying linear algebra for the best performance. You just need to activate the cmake option `BUILD_WITH_VECTORIZATION_SUPPORT=ON`, like: \code mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_WITH_SIMD_SUPPORT=ON +cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_WITH_VECTORIZATION_SUPPORT=ON make make install \endcode diff --git a/doc/5-installation.md b/doc/5-installation.md index 67dc810af..48b22067c 100644 --- a/doc/5-installation.md +++ b/doc/5-installation.md @@ -15,16 +15,15 @@ The following dependencies are required at compile time: 1. Clone this repository with: ```bash -git clone https://github.com/Simple-Robotics/proxsuite.git --recursive +git clone https://github.com/Simple-Robotics/proxsuite.git ``` 2. Create a build tree using CMake, build and install: ```bash -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -make -make install +cmake -S proxsuite -B proxsuite-build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF +cmake --build proxsuite-build +cmake --install proxsuite-build --prefix proxsuite-install ``` Note: if you are building Proxsuite within a conda environment, consider passing `-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX`. @@ -34,10 +33,9 @@ Note: if you are building Proxsuite within a conda environment, consider passing You just need to ensure that Python3 is indeed present on your system and activate the cmake option `BUILD_PYTHON_INTERFACE=ON` by replacing: ```bash -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_PYTHON_INTERFACE=ON -make -make install +cmake -S proxsuite -B proxsuite-build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_PYTHON_INTERFACE=ON +cmake --build proxsuite-build +cmake --install proxsuite-build --prefix proxsuite-install ``` 4. Generate the doc @@ -57,10 +55,9 @@ Yet, some CPU architectures may not support such operations. You just need to deactivate the cmake option `BUILD_WITH_VECTORIZATION_SUPPORT=OFF`, like: ```bash -mkdir build && cd build -cmake .. -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_WITH_VECTORIZATION_SUPPORT=OFF -make -make install +cmake -S proxsuite -B proxsuite-build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DBUILD_WITH_VECTORIZATION_SUPPORT=OFF +cmake --build proxsuite-build +cmake --install proxsuite-build --prefix proxsuite-install ``` #### Testing diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 000000000..0518e8c81 --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,68 @@ +# Set Doxygen module options +set(DOXYGEN_GENERATE_HTML YES) +set(DOXYGEN_GENERATE_LATEX NO) +set(DOXYGEN_QUIET YES) +set(DOXYGEN_WARN_IF_UNDOCUMENTED NO) +set(DOXYGEN_WARN_NO_PARAMDOC NO) +set(DOXYGEN_USE_MATHJAX YES) + +# Set Doxygen options +set( + DOXYGEN_FILE_PATTERNS + *.cc + *.cpp + *.h + *.hpp + *.dox + *.md + *.py +) +set(DOXYGEN_RECURSIVE YES) +set(DOXYGEN_SORT_MEMBER_DOCS NO) +set(DOXYGEN_SORT_BRIEF_DOCS NO) +set(DOXYGEN_SORT_MEMBERS_CTORS_1ST YES) +set(DOXYGEN_GENERATE_TESTLIST YES) +set(DOXYGEN_EXTRACT_STATIC YES) +set(DOXYGEN_EXTRACT_PRIV_VIRTUAL YES) +set(DOXYGEN_ENABLE_PREPROCESSING YES) +set(DOXYGEN_MACRO_EXPANSION YES) +set(DOXYGEN_EXPAND_ONLY_PREDEF YES) +set(DOXYGEN_PREDEFINED "EIGEN_MAKE_ALIGNED_OPERATOR_NEW") +set(DOXYGEN_FULL_PATH_NAMES YES) +set(DOXYGEN_EXCLUDE_SYMBOLS "*::internal, internal::*, *::internal::*") +set(DOXYGEN_EXCLUDE_PATTERNS "*.hxx") +set(DOXYGEN_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/include) +set(DOXYGEN_EXCLUDE_SYMLINKS YES) +set(DOXYGEN_EXAMPLE_PATH ${PROJECT_SOURCE_DIR}/examples) +set(DOXYGEN_EXTRA_PACKAGES "{bm stmaryrd amsmath amssymb}") +set(DOXYGEN_GENERATE_TREEVIEW YES) +set(DOXYGEN_VERBATIM_HEADERS YES) +set(DOXYGEN_HTML_HEADER ${PROJECT_SOURCE_DIR}/doc/header.html) +set(DOXYGEN_TAGFILES "") +set(DOXYGEN_SHOW_FILES YES) +set(DOXYGEN_SHOW_NAMESPACES YES) +set(DOXYGEN_MATHJAX_FORMAT SVG) +set(DOXYGEN_SOURCE_BROWSER YES) +set(DOXYGEN_ALPHABETICAL_INDEX YES) +set(DOXYGEN_USE_MDFILE_AS_MAINPAGE ${PROJECT_SOURCE_DIR}/doc/1-Overview.md) +set(DOXYGEN_BUILTIN_STL_SUPPORT YES) +set(DOXYGEN_HAVE_DOT YES) +set(DOXYGEN_DOT_IMAGE_FORMAT SVG) +set(DOXYGEN_DOT_TRANSPARENT YES) + +# Configure Doxygen +doxygen_add_docs( + doc + ${PROJECT_SOURCE_DIR}/doc + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/bindings/python/proxsuite + COMMENT "Generating API documentation with Doxygen" +) + +if(INSTALL_DOCUMENTATION) + install( + DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/doc/proxsuite + COMPONENT doc + ) +endif() diff --git a/doc/Doxyfile.extra.in b/doc/Doxyfile.extra.in deleted file mode 100644 index 7e8e5f303..000000000 --- a/doc/Doxyfile.extra.in +++ /dev/null @@ -1,59 +0,0 @@ -INPUT = @PROJECT_SOURCE_DIR@/doc \ - @PROJECT_SOURCE_DIR@/include \ - @PROJECT_SOURCE_DIR@/bindings/python/proxsuite \ - -RECURSIVE = YES - -FILE_PATTERNS = *.cc *.cpp *.h *.hpp *.dox *.md *.py - -# Document members in declaration order -SORT_MEMBER_DOCS = NO -SORT_BRIEF_DOCS = NO -SORT_MEMBERS_CTORS_1ST = YES - -GENERATE_TESTLIST = YES -EXTRACT_STATIC = YES - -EXTRACT_PRIV_VIRTUAL = YES -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = YES -EXPAND_ONLY_PREDEF = YES -PREDEFINED += EIGEN_MAKE_ALIGNED_OPERATOR_NEW \ - -FULL_PATH_NAMES = YES -EXCLUDE_SYMBOLS = *::internal, internal::*, *::internal::* -# Do not show source files -EXCLUDE_PATTERNS = *.hxx - -INCLUDE_PATH = @PROJECT_SOURCE_DIR@/include - -EXCLUDE_SYMLINKS = YES - -EXAMPLE_PATH = @PROJECT_SOURCE_DIR@/examples - -EXTRA_PACKAGES = bm stmaryrd amsmath amssymb - -GENERATE_TREEVIEW = YES - -VERBATIM_HEADERS = YES - - -HTML_HEADER = @PROJECT_SOURCE_DIR@/doc/header.html - - -TAGFILES = - -SHOW_FILES = YES -SHOW_NAMESPACES = YES - -MATHJAX_FORMAT = SVG - -SOURCE_BROWSER = YES - -ALPHABETICAL_INDEX = YES - -USE_MDFILE_AS_MAINPAGE = @PROJECT_SOURCE_DIR@/doc/1-Overview.md - -BUILTIN_STL_SUPPORT = YES -HAVE_DOT = YES -DOT_IMAGE_FORMAT = SVG diff --git a/doc/images/proxsuite-logo-transparent.png b/doc/images/proxsuite-logo-transparent.png new file mode 100644 index 000000000..51835c07a Binary files /dev/null and b/doc/images/proxsuite-logo-transparent.png differ diff --git a/doc/images/proxsuite-logo.png b/doc/images/proxsuite-logo.png index 51835c07a..ed1b44988 100644 Binary files a/doc/images/proxsuite-logo.png and b/doc/images/proxsuite-logo.png differ diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 6208b183a..bc2b1fb2a 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -2,17 +2,8 @@ add_subdirectory(cpp) if(BUILD_PYTHON_INTERFACE) add_subdirectory(python) -endif(BUILD_PYTHON_INTERFACE) +endif() if(TEST_JULIA_INTERFACE) - find_package(Julia REQUIRED) - - JULIA_CHECK_PACKAGE(PyCall) - if(NOT Julia_PyCall_found) - message( - FATAL_ERROR - "PyCall not installed. Please use import Pkg; Pkg.add(\"PyCall\")" - ) - endif() add_subdirectory(julia) endif() diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index 6ae1bd686..17d24fc5b 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -1,20 +1,38 @@ -# -# Copyright (c) 2022 INRIA -# +add_custom_target(proxsuite-examples-cpp) -add_custom_target(${PROJECT_NAME}-example-cpp) +function(proxsuite_add_example name) + add_executable(proxsuite-example-cpp.${name} ${name}.cpp) + target_link_libraries(proxsuite-example-cpp.${name} PRIVATE proxsuite) + if(BUILD_TESTING) + add_test(NAME proxsuite-example-cpp.${name} COMMAND proxsuite-example-cpp.${name}) + endif() + add_dependencies(proxsuite-examples-cpp proxsuite-example-cpp.${name}) +endfunction() -function(ADD_PROXSUITE_CPP_EXAMPLE EXAMPLE) - get_filename_component(EXAMPLE_NAME ${EXAMPLE} NAME_WE) - set(EXAMPLE_TARGET "${PROJECT_NAME}-example-cpp-${EXAMPLE_NAME}") - ADD_UNIT_TEST(${EXAMPLE_TARGET} "${EXAMPLE}") - target_link_libraries(${EXAMPLE_TARGET} PRIVATE proxsuite-test-util) +proxsuite_add_example(estimate_nonconvex_eigenvalue) +proxsuite_add_example(first_example_dense) +proxsuite_add_example(first_example_sparse) +proxsuite_add_example(init_dense_qp_with_box) - add_dependencies(${PROJECT_NAME}-example-cpp ${EXAMPLE_TARGET}) -endfunction() +proxsuite_add_example(init_dense_qp_with_other_options) +proxsuite_add_example(init_dense_qp_with_timings) +proxsuite_add_example(init_dense_qp) +proxsuite_add_example(init_with_default_options) + +proxsuite_add_example(initializing_with_none_without_api) +proxsuite_add_example(initializing_with_none) + +proxsuite_add_example(loading_dense_qp_with_box_ineq) +proxsuite_add_example(loading_dense_qp_with_different_backend_choice) +proxsuite_add_example(loading_dense_qp) +proxsuite_add_example(loading_sparse_qp) -file(GLOB_RECURSE ${PROJECT_NAME}_CPP_EXAMPLES *.cpp) +proxsuite_add_example(overview-simple) +proxsuite_add_example(solve_dense_qp_with_setting) +proxsuite_add_example(solve_dense_qp) +proxsuite_add_example(solve_without_api_and_option) +proxsuite_add_example(solve_without_api) -foreach(EXAMPLE ${${PROJECT_NAME}_CPP_EXAMPLES}) - add_proxsuite_cpp_example(${EXAMPLE}) -endforeach() +proxsuite_add_example(update_dense_qp_ws_previous_result) +proxsuite_add_example(update_dense_qp) +proxsuite_add_example(update_sparse_qp) diff --git a/examples/julia/CMakeLists.txt b/examples/julia/CMakeLists.txt index 051eb61a4..a2d9423d2 100644 --- a/examples/julia/CMakeLists.txt +++ b/examples/julia/CMakeLists.txt @@ -1,15 +1,14 @@ -file(GLOB_RECURSE ${PROJECT_NAME}_JULIA_EXAMPLES *.jl) +find_program(Julia_EXECUTABLE julia REQUIRED) +message(STATUS "Found Julia executable: ${Julia_EXECUTABLE}") -foreach(EXAMPLE ${${PROJECT_NAME}_JULIA_EXAMPLES}) - string( - REGEX REPLACE - "${PROJECT_SOURCE_DIR}/examples/julia/" - "" - EXAMPLE - ${EXAMPLE} - ) - ADD_JULIA_UNIT_TEST( - "${PROJECT_NAME}-example-jl-${EXAMPLE}" - "examples/julia/${EXAMPLE}" - ) -endforeach() +add_test( + NAME proxsuite-example-jl-overview-simple + COMMAND ${Julia_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/overview-simple.jl +) +set_property( + TEST proxsuite-example-jl-overview-simple + PROPERTY + ENVIRONMENT + "PYTHON=$" + "PYTHONPATH=$/.." +) diff --git a/examples/julia/overview-simple.jl b/examples/julia/overview-simple.jl index 163eaa445..aada706d0 100644 --- a/examples/julia/overview-simple.jl +++ b/examples/julia/overview-simple.jl @@ -1,5 +1,8 @@ import Pkg Pkg.add("PyCall") +if haskey(ENV, "PYTHON") + Pkg.build("PyCall") +end using PyCall using Printf diff --git a/examples/python/CMakeLists.txt b/examples/python/CMakeLists.txt index 31f46b63d..abab9717e 100644 --- a/examples/python/CMakeLists.txt +++ b/examples/python/CMakeLists.txt @@ -1,11 +1,43 @@ -file(GLOB_RECURSE ${PROJECT_NAME}_PYTHON_EXAMPLES *.py) +add_custom_target(proxsuite-examples-python) -foreach(EXAMPLE_FILE ${${PROJECT_NAME}_PYTHON_EXAMPLES}) - get_filename_component(EXAMPLE_NAME ${EXAMPLE_FILE} NAME_WE) - string(REGEX REPLACE "${PROJECT_SOURCE_DIR}" "" EXAMPLE_FILE ${EXAMPLE_FILE}) - ADD_PYTHON_UNIT_TEST( - "${PROJECT_NAME}-example-py-${EXAMPLE_NAME}" - "${EXAMPLE_FILE}" - "bindings/python" +function(proxsuite_add_python_example name) + add_custom_target( + proxsuite-example-py-${name} + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + DEPENDS proxsuite_pywrap ) -endforeach() + if(BUILD_TESTING) + add_test( + NAME proxsuite-example-python.${name} + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + ) + set_tests_properties( + proxsuite-example-python.${name} + PROPERTIES ENVIRONMENT "PYTHONPATH=$/.." LABELS python + ) + endif() + add_dependencies(proxsuite-examples-python proxsuite-example-py-${name}) +endfunction() + +proxsuite_add_python_example(estimate_nonconvex_eigenvalue) +proxsuite_add_python_example(init_dense_qp_with_box) +proxsuite_add_python_example(init_dense_qp_with_other_options) +proxsuite_add_python_example(init_dense_qp_with_timings) +proxsuite_add_python_example(init_dense_qp) +proxsuite_add_python_example(init_with_default_options) +proxsuite_add_python_example(initializing_with_none_without_api) +proxsuite_add_python_example(initializing_with_none) +proxsuite_add_python_example(loading_dense_qp_with_box_ineq) +proxsuite_add_python_example(loading_dense_qp_with_different_backend_choice) +proxsuite_add_python_example(loading_dense_qp) +proxsuite_add_python_example(loading_sparse_qp) +proxsuite_add_python_example(overview-simple) +proxsuite_add_python_example(qplayer_sudoku) +proxsuite_add_python_example(solve_dense_lp) +proxsuite_add_python_example(solve_dense_qp_with_setting) +proxsuite_add_python_example(solve_dense_qp) +proxsuite_add_python_example(solve_without_api_and_option) +proxsuite_add_python_example(solve_without_api) +proxsuite_add_python_example(update_dense_qp_ws_previous_result) +proxsuite_add_python_example(update_dense_qp) +proxsuite_add_python_example(update_sparse_qp) diff --git a/examples/python/estimate_nonconvex_eigenvalue.py b/examples/python/estimate_nonconvex_eigenvalue.py index 7b6ecac59..d023f845c 100644 --- a/examples/python/estimate_nonconvex_eigenvalue.py +++ b/examples/python/estimate_nonconvex_eigenvalue.py @@ -1,6 +1,6 @@ import proxsuite import numpy as np -import scipy.sparse as spa +import scipy.sparse.linalg as spla from util import generate_mixed_qp @@ -18,7 +18,7 @@ ) ) qp.init(H, g, A, b, C, l, u, manual_minimal_H_eigenvalue=estimate_minimal_eigen_value) -vals, _ = spa.linalg.eigs(H, which="SR") +vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) # print the estimates print(f"{min_eigenvalue=}") diff --git a/external/cereal b/external/cereal deleted file mode 160000 index ddd467244..000000000 --- a/external/cereal +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ddd467244713ea4fe63733628992efcdd6a9187d diff --git a/include/proxsuite/helpers/tl-optional.hpp b/include/proxsuite/helpers/tl-optional.hpp deleted file mode 100644 index 65859cbb7..000000000 --- a/include/proxsuite/helpers/tl-optional.hpp +++ /dev/null @@ -1,2471 +0,0 @@ - -/// -// optional - An implementation of std::optional with extensions -// Written in 2017 by Sy Brand (tartanllama@gmail.com, @TartanLlama) -// -// Documentation available at https://tl.tartanllama.xyz/ -// -// To the extent possible under law, the author(s) have dedicated all -// copyright and related and neighboring rights to this software to the -// public domain worldwide. This software is distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication -// along with this software. If not, see -// . -/// - -#ifndef TL_OPTIONAL_HPP -#define TL_OPTIONAL_HPP - -#define TL_OPTIONAL_VERSION_MAJOR 1 -#define TL_OPTIONAL_VERSION_MINOR 1 -#define TL_OPTIONAL_VERSION_PATCH 0 - -#include -#include -#include -#include -#include - -#if (defined(_MSC_VER) && _MSC_VER == 1900) -#define TL_OPTIONAL_MSVC2015 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ - !defined(__clang__)) -#define TL_OPTIONAL_GCC49 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4 && \ - !defined(__clang__)) -#define TL_OPTIONAL_GCC54 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 5 && \ - !defined(__clang__)) -#define TL_OPTIONAL_GCC55 -#endif - -#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \ - !defined(__clang__)) -// GCC < 5 doesn't support overloading on const&& for member functions -#define TL_OPTIONAL_NO_CONSTRR - -// GCC < 5 doesn't support some standard C++11 type traits -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - std::has_trivial_copy_constructor::value -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::has_trivial_copy_assign::value - -// This one will be different for GCC 5.7 if it's ever supported -#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible::value - -// GCC 5 < v < 8 has a bug in is_trivially_copy_constructible which breaks -// std::vector for non-copyable types -#elif (defined(__GNUC__) && __GNUC__ < 8 && !defined(__clang__)) -#ifndef TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX -#define TL_GCC_LESS_8_TRIVIALLY_COPY_CONSTRUCTIBLE_MUTEX -namespace tl { -namespace detail { -template -struct is_trivially_copy_constructible : std::is_trivially_copy_constructible -{}; -#ifdef _GLIBCXX_VECTOR -template -struct is_trivially_copy_constructible> - : std::is_trivially_copy_constructible -{}; -#endif -} -} -#endif - -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - tl::detail::is_trivially_copy_constructible::value -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::is_trivially_copy_assignable::value -#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible::value -#else -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \ - std::is_trivially_copy_constructible::value -#define TL_OPTIONAL_IS_TRIVIALLY_COPY_ASSIGNABLE(T) \ - std::is_trivially_copy_assignable::value -#define TL_OPTIONAL_IS_TRIVIALLY_DESTRUCTIBLE(T) \ - std::is_trivially_destructible::value -#endif - -#if __cplusplus > 201103L -#define TL_OPTIONAL_CXX14 -#endif - -// constexpr implies const in C++11, not C++14 -#if (__cplusplus == 201103L || defined(TL_OPTIONAL_MSVC2015) || \ - defined(TL_OPTIONAL_GCC49)) -#define TL_OPTIONAL_11_CONSTEXPR -#else -#define TL_OPTIONAL_11_CONSTEXPR constexpr -#endif - -namespace tl { -#ifndef TL_MONOSTATE_INPLACE_MUTEX -#define TL_MONOSTATE_INPLACE_MUTEX -/// Used to represent an optional with no data; essentially a bool -class monostate -{}; - -/// A tag type to tell optional to construct its value in-place -struct in_place_t -{ - explicit in_place_t() = default; -}; -/// A tag to tell optional to construct its value in-place -static constexpr in_place_t in_place{}; -#endif - -template -class optional; - -namespace detail { -#ifndef TL_TRAITS_MUTEX -#define TL_TRAITS_MUTEX -// C++14-style aliases for brevity -template -using remove_const_t = typename std::remove_const::type; -template -using remove_reference_t = typename std::remove_reference::type; -template -using decay_t = typename std::decay::type; -template -using enable_if_t = typename std::enable_if::type; -template -using conditional_t = typename std::conditional::type; - -// std::conjunction from C++17 -template -struct conjunction : std::true_type -{}; -template -struct conjunction : B -{}; -template -struct conjunction - : std::conditional, B>::type -{}; - -#if defined(_LIBCPP_VERSION) && __cplusplus == 201103L -#define TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND -#endif - -// In C++11 mode, there's an issue in libc++'s std::mem_fn -// which results in a hard-error when using it in a noexcept expression -// in some cases. This is a check to workaround the common failing case. -#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND -template -struct is_pointer_to_non_const_member_func : std::false_type -{}; -template -struct is_pointer_to_non_const_member_func : std::true_type -{}; -template -struct is_pointer_to_non_const_member_func - : std::true_type -{}; -template -struct is_pointer_to_non_const_member_func - : std::true_type -{}; -template -struct is_pointer_to_non_const_member_func - : std::true_type -{}; -template -struct is_pointer_to_non_const_member_func - : std::true_type -{}; -template -struct is_pointer_to_non_const_member_func - : std::true_type -{}; - -template -struct is_const_or_const_ref : std::false_type -{}; -template -struct is_const_or_const_ref : std::true_type -{}; -template -struct is_const_or_const_ref : std::true_type -{}; -#endif - -// std::invoke from C++17 -// https://stackoverflow.com/questions/38288042/c11-14-invoke-workaround -template< - typename Fn, - typename... Args, -#ifdef TL_TRAITS_LIBCXX_MEM_FN_WORKAROUND - typename = enable_if_t::value && - is_const_or_const_ref::value)>, -#endif - typename = enable_if_t>::value>, - int = 0> -constexpr auto -invoke(Fn&& f, Args&&... args) noexcept( - noexcept(std::mem_fn(f)(std::forward(args)...))) - -> decltype(std::mem_fn(f)(std::forward(args)...)) -{ - return std::mem_fn(f)(std::forward(args)...); -} - -template>::value>> -constexpr auto -invoke(Fn&& f, Args&&... args) noexcept( - noexcept(std::forward(f)(std::forward(args)...))) - -> decltype(std::forward(f)(std::forward(args)...)) -{ - return std::forward(f)(std::forward(args)...); -} - -// std::invoke_result from C++17 -template -struct invoke_result_impl; - -template -struct invoke_result_impl< - F, - decltype(detail::invoke(std::declval(), std::declval()...), void()), - Us...> -{ - using type = - decltype(detail::invoke(std::declval(), std::declval()...)); -}; - -template -using invoke_result = invoke_result_impl; - -template -using invoke_result_t = typename invoke_result::type; - -#if defined(_MSC_VER) && _MSC_VER <= 1900 -// TODO make a version which works with MSVC 2015 -template -struct is_swappable : std::true_type -{}; - -template -struct is_nothrow_swappable : std::true_type -{}; -#else -// https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept -namespace swap_adl_tests { -// if swap ADL finds this then it would call std::swap otherwise (same -// signature) -struct tag -{}; - -template -tag -swap(T&, T&); -template -tag swap(T (&a)[N], T (&b)[N]); - -// helper functions to test if an unqualified swap is possible, and if it -// becomes std::swap -template -std::false_type -can_swap(...) noexcept(false); -template(), std::declval()))> -std::true_type -can_swap(int) noexcept(noexcept(swap(std::declval(), std::declval()))); - -template -std::false_type -uses_std(...); -template -std::is_same(), std::declval())), tag> -uses_std(int); - -template -struct is_std_swap_noexcept - : std::integral_constant::value && - std::is_nothrow_move_assignable::value> -{}; - -template -struct is_std_swap_noexcept : is_std_swap_noexcept -{}; - -template -struct is_adl_swap_noexcept - : std::integral_constant(0))> -{}; -} // namespace swap_adl_tests - -template -struct is_swappable - : std::integral_constant< - bool, - decltype(detail::swap_adl_tests::can_swap(0))::value && - (!decltype(detail::swap_adl_tests::uses_std(0))::value || - (std::is_move_assignable::value && - std::is_move_constructible::value))> -{}; - -template -struct is_swappable - : std::integral_constant< - bool, - decltype(detail::swap_adl_tests::can_swap(0))::value && - (!decltype(detail::swap_adl_tests::uses_std(0))::value || - is_swappable::value)> -{}; - -template -struct is_nothrow_swappable - : std::integral_constant< - bool, - is_swappable::value && - ((decltype(detail::swap_adl_tests::uses_std(0))::value && - detail::swap_adl_tests::is_std_swap_noexcept::value) || - (!decltype(detail::swap_adl_tests::uses_std(0))::value && - detail::swap_adl_tests::is_adl_swap_noexcept::value))> -{}; -#endif -#endif - -// std::void_t from C++17 -template -struct voider -{ - using type = void; -}; -template -using void_t = typename voider::type; - -// Trait for checking if a type is a tl::optional -template -struct is_optional_impl : std::false_type -{}; -template -struct is_optional_impl> : std::true_type -{}; -template -using is_optional = is_optional_impl>; - -// Change void to tl::monostate -template -using fixup_void = conditional_t::value, monostate, U>; - -template> -using get_map_return = optional>>; - -// Check if invoking F for some Us returns void -template -struct returns_void_impl; -template -struct returns_void_impl>, U...> - : std::is_void> -{}; -template -using returns_void = returns_void_impl; - -template -using enable_if_ret_void = enable_if_t::value>; - -template -using disable_if_ret_void = enable_if_t::value>; - -template -using enable_forward_value = - detail::enable_if_t::value && - !std::is_same, in_place_t>::value && - !std::is_same, detail::decay_t>::value>; - -template -using enable_from_other = - detail::enable_if_t::value && - !std::is_constructible&>::value && - !std::is_constructible&&>::value && - !std::is_constructible&>::value && - !std::is_constructible&&>::value && - !std::is_convertible&, T>::value && - !std::is_convertible&&, T>::value && - !std::is_convertible&, T>::value && - !std::is_convertible&&, T>::value>; - -template -using enable_assign_forward = detail::enable_if_t< - !std::is_same, detail::decay_t>::value && - !detail::conjunction, - std::is_same>>::value && - std::is_constructible::value && std::is_assignable::value>; - -template -using enable_assign_from_other = - detail::enable_if_t::value && - std::is_assignable::value && - !std::is_constructible&>::value && - !std::is_constructible&&>::value && - !std::is_constructible&>::value && - !std::is_constructible&&>::value && - !std::is_convertible&, T>::value && - !std::is_convertible&&, T>::value && - !std::is_convertible&, T>::value && - !std::is_convertible&&, T>::value && - !std::is_assignable&>::value && - !std::is_assignable&&>::value && - !std::is_assignable&>::value && - !std::is_assignable&&>::value>; - -// The storage base manages the actual storage, and correctly propagates -// trivial destruction from T. This case is for when T is not trivially -// destructible. -template::value> -struct optional_storage_base -{ - TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept - : m_dummy() - , m_has_value(false) - { - } - - template - TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) - : m_value(std::forward(u)...) - , m_has_value(true) - { - } - - ~optional_storage_base() - { - if (m_has_value) { - m_value.~T(); - m_has_value = false; - } - } - - struct dummy - {}; - union - { - dummy m_dummy; - T m_value; - }; - - bool m_has_value; -}; - -// This case is for when T is trivially destructible. -template -struct optional_storage_base -{ - TL_OPTIONAL_11_CONSTEXPR optional_storage_base() noexcept - : m_dummy() - , m_has_value(false) - { - } - - template - TL_OPTIONAL_11_CONSTEXPR optional_storage_base(in_place_t, U&&... u) - : m_value(std::forward(u)...) - , m_has_value(true) - { - } - - // No destructor, so this class is trivially destructible - - struct dummy - {}; - union - { - dummy m_dummy; - T m_value; - }; - - bool m_has_value = false; -}; - -// This base class provides some handy member functions which can be used in -// further derived classes -template -struct optional_operations_base : optional_storage_base -{ - using optional_storage_base::optional_storage_base; - - void hard_reset() noexcept - { - get().~T(); - this->m_has_value = false; - } - - template - void construct(Args&&... args) - { - new (std::addressof(this->m_value)) T(std::forward(args)...); - this->m_has_value = true; - } - - template - void assign(Opt&& rhs) - { - if (this->has_value()) { - if (rhs.has_value()) { - this->m_value = std::forward(rhs).get(); - } else { - this->m_value.~T(); - this->m_has_value = false; - } - } - - else if (rhs.has_value()) { - construct(std::forward(rhs).get()); - } - } - - bool has_value() const { return this->m_has_value; } - - TL_OPTIONAL_11_CONSTEXPR T& get() & { return this->m_value; } - TL_OPTIONAL_11_CONSTEXPR const T& get() const& { return this->m_value; } - TL_OPTIONAL_11_CONSTEXPR T&& get() && { return std::move(this->m_value); } -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr const T&& get() const&& { return std::move(this->m_value); } -#endif -}; - -// This class manages conditionally having a trivial copy constructor -// This specialization is for when T is trivially copy constructible -template -struct optional_copy_base : optional_operations_base -{ - using optional_operations_base::optional_operations_base; -}; - -// This specialization is for when T is not trivially copy constructible -template -struct optional_copy_base : optional_operations_base -{ - using optional_operations_base::optional_operations_base; - - optional_copy_base() = default; - optional_copy_base(const optional_copy_base& rhs) - : optional_operations_base() - { - if (rhs.has_value()) { - this->construct(rhs.get()); - } else { - this->m_has_value = false; - } - } - - optional_copy_base(optional_copy_base&& rhs) = default; - optional_copy_base& operator=(const optional_copy_base& rhs) = default; - optional_copy_base& operator=(optional_copy_base&& rhs) = default; -}; - -// This class manages conditionally having a trivial move constructor -// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it -// doesn't implement an analogue to std::is_trivially_move_constructible. We -// have to make do with a non-trivial move constructor even if T is trivially -// move constructible -#ifndef TL_OPTIONAL_GCC49 -template::value> -struct optional_move_base : optional_copy_base -{ - using optional_copy_base::optional_copy_base; -}; -#else -template -struct optional_move_base; -#endif -template -struct optional_move_base : optional_copy_base -{ - using optional_copy_base::optional_copy_base; - - optional_move_base() = default; - optional_move_base(const optional_move_base& rhs) = default; - - optional_move_base(optional_move_base&& rhs) noexcept( - std::is_nothrow_move_constructible::value) - { - if (rhs.has_value()) { - this->construct(std::move(rhs.get())); - } else { - this->m_has_value = false; - } - } - optional_move_base& operator=(const optional_move_base& rhs) = default; - optional_move_base& operator=(optional_move_base&& rhs) = default; -}; - -// This class manages conditionally having a trivial copy assignment operator -template -struct optional_copy_assign_base : optional_move_base -{ - using optional_move_base::optional_move_base; -}; - -template -struct optional_copy_assign_base : optional_move_base -{ - using optional_move_base::optional_move_base; - - optional_copy_assign_base() = default; - optional_copy_assign_base(const optional_copy_assign_base& rhs) = default; - - optional_copy_assign_base(optional_copy_assign_base&& rhs) = default; - optional_copy_assign_base& operator=(const optional_copy_assign_base& rhs) - { - this->assign(rhs); - return *this; - } - optional_copy_assign_base& operator=(optional_copy_assign_base&& rhs) = - default; -}; - -// This class manages conditionally having a trivial move assignment operator -// Unfortunately there's no way to achieve this in GCC < 5 AFAIK, since it -// doesn't implement an analogue to std::is_trivially_move_assignable. We have -// to make do with a non-trivial move assignment operator even if T is trivially -// move assignable -#ifndef TL_OPTIONAL_GCC49 -template::value && - std::is_trivially_move_constructible::value && - std::is_trivially_move_assignable::value> -struct optional_move_assign_base : optional_copy_assign_base -{ - using optional_copy_assign_base::optional_copy_assign_base; -}; -#else -template -struct optional_move_assign_base; -#endif - -template -struct optional_move_assign_base : optional_copy_assign_base -{ - using optional_copy_assign_base::optional_copy_assign_base; - - optional_move_assign_base() = default; - optional_move_assign_base(const optional_move_assign_base& rhs) = default; - - optional_move_assign_base(optional_move_assign_base&& rhs) = default; - - optional_move_assign_base& operator=(const optional_move_assign_base& rhs) = - default; - - optional_move_assign_base& - operator=(optional_move_assign_base&& rhs) noexcept( - std::is_nothrow_move_constructible::value && - std::is_nothrow_move_assignable::value) - { - this->assign(std::move(rhs)); - return *this; - } -}; - -// optional_delete_ctor_base will conditionally delete copy and move -// constructors depending on whether T is copy/move constructible -template::value, - bool EnableMove = std::is_move_constructible::value> -struct optional_delete_ctor_base -{ - optional_delete_ctor_base() = default; - optional_delete_ctor_base(const optional_delete_ctor_base&) = default; - optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = default; - optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = - default; - optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = - default; -}; - -template -struct optional_delete_ctor_base -{ - optional_delete_ctor_base() = default; - optional_delete_ctor_base(const optional_delete_ctor_base&) = default; - optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = delete; - optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = - default; - optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = - default; -}; - -template -struct optional_delete_ctor_base -{ - optional_delete_ctor_base() = default; - optional_delete_ctor_base(const optional_delete_ctor_base&) = delete; - optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = default; - optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = - default; - optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = - default; -}; - -template -struct optional_delete_ctor_base -{ - optional_delete_ctor_base() = default; - optional_delete_ctor_base(const optional_delete_ctor_base&) = delete; - optional_delete_ctor_base(optional_delete_ctor_base&&) noexcept = delete; - optional_delete_ctor_base& operator=(const optional_delete_ctor_base&) = - default; - optional_delete_ctor_base& operator=(optional_delete_ctor_base&&) noexcept = - default; -}; - -// optional_delete_assign_base will conditionally delete copy and move -// constructors depending on whether T is copy/move constructible + assignable -template::value && - std::is_copy_assignable::value), - bool EnableMove = (std::is_move_constructible::value && - std::is_move_assignable::value)> -struct optional_delete_assign_base -{ - optional_delete_assign_base() = default; - optional_delete_assign_base(const optional_delete_assign_base&) = default; - optional_delete_assign_base(optional_delete_assign_base&&) noexcept = default; - optional_delete_assign_base& operator=(const optional_delete_assign_base&) = - default; - optional_delete_assign_base& operator=( - optional_delete_assign_base&&) noexcept = default; -}; - -template -struct optional_delete_assign_base -{ - optional_delete_assign_base() = default; - optional_delete_assign_base(const optional_delete_assign_base&) = default; - optional_delete_assign_base(optional_delete_assign_base&&) noexcept = default; - optional_delete_assign_base& operator=(const optional_delete_assign_base&) = - default; - optional_delete_assign_base& operator=( - optional_delete_assign_base&&) noexcept = delete; -}; - -template -struct optional_delete_assign_base -{ - optional_delete_assign_base() = default; - optional_delete_assign_base(const optional_delete_assign_base&) = default; - optional_delete_assign_base(optional_delete_assign_base&&) noexcept = default; - optional_delete_assign_base& operator=(const optional_delete_assign_base&) = - delete; - optional_delete_assign_base& operator=( - optional_delete_assign_base&&) noexcept = default; -}; - -template -struct optional_delete_assign_base -{ - optional_delete_assign_base() = default; - optional_delete_assign_base(const optional_delete_assign_base&) = default; - optional_delete_assign_base(optional_delete_assign_base&&) noexcept = default; - optional_delete_assign_base& operator=(const optional_delete_assign_base&) = - delete; - optional_delete_assign_base& operator=( - optional_delete_assign_base&&) noexcept = delete; -}; - -} // namespace detail - -/// A tag type to represent an empty optional -struct nullopt_t -{ - struct do_not_use - {}; - constexpr explicit nullopt_t(do_not_use, do_not_use) noexcept {} -}; -/// Represents an empty optional -static constexpr nullopt_t nullopt{ nullopt_t::do_not_use{}, - nullopt_t::do_not_use{} }; - -class bad_optional_access : public std::exception -{ -public: - bad_optional_access() = default; - const char* what() const noexcept { return "Optional has no value"; } -}; - -/// An optional object is an object that contains the storage for another -/// object and manages the lifetime of this contained object, if any. The -/// contained object may be initialized after the optional object has been -/// initialized, and may be destroyed before the optional object has been -/// destroyed. The initialization state of the contained object is tracked by -/// the optional object. -template -class optional - : private detail::optional_move_assign_base - , private detail::optional_delete_ctor_base - , private detail::optional_delete_assign_base -{ - using base = detail::optional_move_assign_base; - - static_assert(!std::is_same::value, - "instantiation of optional with in_place_t is ill-formed"); - static_assert(!std::is_same, nullopt_t>::value, - "instantiation of optional with nullopt_t is ill-formed"); - -public: -// The different versions for C++14 and 11 are needed because deduced return -// types are not SFINAE-safe. This provides better support for things like -// generic lambdas. C.f. -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - /// Carries out some operation which returns an optional on the stored - /// object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : result(nullopt); - } - - template - constexpr auto and_then(F&& f) const& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr auto and_then(F&& f) const&& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : result(nullopt); - } -#endif -#else - /// Carries out some operation which returns an optional on the stored - /// object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F&& f) & - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F&& f) && - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : result(nullopt); - } - - template - constexpr detail::invoke_result_t and_then(F&& f) const& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr detail::invoke_result_t and_then(F&& f) const&& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : result(nullopt); - } -#endif -#endif - -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & - { - return optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && - { - return optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr auto map(F&& f) const& - { - return optional_map_impl(*this, std::forward(f)); - } - - template - constexpr auto map(F&& f) const&& - { - return optional_map_impl(std::move(*this), std::forward(f)); - } -#else - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval(), - std::declval())) - map(F&& f) & - { - return optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl( - std::declval(), - std::declval())) - map(F&& f) && - { - return optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr decltype(optional_map_impl(std::declval(), - std::declval())) - map(F&& f) const& - { - return optional_map_impl(*this, std::forward(f)); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr decltype(optional_map_impl(std::declval(), - std::declval())) map(F&& f) const&& - { - return optional_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f) & - { - return optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f) && - { - return optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr auto transform(F&& f) const& - { - return optional_map_impl(*this, std::forward(f)); - } - - template - constexpr auto transform(F&& f) const&& - { - return optional_map_impl(std::move(*this), std::forward(f)); - } -#else - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl(std::declval(), - std::declval())) - transform(F&& f) & - { - return optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR decltype(optional_map_impl( - std::declval(), - std::declval())) - transform(F&& f) && - { - return optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr decltype(optional_map_impl(std::declval(), - std::declval())) - transform(F&& f) const& - { - return optional_map_impl(*this, std::forward(f)); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr decltype(optional_map_impl(std::declval(), - std::declval())) transform(F&& f) - const&& - { - return optional_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - - /// Calls `f` if the optional is empty - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & - { - if (has_value()) - return *this; - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & - { - return has_value() ? *this : std::forward(f)(); - } - - template* = nullptr> - optional or_else(F&& f) && - { - if (has_value()) - return std::move(*this); - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) && - { - return has_value() ? std::move(*this) : std::forward(f)(); - } - - template* = nullptr> - optional or_else(F&& f) const& - { - if (has_value()) - return *this; - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& - { - return has_value() ? *this : std::forward(f)(); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template* = nullptr> - optional or_else(F&& f) const&& - { - if (has_value()) - return std::move(*this); - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional or_else(F&& f) const&& - { - return has_value() ? std::move(*this) : std::forward(f)(); - } -#endif - - /// Maps the stored value with `f` if there is one, otherwise returns `u`. - template - U map_or(F&& f, U&& u) & - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u); - } - - template - U map_or(F&& f, U&& u) && - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u); - } - - template - U map_or(F&& f, U&& u) const& - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - U map_or(F&& f, U&& u) const&& - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u); - } -#endif - - /// Maps the stored value with `f` if there is one, otherwise calls - /// `u` and returns the result. - template - detail::invoke_result_t map_or_else(F&& f, U&& u) & - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u)(); - } - - template - detail::invoke_result_t map_or_else(F&& f, U&& u) && - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u)(); - } - - template - detail::invoke_result_t map_or_else(F&& f, U&& u) const& - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u)(); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - detail::invoke_result_t map_or_else(F&& f, U&& u) const&& - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u)(); - } -#endif - - /// Returns `u` if `*this` has a value, otherwise an empty optional. - template - constexpr optional::type> conjunction(U&& u) const - { - using result = optional>; - return has_value() ? result{ u } : result{ nullopt }; - } - - /// Returns `rhs` if `*this` is empty, otherwise the current value. - TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) & - { - return has_value() ? *this : rhs; - } - - constexpr optional disjunction(const optional& rhs) const& - { - return has_value() ? *this : rhs; - } - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) && - { - return has_value() ? std::move(*this) : rhs; - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr optional disjunction(const optional& rhs) const&& - { - return has_value() ? std::move(*this) : rhs; - } -#endif - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) & - { - return has_value() ? *this : std::move(rhs); - } - - constexpr optional disjunction(optional&& rhs) const& - { - return has_value() ? *this : std::move(rhs); - } - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) && - { - return has_value() ? std::move(*this) : std::move(rhs); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr optional disjunction(optional&& rhs) const&& - { - return has_value() ? std::move(*this) : std::move(rhs); - } -#endif - - /// Takes the value out of the optional, leaving it empty - optional take() - { - optional ret = std::move(*this); - reset(); - return ret; - } - - using value_type = T; - - /// Constructs an optional that does not contain a value. - constexpr optional() noexcept = default; - - constexpr optional(nullopt_t) noexcept {} - - /// Copy constructor - /// - /// If `rhs` contains a value, the stored value is direct-initialized with - /// it. Otherwise, the constructed optional is empty. - TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) = default; - - /// Move constructor - /// - /// If `rhs` contains a value, the stored value is direct-initialized with - /// it. Otherwise, the constructed optional is empty. - TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default; - - /// Constructs the stored value in-place using the given arguments. - template - constexpr explicit optional( - detail::enable_if_t::value, in_place_t>, - Args&&... args) - : base(in_place, std::forward(args)...) - { - } - - template - TL_OPTIONAL_11_CONSTEXPR explicit optional( - detail::enable_if_t< - std::is_constructible&, Args&&...>::value, - in_place_t>, - std::initializer_list il, - Args&&... args) - { - this->construct(il, std::forward(args)...); - } - - /// Constructs the stored value with `u`. - template::value>* = nullptr, - detail::enable_forward_value* = nullptr> - constexpr optional(U&& u) - : base(in_place, std::forward(u)) - { - } - - template::value>* = nullptr, - detail::enable_forward_value* = nullptr> - constexpr explicit optional(U&& u) - : base(in_place, std::forward(u)) - { - } - - /// Converting copy constructor. - template< - class U, - detail::enable_from_other* = nullptr, - detail::enable_if_t::value>* = nullptr> - optional(const optional& rhs) - { - if (rhs.has_value()) { - this->construct(*rhs); - } - } - - template< - class U, - detail::enable_from_other* = nullptr, - detail::enable_if_t::value>* = nullptr> - explicit optional(const optional& rhs) - { - if (rhs.has_value()) { - this->construct(*rhs); - } - } - - /// Converting move constructor. - template* = nullptr, - detail::enable_if_t::value>* = nullptr> - optional(optional&& rhs) - { - if (rhs.has_value()) { - this->construct(std::move(*rhs)); - } - } - - template* = nullptr, - detail::enable_if_t::value>* = nullptr> - explicit optional(optional&& rhs) - { - if (rhs.has_value()) { - this->construct(std::move(*rhs)); - } - } - - /// Destroys the stored value if there is one. - ~optional() = default; - - /// Assignment to empty. - /// - /// Destroys the current value if there is one. - optional& operator=(nullopt_t) noexcept - { - if (has_value()) { - this->m_value.~T(); - this->m_has_value = false; - } - - return *this; - } - - /// Copy assignment. - /// - /// Copies the value from `rhs` if there is one. Otherwise resets the stored - /// value in `*this`. - optional& operator=(const optional& rhs) = default; - - /// Move assignment. - /// - /// Moves the value from `rhs` if there is one. Otherwise resets the stored - /// value in `*this`. - optional& operator=(optional&& rhs) = default; - - /// Assigns the stored value from `u`, destroying the old value if there was - /// one. - template* = nullptr> - optional& operator=(U&& u) - { - if (has_value()) { - this->m_value = std::forward(u); - } else { - this->construct(std::forward(u)); - } - - return *this; - } - - /// Converting copy assignment operator. - /// - /// Copies the value from `rhs` if there is one. Otherwise resets the stored - /// value in `*this`. - template* = nullptr> - optional& operator=(const optional& rhs) - { - if (has_value()) { - if (rhs.has_value()) { - this->m_value = *rhs; - } else { - this->hard_reset(); - } - } - - else if (rhs.has_value()) { - this->construct(*rhs); - } - - return *this; - } - - // TODO check exception guarantee - /// Converting move assignment operator. - /// - /// Moves the value from `rhs` if there is one. Otherwise resets the stored - /// value in `*this`. - template* = nullptr> - optional& operator=(optional&& rhs) - { - if (has_value()) { - if (rhs.has_value()) { - this->m_value = std::move(*rhs); - } else { - this->hard_reset(); - } - } - - else if (rhs.has_value()) { - this->construct(std::move(*rhs)); - } - - return *this; - } - - /// Constructs the value in-place, destroying the current one if there is - /// one. - template - T& emplace(Args&&... args) - { - static_assert(std::is_constructible::value, - "T must be constructible with Args"); - - *this = nullopt; - this->construct(std::forward(args)...); - return value(); - } - - template - detail::enable_if_t< - std::is_constructible&, Args&&...>::value, - T&> - emplace(std::initializer_list il, Args&&... args) - { - *this = nullopt; - this->construct(il, std::forward(args)...); - return value(); - } - - /// Swaps this optional with the other. - /// - /// If neither optionals have a value, nothing happens. - /// If both have a value, the values are swapped. - /// If one has a value, it is moved to the other and the movee is left - /// valueless. - void swap(optional& rhs) noexcept( - std::is_nothrow_move_constructible::value && - detail::is_nothrow_swappable::value) - { - using std::swap; - if (has_value()) { - if (rhs.has_value()) { - swap(**this, *rhs); - } else { - new (std::addressof(rhs.m_value)) T(std::move(this->m_value)); - this->m_value.T::~T(); - } - } else if (rhs.has_value()) { - new (std::addressof(this->m_value)) T(std::move(rhs.m_value)); - rhs.m_value.T::~T(); - } - swap(this->m_has_value, rhs.m_has_value); - } - - /// Returns a pointer to the stored value - constexpr const T* operator->() const - { - return std::addressof(this->m_value); - } - - TL_OPTIONAL_11_CONSTEXPR T* operator->() - { - return std::addressof(this->m_value); - } - - /// Returns the stored value - TL_OPTIONAL_11_CONSTEXPR T& operator*() & { return this->m_value; } - - constexpr const T& operator*() const& { return this->m_value; } - - TL_OPTIONAL_11_CONSTEXPR T&& operator*() && - { - return std::move(this->m_value); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr const T&& operator*() const&& { return std::move(this->m_value); } -#endif - - /// Returns whether or not the optional has a value - constexpr bool has_value() const noexcept { return this->m_has_value; } - - constexpr explicit operator bool() const noexcept - { - return this->m_has_value; - } - - /// Returns the contained value if there is one, otherwise throws - /// bad_optional_access - TL_OPTIONAL_11_CONSTEXPR T& value() & - { - if (has_value()) - return this->m_value; - throw bad_optional_access(); - } - TL_OPTIONAL_11_CONSTEXPR const T& value() const& - { - if (has_value()) - return this->m_value; - throw bad_optional_access(); - } - TL_OPTIONAL_11_CONSTEXPR T&& value() && - { - if (has_value()) - return std::move(this->m_value); - throw bad_optional_access(); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - TL_OPTIONAL_11_CONSTEXPR const T&& value() const&& - { - if (has_value()) - return std::move(this->m_value); - throw bad_optional_access(); - } -#endif - - /// Returns the stored value if there is one, otherwise returns `u` - template - constexpr T value_or(U&& u) const& - { - static_assert(std::is_copy_constructible::value && - std::is_convertible::value, - "T must be copy constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); - } - - template - TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && - { - static_assert(std::is_move_constructible::value && - std::is_convertible::value, - "T must be move constructible and convertible from U"); - return has_value() ? std::move(**this) : static_cast(std::forward(u)); - } - - /// Destroys the stored value if one exists, making the optional empty - void reset() noexcept - { - if (has_value()) { - this->m_value.~T(); - this->m_has_value = false; - } - } -}; // namespace tl - -/// Compares two optional objects -template -inline constexpr bool -operator==(const optional& lhs, const optional& rhs) -{ - return lhs.has_value() == rhs.has_value() && - (!lhs.has_value() || *lhs == *rhs); -} -template -inline constexpr bool -operator!=(const optional& lhs, const optional& rhs) -{ - return lhs.has_value() != rhs.has_value() || - (lhs.has_value() && *lhs != *rhs); -} -template -inline constexpr bool -operator<(const optional& lhs, const optional& rhs) -{ - return rhs.has_value() && (!lhs.has_value() || *lhs < *rhs); -} -template -inline constexpr bool -operator>(const optional& lhs, const optional& rhs) -{ - return lhs.has_value() && (!rhs.has_value() || *lhs > *rhs); -} -template -inline constexpr bool -operator<=(const optional& lhs, const optional& rhs) -{ - return !lhs.has_value() || (rhs.has_value() && *lhs <= *rhs); -} -template -inline constexpr bool -operator>=(const optional& lhs, const optional& rhs) -{ - return !rhs.has_value() || (lhs.has_value() && *lhs >= *rhs); -} - -/// Compares an optional to a `nullopt` -template -inline constexpr bool -operator==(const optional& lhs, nullopt_t) noexcept -{ - return !lhs.has_value(); -} -template -inline constexpr bool -operator==(nullopt_t, const optional& rhs) noexcept -{ - return !rhs.has_value(); -} -template -inline constexpr bool -operator!=(const optional& lhs, nullopt_t) noexcept -{ - return lhs.has_value(); -} -template -inline constexpr bool -operator!=(nullopt_t, const optional& rhs) noexcept -{ - return rhs.has_value(); -} -template -inline constexpr bool -operator<(const optional&, nullopt_t) noexcept -{ - return false; -} -template -inline constexpr bool -operator<(nullopt_t, const optional& rhs) noexcept -{ - return rhs.has_value(); -} -template -inline constexpr bool -operator<=(const optional& lhs, nullopt_t) noexcept -{ - return !lhs.has_value(); -} -template -inline constexpr bool -operator<=(nullopt_t, const optional&) noexcept -{ - return true; -} -template -inline constexpr bool -operator>(const optional& lhs, nullopt_t) noexcept -{ - return lhs.has_value(); -} -template -inline constexpr bool -operator>(nullopt_t, const optional&) noexcept -{ - return false; -} -template -inline constexpr bool -operator>=(const optional&, nullopt_t) noexcept -{ - return true; -} -template -inline constexpr bool -operator>=(nullopt_t, const optional& rhs) noexcept -{ - return !rhs.has_value(); -} - -/// Compares the optional with a value. -template -inline constexpr bool -operator==(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs == rhs : false; -} -template -inline constexpr bool -operator==(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs == *rhs : false; -} -template -inline constexpr bool -operator!=(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs != rhs : true; -} -template -inline constexpr bool -operator!=(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs != *rhs : true; -} -template -inline constexpr bool -operator<(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs < rhs : true; -} -template -inline constexpr bool -operator<(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs < *rhs : false; -} -template -inline constexpr bool -operator<=(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs <= rhs : true; -} -template -inline constexpr bool -operator<=(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs <= *rhs : false; -} -template -inline constexpr bool -operator>(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs > rhs : false; -} -template -inline constexpr bool -operator>(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs > *rhs : true; -} -template -inline constexpr bool -operator>=(const optional& lhs, const U& rhs) -{ - return lhs.has_value() ? *lhs >= rhs : false; -} -template -inline constexpr bool -operator>=(const U& lhs, const optional& rhs) -{ - return rhs.has_value() ? lhs >= *rhs : true; -} - -template::value>* = nullptr, - detail::enable_if_t::value>* = nullptr> -void -swap(optional& lhs, optional& rhs) noexcept(noexcept(lhs.swap(rhs))) -{ - return lhs.swap(rhs); -} - -namespace detail { -struct i_am_secret -{}; -} // namespace detail - -template< - class T = detail::i_am_secret, - class U, - class Ret = detail::conditional_t::value, - detail::decay_t, - T>> -inline constexpr optional -make_optional(U&& v) -{ - return optional(std::forward(v)); -} - -template -inline constexpr optional -make_optional(Args&&... args) -{ - return optional(in_place, std::forward(args)...); -} -template -inline constexpr optional -make_optional(std::initializer_list il, Args&&... args) -{ - return optional(in_place, il, std::forward(args)...); -} - -#if __cplusplus >= 201703L -template -optional(T) -> optional; -#endif - -/// \exclude -namespace detail { -#ifdef TL_OPTIONAL_CXX14 -template(), - *std::declval())), - detail::enable_if_t::value>* = nullptr> -constexpr auto -optional_map_impl(Opt&& opt, F&& f) -{ - return opt.has_value() - ? detail::invoke(std::forward(f), *std::forward(opt)) - : optional(nullopt); -} - -template(), - *std::declval())), - detail::enable_if_t::value>* = nullptr> -auto -optional_map_impl(Opt&& opt, F&& f) -{ - if (opt.has_value()) { - detail::invoke(std::forward(f), *std::forward(opt)); - return make_optional(monostate{}); - } - - return optional(nullopt); -} -#else -template(), - *std::declval())), - detail::enable_if_t::value>* = nullptr> - -constexpr auto -optional_map_impl(Opt&& opt, F&& f) -> optional -{ - return opt.has_value() - ? detail::invoke(std::forward(f), *std::forward(opt)) - : optional(nullopt); -} - -template(), - *std::declval())), - detail::enable_if_t::value>* = nullptr> - -auto -optional_map_impl(Opt&& opt, F&& f) -> optional -{ - if (opt.has_value()) { - detail::invoke(std::forward(f), *std::forward(opt)); - return monostate{}; - } - - return nullopt; -} -#endif -} // namespace detail - -/// Specialization for when `T` is a reference. `optional` acts similarly -/// to a `T*`, but provides more operations and shows intent more clearly. -template -class optional -{ -public: -// The different versions for C++14 and 11 are needed because deduced return -// types are not SFINAE-safe. This provides better support for things like -// generic lambdas. C.f. -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0826r0.html -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - - /// Carries out some operation which returns an optional on the stored - /// object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) & - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto and_then(F&& f) && - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - constexpr auto and_then(F&& f) const& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr auto and_then(F&& f) const&& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } -#endif -#else - /// Carries out some operation which returns an optional on the stored - /// object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F&& f) & - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - TL_OPTIONAL_11_CONSTEXPR detail::invoke_result_t and_then(F&& f) && - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - - template - constexpr detail::invoke_result_t and_then(F&& f) const& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), **this) - : result(nullopt); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr detail::invoke_result_t and_then(F&& f) const&& - { - using result = detail::invoke_result_t; - static_assert(detail::is_optional::value, - "F must return an optional"); - - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : result(nullopt); - } -#endif -#endif - -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) & - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto map(F&& f) && - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr auto map(F&& f) const& - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - template - constexpr auto map(F&& f) const&& - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } -#else - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( - std::declval(), - std::declval())) - map(F&& f) & - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( - std::declval(), - std::declval())) - map(F&& f) && - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr decltype(detail::optional_map_impl(std::declval(), - std::declval())) - map(F&& f) const& - { - return detail::optional_map_impl(*this, std::forward(f)); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr decltype(detail::optional_map_impl(std::declval(), - std::declval())) map(F&& f) - const&& - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - -#if defined(TL_OPTIONAL_CXX14) && !defined(TL_OPTIONAL_GCC49) && \ - !defined(TL_OPTIONAL_GCC54) && !defined(TL_OPTIONAL_GCC55) - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f) & - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - template - TL_OPTIONAL_11_CONSTEXPR auto transform(F&& f) && - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr auto transform(F&& f) const& - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - template - constexpr auto transform(F&& f) const&& - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } -#else - /// Carries out some operation on the stored object if there is one. - template - TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( - std::declval(), - std::declval())) - transform(F&& f) & - { - return detail::optional_map_impl(*this, std::forward(f)); - } - - /// \group map - /// \synopsis template auto transform(F &&f) &&; - template - TL_OPTIONAL_11_CONSTEXPR decltype(detail::optional_map_impl( - std::declval(), - std::declval())) - transform(F&& f) && - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } - - template - constexpr decltype(detail::optional_map_impl(std::declval(), - std::declval())) - transform(F&& f) const& - { - return detail::optional_map_impl(*this, std::forward(f)); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - constexpr decltype(detail::optional_map_impl( - std::declval(), - std::declval())) transform(F&& f) const&& - { - return detail::optional_map_impl(std::move(*this), std::forward(f)); - } -#endif -#endif - - /// Calls `f` if the optional is empty - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & - { - if (has_value()) - return *this; - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) & - { - return has_value() ? *this : std::forward(f)(); - } - - template* = nullptr> - optional or_else(F&& f) && - { - if (has_value()) - return std::move(*this); - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) && - { - return has_value() ? std::move(*this) : std::forward(f)(); - } - - template* = nullptr> - optional or_else(F&& f) const& - { - if (has_value()) - return *this; - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional TL_OPTIONAL_11_CONSTEXPR or_else(F&& f) const& - { - return has_value() ? *this : std::forward(f)(); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template* = nullptr> - optional or_else(F&& f) const&& - { - if (has_value()) - return std::move(*this); - - std::forward(f)(); - return nullopt; - } - - template* = nullptr> - optional or_else(F&& f) const&& - { - return has_value() ? std::move(*this) : std::forward(f)(); - } -#endif - - /// Maps the stored value with `f` if there is one, otherwise returns `u` - template - U map_or(F&& f, U&& u) & - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u); - } - - template - U map_or(F&& f, U&& u) && - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u); - } - - template - U map_or(F&& f, U&& u) const& - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - U map_or(F&& f, U&& u) const&& - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u); - } -#endif - - /// Maps the stored value with `f` if there is one, otherwise calls - /// `u` and returns the result. - template - detail::invoke_result_t map_or_else(F&& f, U&& u) & - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u)(); - } - - template - detail::invoke_result_t map_or_else(F&& f, U&& u) && - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u)(); - } - - template - detail::invoke_result_t map_or_else(F&& f, U&& u) const& - { - return has_value() ? detail::invoke(std::forward(f), **this) - : std::forward(u)(); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - template - detail::invoke_result_t map_or_else(F&& f, U&& u) const&& - { - return has_value() ? detail::invoke(std::forward(f), std::move(**this)) - : std::forward(u)(); - } -#endif - - /// Returns `u` if `*this` has a value, otherwise an empty optional. - template - constexpr optional::type> conjunction(U&& u) const - { - using result = optional>; - return has_value() ? result{ u } : result{ nullopt }; - } - - /// Returns `rhs` if `*this` is empty, otherwise the current value. - TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) & - { - return has_value() ? *this : rhs; - } - - constexpr optional disjunction(const optional& rhs) const& - { - return has_value() ? *this : rhs; - } - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(const optional& rhs) && - { - return has_value() ? std::move(*this) : rhs; - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr optional disjunction(const optional& rhs) const&& - { - return has_value() ? std::move(*this) : rhs; - } -#endif - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) & - { - return has_value() ? *this : std::move(rhs); - } - - constexpr optional disjunction(optional&& rhs) const& - { - return has_value() ? *this : std::move(rhs); - } - - TL_OPTIONAL_11_CONSTEXPR optional disjunction(optional&& rhs) && - { - return has_value() ? std::move(*this) : std::move(rhs); - } - -#ifndef TL_OPTIONAL_NO_CONSTRR - constexpr optional disjunction(optional&& rhs) const&& - { - return has_value() ? std::move(*this) : std::move(rhs); - } -#endif - - /// Takes the value out of the optional, leaving it empty - optional take() - { - optional ret = std::move(*this); - reset(); - return ret; - } - - using value_type = T&; - - /// Constructs an optional that does not contain a value. - constexpr optional() noexcept - : m_value(nullptr) - { - } - - constexpr optional(nullopt_t) noexcept - : m_value(nullptr) - { - } - - /// Copy constructor - /// - /// If `rhs` contains a value, the stored value is direct-initialized with - /// it. Otherwise, the constructed optional is empty. - TL_OPTIONAL_11_CONSTEXPR optional(const optional& rhs) noexcept = default; - - /// Move constructor - /// - /// If `rhs` contains a value, the stored value is direct-initialized with - /// it. Otherwise, the constructed optional is empty. - TL_OPTIONAL_11_CONSTEXPR optional(optional&& rhs) = default; - - /// Constructs the stored value with `u`. - template>::value>* = nullptr> - constexpr optional(U&& u) noexcept - : m_value(std::addressof(u)) - { - static_assert(std::is_lvalue_reference::value, "U must be an lvalue"); - } - - template - constexpr explicit optional(const optional& rhs) noexcept - : optional(*rhs) - { - } - - /// No-op - ~optional() = default; - - /// Assignment to empty. - /// - /// Destroys the current value if there is one. - optional& operator=(nullopt_t) noexcept - { - m_value = nullptr; - return *this; - } - - /// Copy assignment. - /// - /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise - /// resets the stored value in `*this`. - optional& operator=(const optional& rhs) = default; - - /// Rebinds this optional to `u`. - template>::value>* = nullptr> - optional& operator=(U&& u) - { - static_assert(std::is_lvalue_reference::value, "U must be an lvalue"); - m_value = std::addressof(u); - return *this; - } - - /// Converting copy assignment operator. - /// - /// Rebinds this optional to the referee of `rhs` if there is one. Otherwise - /// resets the stored value in `*this`. - template - optional& operator=(const optional& rhs) noexcept - { - m_value = std::addressof(rhs.value()); - return *this; - } - - /// Rebinds this optional to `u`. - template>::value>* = nullptr> - optional& emplace(U&& u) noexcept - { - return *this = std::forward(u); - } - - void swap(optional& rhs) noexcept { std::swap(m_value, rhs.m_value); } - - /// Returns a pointer to the stored value - constexpr const T* operator->() const noexcept { return m_value; } - - TL_OPTIONAL_11_CONSTEXPR T* operator->() noexcept { return m_value; } - - /// Returns the stored value - TL_OPTIONAL_11_CONSTEXPR T& operator*() noexcept { return *m_value; } - - constexpr const T& operator*() const noexcept { return *m_value; } - - constexpr bool has_value() const noexcept { return m_value != nullptr; } - - constexpr explicit operator bool() const noexcept - { - return m_value != nullptr; - } - - /// Returns the contained value if there is one, otherwise throws - /// bad_optional_access - TL_OPTIONAL_11_CONSTEXPR T& value() - { - if (has_value()) - return *m_value; - throw bad_optional_access(); - } - TL_OPTIONAL_11_CONSTEXPR const T& value() const - { - if (has_value()) - return *m_value; - throw bad_optional_access(); - } - - /// Returns the stored value if there is one, otherwise returns `u` - template - constexpr T value_or(U&& u) const& noexcept - { - static_assert(std::is_copy_constructible::value && - std::is_convertible::value, - "T must be copy constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); - } - - /// \group value_or - template - TL_OPTIONAL_11_CONSTEXPR T value_or(U&& u) && noexcept - { - static_assert(std::is_move_constructible::value && - std::is_convertible::value, - "T must be move constructible and convertible from U"); - return has_value() ? **this : static_cast(std::forward(u)); - } - - /// Destroys the stored value if one exists, making the optional empty - void reset() noexcept { m_value = nullptr; } - -private: - T* m_value; -}; // namespace tl - -} // namespace tl - -namespace std { -// TODO SFINAE -template -struct hash> -{ - ::std::size_t operator()(const tl::optional& o) const - { - if (!o.has_value()) - return 0; - - return std::hash>()(*o); - } -}; -} // namespace std - -#endif diff --git a/include/proxsuite/linalg/sparse/factorize.hpp b/include/proxsuite/linalg/sparse/factorize.hpp index 225a82f7b..78ade7863 100644 --- a/include/proxsuite/linalg/sparse/factorize.hpp +++ b/include/proxsuite/linalg/sparse/factorize.hpp @@ -392,7 +392,7 @@ ereach(usize& count, usize(len) * sizeof(I)); // move down the top of the stack - top = util::wrapping_plus(top, -len); + top -= len; } for (usize q = top; q < n; ++q) { diff --git a/include/proxsuite/linalg/veg/tuple.hpp b/include/proxsuite/linalg/veg/tuple.hpp index 6e7dc1ca2..a3ad0e3e7 100644 --- a/include/proxsuite/linalg/veg/tuple.hpp +++ b/include/proxsuite/linalg/veg/tuple.hpp @@ -754,16 +754,9 @@ struct cat proxsuite::linalg::veg::meta::false_type /*unused*/, Tuples&&... tups) VEG_NOEXCEPT -> Concat { -#if defined(_MSC_VER) || (defined(__clang__) && __clang_major__ >= 19) || \ - (defined(__APPLE__) && defined(__clang__) && __clang_major__ >= 17) return cat::from_ref_to_result( Tag>{}, cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); -#else - return cat::template from_ref_to_result( - Tag>{}, - cat::apply(_detail::_tuple::tuple_fwd(VEG_FWD(tups))...)); -#endif } template diff --git a/include/proxsuite/proxqp/dense/backward_data.hpp b/include/proxsuite/proxqp/dense/backward_data.hpp index 7ebe8734b..00f6aefbd 100644 --- a/include/proxsuite/proxqp/dense/backward_data.hpp +++ b/include/proxsuite/proxqp/dense/backward_data.hpp @@ -8,7 +8,6 @@ #define PROXSUITE_PROXQP_DENSE_BACKWARD_DATA_HPP #include -#include #include "proxsuite/linalg/veg/type_traits/core.hpp" #include "proxsuite/proxqp/dense/fwd.hpp" diff --git a/include/proxsuite/proxqp/sparse/workspace.hpp b/include/proxsuite/proxqp/sparse/workspace.hpp index 5d763e3ad..5bc485dcf 100644 --- a/include/proxsuite/proxqp/sparse/workspace.hpp +++ b/include/proxsuite/proxqp/sparse/workspace.hpp @@ -491,12 +491,12 @@ struct Workspace } } - auto lnnz = isize(zero_extend(ldl.col_ptrs[n_tot])); + const auto local_lnnz = isize(zero_extend(ldl.col_ptrs[n_tot])); // if ldlt is too sparse - // do_ldlt = !overflow && lnnz < (10000000); + // do_ldlt = !overflow && local_lnnz < (10000000); if (settings.sparse_backend == SparseBackend::Automatic) { - do_ldlt = !overflow && lnnz < 10000000; + do_ldlt = !overflow && local_lnnz < 10000000; } else if (settings.sparse_backend == SparseBackend::SparseCholesky) { do_ldlt = true; } else { diff --git a/include/proxsuite/proxqp/utils/random_qp_problems.hpp b/include/proxsuite/proxqp/utils/random_qp_problems.hpp index e08641d47..c5f7bbac3 100644 --- a/include/proxsuite/proxqp/utils/random_qp_problems.hpp +++ b/include/proxsuite/proxqp/utils/random_qp_problems.hpp @@ -13,6 +13,10 @@ #include #include +#if defined(_MSC_VER) +#include +#endif + namespace proxsuite { namespace proxqp { namespace utils { @@ -67,41 +71,11 @@ namespace rand { using proxqp::u32; using proxqp::u64; -#ifdef _MSC_VER -/* Using the MSCV compiler on Windows causes problems because the type uint128 -is not available. Therefore, we use a random number generator from the stdlib -instead of our custom Lehmer random number generator. The necessary lehmer -functions used in in our code are remplaced with calls to the stdlib.*/ -std::mt19937 gen(1234); -std::uniform_real_distribution<> uniform_dist(0.0, 1.0); -std::normal_distribution normal_dist; -using u128 = u64; -inline auto -uniform_rand() -> double -{ - double output = double(uniform_dist(gen)); - return output; -} -inline auto -lehmer_global() -> u128& -{ - static u64 output = gen(); - return output; -} - -inline void -set_seed(u64 seed) -{ - gen.seed(seed); -} - -inline auto -normal_rand() -> double -{ - return normal_dist(gen); -} +#if defined(_MSC_VER) +using u128 = uint128_t; #else using u128 = __uint128_t; +#endif constexpr u128 lehmer64_constant(0xda942042e4dd58b5); inline auto @@ -145,7 +119,6 @@ normal_rand() -> double return sqrt * std::cos(pi2 * u2); } -#endif template auto diff --git a/include/proxsuite/proxqp/utils/uint128_msvc.hpp b/include/proxsuite/proxqp/utils/uint128_msvc.hpp new file mode 100644 index 000000000..a1f4940be --- /dev/null +++ b/include/proxsuite/proxqp/utils/uint128_msvc.hpp @@ -0,0 +1,236 @@ +#pragma once + +#if !defined(_MSC_VER) +#error "This file is only compatible with the MSVC compiler" +#endif + +#include +#include + +class uint128_t +{ +public: + uint64_t low; + uint64_t high; + + // --- Constructors --- + constexpr uint128_t() + : low(0) + , high(0) + { + } + constexpr uint128_t(uint64_t l) + : low(l) + , high(0) + { + } + constexpr uint128_t(uint64_t l, uint64_t h) + : low(l) + , high(h) + { + } + + // --- Type Conversions --- + explicit operator bool() const { return low || high; } + explicit operator uint64_t() const { return low; } + explicit operator int64_t() const { return static_cast(low); } + + // --- Arithmetic Operators --- + + // Addition + uint128_t operator+(const uint128_t& rhs) const + { + uint128_t result; + unsigned char carry = _addcarry_u64(0, low, rhs.low, &result.low); + _addcarry_u64(carry, high, rhs.high, &result.high); + return result; + } + + uint128_t& operator+=(const uint128_t& rhs) + { + *this = *this + rhs; + return *this; + } + + // Subtraction + uint128_t operator-(const uint128_t& rhs) const + { + uint128_t result; + unsigned char borrow = _subborrow_u64(0, low, rhs.low, &result.low); + _subborrow_u64(borrow, high, rhs.high, &result.high); + return result; + } + + uint128_t& operator-=(const uint128_t& rhs) + { + *this = *this - rhs; + return *this; + } + + // Multiplication + uint128_t operator*(const uint128_t& rhs) const + { + uint64_t product_high; + uint64_t product_low = _umul128(low, rhs.low, &product_high); + + // The total high part is the high part of (low * rhs.low) + // plus the cross terms (low * rhs.high) and (high * rhs.low) + product_high += (low * rhs.high) + (high * rhs.low); + + return uint128_t(product_low, product_high); + } + + uint128_t& operator*=(const uint128_t& rhs) + { + *this = *this * rhs; + return *this; + } + + // Division (Note: Full 128-bit division is complex to implement purely with + // intrinsics if the divisor is > 64 bits. This is a simplified version + // handling common cases). For production-grade full 128/128 division, usage + // of a library like Boost is strongly advised. However, if divisor fits in 64 + // bits, we can use _udiv128. + uint128_t operator/(const uint128_t& rhs) const + { + if (rhs.high == 0) { + // Optimization for 64-bit divisor + uint64_t remainder; + uint64_t quotient_high = 0; // High part of result + uint64_t quotient_low; + + // If our high part is distinct, we divide the high part first + if (high > 0) { + // This is slightly tricky with _udiv128 directly as it does 128/64 + // -> 64. Standard long division algorithm is safer here for the general + // implementation. For simplicity in this snippet, we will fallback to a + // naive loop or simple approximation OR promote strictly the 64-bit + // divisor case which is most common: + + quotient_high = high / rhs.low; + uint64_t r_high = high % rhs.low; + + quotient_low = _udiv128(r_high, low, rhs.low, &remainder); + return uint128_t(quotient_low, quotient_high); + } else { + return uint128_t(low / rhs.low, 0); + } + } + // Fallback for full 128-bit divisor: Very slow basic binary long division + if (rhs > *this) + return uint128_t(0); + if (rhs == *this) + return uint128_t(1); + + uint128_t temp = *this; + uint128_t quot = 0; + uint128_t one = 1; + + // This is slow O(N) division, acceptable for simple utility, bad for heavy + // math + while (temp >= rhs) { + // Find shift + uint128_t shift_rhs = rhs; + uint128_t shift_count = 1; + while ((shift_rhs.high & 0x8000000000000000) == 0 && + (shift_rhs << 1) <= temp) { + shift_rhs <<= 1; + shift_count <<= 1; + } + temp -= shift_rhs; + quot += shift_count; + } + return quot; + } + + // Modulus + uint128_t operator%(const uint128_t& rhs) const + { + return *this - (*this / rhs) * rhs; + } + + uint128_t& operator%=(const uint128_t& rhs) + { + *this = *this % rhs; + return *this; + } + + // --- Bitwise Operators --- + uint128_t operator<<(int shift) const + { + shift &= 127; // Mask the shift amount to imitate native hardware behavior + // (modulo 128) + if (shift == 0) + return *this; + if (shift >= 64) { + return uint128_t(0, low << (shift - 64)); + } + return uint128_t((low << shift), (high << shift) | (low >> (64 - shift))); + } + + uint128_t operator>>(int shift) const + { + shift &= 127; // Mask the shift amount to imitate native hardware behavior + // (modulo 128) + if (shift == 0) + return *this; + if (shift >= 64) { + return uint128_t(high >> (shift - 64), 0); + } + return uint128_t((low >> shift) | (high << (64 - shift)), (high >> shift)); + } + + // --- Shift by uint128_t Overloads --- + uint128_t operator>>(const uint128_t& shift) const + { + // If shift amount is >= 128, the result behavior mimics hardware (modulo + // 128) + return *this >> static_cast(shift.low); + } + + uint128_t operator<<(const uint128_t& shift) const + { + // If shift amount is >= 128, the result behavior mimics hardware (modulo + // 128) + return *this << static_cast(shift.low); + } + + uint128_t& operator<<=(int shift) + { + *this = *this << shift; + return *this; + } + uint128_t& operator>>=(int shift) + { + *this = *this >> shift; + return *this; + } + + uint128_t operator|(const uint128_t& rhs) const + { + return uint128_t(low | rhs.low, high | rhs.high); + } + uint128_t operator&(const uint128_t& rhs) const + { + return uint128_t(low & rhs.low, high & rhs.high); + } + uint128_t operator^(const uint128_t& rhs) const + { + return uint128_t(low ^ rhs.low, high ^ rhs.high); + } + uint128_t operator~() const { return uint128_t(~low, ~high); } + + // --- Comparison Operators --- + bool operator==(const uint128_t& rhs) const + { + return low == rhs.low && high == rhs.high; + } + bool operator!=(const uint128_t& rhs) const { return !(*this == rhs); } + bool operator<(const uint128_t& rhs) const + { + return high < rhs.high || (high == rhs.high && low < rhs.low); + } + bool operator>(const uint128_t& rhs) const { return rhs < *this; } + bool operator<=(const uint128_t& rhs) const { return !(*this > rhs); } + bool operator>=(const uint128_t& rhs) const { return !(*this < rhs); } +}; diff --git a/package.xml b/package.xml index d072bfb59..08e581581 100644 --- a/package.xml +++ b/package.xml @@ -22,16 +22,18 @@ https://github.com/Simple-Robotics/proxsuite https://github.com/Simple-Robotics/proxsuite/issues + python3-dev git doxygen + libcereal-dev + graphviz eigen - - simde - python-numpy - python3-numpy - python-scipy - python3-scipy + simde + python3-numpy + python3-scipy + matio + catch2 catkin diff --git a/pixi.lock b/pixi.lock new file mode 100644 index 000000000..d347aa9ff --- /dev/null +++ b/pixi.lock @@ -0,0 +1,6200 @@ +version: 6 +environments: + default: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/catch2-3.13.0-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cereal-1.3.2-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.3.1-hc85cc9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/eigen-5.0.1-hc65338a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.6-nompi_h19486de_108.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmatio-1.5.30-he0a2e19_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.4-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-2.12.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/simde-0.8.2-h84d6215_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + osx-64: + - conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.11.0-h7a00415_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/catch2-3.13.0-hebe015c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1030.6.3-llvm19_1_h67a6458_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm19_1_h7d82c7c_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm19_1_h8f0d4bb_4.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cereal-1.3.2-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19-19.1.7-default_h9399c5b_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19.1.7-default_h1323312_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-19.1.7-default_ha1a018a_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-19.1.7-h8a78ed7_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-19.1.7-default_h9089c59_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-19.1.7-default_ha1a018a_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-19.1.7-h8a78ed7_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-4.3.1-h2426fb6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-19.1.7-he914875_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-19.1.7-h138dee1_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.11.0-h307afc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/eigen-5.0.1-h4ff50a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.6-nompi_h13accda_108.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-956.6-llvm19_1_hc3792c1_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-956.6-llvm19_1_hcae3351_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.5-he7c3a48_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-6_he492b99_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-6_h9b27e0a_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp19.1-19.1.7-default_h9399c5b_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-19.1.7-h7c275be_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-6_h859234e_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm19-19.1.7-h56e7563_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmatio-1.5.30-h0881fde_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.32-openmp_h9e49c7b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.2-h0d3cbff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19-19.1.7-h879f4bc_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19.1.7-hb0207f0_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-2.12.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.3-py314h7b24d9b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.1-py314h5727af0_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/simde-0.8.2-h37c8870_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1600.0.11.8-h8d8e812_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/catch2-3.13.0-h3feff0a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cereal-1.3.2-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.3.1-h8cb302d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/eigen-5.0.1-h44d0d2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.6-nompi_had3affe_108.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.5-h8664d51_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-6_h51639a9_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-6_hb0561ab_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-6_hd9741b5_openblas.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmatio-1.5.30-h8eade5c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657e61_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.2-hc7d1edf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-2.12.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.3-py314h1569ea8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/simde-0.8.2-h7b3277c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.3-haa4e116_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/catch2-3.13.0-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ccache-4.13.2-h7fd822b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/cereal-1.3.2-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.3.1-hdcbee5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/eigen-5.0.1-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.6-nompi_hae35d4c_108.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.5-haf901d7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-6_hf2e6a31_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a3cdd5_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhiredis-1.3.0-he0c23c2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hf9ab0e9_mkl.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmatio-1.5.30-hbeb426f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.2-h4fa8253_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.1-hac47afa_11.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-2.12.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.3-py314h02f10f6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py314h221f224_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/simde-0.8.2-hc790b64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xxhash-0.8.3-hbba6f48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + doc: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/adwaita-icon-theme-49.0-unix_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-atk-2.38.0-h0630a04_3.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-core-2.40.3-h0630a04_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.3.1-hc85cc9f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/eigen-5.0.1-hc65338a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/epoxy-1.5.10-hb03c661_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.44.6-h2b0a6b4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-14.1.2-h8b86629_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gtk3-3.24.52-ha5ea40c_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/hicolor-icon-theme-0.17-ha770c72_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-h5fbf134_12.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.62.1-h4c96295_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.4-h5347b49_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/simde-0.8.2-h84d6215_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxinerama-1.1.6-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + osx-64: + - conda: https://conda.anaconda.org/conda-forge/noarch/adwaita-icon-theme-49.0-unix_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/atk-1.0-2.38.0-h4bec284_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.11.0-h7a00415_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.18.4-h7656bdc_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1030.6.3-llvm19_1_h67a6458_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm19_1_h7d82c7c_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm19_1_h8f0d4bb_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19-19.1.7-default_h9399c5b_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19.1.7-default_h1323312_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-19.1.7-default_ha1a018a_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-19.1.7-h8a78ed7_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-19.1.7-default_h9089c59_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-19.1.7-default_ha1a018a_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-19.1.7-h8a78ed7_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-4.3.1-h2426fb6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-19.1.7-he914875_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-19.1.7-h138dee1_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.11.0-h307afc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/doxygen-1.13.2-h27064b9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/eigen-5.0.1-h4ff50a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/epoxy-1.5.10-h8616949_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.17.1-h7a4440b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fribidi-1.0.16-h8616949_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.44.6-hae309b2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.86.4-h8501676_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/graphite2-1.3.14-h21dd04a_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/graphviz-14.1.2-h44fc223_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gtk3-3.24.52-hf2d442a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gts-0.7.6-h53e17e3_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-13.2.1-hf0bc557_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/hicolor-icon-theme-0.17-h694c41f_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-956.6-llvm19_1_hc3792c1_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-956.6-llvm19_1_hcae3351_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp19.1-19.1.7-default_h9399c5b_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-19.1.7-h7c275be_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libgd-2.3.3-hb2c11ec_12.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.4-hec30fc1_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm19-19.1.7-h56e7563_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.56-he930e7c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/librsvg-2.62.1-h7321050_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.2-h0d3cbff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19-19.1.7-h879f4bc_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19.1.7-hb0207f0_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pango-1.56.4-hf280016_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pixman-0.46.4-ha059160_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/simde-0.8.2-h37c8870_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1600.0.11.8-h8d8e812_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/noarch/adwaita-icon-theme-49.0-unix_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.18.4-he0f2337_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.3.1-h8cb302d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/doxygen-1.13.2-h493aca8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/eigen-5.0.1-h44d0d2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/epoxy-1.5.10-hc919400_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.17.1-h2b252f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fribidi-1.0.16-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.44.6-h4e57454_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.86.4-h60c1bae_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphite2-1.3.14-hec049ff_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-14.1.2-hec8c438_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtk3-3.24.52-hc0f3e19_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gts-0.7.6-he42f4ea_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-13.2.1-h3103d1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hicolor-icon-theme-0.17-hce30654_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.1.0-h1eee2c3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgd-2.3.3-h05bcc79_12.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.4-he378b5c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.56-h132b30e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.62.1-he8aa2a2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.2-hc7d1edf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.56.4-hf80efc4_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pixman-0.46.4-h81086ad_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/simde-0.8.2-h7b3277c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.3-haa4e116_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ccache-4.13.2-h7fd822b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.3.1-hdcbee5b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/doxygen-1.13.2-hbf3f430_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/eigen-5.0.1-h5112557_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/getopt-win32-0.1-h6a83c73_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-14.1.2-h4c50273_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gts-0.7.6-h6b5321d_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.1-h5a1b470_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgd-2.3.3-h4974f7c_12.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libhiredis-1.3.0-he0c23c2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.56-h7351971_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/simde-0.8.2-hc790b64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libice-1.1.2-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libsm-1.2.6-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libx11-1.8.13-hfa52320_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxext-1.3.7-hba3369d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxpm-3.5.18-hba3369d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxt-1.3.1-h0e40799_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/xxhash-0.8.3-hbba6f48_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + prek: + channels: + - url: https://conda.anaconda.org/conda-forge/ + options: + pypi-prerelease-mode: if-necessary-or-explicit + packages: + linux-64: + - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/prek-0.3.8-hb17b654_0.conda + osx-64: + - conda: https://conda.anaconda.org/conda-forge/osx-64/prek-0.3.8-h19f9e61_0.conda + osx-arm64: + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/prek-0.3.8-h6fdd925_0.conda + win-64: + - conda: https://conda.anaconda.org/conda-forge/win-64/prek-0.3.8-h18a1a76_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda +packages: +- conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 1dd3fffd892081df9726d7eb7e0dea6198962ba775bd88842135a4ddb4deb3c9 + md5: a9f577daf3de00bca7c3c76c0ecbd1de + depends: + - __glibc >=2.17,<3.0.a0 + - libgomp >=7.5.0 + constrains: + - openmp_impl <0.0a0 + license: BSD-3-Clause + license_family: BSD + size: 28948 + timestamp: 1770939786096 +- conda: https://conda.anaconda.org/conda-forge/osx-64/_openmp_mutex-4.5-7_kmp_llvm.conda + build_number: 7 + sha256: 30006902a9274de8abdad5a9f02ef7c8bb3d69a503486af0c1faee30b023e5b7 + md5: eaac87c21aff3ed21ad9656697bb8326 + depends: + - llvm-openmp >=9.0.1 + license: BSD-3-Clause + license_family: BSD + size: 8328 + timestamp: 1764092562779 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/_openmp_mutex-4.5-7_kmp_llvm.conda + build_number: 7 + sha256: 7acaa2e0782cad032bdaf756b536874346ac1375745fb250e9bdd6a48a7ab3cd + md5: a44032f282e7d2acdeb1c240308052dd + depends: + - llvm-openmp >=9.0.1 + license: BSD-3-Clause + license_family: BSD + size: 8325 + timestamp: 1764092507920 +- conda: https://conda.anaconda.org/conda-forge/win-64/_openmp_mutex-4.5-20_gnu.conda + build_number: 20 + sha256: 8a1cee28bd0ee7451ada1cd50b64720e57e17ff994fc62dd8329bef570d382e4 + md5: 1626967b574d1784b578b52eaeb071e7 + depends: + - libgomp >=7.5.0 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - openmp_impl <0.0a0 + - msys2-conda-epoch <0.0a0 + license: BSD-3-Clause + license_family: BSD + size: 52252 + timestamp: 1770943776666 +- conda: https://conda.anaconda.org/conda-forge/noarch/adwaita-icon-theme-49.0-unix_0.conda + sha256: a362b4f5c96a0bf4def96be1a77317e2730af38915eb9bec85e2a92836501ed7 + md5: b3f0179590f3c0637b7eb5309898f79e + depends: + - __unix + - hicolor-icon-theme + - librsvg + license: LGPL-3.0-or-later OR CC-BY-SA-3.0 + license_family: LGPL + size: 631452 + timestamp: 1758743294412 +- conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-atk-2.38.0-h0630a04_3.tar.bz2 + sha256: 26ab9386e80bf196e51ebe005da77d57decf6d989b4f34d96130560bc133479c + md5: 6b889f174df1e0f816276ae69281af4d + depends: + - at-spi2-core >=2.40.0,<2.41.0a0 + - atk-1.0 >=2.36.0 + - dbus >=1.13.6,<2.0a0 + - libgcc-ng >=9.3.0 + - libglib >=2.68.1,<3.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + size: 339899 + timestamp: 1619122953439 +- conda: https://conda.anaconda.org/conda-forge/linux-64/at-spi2-core-2.40.3-h0630a04_0.tar.bz2 + sha256: c4f9b66bd94c40d8f1ce1fad2d8b46534bdefda0c86e3337b28f6c25779f258d + md5: 8cb2fc4cd6cc63f1369cfa318f581cc3 + depends: + - dbus >=1.13.6,<2.0a0 + - libgcc-ng >=9.3.0 + - libglib >=2.68.3,<3.0a0 + - xorg-libx11 + - xorg-libxi + - xorg-libxtst + license: LGPL-2.1-or-later + license_family: LGPL + size: 658390 + timestamp: 1625848454791 +- conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda + sha256: df682395d05050cd1222740a42a551281210726a67447e5258968dd55854302e + md5: f730d54ba9cd543666d7220c9f7ed563 + depends: + - libgcc-ng >=12 + - libglib >=2.80.0,<3.0a0 + - libstdcxx-ng >=12 + constrains: + - atk-1.0 2.38.0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 355900 + timestamp: 1713896169874 +- conda: https://conda.anaconda.org/conda-forge/osx-64/atk-1.0-2.38.0-h4bec284_2.conda + sha256: a5972a943764e46478c966b26be61de70dcd7d0cfda4bd0b0c46916ae32e0492 + md5: d9684247c943d492d9aac8687bc5db77 + depends: + - __osx >=10.9 + - libcxx >=16 + - libglib >=2.80.0,<3.0a0 + - libintl >=0.22.5,<1.0a0 + constrains: + - atk-1.0 2.38.0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 349989 + timestamp: 1713896423623 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda + sha256: b0747f9b1bc03d1932b4d8c586f39a35ac97e7e72fe6e63f2b2a2472d466f3c1 + md5: 57301986d02d30d6805fdce6c99074ee + depends: + - __osx >=11.0 + - libcxx >=16 + - libglib >=2.80.0,<3.0a0 + - libintl >=0.22.5,<1.0a0 + constrains: + - atk-1.0 2.38.0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 347530 + timestamp: 1713896411580 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils-2.45.1-default_h4852527_102.conda + sha256: 3c7c5580c1720206f28b7fa3d60d17986b3f32465e63009c14c9ae1ea64f926c + md5: 212fe5f1067445544c99dc1c847d032c + depends: + - binutils_impl_linux-64 >=2.45.1,<2.45.2.0a0 + license: GPL-3.0-only + license_family: GPL + size: 35436 + timestamp: 1774197482571 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_impl_linux-64-2.45.1-default_hfdba357_102.conda + sha256: 0a7d405064f53b9d91d92515f1460f7906ee5e8523f3cd8973430e81219f4917 + md5: 8165352fdce2d2025bf884dc0ee85700 + depends: + - ld_impl_linux-64 2.45.1 default_hbd61a6d_102 + - sysroot_linux-64 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + size: 3661455 + timestamp: 1774197460085 +- conda: https://conda.anaconda.org/conda-forge/linux-64/binutils_linux-64-2.45.1-default_h4852527_102.conda + sha256: 78a58d523d072b7f8e591b8f8572822e044b31764ed7e8d170392e7bc6d58339 + md5: 2a307a17309d358c9b42afdd3199ddcc + depends: + - binutils_impl_linux-64 2.45.1 default_hfdba357_102 + license: GPL-3.0-only + license_family: GPL + size: 36304 + timestamp: 1774197485247 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda + sha256: 0b75d45f0bba3e95dc693336fa51f40ea28c980131fec438afb7ce6118ed05f6 + md5: d2ffd7602c02f2b316fd921d39876885 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: bzip2-1.0.6 + license_family: BSD + size: 260182 + timestamp: 1771350215188 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_9.conda + sha256: 9f242f13537ef1ce195f93f0cc162965d6cc79da578568d6d8e50f70dd025c42 + md5: 4173ac3b19ec0a4f400b4f782910368b + depends: + - __osx >=10.13 + license: bzip2-1.0.6 + license_family: BSD + size: 133427 + timestamp: 1771350680709 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda + sha256: 540fe54be35fac0c17feefbdc3e29725cce05d7367ffedfaaa1bdda234b019df + md5: 620b85a3f45526a8bc4d23fd78fc22f0 + depends: + - __osx >=11.0 + license: bzip2-1.0.6 + license_family: BSD + size: 124834 + timestamp: 1771350416561 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_9.conda + sha256: 76dfb71df5e8d1c4eded2dbb5ba15bb8fb2e2b0fe42d94145d5eed4c75c35902 + md5: 4cb8e6b48f67de0b018719cdf1136306 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: bzip2-1.0.6 + license_family: BSD + size: 56115 + timestamp: 1771350256444 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.34.6-hb03c661_0.conda + sha256: cc9accf72fa028d31c2a038460787751127317dcfa991f8d1f1babf216bb454e + md5: 920bb03579f15389b9e512095ad995b7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 207882 + timestamp: 1765214722852 +- conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.34.6-hb5e19a0_0.conda + sha256: 2f5bc0292d595399df0d168355b4e9820affc8036792d6984bd751fdda2bcaea + md5: fc9a153c57c9f070bebaa7eef30a8f17 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 186122 + timestamp: 1765215100384 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.34.6-hc919400_0.conda + sha256: 2995f2aed4e53725e5efbc28199b46bf311c3cab2648fc4f10c2227d6d5fa196 + md5: bcb3cba70cf1eec964a03b4ba7775f01 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 180327 + timestamp: 1765215064054 +- conda: https://conda.anaconda.org/conda-forge/linux-64/c-compiler-1.11.0-h4d9bdce_0.conda + sha256: 8e7a40f16400d7839c82581410aa05c1f8324a693c9d50079f8c50dc9fb241f0 + md5: abd85120de1187b0d1ec305c2173c71b + depends: + - binutils + - gcc + - gcc_linux-64 14.* + license: BSD-3-Clause + license_family: BSD + size: 6693 + timestamp: 1753098721814 +- conda: https://conda.anaconda.org/conda-forge/osx-64/c-compiler-1.11.0-h7a00415_0.conda + sha256: 2bd1cf3d26789b7e1d04e914ccd169bd618fceed68abf7b6a305266b88dcf861 + md5: 2b23ec416cef348192a5a17737ddee60 + depends: + - cctools >=949.0.1 + - clang_osx-64 19.* + - ld64 >=530 + - llvm-openmp + license: BSD-3-Clause + license_family: BSD + size: 6695 + timestamp: 1753098825695 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-compiler-1.11.0-h61f9b84_0.conda + sha256: b51bd1551cfdf41500f732b4bd1e4e70fb1e74557165804a648f32fa9c671eec + md5: 148516e0c9edf4e9331a4d53ae806a9b + depends: + - cctools >=949.0.1 + - clang_osx-arm64 19.* + - ld64 >=530 + - llvm-openmp + license: BSD-3-Clause + license_family: BSD + size: 6697 + timestamp: 1753098737760 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-h4c7d964_0.conda + sha256: 37950019c59b99585cee5d30dbc2cc9696ed4e11f5742606a4db1621ed8f94d6 + md5: f001e6e220355b7f87403a4d0e5bf1ca + depends: + - __win + license: ISC + size: 147734 + timestamp: 1772006322223 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda + sha256: 67cc7101b36421c5913a1687ef1b99f85b5d6868da3abbf6ec1a4181e79782fc + md5: 4492fd26db29495f0ba23f146cd5638d + depends: + - __unix + license: ISC + size: 147413 + timestamp: 1772006283803 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.4-he90730b_1.conda + sha256: 06525fa0c4e4f56e771a3b986d0fdf0f0fc5a3270830ee47e127a5105bde1b9a + md5: bb6c4808bfa69d6f7f6b07e5846ced37 + depends: + - __glibc >=2.17,<3.0.a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libgcc >=14 + - libglib >=2.86.3,<3.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libstdcxx >=14 + - libxcb >=1.17.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.46.4,<1.0a0 + - xorg-libice >=1.1.2,<2.0a0 + - xorg-libsm >=1.2.6,<2.0a0 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: LGPL-2.1-only or MPL-1.1 + size: 989514 + timestamp: 1766415934926 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.18.4-h7656bdc_1.conda + sha256: 88e7e1efb6a0f6b1477e617338e0ed3d27d4572a3283f8341ce6143b7118e31a + md5: 9917add2ab43df894b9bb6f5bf485975 + depends: + - __osx >=10.13 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libcxx >=19 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libglib >=2.86.3,<3.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.46.4,<1.0a0 + license: LGPL-2.1-only or MPL-1.1 + size: 896676 + timestamp: 1766416262450 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.18.4-he0f2337_1.conda + sha256: cde9b79ee206fe3ba6ca2dc5906593fb7a1350515f85b2a1135a4ce8ec1539e3 + md5: 36200ecfbbfbcb82063c87725434161f + depends: + - __osx >=11.0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libcxx >=19 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libglib >=2.86.3,<3.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.46.4,<1.0a0 + license: LGPL-2.1-only or MPL-1.1 + size: 900035 + timestamp: 1766416416791 +- conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.4-h477c42c_1.conda + sha256: 9ee4ad706c5d3e1c6c469785d60e3c2b263eec569be0eac7be33fbaef978bccc + md5: 52ea1beba35b69852d210242dd20f97d + depends: + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libglib >=2.86.3,<3.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - pixman >=0.46.4,<1.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only or MPL-1.1 + size: 1537783 + timestamp: 1766416059188 +- conda: https://conda.anaconda.org/conda-forge/linux-64/catch2-3.13.0-h171cf75_0.conda + sha256: 885f8ad08af2e1a8fc5a7ae1236cd0866c7f5d941865fab37b103b47c11424cc + md5: 6df8e1de9b8f4080857b73935c4c5e29 + depends: + - __glibc >=2.17,<3.0.a0 + - libstdcxx >=14 + - libgcc >=14 + license: BSL-1.0 + size: 649968 + timestamp: 1771213420340 +- conda: https://conda.anaconda.org/conda-forge/osx-64/catch2-3.13.0-hebe015c_0.conda + sha256: 11be80e73601ee6af36053a79b3c72cb5a8282bd8126e623bd49c17b29ddccc9 + md5: 5845259ac24bb6af89b1c0d6219d9876 + depends: + - __osx >=11.0 + - libcxx >=19 + license: BSL-1.0 + size: 524822 + timestamp: 1771213553177 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/catch2-3.13.0-h3feff0a_0.conda + sha256: 8efbf22c29f278100602af0dc502a221b3a4b1b9467ec94b5a4f4fe70a5fd99c + md5: 4ec5a7249e90c05fb1433da2934e217c + depends: + - libcxx >=19 + - __osx >=11.0 + license: BSL-1.0 + size: 506741 + timestamp: 1771213507303 +- conda: https://conda.anaconda.org/conda-forge/win-64/catch2-3.13.0-h477610d_0.conda + sha256: 5044286b28542cc7c7d917fcb495e92ce3ccf5d9e2f2cdb72ef6b1afb623d2bd + md5: a21989a9a6611d751f77f69aff55cbfb + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: BSL-1.0 + size: 1007978 + timestamp: 1771213425993 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ccache-4.13.2-hedf47ba_0.conda + sha256: ec94ed03d2d7b7ea7f0ffc7df347808e9762d1ea8bc33f990901491956efd69c + md5: 49346bc551d07c6940e811a1f93ba373 + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libhiredis >=1.3.0,<1.4.0a0 + - xxhash >=0.8.3,<0.8.4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + size: 847826 + timestamp: 1774189203440 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ccache-4.13.2-h894318c_0.conda + sha256: 2b00e119f7c194ffdf7d2ec239dfb0a2bb584db1762bce5539edb783358a58ff + md5: e77ab67215939f46bb6ec8226a242e6a + depends: + - __osx >=11.0 + - libcxx >=19 + - libhiredis >=1.3.0,<1.4.0a0 + - xxhash >=0.8.3,<0.8.4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + size: 654530 + timestamp: 1774189372899 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ccache-4.13.2-h414bf82_0.conda + sha256: d9547c2cb6963f7763eb8910724d5c843d1bb7af4b1b8c54023d87d946cc7880 + md5: baeca21071729b617b20b019f85beedf + depends: + - __osx >=11.0 + - libcxx >=19 + - zstd >=1.5.7,<1.6.0a0 + - xxhash >=0.8.3,<0.8.4.0a0 + - libhiredis >=1.3.0,<1.4.0a0 + license: GPL-3.0-only + license_family: GPL + size: 598937 + timestamp: 1774189390770 +- conda: https://conda.anaconda.org/conda-forge/win-64/ccache-4.13.2-h7fd822b_0.conda + sha256: fd5928b70b952595b89ce730d7444a1f3ed4ba0bd1520b1470e5663023c934f6 + md5: 9e4446307f83246c5889911f2b89a202 + depends: + - ucrt + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libhiredis >=1.3.0,<1.4.0a0 + - xxhash >=0.8.3,<0.8.4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: GPL-3.0-only + license_family: GPL + size: 689752 + timestamp: 1774189255514 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools-1030.6.3-llvm19_1_h67a6458_4.conda + sha256: 0563fb193edde8002059e1a7fc32b23b5bd48389d9abdf5e49ff81e7490da722 + md5: 7b4852df7d4ed4e45bcb70c5d4b08cd0 + depends: + - cctools_impl_osx-64 1030.6.3 llvm19_1_h7d82c7c_4 + - ld64 956.6 llvm19_1_hc3792c1_4 + - libllvm19 >=19.1.7,<19.2.0a0 + license: APSL-2.0 + license_family: Other + size: 24262 + timestamp: 1768852850946 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools-1030.6.3-llvm19_1_hd01ab73_4.conda + sha256: 4f408036b5175be0d2c7940250d00dae5ea7a71d194a1ffb35881fb9df6211fc + md5: caf7c8e48827c2ad0c402716159fe0a2 + depends: + - cctools_impl_osx-arm64 1030.6.3 llvm19_1_he8a363d_4 + - ld64 956.6 llvm19_1_he86490a_4 + - libllvm19 >=19.1.7,<19.2.0a0 + license: APSL-2.0 + license_family: Other + size: 24313 + timestamp: 1768852906882 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_impl_osx-64-1030.6.3-llvm19_1_h7d82c7c_4.conda + sha256: 43928e68f59a8e4135d20df702cf97073b07a162979a30258d93f6e44b1220db + md5: bb274e464cf9479e0a6da2cf2e33bc16 + depends: + - __osx >=10.13 + - ld64_osx-64 >=956.6,<956.7.0a0 + - libcxx + - libllvm19 >=19.1.7,<19.2.0a0 + - libzlib >=1.3.1,<2.0a0 + - llvm-tools 19.1.* + - sigtool-codesign + constrains: + - cctools 1030.6.3.* + - clang 19.1.* + - ld64 956.6.* + license: APSL-2.0 + license_family: Other + size: 745672 + timestamp: 1768852809822 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_impl_osx-arm64-1030.6.3-llvm19_1_he8a363d_4.conda + sha256: c444442e0c01de92a75b58718a100f2e272649658d4f3dd915bbfc2316b25638 + md5: 76c651b923e048f3f3e0ecb22c966f70 + depends: + - __osx >=11.0 + - ld64_osx-arm64 >=956.6,<956.7.0a0 + - libcxx + - libllvm19 >=19.1.7,<19.2.0a0 + - libzlib >=1.3.1,<2.0a0 + - llvm-tools 19.1.* + - sigtool-codesign + constrains: + - ld64 956.6.* + - cctools 1030.6.3.* + - clang 19.1.* + license: APSL-2.0 + license_family: Other + size: 749918 + timestamp: 1768852866532 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cctools_osx-64-1030.6.3-llvm19_1_h8f0d4bb_4.conda + sha256: 258f7bde2b5f664f60130d0066f5cee96a308d946e95bacc82b44b76c776124a + md5: fdef8a054844f72a107dfd888331f4a7 + depends: + - cctools_impl_osx-64 1030.6.3 llvm19_1_h7d82c7c_4 + - ld64_osx-64 956.6 llvm19_1_hcae3351_4 + constrains: + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + size: 23193 + timestamp: 1768852854819 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cctools_osx-arm64-1030.6.3-llvm19_1_hd01ab73_4.conda + sha256: 684a19ab44f3d32c668cf1f509bbac20b10f7e9990c7449a2739930915cda8b4 + md5: 0d059c5db9d880ff37b2da53bf06509e + depends: + - cctools_impl_osx-arm64 1030.6.3 llvm19_1_he8a363d_4 + - ld64_osx-arm64 956.6 llvm19_1_ha2625f7_4 + constrains: + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + size: 23429 + timestamp: 1772019026855 +- conda: https://conda.anaconda.org/conda-forge/noarch/cereal-1.3.2-hd8ed1ab_1.conda + sha256: c32c97e0238aa0a9c480ca2cdffbbe1d898298f4e50ec19b21df87ebf3ad12f2 + md5: 78be8886fc8b989bd9f2a805a3ceca8f + license: BSD-3-Clause + license_family: BSD + size: 203811 + timestamp: 1770054823665 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19.1.7-default_h1323312_8.conda + sha256: 100109bf7837298607f53121f102ed8acc5efb15af6a3f2bc4e199a429c60e6b + md5: fd53f2ec0db69ed874d9ce2b75662633 + depends: + - cctools + - clang-19 19.1.7.* default_* + - clang_impl_osx-64 19.1.7 default_ha1a018a_8 + - ld64 + - ld64_osx-64 * llvm19_1_* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24757 + timestamp: 1772399655792 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19.1.7-default_hf9bcbb7_8.conda + sha256: 964330d0d03a670e442ef73038c576f0837c5f5f4101f29f7c72dca5fe2a98bd + md5: ededa5c4f241dad0a7ebc99bb11e5dbb + depends: + - cctools + - clang-19 19.1.7.* default_* + - clang_impl_osx-arm64 19.1.7 default_hc11f16d_8 + - ld64 + - ld64_osx-arm64 * llvm19_1_* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24838 + timestamp: 1772400473621 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clang-19-19.1.7-default_h9399c5b_8.conda + sha256: ac3b9d1903f74d44698efb0f93101118e24dacf52f635d5d0a4f65df4484e416 + md5: f3f31a8c3982f9a4c077842b5178cc3c + depends: + - __osx >=11.0 + - libclang-cpp19.1 19.1.7 default_h9399c5b_8 + - libcxx >=19.1.7 + - libllvm19 >=19.1.7,<19.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 763378 + timestamp: 1772399381782 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang-19-19.1.7-default_hf3020a7_8.conda + sha256: 99dbb100804eba42e57903b64f41948d0ff0dbbc05190d4c5349df39d81b6c9c + md5: 06c1a0f7eb6c393e16cc99e280784b36 + depends: + - __osx >=11.0 + - libclang-cpp19.1 19.1.7 default_hf3020a7_8 + - libcxx >=19.1.7 + - libllvm19 >=19.1.7,<19.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 765865 + timestamp: 1772400229152 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_impl_osx-64-19.1.7-default_ha1a018a_8.conda + sha256: 02d729505c073204dd34df5c3bfaca34e34ecef773550cc119e6089b44b3af89 + md5: 1895f622944c8c344ff73f42e2a6d034 + depends: + - cctools_impl_osx-64 + - clang-19 19.1.7.* default_* + - compiler-rt 19.1.7.* + - compiler-rt_osx-64 + - ld64_osx-64 * llvm19_1_* + - llvm-openmp >=19.1.7 + - llvm-tools 19.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24787 + timestamp: 1772399633552 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + sha256: e1f90ba9eeb6814309f5ae84fc2838c1aef04ae731e7ce58f5444b1307fea984 + md5: 6bee2e04d81e5023286770ef6b56e146 + depends: + - cctools_impl_osx-arm64 + - clang-19 19.1.7.* default_* + - compiler-rt 19.1.7.* + - compiler-rt_osx-arm64 + - ld64_osx-arm64 * llvm19_1_* + - llvm-openmp >=19.1.7 + - llvm-tools 19.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24744 + timestamp: 1772400450288 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clang_osx-64-19.1.7-h8a78ed7_31.conda + sha256: aa12658e55300efcdc34010312ee62d350464ae0ae8c30d1f7340153c9baa5aa + md5: faf4b6245c4287a4f13e793ca2826842 + depends: + - cctools_osx-64 + - clang 19.* + - clang_impl_osx-64 19.1.7.* + - sdkroot_env_osx-64 + license: BSD-3-Clause + license_family: BSD + size: 21157 + timestamp: 1769482965411 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clang_osx-arm64-19.1.7-h75f8d18_31.conda + sha256: c9daaa0e7785fe7c5799e3d691c6aa5ab8b4a54bbf49835037068dd78e0a7b35 + md5: 6645630920c0980a33f055a49fbdb88e + depends: + - cctools_osx-arm64 + - clang 19.* + - clang_impl_osx-arm64 19.1.7.* + - sdkroot_env_osx-arm64 + license: BSD-3-Clause + license_family: BSD + size: 21135 + timestamp: 1769482854554 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx-19.1.7-default_h9089c59_8.conda + sha256: d3d4ebd917a17f3da9a9f7538dc6b225a2600538d63b6cd17dec89a77003e3d6 + md5: 9fa35b03d31d125cd8db1f268d6bfea2 + depends: + - clang 19.1.7 default_h1323312_8 + - clangxx_impl_osx-64 19.1.7.* default_* + - libcxx-devel 19.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24771 + timestamp: 1772399976038 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx-19.1.7-default_hc995acf_8.conda + sha256: 441ce0b390fe1cb945fcd3db40f97a8ddbc9543895dd07a109e27dd431a5d6b1 + md5: 5ec2b8416b3a6af3650f9bb3984ba439 + depends: + - clang 19.1.7 default_hf9bcbb7_8 + - clangxx_impl_osx-arm64 19.1.7.* default_* + - libcxx-devel 19.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24759 + timestamp: 1772400631747 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_impl_osx-64-19.1.7-default_ha1a018a_8.conda + sha256: 7ad39ca7ea2a64ac421e0170d53762cfaa3013f087d31d8bccfacc2d60297c93 + md5: 812549bdef1d523452d711c166382d1b + depends: + - clang-19 19.1.7.* default_* + - clang_impl_osx-64 19.1.7 default_ha1a018a_8 + - libcxx-devel 19.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24697 + timestamp: 1772399933168 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_impl_osx-arm64-19.1.7-default_hc11f16d_8.conda + sha256: fd8404e75e6863de75ce1ab84f22222dd19b9a4c1b314196d3bfb5336028741c + md5: c5d2fcbd218812e18feb9f60a04359e3 + depends: + - clang-19 19.1.7.* default_* + - clang_impl_osx-arm64 19.1.7 default_hc11f16d_8 + - libcxx-devel 19.1.* + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 24702 + timestamp: 1772400609414 +- conda: https://conda.anaconda.org/conda-forge/osx-64/clangxx_osx-64-19.1.7-h8a78ed7_31.conda + sha256: 308df8233f2a7a258e6441fb02553a1b5a54afe5e93d63b016dd9c0f1d28d5ab + md5: c3b46b5d6cd2a6d1f12b870b2c69aed4 + depends: + - cctools_osx-64 + - clang_osx-64 19.1.7 h8a78ed7_31 + - clangxx 19.* + - clangxx_impl_osx-64 19.1.7.* + - sdkroot_env_osx-64 + license: BSD-3-Clause + license_family: BSD + size: 19974 + timestamp: 1769482973715 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/clangxx_osx-arm64-19.1.7-h75f8d18_31.conda + sha256: f3a81f8e5451377d2b84a31f4a4e305cb92f5a4c4ba0126e7d1a3cfa4d66bf47 + md5: bd6926e81dc196064373b614af3bc9ff + depends: + - cctools_osx-arm64 + - clang_osx-arm64 19.1.7 h75f8d18_31 + - clangxx 19.* + - clangxx_impl_osx-arm64 19.1.7.* + - sdkroot_env_osx-arm64 + license: BSD-3-Clause + license_family: BSD + size: 19914 + timestamp: 1769482862579 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cmake-4.3.1-hc85cc9f_0.conda + sha256: 8ff9f2c159c55ea2b920c4ea41f39cd3b9ecf86b218a377f2941cb1c8b534741 + md5: 0f753e779c0fee33c84ed1a110c0cb4a + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libexpat >=2.7.4,<3.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libstdcxx >=14 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 23093161 + timestamp: 1774645184037 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cmake-4.3.1-h2426fb6_0.conda + sha256: 623593da13ae0f2cd0aeef05344bfc665459e5340d5e9ef0c7acf116e43e84f3 + md5: e941ad268dd394c2e5420d12f36a5c50 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libcxx >=19 + - libexpat >=2.7.4,<3.0a0 + - liblzma >=5.8.2,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 19503666 + timestamp: 1774647328042 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cmake-4.3.1-h8cb302d_0.conda + sha256: 2f33e0157b553c752b609bc5907a537afe9c34f5b282abc1b03ffa898c8ac43e + md5: fdda7688fea2d343e8b73ab9be037501 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libcxx >=19 + - libexpat >=2.7.4,<3.0a0 + - liblzma >=5.8.2,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ncurses >=6.5,<7.0a0 + - rhash >=1.4.6,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 18158020 + timestamp: 1774647856214 +- conda: https://conda.anaconda.org/conda-forge/win-64/cmake-4.3.1-hdcbee5b_0.conda + sha256: f2ab8f116055dc97385db8b1cf04f9929d8038f88ab1af9103a536cdd4034b28 + md5: d5e76415788f7ed5ec619dc1f055cf2f + depends: + - bzip2 >=1.0.8,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libexpat >=2.7.4,<3.0a0 + - liblzma >=5.8.2,<6.0a0 + - libuv >=1.51.0,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: BSD-3-Clause + license_family: BSD + size: 16262043 + timestamp: 1774646510689 +- conda: https://conda.anaconda.org/conda-forge/osx-64/compiler-rt-19.1.7-he914875_1.conda + sha256: 28e5f0a6293acba68ebc54694a2fc40b1897202735e8e8cbaaa0e975ba7b235b + md5: e6b9e71e5cb08f9ed0185d31d33a074b + depends: + - __osx >=10.13 + - clang 19.1.7.* + - compiler-rt_osx-64 19.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 96722 + timestamp: 1757412473400 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/compiler-rt-19.1.7-h855ad52_1.conda + sha256: b58a481828aee699db7f28bfcbbe72fb133277ac60831dfe70ee2465541bcb93 + md5: 39451684370ae65667fa5c11222e43f7 + depends: + - __osx >=11.0 + - clang 19.1.7.* + - compiler-rt_osx-arm64 19.1.7.* + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 97085 + timestamp: 1757411887557 +- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-64-19.1.7-h138dee1_1.conda + sha256: e6effe89523fc6143819f7a68372b28bf0c176af5b050fe6cf75b62e9f6c6157 + md5: 32deecb68e11352deaa3235b709ddab2 + depends: + - clang 19.1.7.* + constrains: + - compiler-rt 19.1.7 + - clangxx 19.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 10425780 + timestamp: 1757412396490 +- conda: https://conda.anaconda.org/conda-forge/noarch/compiler-rt_osx-arm64-19.1.7-he32a8d3_1.conda + sha256: 8c32a3db8adf18ed58197e8895ce4f24a83ed63c817512b9a26724753b116f2a + md5: 8d99c82e0f5fed6cc36fcf66a11e03f0 + depends: + - clang 19.1.7.* + constrains: + - compiler-rt 19.1.7 + - clangxx 19.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: APACHE + size: 10490535 + timestamp: 1757411851093 +- conda: https://conda.anaconda.org/conda-forge/linux-64/conda-gcc-specs-14.3.0-he8ccf15_18.conda + sha256: b90ec0e6a9eb22f7240b3584fe785457cff961fec68d40e6aece5d596f9bbd9a + md5: 0e3e144115c43c9150d18fa20db5f31c + depends: + - gcc_impl_linux-64 >=14.3.0,<14.3.1.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 31705 + timestamp: 1771378159534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/cxx-compiler-1.11.0-hfcd1e18_0.conda + sha256: 3fcc97ae3e89c150401a50a4de58794ffc67b1ed0e1851468fcc376980201e25 + md5: 5da8c935dca9186673987f79cef0b2a5 + depends: + - c-compiler 1.11.0 h4d9bdce_0 + - gxx + - gxx_linux-64 14.* + license: BSD-3-Clause + license_family: BSD + size: 6635 + timestamp: 1753098722177 +- conda: https://conda.anaconda.org/conda-forge/osx-64/cxx-compiler-1.11.0-h307afc9_0.conda + sha256: d6976f8d8b51486072abfe1e76a733688380dcbd1a8e993a43d59b80f7288478 + md5: 463bb03bb27f9edc167fb3be224efe96 + depends: + - c-compiler 1.11.0 h7a00415_0 + - clangxx_osx-64 19.* + license: BSD-3-Clause + license_family: BSD + size: 6732 + timestamp: 1753098827160 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/cxx-compiler-1.11.0-h88570a1_0.conda + sha256: 99800d97a3a2ee9920dfc697b6d4c64e46dc7296c78b1b6c746ff1c24dea5e6c + md5: 043afed05ca5a0f2c18252ae4378bdee + depends: + - c-compiler 1.11.0 h61f9b84_0 + - clangxx_osx-arm64 19.* + license: BSD-3-Clause + license_family: BSD + size: 6715 + timestamp: 1753098739952 +- conda: https://conda.anaconda.org/conda-forge/win-64/cxx-compiler-1.11.0-h1c1089f_0.conda + sha256: c888f4fe9ec117c1c01bfaa4c722ca475ebbb341c92d1718afa088bb0d710619 + md5: 4d94d3c01add44dc9d24359edf447507 + depends: + - vs2022_win-64 + license: BSD-3-Clause + license_family: BSD + size: 6957 + timestamp: 1753098809481 +- conda: https://conda.anaconda.org/conda-forge/linux-64/dbus-1.16.2-h24cb091_1.conda + sha256: 8bb557af1b2b7983cf56292336a1a1853f26555d9c6cecf1e5b2b96838c9da87 + md5: ce96f2f470d39bd96ce03945af92e280 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - libglib >=2.86.2,<3.0a0 + - libexpat >=2.7.3,<3.0a0 + license: AFL-2.1 OR GPL-2.0-or-later + size: 447649 + timestamp: 1764536047944 +- conda: https://conda.anaconda.org/conda-forge/linux-64/doxygen-1.13.2-h8e693c7_0.conda + sha256: 349c4c872357b4a533e127b2ade8533796e8e062abc2cd685756a1a063ae1e35 + md5: 0869f41ea5c64643dd2f5b47f32709ca + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libiconv >=1.17,<2.0a0 + - libstdcxx >=13 + license: GPL-2.0-only + license_family: GPL + size: 13148627 + timestamp: 1738164137421 +- conda: https://conda.anaconda.org/conda-forge/osx-64/doxygen-1.13.2-h27064b9_0.conda + sha256: 3eae05a4e8453698a52a265455a7045c70570e312db82c0829d33c576471da08 + md5: c8504720e9ad1565788e8bf91bfb0aeb + depends: + - __osx >=10.13 + - libcxx >=18 + - libiconv >=1.17,<2.0a0 + license: GPL-2.0-only + license_family: GPL + size: 11693372 + timestamp: 1738164323712 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/doxygen-1.13.2-h493aca8_0.conda + sha256: 2327ad4e6214accc1e71aea371aee9b9fed864ec36c20f829fd1cb71d4c85202 + md5: 3f5795e9004521711fa3a586b65fde05 + depends: + - __osx >=11.0 + - libcxx >=18 + - libiconv >=1.17,<2.0a0 + license: GPL-2.0-only + license_family: GPL + size: 11260324 + timestamp: 1738164659 +- conda: https://conda.anaconda.org/conda-forge/win-64/doxygen-1.13.2-hbf3f430_0.conda + sha256: 7a0fd40fd704e97a8f6533a081ba29579766d7a60bcb8e5de76679b066c4a72e + md5: 5cb2e11931773612d7a24b53f0c57594 + depends: + - libiconv >=1.17,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: GPL-2.0-only + license_family: GPL + size: 9219343 + timestamp: 1738165042524 +- conda: https://conda.anaconda.org/conda-forge/linux-64/eigen-5.0.1-hc65338a_0.conda + sha256: f122c5bb618532eb40124f34dc3d467b9142c4a573c206e3e6a51df671345d6a + md5: fcc98d38ae074ee72ee9152e357bcbf2 + license: MPL-2.0 + license_family: MOZILLA + size: 1311364 + timestamp: 1773744756289 +- conda: https://conda.anaconda.org/conda-forge/osx-64/eigen-5.0.1-h4ff50a2_0.conda + sha256: d601646c6cbda53490da0db7c4e81ae63def251d269d4076f71d6f537cc0b8e7 + md5: 95c378e3b4d95560f8cb43e97657f957 + license: MPL-2.0 + license_family: MOZILLA + size: 1313286 + timestamp: 1773745053527 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/eigen-5.0.1-h44d0d2d_0.conda + sha256: 078a5e52e3a845585b39ad441db4445a61eb033ab272991351bfbf722dcb1a72 + md5: 56a644c825e7ea8da0866fcc016190f3 + license: MPL-2.0 + license_family: MOZILLA + size: 1314362 + timestamp: 1773744888755 +- conda: https://conda.anaconda.org/conda-forge/win-64/eigen-5.0.1-h5112557_0.conda + sha256: a99c0cc584abb5bb4f0279ec1566cd63a4f943244b3cfdb0064b94eb37a80104 + md5: 0580baa22b9e354b61529f59b10ef651 + license: MPL-2.0 + license_family: MOZILLA + size: 1308183 + timestamp: 1773744771265 +- conda: https://conda.anaconda.org/conda-forge/linux-64/epoxy-1.5.10-hb03c661_2.conda + sha256: a5b51e491fec22bcc1765f5b2c8fff8a97428e9a5a7ee6730095fb9d091b0747 + md5: 057083b06ccf1c2778344b6dabace38b + depends: + - __glibc >=2.17,<3.0.a0 + - libdrm >=2.4.125,<2.5.0a0 + - libegl >=1.7.0,<2.0a0 + - libegl-devel + - libgcc >=14 + - libgl >=1.7.0,<2.0a0 + - libgl-devel + - libglx >=1.7.0,<2.0a0 + - libglx-devel + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxdamage >=1.1.6,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + - xorg-libxxf86vm >=1.1.6,<2.0a0 + license: MIT + license_family: MIT + size: 411735 + timestamp: 1758743520805 +- conda: https://conda.anaconda.org/conda-forge/osx-64/epoxy-1.5.10-h8616949_2.conda + sha256: d5c466bddf423a788ce5c39af20af41ebaf3de9dc9e807098fc9bf45c3c7db45 + md5: efe7fa6c60b20cb0a3a22e8c3e7b721e + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 283016 + timestamp: 1758743470535 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/epoxy-1.5.10-hc919400_2.conda + sha256: ba685b87529c95a4bf9de140a33d703d57dc46b036e9586ed26890de65c1c0d5 + md5: 3b87dabebe54c6d66a07b97b53ac5874 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 296347 + timestamp: 1758743805063 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-dejavu-sans-mono-2.37-hab24e00_0.tar.bz2 + sha256: 58d7f40d2940dd0a8aa28651239adbf5613254df0f75789919c4e6762054403b + md5: 0c96522c6bdaed4b1566d11387caaf45 + license: BSD-3-Clause + license_family: BSD + size: 397370 + timestamp: 1566932522327 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-inconsolata-3.000-h77eed37_0.tar.bz2 + sha256: c52a29fdac682c20d252facc50f01e7c2e7ceac52aa9817aaf0bb83f7559ec5c + md5: 34893075a5c9e55cdafac56607368fc6 + license: OFL-1.1 + license_family: Other + size: 96530 + timestamp: 1620479909603 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-source-code-pro-2.038-h77eed37_0.tar.bz2 + sha256: 00925c8c055a2275614b4d983e1df637245e19058d79fc7dd1a93b8d9fb4b139 + md5: 4d59c254e01d9cde7957100457e2d5fb + license: OFL-1.1 + license_family: Other + size: 700814 + timestamp: 1620479612257 +- conda: https://conda.anaconda.org/conda-forge/noarch/font-ttf-ubuntu-0.83-h77eed37_3.conda + sha256: 2821ec1dc454bd8b9a31d0ed22a7ce22422c0aef163c59f49dfdf915d0f0ca14 + md5: 49023d73832ef61042f6a237cb2687e7 + license: LicenseRef-Ubuntu-Font-Licence-Version-1.0 + license_family: Other + size: 1620504 + timestamp: 1727511233259 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.17.1-h27c8c51_0.conda + sha256: aa4a44dba97151221100a637c7f4bde619567afade9c0265f8e1c8eed8d7bd8c + md5: 867127763fbe935bab59815b6e0b7b5c + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libgcc >=14 + - libuuid >=2.41.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 270705 + timestamp: 1771382710863 +- conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.17.1-h7a4440b_0.conda + sha256: a972a114e618891bb50e50d8b13f5accb0085847f3aab1cf208e4552c1ab9c24 + md5: 4646a20e8bbb54903d6b8e631ceb550d + depends: + - __osx >=11.0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 237866 + timestamp: 1771382969241 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.17.1-h2b252f5_0.conda + sha256: 851e9c778bfc54645dcab7038c0383445cbebf16f6bb2d3f62ce422b1605385a + md5: d06ae1a11b46cc4c74177ecd28de7c7a + depends: + - __osx >=11.0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 237308 + timestamp: 1771382999247 +- conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.17.1-hd47e2ca_0.conda + sha256: ff2db9d305711854de430f946dc59bd40167940a1de38db29c5a78659f219d9c + md5: a0b1b87e871011ca3b783bbf410bc39f + depends: + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 195332 + timestamp: 1771382820659 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 + sha256: a997f2f1921bb9c9d76e6fa2f6b408b7fa549edd349a77639c9fe7a23ea93e61 + md5: fee5683a3f04bd15cbd8318b096a27ab + depends: + - fonts-conda-forge + license: BSD-3-Clause + license_family: BSD + size: 3667 + timestamp: 1566974674465 +- conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-hc364b38_1.conda + sha256: 54eea8469786bc2291cc40bca5f46438d3e062a399e8f53f013b6a9f50e98333 + md5: a7970cd949a077b7cb9696379d338681 + depends: + - font-ttf-ubuntu + - font-ttf-inconsolata + - font-ttf-dejavu-sans-mono + - font-ttf-source-code-pro + license: BSD-3-Clause + license_family: BSD + size: 4059 + timestamp: 1762351264405 +- conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.16-hb03c661_0.conda + sha256: 858283ff33d4c033f4971bf440cebff217d5552a5222ba994c49be990dacd40d + md5: f9f81ea472684d75b9dd8d0b328cf655 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-or-later + size: 61244 + timestamp: 1757438574066 +- conda: https://conda.anaconda.org/conda-forge/osx-64/fribidi-1.0.16-h8616949_0.conda + sha256: 53dd0a6c561cf31038633aaa0d52be05da1f24e86947f06c4e324606c72c7413 + md5: 4422491d30462506b9f2d554ab55e33d + depends: + - __osx >=10.13 + license: LGPL-2.1-or-later + size: 60923 + timestamp: 1757438791418 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/fribidi-1.0.16-hc919400_0.conda + sha256: d856dc6744ecfba78c5f7df3378f03a75c911aadac803fa2b41a583667b4b600 + md5: 04bdce8d93a4ed181d1d726163c2d447 + depends: + - __osx >=11.0 + license: LGPL-2.1-or-later + size: 59391 + timestamp: 1757438897523 +- conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.16-hfd05255_0.conda + sha256: 15011071ee56c216ffe276c8d734427f1f893f275ef733f728d13f610ed89e6e + md5: c27bd87e70f970010c1c6db104b88b18 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-or-later + size: 64394 + timestamp: 1757438741305 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc-14.3.0-h0dff253_18.conda + sha256: 9b34b57b06b485e33a40d430f71ac88c8f381673592507cf7161c50ff0832772 + md5: 52d6457abc42e320787ada5f9033fa99 + depends: + - conda-gcc-specs + - gcc_impl_linux-64 14.3.0 hbdf3cc3_18 + license: BSD-3-Clause + license_family: BSD + size: 29506 + timestamp: 1771378321585 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_impl_linux-64-14.3.0-hbdf3cc3_18.conda + sha256: 3b31a273b806c6851e16e9cf63ef87cae28d19be0df148433f3948e7da795592 + md5: 30bb690150536f622873758b0e8d6712 + depends: + - binutils_impl_linux-64 >=2.45 + - libgcc >=14.3.0 + - libgcc-devel_linux-64 14.3.0 hf649bbc_118 + - libgomp >=14.3.0 + - libsanitizer 14.3.0 h8f1669f_18 + - libstdcxx >=14.3.0 + - libstdcxx-devel_linux-64 14.3.0 h9f08a49_118 + - sysroot_linux-64 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 76302378 + timestamp: 1771378056505 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gcc_linux-64-14.3.0-h298d278_22.conda + sha256: 676444fd28bde495e27d32999c6f2e4cb7f96cf05c2ce5e8bf4b37ef0b428dfb + md5: 0b6cd616dab5e509c5c368d58a01982d + depends: + - gcc_impl_linux-64 14.3.0.* + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + size: 28918 + timestamp: 1774728910114 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.44.6-h2b0a6b4_0.conda + sha256: c5594497f0646e9079705b3199dbb2d5b13c48173cf110000fa1c8818e2b3e0c + md5: 7892f39a39ed39591a89a28eba03e987 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + size: 577414 + timestamp: 1774985848058 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.44.6-hae309b2_0.conda + sha256: 27a223201fd86f85284c7e218121ac9ecf0be16e0a73eea42776701c8c90c50b + md5: 5f0f81650af65aa247f6fbc25ebcbdd4 + depends: + - __osx >=11.0 + - libglib >=2.86.4,<3.0a0 + - libintl >=0.25.1,<1.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + size: 552947 + timestamp: 1774986327487 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.44.6-h4e57454_0.conda + sha256: 07cbba4e12430de35ea608eb3006cf1f7f63832c4f89a081cd6f3872944c1aa6 + md5: e67ebd2f639f46e52af8531622fa6051 + depends: + - __osx >=11.0 + - libglib >=2.86.4,<3.0a0 + - libintl >=0.25.1,<1.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - liblzma >=5.8.2,<6.0a0 + - libpng >=1.6.56,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + license: LGPL-2.1-or-later + license_family: LGPL + size: 548309 + timestamp: 1774986047281 +- conda: https://conda.anaconda.org/conda-forge/win-64/getopt-win32-0.1-h6a83c73_3.conda + sha256: d04c4a6c11daa72c4a0242602e1d00c03291ef66ca2d7cd0e171088411d57710 + md5: 49c36fcad2e9af6b91e91f2ce5be8ebd + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: LGPL-3.0-only + license_family: LGPL + size: 26238 + timestamp: 1750744808182 +- conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.86.4-hf516916_1.conda + sha256: 441586fc577c5a3f2ad7bf83578eb135dac94fb0cb75cc4da35f8abb5823b857 + md5: b52b769cd13f7adaa6ccdc68ef801709 + depends: + - __glibc >=2.17,<3.0.a0 + - libffi + - libgcc >=14 + - libglib 2.86.4 h6548e54_1 + license: LGPL-2.1-or-later + size: 214712 + timestamp: 1771863307416 +- conda: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.86.4-h8501676_1.conda + sha256: 2ca7c217f15cc06bc17b3dcde7cdaf6450d92695e012b5048386e2b9dd497fa0 + md5: 39bd80ba97914860f3027f2fb2242b0d + depends: + - __osx >=11.0 + - libffi + - libglib 2.86.4 hec30fc1_1 + - libintl >=0.25.1,<1.0a0 + license: LGPL-2.1-or-later + size: 188660 + timestamp: 1771864169877 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.86.4-h60c1bae_1.conda + sha256: 339adcf9170d1c6eaf125a309debd541d20cb72964bff8edd51197ed1154e13b + md5: 2e1684508bcd4b343b34c27731fa5bbe + depends: + - __osx >=11.0 + - libffi + - libglib 2.86.4 he378b5c_1 + - libintl >=0.25.1,<1.0a0 + license: LGPL-2.1-or-later + size: 183089 + timestamp: 1771864291777 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.14-hecca717_2.conda + sha256: 25ba37da5c39697a77fce2c9a15e48cf0a84f1464ad2aafbe53d8357a9f6cc8c + md5: 2cd94587f3a401ae05e03a6caf09539d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: LGPL-2.0-or-later + license_family: LGPL + size: 99596 + timestamp: 1755102025473 +- conda: https://conda.anaconda.org/conda-forge/osx-64/graphite2-1.3.14-h21dd04a_2.conda + sha256: c356eb7a42775bd2bae243d9987436cd1a442be214b1580251bb7fdc136d804b + md5: ba63822087afc37e01bf44edcc2479f3 + depends: + - __osx >=10.13 + - libcxx >=19 + license: LGPL-2.0-or-later + license_family: LGPL + size: 85465 + timestamp: 1755102182985 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphite2-1.3.14-hec049ff_2.conda + sha256: c507ae9989dbea7024aa6feaebb16cbf271faac67ac3f0342ef1ab747c20475d + md5: 0fc46fee39e88bbcf5835f71a9d9a209 + depends: + - __osx >=11.0 + - libcxx >=19 + license: LGPL-2.0-or-later + license_family: LGPL + size: 81202 + timestamp: 1755102333712 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.14-hac47afa_2.conda + sha256: 5f1714b07252f885a62521b625898326ade6ca25fbc20727cfe9a88f68a54bfd + md5: b785694dd3ec77a011ccf0c24725382b + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.0-or-later + license_family: LGPL + size: 96336 + timestamp: 1755102441729 +- conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-14.1.2-h8b86629_0.conda + sha256: 48d4aae8d2f7dd038b8c2b6a1b68b7bca13fa6b374b78c09fcc0757fa21234a1 + md5: 341fc61cfe8efa5c72d24db56c776f44 + depends: + - __glibc >=2.17,<3.0.a0 + - adwaita-icon-theme + - cairo >=1.18.4,<2.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.4,<3.0a0 + - gtk3 >=3.24.43,<4.0a0 + - gts >=0.7.6,<0.8.0a0 + - libexpat >=2.7.3,<3.0a0 + - libgcc >=14 + - libgd >=2.3.3,<2.4.0a0 + - libglib >=2.86.3,<3.0a0 + - librsvg >=2.60.0,<3.0a0 + - libstdcxx >=14 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pango >=1.56.4,<2.0a0 + license: EPL-1.0 + license_family: Other + size: 2426455 + timestamp: 1769427102743 +- conda: https://conda.anaconda.org/conda-forge/osx-64/graphviz-14.1.2-h44fc223_0.conda + sha256: dd6a5e3599a2e07c04f4d33e61ecd5c26738eee9e88b9faa1da0f8b062ac9ca3 + md5: 4c1c78d65d867d032c07303cf38117ba + depends: + - __osx >=10.13 + - adwaita-icon-theme + - cairo >=1.18.4,<2.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.4,<3.0a0 + - gtk3 >=3.24.43,<4.0a0 + - gts >=0.7.6,<0.8.0a0 + - libcxx >=19 + - libexpat >=2.7.3,<3.0a0 + - libgd >=2.3.3,<2.4.0a0 + - libglib >=2.86.3,<3.0a0 + - librsvg >=2.60.0,<3.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pango >=1.56.4,<2.0a0 + license: EPL-1.0 + license_family: Other + size: 2297868 + timestamp: 1769427939677 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-14.1.2-hec8c438_0.conda + sha256: 755c72d469330265f80a615912a3b522aef6f26cbc52763862b6a3c492fbf97c + md5: 1f3d859de3ca2bcaa845e92e87d73660 + depends: + - __osx >=11.0 + - adwaita-icon-theme + - cairo >=1.18.4,<2.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.4,<3.0a0 + - gtk3 >=3.24.43,<4.0a0 + - gts >=0.7.6,<0.8.0a0 + - libcxx >=19 + - libexpat >=2.7.3,<3.0a0 + - libgd >=2.3.3,<2.4.0a0 + - libglib >=2.86.3,<3.0a0 + - librsvg >=2.60.0,<3.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pango >=1.56.4,<2.0a0 + license: EPL-1.0 + license_family: Other + size: 2218284 + timestamp: 1769427599940 +- conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-14.1.2-h4c50273_0.conda + sha256: 58f83755509a19501a9efe40c484727ffa61fcfaf6a237870678a79638fa6982 + md5: afabed4c46b197b89eb974aa038d12db + depends: + - cairo >=1.18.4,<2.0a0 + - getopt-win32 >=0.1,<0.1.1.0a0 + - gts >=0.7.6,<0.8.0a0 + - libexpat >=2.7.3,<3.0a0 + - libgd >=2.3.3,<2.4.0a0 + - libglib >=2.86.3,<3.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pango >=1.56.4,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: EPL-1.0 + license_family: Other + size: 1223547 + timestamp: 1769427507016 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gtk3-3.24.52-ha5ea40c_0.conda + sha256: c6bb4f06331bcb0a566d84e0f0fad7af4b9035a03b13e2d5ecfaf13be57e6e10 + md5: bcaea22d85999a4f17918acfab877e61 + depends: + - __glibc >=2.17,<3.0.a0 + - at-spi2-atk >=2.38.0,<3.0a0 + - atk-1.0 >=2.38.0 + - cairo >=1.18.4,<2.0a0 + - epoxy >=1.5.10,<1.6.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - gdk-pixbuf >=2.44.5,<3.0a0 + - glib-tools + - harfbuzz >=13.2.1 + - hicolor-icon-theme + - libcups >=2.3.3,<2.4.0a0 + - libcups >=2.3.3,<3.0a0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - liblzma >=5.8.2,<6.0a0 + - libxkbcommon >=1.13.1,<2.0a0 + - libzlib >=1.3.2,<2.0a0 + - pango >=1.56.4,<2.0a0 + - wayland >=1.25.0,<2.0a0 + - xorg-libx11 >=1.8.13,<2.0a0 + - xorg-libxcomposite >=0.4.7,<1.0a0 + - xorg-libxcursor >=1.2.3,<2.0a0 + - xorg-libxdamage >=1.1.6,<2.0a0 + - xorg-libxext >=1.3.7,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + - xorg-libxi >=1.8.2,<2.0a0 + - xorg-libxinerama >=1.1.6,<1.2.0a0 + - xorg-libxrandr >=1.5.5,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 5939083 + timestamp: 1774288645605 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gtk3-3.24.52-hf2d442a_0.conda + sha256: c69a03b1eec71c0a764658d67f81eaf9a316276ae900b107cd8d77766bc13cf8 + md5: 76be17e448c23c6d1c99a56c15b15925 + depends: + - __osx >=11.0 + - atk-1.0 >=2.38.0 + - cairo >=1.18.4,<2.0a0 + - epoxy >=1.5.10,<1.6.0a0 + - fribidi >=1.0.16,<2.0a0 + - gdk-pixbuf >=2.44.5,<3.0a0 + - glib-tools + - harfbuzz >=13.2.1 + - hicolor-icon-theme + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libintl >=0.25.1,<1.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - pango >=1.56.4,<2.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 5269457 + timestamp: 1774289309822 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtk3-3.24.52-hc0f3e19_0.conda + sha256: 26862a9898054b8552e55e609e5ce73c7ef1eb28bbe6fb87f0b9109d73cd09df + md5: 5557a2433b1339b8e536c264afea41ef + depends: + - __osx >=11.0 + - atk-1.0 >=2.38.0 + - cairo >=1.18.4,<2.0a0 + - epoxy >=1.5.10,<1.6.0a0 + - fribidi >=1.0.16,<2.0a0 + - gdk-pixbuf >=2.44.5,<3.0a0 + - glib-tools + - harfbuzz >=13.2.1 + - hicolor-icon-theme + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libintl >=0.25.1,<1.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.2,<2.0a0 + - pango >=1.56.4,<2.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 9385734 + timestamp: 1774288504338 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda + sha256: b5cd16262fefb836f69dc26d879b6508d29f8a5c5948a966c47fe99e2e19c99b + md5: 4d8df0b0db060d33c9a702ada998a8fe + depends: + - libgcc-ng >=12 + - libglib >=2.76.3,<3.0a0 + - libstdcxx-ng >=12 + license: LGPL-2.0-or-later + license_family: LGPL + size: 318312 + timestamp: 1686545244763 +- conda: https://conda.anaconda.org/conda-forge/osx-64/gts-0.7.6-h53e17e3_4.conda + sha256: d5b82a36f7e9d7636b854e56d1b4fe01c4d895128a7b73e2ec6945b691ff3314 + md5: 848cc963fcfbd063c7a023024aa3bec0 + depends: + - libcxx >=15.0.7 + - libglib >=2.76.3,<3.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 280972 + timestamp: 1686545425074 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/gts-0.7.6-he42f4ea_4.conda + sha256: e0f8c7bc1b9ea62ded78ffa848e37771eeaaaf55b3146580513c7266862043ba + md5: 21b4dd3098f63a74cf2aa9159cbef57d + depends: + - libcxx >=15.0.7 + - libglib >=2.76.3,<3.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 304331 + timestamp: 1686545503242 +- conda: https://conda.anaconda.org/conda-forge/win-64/gts-0.7.6-h6b5321d_4.conda + sha256: b79755d2f9fc2113b6949bfc170c067902bc776e2c20da26e746e780f4f5a2d4 + md5: a41f14768d5e377426ad60c613f2923b + depends: + - libglib >=2.76.3,<3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.0-or-later + license_family: LGPL + size: 188688 + timestamp: 1686545648050 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx-14.3.0-h76987e4_18.conda + sha256: 1b490c9be9669f9c559db7b2a1f7d8b973c58ca0c6f21a5d2ba3f0ab2da63362 + md5: 19189121d644d4ef75fed05383bc75f5 + depends: + - gcc 14.3.0 h0dff253_18 + - gxx_impl_linux-64 14.3.0 h2185e75_18 + license: BSD-3-Clause + license_family: BSD + size: 28883 + timestamp: 1771378355605 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_impl_linux-64-14.3.0-h2185e75_18.conda + sha256: 38ffca57cc9c264d461ac2ce9464a9d605e0f606d92d831de9075cb0d95fc68a + md5: 6514b3a10e84b6a849e1b15d3753eb22 + depends: + - gcc_impl_linux-64 14.3.0 hbdf3cc3_18 + - libstdcxx-devel_linux-64 14.3.0 h9f08a49_118 + - sysroot_linux-64 + - tzdata + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 14566100 + timestamp: 1771378271421 +- conda: https://conda.anaconda.org/conda-forge/linux-64/gxx_linux-64-14.3.0-h7ab9642_22.conda + sha256: 0331f697ddd97f4d0ddbf66badf6f94bb397b39c534bcf604967d362dea428b1 + md5: ac8519fa5fe0e5d779b5f6d658c10ed5 + depends: + - gxx_impl_linux-64 14.3.0.* + - gcc_linux-64 ==14.3.0 h298d278_22 + - binutils_linux-64 + - sysroot_linux-64 + license: BSD-3-Clause + size: 27468 + timestamp: 1774728910114 +- conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-13.2.1-h6083320_0.conda + sha256: 477f2c553f72165020d3c56740ba354be916c2f0b76fd9f535e83d698277d5ec + md5: 14470902326beee192e33719a2e8bb7f + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + size: 2384060 + timestamp: 1774276284520 +- conda: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-13.2.1-hf0bc557_0.conda + sha256: 72fd48c613da1880f677f36aa46f2cabfb27052ca736fad54e804f9495b604c3 + md5: 3c0e7beb248c312b201dc7c317e2963a + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libcxx >=19 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + size: 1728695 + timestamp: 1774277140385 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-13.2.1-h3103d1b_0.conda + sha256: 7bfb3037cc73dabf755b4308eb4ac885e40806df824838928904758ef1bc92c9 + md5: 07313476933d7bf01bfe9a0ae9a5ca4d + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libcxx >=19 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + license: MIT + license_family: MIT + size: 1649886 + timestamp: 1774277167588 +- conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-13.2.1-h5a1b470_0.conda + sha256: 530f69ed9165a88eadf6d3165e7fc0098ed602812ba1527ebd92f78e0d0a2158 + md5: f6414f2f905326bcf0e7c87a04d175a2 + depends: + - cairo >=1.18.4,<2.0a0 + - graphite2 >=1.3.14,<2.0a0 + - icu >=78.3,<79.0a0 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 1288878 + timestamp: 1774276695458 +- conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.6-nompi_h19486de_108.conda + sha256: 795c3a34643aa766450b8363b8c5dd6e65ad40e5cc64d138c3678d05068a380a + md5: cbb2d15a6e9aeb85f18f1a8f01c29b81 + depends: + - __glibc >=2.17,<3.0.a0 + - libaec >=1.1.5,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + - libstdcxx >=14 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 3719931 + timestamp: 1774406907641 +- conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.6-nompi_h13accda_108.conda + sha256: 6b6b6614ddfceb97692169dc4e7759a1ca23113b0a8a7d667ad04a5a885ab864 + md5: 0584e06ff7d8379163467e23b1eadccb + depends: + - __osx >=11.0 + - libaec >=1.1.5,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libcxx >=19 + - libgfortran + - libgfortran5 >=14.3.0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 3519181 + timestamp: 1774409106104 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.6-nompi_had3affe_108.conda + sha256: 997c7c875d70873fbd931f44aa813f98e3195bdc80957b5bb24dacb859ad7b20 + md5: da1f9cc54397e702a1ace51e2800a066 + depends: + - __osx >=11.0 + - libaec >=1.1.5,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libcxx >=19 + - libgfortran + - libgfortran5 >=14.3.0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 3292751 + timestamp: 1774407465085 +- conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.6-nompi_hae35d4c_108.conda + sha256: e85b8f7d3e1020f21eae0248723b887be986bbb6516aaa5678c5740f72b5d0e7 + md5: 534b3fa3d3729d903746c258185650b5 + depends: + - libaec >=1.1.5,<2.0a0 + - libcurl >=8.19.0,<9.0a0 + - libzlib >=1.3.2,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + size: 2383951 + timestamp: 1774406723765 +- conda: https://conda.anaconda.org/conda-forge/linux-64/hicolor-icon-theme-0.17-ha770c72_3.conda + sha256: 6d7e6e1286cb521059fe69696705100a03b006efb914ffe82a2ae97ecbae66b7 + md5: 129e404c5b001f3ef5581316971e3ea0 + license: GPL-2.0-or-later + license_family: GPL + size: 17625 + timestamp: 1771539597968 +- conda: https://conda.anaconda.org/conda-forge/osx-64/hicolor-icon-theme-0.17-h694c41f_3.conda + sha256: 3321e8d2c2198ac796b0ae800473173ade528b49f84b6c6e4e112a9704698b41 + md5: 690e5077aaccf8d280a4284d7c9ec6b4 + license: GPL-2.0-or-later + license_family: GPL + size: 17650 + timestamp: 1771539977217 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/hicolor-icon-theme-0.17-hce30654_3.conda + sha256: 46a4958f2f916c5938f2a6dc0709f78b175ece42f601d79a04e0276d55d25d07 + md5: cfb39109ac5fa8601eb595d66d5bf156 + license: GPL-2.0-or-later + license_family: GPL + size: 17616 + timestamp: 1771539622983 +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.3-h33c6efd_0.conda + sha256: fbf86c4a59c2ed05bbffb2ba25c7ed94f6185ec30ecb691615d42342baa1a16a + md5: c80d8a3b84358cb967fa81e7075fbc8a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + size: 12723451 + timestamp: 1773822285671 +- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.3-h25d91c4_0.conda + sha256: 1294117122d55246bb83ad5b589e2a031aacdf2d0b1f99fd338aa4394f881735 + md5: 627eca44e62e2b665eeec57a984a7f00 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 12273764 + timestamp: 1773822733780 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda + sha256: 3a7907a17e9937d3a46dfd41cffaf815abad59a569440d1e25177c15fd0684e5 + md5: f1182c91c0de31a7abd40cedf6a5ebef + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 12361647 + timestamp: 1773822915649 +- conda: https://conda.anaconda.org/conda-forge/win-64/icu-78.3-h637d24d_0.conda + sha256: 1bda728d70a619731b278c859eda364146cb5b4b8c739a64da8128353d81d1c4 + md5: 0097b24800cb696915c3dbd1f5335d3f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 14954024 + timestamp: 1773822508646 +- conda: https://conda.anaconda.org/conda-forge/noarch/kernel-headers_linux-64-4.18.0-he073ed8_9.conda + sha256: 41557eeadf641de6aeae49486cef30d02a6912d8da98585d687894afd65b356a + md5: 86d9cba083cd041bfbf242a01a7a1999 + constrains: + - sysroot_linux-64 ==2.28 + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later + license_family: GPL + size: 1278712 + timestamp: 1765578681495 +- conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda + sha256: 0960d06048a7185d3542d850986d807c6e37ca2e644342dd0c72feefcf26c2a4 + md5: b38117a3c920364aff79f870c984b4a3 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: LGPL-2.1-or-later + size: 134088 + timestamp: 1754905959823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda + sha256: 3e307628ca3527448dd1cb14ad7bb9d04d1d28c7d4c5f97ba196ae984571dd25 + md5: fb53fb07ce46a575c5d004bbc96032c2 + depends: + - __glibc >=2.17,<3.0.a0 + - keyutils >=1.6.3,<2.0a0 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - libgcc >=14 + - libstdcxx >=14 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 1386730 + timestamp: 1769769569681 +- conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.22.2-h207b36a_0.conda + sha256: df009385e8262c234c0dae9016540b86dad3d299f0d9366d08e327e8e7731634 + md5: e66e2c52d2fdddcf314ad750fb4ebb4a + depends: + - __osx >=10.13 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 1193620 + timestamp: 1769770267475 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda + sha256: c0a0bf028fe7f3defcdcaa464e536cf1b202d07451e18ad83fdd169d15bef6ed + md5: e446e1822f4da8e5080a9de93474184d + depends: + - __osx >=11.0 + - libcxx >=19 + - libedit >=3.1.20250104,<3.2.0a0 + - libedit >=3.1.20250104,<4.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 1160828 + timestamp: 1769770119811 +- conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.22.2-h0ea6238_0.conda + sha256: eb60f1ad8b597bcf95dee11bc11fe71a8325bc1204cf51d2bb1f2120ffd77761 + md5: 4432f52dc0c8eb6a7a6abc00a037d93c + depends: + - openssl >=3.5.5,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 751055 + timestamp: 1769769688841 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64-956.6-llvm19_1_hc3792c1_4.conda + sha256: 6f821c4c6a19722162ef2905c45e0f8034544dab70bb86c647fb4e022a9c27b4 + md5: 4d51a4b9f959c1fac780645b9d480a82 + depends: + - ld64_osx-64 956.6 llvm19_1_hcae3351_4 + - libllvm19 >=19.1.7,<19.2.0a0 + constrains: + - cctools 1030.6.3.* + - cctools_osx-64 1030.6.3.* + license: APSL-2.0 + license_family: Other + size: 21560 + timestamp: 1768852832804 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64-956.6-llvm19_1_he86490a_4.conda + sha256: d6197b4825ece12ab63097bd677294126439a1a6222c7098885aa23464ef280c + md5: 22eb76f8d98f4d3b8319d40bda9174de + depends: + - ld64_osx-arm64 956.6 llvm19_1_ha2625f7_4 + - libllvm19 >=19.1.7,<19.2.0a0 + constrains: + - cctools_osx-arm64 1030.6.3.* + - cctools 1030.6.3.* + license: APSL-2.0 + license_family: Other + size: 21592 + timestamp: 1768852886875 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ld64_osx-64-956.6-llvm19_1_hcae3351_4.conda + sha256: 2ae4c885ea34bc976232fbfb8129a2a3f0a79b0f42a8f7437e06d571d1b6760c + md5: 2329a96b45c853dd22af9d11762f9057 + depends: + - __osx >=10.13 + - libcxx + - libllvm19 >=19.1.7,<19.2.0a0 + - sigtool-codesign + - tapi >=1600.0.11.8,<1601.0a0 + constrains: + - cctools 1030.6.3.* + - clang 19.1.* + - cctools_impl_osx-64 1030.6.3.* + - ld64 956.6.* + license: APSL-2.0 + license_family: Other + size: 1110678 + timestamp: 1768852747927 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ld64_osx-arm64-956.6-llvm19_1_ha2625f7_4.conda + sha256: 4161eec579cea07903ee2fafdde6f8f9991dabd54f3ca6609a1bf75bed3dc788 + md5: eaf3d06e3a8a10dee7565e8d76ae618d + depends: + - __osx >=11.0 + - libcxx + - libllvm19 >=19.1.7,<19.2.0a0 + - sigtool-codesign + - tapi >=1600.0.11.8,<1601.0a0 + constrains: + - cctools_impl_osx-arm64 1030.6.3.* + - ld64 956.6.* + - cctools 1030.6.3.* + - clang 19.1.* + license: APSL-2.0 + license_family: Other + size: 1040464 + timestamp: 1768852821767 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda + sha256: 3d584956604909ff5df353767f3a2a2f60e07d070b328d109f30ac40cd62df6c + md5: 18335a698559cdbcd86150a48bf54ba6 + depends: + - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 + constrains: + - binutils_impl_linux-64 2.45.1 + license: GPL-3.0-only + license_family: GPL + size: 728002 + timestamp: 1774197446916 +- conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.1.0-hdb68285_0.conda + sha256: f84cb54782f7e9cea95e810ea8fef186e0652d0fa73d3009914fa2c1262594e1 + md5: a752488c68f2e7c456bcbd8f16eec275 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: Apache-2.0 + license_family: Apache + size: 261513 + timestamp: 1773113328888 +- conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.1.0-h35c7297_0.conda + sha256: f918716c71c8bebbc0c40e1050878aa512fea92c1d17c363ca35650bc60f6c35 + md5: d2fe7e177d1c97c985140bd54e2a5e33 + depends: + - __osx >=11.0 + - libcxx >=19 + license: Apache-2.0 + license_family: Apache + size: 215089 + timestamp: 1773114468701 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.1.0-h1eee2c3_0.conda + sha256: 66e5ffd301a44da696f3efc2f25d6d94f42a9adc0db06c44ad753ab844148c51 + md5: 095e5749868adab9cae42d4b460e5443 + depends: + - __osx >=11.0 + - libcxx >=19 + license: Apache-2.0 + license_family: Apache + size: 164222 + timestamp: 1773114244984 +- conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.1.0-hd936e49_0.conda + sha256: 45df58fca800b552b17c3914cc9ab0d55a82c5172d72b5c44a59c710c06c5473 + md5: 54b231d595bc1ff9bff668dd443ee012 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + size: 172395 + timestamp: 1773113455582 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.5-h088129d_0.conda + sha256: 822e4ae421a7e9c04e841323526321185f6659222325e1a9aedec811c686e688 + md5: 86f7414544ae606282352fa1e116b41f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: BSD-2-Clause + license_family: BSD + size: 36544 + timestamp: 1769221884824 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.5-he7c3a48_0.conda + sha256: b42ac9c684c730cb97cb3931a0a97aaf791da38bace4f6944eca10de609e5946 + md5: 975f98248cde8d54884c6d1eb5184e13 + depends: + - __osx >=10.13 + - libcxx >=19 + license: BSD-2-Clause + license_family: BSD + size: 30555 + timestamp: 1769222189944 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.5-h8664d51_0.conda + sha256: af9cd8db11eb719e38a3340c88bb4882cf19b5b4237d93845224489fc2a13b46 + md5: 13e6d9ae0efbc9d2e9a01a91f4372b41 + depends: + - __osx >=11.0 + - libcxx >=19 + license: BSD-2-Clause + license_family: BSD + size: 30390 + timestamp: 1769222133373 +- conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.5-haf901d7_0.conda + sha256: e54c08964262c73671d9e80e400333e59c617e0b454476ad68933c0c458156c8 + md5: 43b6385cfad52a7083f2c41984eb4e91 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + size: 34463 + timestamp: 1769221960556 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libblas-3.11.0-6_h4a7cf45_openblas.conda + build_number: 6 + sha256: 7bfe936dbb5db04820cf300a9cc1f5ee8d5302fc896c2d66e30f1ee2f20fbfd6 + md5: 6d6d225559bfa6e2f3c90ee9c03d4e2e + depends: + - libopenblas >=0.3.32,<0.3.33.0a0 + - libopenblas >=0.3.32,<1.0a0 + constrains: + - blas 2.306 openblas + - liblapack 3.11.0 6*_openblas + - liblapacke 3.11.0 6*_openblas + - libcblas 3.11.0 6*_openblas + - mkl <2026 + license: BSD-3-Clause + license_family: BSD + size: 18621 + timestamp: 1774503034895 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libblas-3.11.0-6_he492b99_openblas.conda + build_number: 6 + sha256: 6865098475f3804208038d0c424edf926f4dc9eacaa568d14e29f59df53731fd + md5: 93e7fc07b395c9e1341d3944dcf2aced + depends: + - libopenblas >=0.3.32,<0.3.33.0a0 + - libopenblas >=0.3.32,<1.0a0 + constrains: + - libcblas 3.11.0 6*_openblas + - blas 2.306 openblas + - mkl <2026 + - liblapacke 3.11.0 6*_openblas + - liblapack 3.11.0 6*_openblas + license: BSD-3-Clause + license_family: BSD + size: 18724 + timestamp: 1774503646078 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libblas-3.11.0-6_h51639a9_openblas.conda + build_number: 6 + sha256: 979227fc03628925037ab2dfda008eb7b5592644d9c2c21dd285cefe8c42553d + md5: e551103471911260488a02155cef9c94 + depends: + - libopenblas >=0.3.32,<0.3.33.0a0 + - libopenblas >=0.3.32,<1.0a0 + constrains: + - liblapacke 3.11.0 6*_openblas + - liblapack 3.11.0 6*_openblas + - blas 2.306 openblas + - libcblas 3.11.0 6*_openblas + - mkl <2026 + license: BSD-3-Clause + license_family: BSD + size: 18859 + timestamp: 1774504387211 +- conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.11.0-6_hf2e6a31_mkl.conda + build_number: 6 + sha256: 10c8054f007adca8c780cd8bb9335fa5d990f0494b825158d3157983a25b1ea2 + md5: 95543eec964b4a4a7ca3c4c9be481aa1 + depends: + - mkl >=2025.3.1,<2026.0a0 + constrains: + - blas 2.306 mkl + - liblapacke 3.11.0 6*_mkl + - liblapack 3.11.0 6*_mkl + - libcblas 3.11.0 6*_mkl + license: BSD-3-Clause + license_family: BSD + size: 68082 + timestamp: 1774503684284 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.11.0-6_h0358290_openblas.conda + build_number: 6 + sha256: 57edafa7796f6fa3ebbd5367692dd4c7f552be42109c2dd1a7c89b55089bf374 + md5: 36ae340a916635b97ac8a0655ace2a35 + depends: + - libblas 3.11.0 6_h4a7cf45_openblas + constrains: + - blas 2.306 openblas + - liblapack 3.11.0 6*_openblas + - liblapacke 3.11.0 6*_openblas + license: BSD-3-Clause + license_family: BSD + size: 18622 + timestamp: 1774503050205 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcblas-3.11.0-6_h9b27e0a_openblas.conda + build_number: 6 + sha256: 8422e1ce083e015bdb44addd25c9a8fe99aa9b0edbd9b7f1239b7ac1e3d04f77 + md5: 2a174868cb9e136c4e92b3ffc2815f04 + depends: + - libblas 3.11.0 6_he492b99_openblas + constrains: + - liblapacke 3.11.0 6*_openblas + - blas 2.306 openblas + - liblapack 3.11.0 6*_openblas + license: BSD-3-Clause + license_family: BSD + size: 18713 + timestamp: 1774503667477 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.11.0-6_hb0561ab_openblas.conda + build_number: 6 + sha256: 2e6b3e9b1ab672133b70fc6730e42290e952793f132cb5e72eee22835463eba0 + md5: 805c6d31c5621fd75e53dfcf21fb243a + depends: + - libblas 3.11.0 6_h51639a9_openblas + constrains: + - liblapacke 3.11.0 6*_openblas + - blas 2.306 openblas + - liblapack 3.11.0 6*_openblas + license: BSD-3-Clause + license_family: BSD + size: 18863 + timestamp: 1774504433388 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.11.0-6_h2a3cdd5_mkl.conda + build_number: 6 + sha256: 02b2a2225f4899c6aaa1dc723e06b3f7a4903d2129988f91fc1527409b07b0a5 + md5: 9e4bf521c07f4d423cba9296b7927e3c + depends: + - libblas 3.11.0 6_hf2e6a31_mkl + constrains: + - blas 2.306 mkl + - liblapacke 3.11.0 6*_mkl + - liblapack 3.11.0 6*_mkl + license: BSD-3-Clause + license_family: BSD + size: 68221 + timestamp: 1774503722413 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-cpp19.1-19.1.7-default_h9399c5b_8.conda + sha256: 951f37df234369110417c7f10d1e9e49ce4ecf5a3a6aab8ef64a71a2c30aaeb4 + md5: a7d5aeecbf1810d10913932823eae26a + depends: + - __osx >=11.0 + - libcxx >=19.1.7 + - libllvm19 >=19.1.7,<19.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 14856053 + timestamp: 1772399122829 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp19.1-19.1.7-default_hf3020a7_8.conda + sha256: f047f0d677bdccef02a844a50874baf9665551b2200e451e4c69b473ad499623 + md5: 445fc95210a8e15e8b5f9f93782e3f80 + depends: + - __osx >=11.0 + - libcxx >=19.1.7 + - libllvm19 >=19.1.7,<19.2.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 14064507 + timestamp: 1772400067348 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h7a8fb5f_6.conda + sha256: 205c4f19550f3647832ec44e35e6d93c8c206782bdd620c1d7cf66237580ff9c + md5: 49c553b47ff679a6a1e9fc80b9c5a2d4 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.22.2,<1.23.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + license: Apache-2.0 + license_family: Apache + size: 4518030 + timestamp: 1770902209173 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.19.0-hcf29cc6_0.conda + sha256: a0390fd0536ebcd2244e243f5f00ab8e76ab62ed9aa214cd54470fe7496620f4 + md5: d50608c443a30c341c24277d28290f76 + depends: + - __glibc >=2.17,<3.0.a0 + - krb5 >=1.22.2,<1.23.0a0 + - libgcc >=14 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + size: 466704 + timestamp: 1773218522665 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.19.0-h8f0b9e4_0.conda + sha256: 55c6b34ae18a7f8f57d9ffe3f4ec2a82ddcc8a87248d2447f9bbba3ba66d8aec + md5: 8bc2742696d50c358f4565b25ba33b08 + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + size: 419039 + timestamp: 1773219507657 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.19.0-hd5a2499_0.conda + sha256: c4d581b067fa60f9dc0e1c5f18b756760ff094a03139e6b206eb98d185ae2bb1 + md5: 9fc7771fc8104abed9119113160be15a + depends: + - __osx >=11.0 + - krb5 >=1.22.2,<1.23.0a0 + - libnghttp2 >=1.67.0,<2.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: curl + license_family: MIT + size: 399616 + timestamp: 1773219210246 +- conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.19.0-h8206538_0.conda + sha256: 6b2143ba5454b399dab4471e9e1d07352a2f33b569975e6b8aedc2d9bf51cbb0 + md5: ed181e29a7ebf0f60b84b98d6140a340 + depends: + - krb5 >=1.22.2,<1.23.0a0 + - libssh2 >=1.11.1,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: curl + license_family: MIT + size: 392543 + timestamp: 1773218585056 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-22.1.2-h19cb2f5_0.conda + sha256: 46561199545890e050a8a90edcfce984e5f881da86b09388926e3a6c6b759dec + md5: ed6f7b7a35f942a0301e581d72616f7d + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 564908 + timestamp: 1774439353713 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.2-h55c6f16_0.conda + sha256: d1402087c8792461bfc081629e8aa97e6e577a31ae0b84e6b9cc144a18f48067 + md5: 4280e0a7fd613b271e022e60dea0138c + depends: + - __osx >=11.0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 568094 + timestamp: 1774439202359 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-devel-19.1.7-h7c275be_2.conda + sha256: 760af3509e723d8ee5a9baa7f923a213a758b3a09e41ffdaf10f3a474898ab3f + md5: 52031c3ab8857ea8bcc96fe6f1b6d778 + depends: + - libcxx >=19.1.7 + - libcxx-headers >=19.1.7,<19.1.8.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 23069 + timestamp: 1764648572536 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-devel-19.1.7-h6dc3340_2.conda + sha256: ec07ebaa226792f4e2bf0f5dba50325632a7474d5f04b951d8291be70af215da + md5: 9f7810b7c0a731dbc84d46d6005890ef + depends: + - libcxx >=19.1.7 + - libcxx-headers >=19.1.7,<19.1.8.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 23000 + timestamp: 1764648270121 +- conda: https://conda.anaconda.org/conda-forge/noarch/libcxx-headers-19.1.7-h707e725_2.conda + sha256: 36485e6807e03a4f15a8018ec982457a9de0a1318b4b49a44c5da75849dbe24f + md5: de91b5ce46dc7968b6e311f9add055a2 + depends: + - __unix + constrains: + - libcxx-devel 19.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 830747 + timestamp: 1764647922410 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.25-h17f619e_0.conda + sha256: aa8e8c4be9a2e81610ddf574e05b64ee131fab5e0e3693210c9d6d2fba32c680 + md5: 6c77a605a7a689d17d4819c0f8ac9a00 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 73490 + timestamp: 1761979956660 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.25-h517ebb2_0.conda + sha256: 025f8b1e85dd8254e0ca65f011919fb1753070eb507f03bca317871a884d24de + md5: 31aa65919a729dc48180893f62c25221 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 70840 + timestamp: 1761980008502 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.25-hc11a715_0.conda + sha256: 5e0b6961be3304a5f027a8c00bd0967fc46ae162cffb7553ff45c70f51b8314c + md5: a6130c709305cd9828b4e1bd9ba0000c + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 55420 + timestamp: 1761980066242 +- conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.25-h51727cc_0.conda + sha256: 834e4881a18b690d5ec36f44852facd38e13afe599e369be62d29bd675f107ee + md5: e77030e67343e28b084fabd7db0ce43e + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 156818 + timestamp: 1761979842440 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda + sha256: c076a213bd3676cc1ef22eeff91588826273513ccc6040d9bea68bccdc849501 + md5: 9314bc5a1fe7d1044dc9dfd3ef400535 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpciaccess >=0.18,<0.19.0a0 + license: MIT + license_family: MIT + size: 310785 + timestamp: 1757212153962 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda + sha256: d789471216e7aba3c184cd054ed61ce3f6dac6f87a50ec69291b9297f8c18724 + md5: c277e0a4d549b03ac1e9d6cbbe3d017b + depends: + - ncurses + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + size: 134676 + timestamp: 1738479519902 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20250104-pl5321ha958ccf_0.conda + sha256: 6cc49785940a99e6a6b8c6edbb15f44c2dd6c789d9c283e5ee7bdfedd50b4cd6 + md5: 1f4ed31220402fcddc083b4bff406868 + depends: + - ncurses + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + size: 115563 + timestamp: 1738479554273 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda + sha256: 66aa216a403de0bb0c1340a88d1a06adaff66bae2cfd196731aa24db9859d631 + md5: 44083d2d2c2025afca315c7a172eab2b + depends: + - ncurses + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: BSD-2-Clause + license_family: BSD + size: 107691 + timestamp: 1738479560845 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda + sha256: 7fd5408d359d05a969133e47af580183fbf38e2235b562193d427bb9dad79723 + md5: c151d5eb730e9b7480e6d48c0fc44048 + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 44840 + timestamp: 1731330973553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libegl-devel-1.7.0-ha4b6fd6_2.conda + sha256: f6e7095260305dc05238062142fb8db4b940346329b5b54894a90610afa6749f + md5: b513eb83b3137eca1192c34bf4f013a7 + depends: + - __glibc >=2.17,<3.0.a0 + - libegl 1.7.0 ha4b6fd6_2 + - libgl-devel 1.7.0 ha4b6fd6_2 + - xorg-libx11 + license: LicenseRef-libglvnd + size: 30380 + timestamp: 1731331017249 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda + sha256: 1cd6048169fa0395af74ed5d8f1716e22c19a81a8a36f934c110ca3ad4dd27b4 + md5: 172bf1cd1ff8629f2b1179945ed45055 + depends: + - libgcc-ng >=12 + license: BSD-2-Clause + license_family: BSD + size: 112766 + timestamp: 1702146165126 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libev-4.33-h10d778d_2.conda + sha256: 0d238488564a7992942aa165ff994eca540f687753b4f0998b29b4e4d030ff43 + md5: 899db79329439820b7e8f8de41bca902 + license: BSD-2-Clause + license_family: BSD + size: 106663 + timestamp: 1702146352558 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda + sha256: 95cecb3902fbe0399c3a7e67a5bed1db813e5ab0e22f4023a5e0f722f2cc214f + md5: 36d33e440c31857372a72137f78bacf5 + license: BSD-2-Clause + license_family: BSD + size: 107458 + timestamp: 1702146414478 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.5-hecca717_0.conda + sha256: e8c2b57f6aacabdf2f1b0924bd4831ce5071ba080baa4a9e8c0d720588b6794c + md5: 49f570f3bc4c874a06ea69b7225753af + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - expat 2.7.5.* + license: MIT + license_family: MIT + size: 76624 + timestamp: 1774719175983 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.5-hcc62823_0.conda + sha256: 341d8a457a8342c396a8ac788da2639cbc8b62568f6ba2a3d322d1ace5aa9e16 + md5: 1d6e71b8c73711e28ffe207acdc4e2f8 + depends: + - __osx >=11.0 + constrains: + - expat 2.7.5.* + license: MIT + license_family: MIT + size: 74797 + timestamp: 1774719557730 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.5-hf6b4638_0.conda + sha256: 06780dec91dd25770c8cf01e158e1062fbf7c576b1406427475ce69a8af75b7e + md5: a32123f93e168eaa4080d87b0fb5da8a + depends: + - __osx >=11.0 + constrains: + - expat 2.7.5.* + license: MIT + license_family: MIT + size: 68192 + timestamp: 1774719211725 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.5-hac47afa_0.conda + sha256: 6850c3a4d5dc215b86f58518cfb8752998533d6569b08da8df1da72e7c68e571 + md5: bfb43f52f13b7c56e7677aa7a8efdf0c + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - expat 2.7.5.* + license: MIT + license_family: MIT + size: 70609 + timestamp: 1774719377850 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda + sha256: 31f19b6a88ce40ebc0d5a992c131f57d919f73c0b92cd1617a5bec83f6e961e6 + md5: a360c33a5abe61c07959e449fa1453eb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 58592 + timestamp: 1769456073053 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-hd1f9c09_0.conda + sha256: 951958d1792238006fdc6fce7f71f1b559534743b26cc1333497d46e5903a2d6 + md5: 66a0dc7464927d0853b590b6f53ba3ea + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 53583 + timestamp: 1769456300951 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda + sha256: 6686a26466a527585e6a75cc2a242bf4a3d97d6d6c86424a441677917f28bec7 + md5: 43c04d9cb46ef176bb2a4c77e324d599 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 40979 + timestamp: 1769456747661 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h3d046cb_0.conda + sha256: 59d01f2dfa8b77491b5888a5ab88ff4e1574c9359f7e229da254cdfe27ddc190 + md5: 720b39f5ec0610457b725eb3f396219a + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 45831 + timestamp: 1769456418774 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype-2.14.3-ha770c72_0.conda + sha256: 38f014a7129e644636e46064ecd6b1945e729c2140e21d75bb476af39e692db2 + md5: e289f3d17880e44b633ba911d57a321b + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + size: 8049 + timestamp: 1774298163029 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype-2.14.3-h694c41f_0.conda + sha256: b5daa4cee3beb98a0317e81a20aa507b9f897a9e21b11fe0b2e32852e372f746 + md5: 63b822fcf984c891f0afab2eedfcfaf4 + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + size: 8088 + timestamp: 1774298785964 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype-2.14.3-hce30654_0.conda + sha256: a047a2f238362a37d484f9620e8cba29f513a933cd9eb68571ad4b270d6f8f3e + md5: f73b109d49568d5d1dda43bb147ae37f + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + size: 8091 + timestamp: 1774298691258 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype-2.14.3-h57928b3_0.conda + sha256: 71fae9ae05563ceec70adceb7bc66faa326a81a6590a8aac8a5074019070a2d8 + md5: d9f70dd06674e26b6d5a657ddd22b568 + depends: + - libfreetype6 >=2.14.3 + license: GPL-2.0-only OR FTL + size: 8379 + timestamp: 1774300468411 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libfreetype6-2.14.3-h73754d4_0.conda + sha256: 16f020f96da79db1863fcdd8f2b8f4f7d52f177dd4c58601e38e9182e91adf1d + md5: fb16b4b69e3f1dcfe79d80db8fd0c55d + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + size: 384575 + timestamp: 1774298162622 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libfreetype6-2.14.3-h58fbd8d_0.conda + sha256: 9d34b5b2be6ebdd3bcd9e21d6598d493afce4d3fcd2d419f3356022cb4d746fd + md5: 27515b8ab8bf4abd8d3d90cf11212411 + depends: + - __osx >=11.0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + size: 364828 + timestamp: 1774298783922 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libfreetype6-2.14.3-hdfa99f5_0.conda + sha256: ff764608e1f2839e95e2cf9b243681475f8778c36af7a42b3f78f476fdbb1dd3 + md5: e98ba7b5f09a5f450eca083d5a1c4649 + depends: + - __osx >=11.0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + size: 338085 + timestamp: 1774298689297 +- conda: https://conda.anaconda.org/conda-forge/win-64/libfreetype6-2.14.3-hdbac1cb_0.conda + sha256: 497e9ab7c80f579e1b2850523740d6a543b8020f6b43be6bd6e83b3a6fb7fb32 + md5: f9975a0177ee6cdda10c86d1db1186b0 + depends: + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - freetype >=2.14.3 + license: GPL-2.0-only OR FTL + size: 340180 + timestamp: 1774300467879 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_18.conda + sha256: faf7d2017b4d718951e3a59d081eb09759152f93038479b768e3d612688f83f5 + md5: 0aa00f03f9e39fb9876085dee11a85d4 + depends: + - __glibc >=2.17,<3.0.a0 + - _openmp_mutex >=4.5 + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 1041788 + timestamp: 1771378212382 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgcc-15.2.0-h08519bb_18.conda + sha256: 83366f11615ab234aa1e0797393f9e07b78124b5a24c4a9f8af0113d02df818e + md5: 9a5cb96e43f5c2296690186e15b3296f + depends: + - _openmp_mutex + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 423025 + timestamp: 1771378225170 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgcc-15.2.0-hcbb3090_18.conda + sha256: 1d9c4f35586adb71bcd23e31b68b7f3e4c4ab89914c26bed5f2859290be5560e + md5: 92df6107310b1fff92c4cc84f0de247b + depends: + - _openmp_mutex + constrains: + - libgcc-ng ==15.2.0=*_18 + - libgomp 15.2.0 18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 401974 + timestamp: 1771378877463 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgcc-15.2.0-h8ee18e1_18.conda + sha256: da2c96563c76b8c601746f03e03ac75d2b4640fa2ee017cb23d6c9fc31f1b2c6 + md5: b085746891cca3bd2704a450a7b4b5ce + depends: + - _openmp_mutex >=4.5 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - libgcc-ng ==15.2.0=*_18 + - msys2-conda-epoch <0.0a0 + - libgomp 15.2.0 h8ee18e1_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 820022 + timestamp: 1771382190160 +- conda: https://conda.anaconda.org/conda-forge/noarch/libgcc-devel_linux-64-14.3.0-hf649bbc_118.conda + sha256: 1abc6a81ee66e8ac9ac09a26e2d6ad7bba23f0a0cc3a6118654f036f9c0e1854 + md5: 06901733131833f5edd68cf3d9679798 + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 3084533 + timestamp: 1771377786730 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_18.conda + sha256: e318a711400f536c81123e753d4c797a821021fb38970cebfb3f454126016893 + md5: d5e96b1ed75ca01906b3d2469b4ce493 + depends: + - libgcc 15.2.0 he0feb66_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27526 + timestamp: 1771378224552 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-h5fbf134_12.conda + sha256: 245be793e831170504f36213134f4c24eedaf39e634679809fd5391ad214480b + md5: 88c1c66987cd52a712eea89c27104be6 + depends: + - __glibc >=2.17,<3.0.a0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libgcc >=14 + - libjpeg-turbo >=3.1.2,<4.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: GD + license_family: BSD + size: 177306 + timestamp: 1766331805898 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgd-2.3.3-hb2c11ec_12.conda + sha256: bf7b0c25b6cca5808f4da46c5c363fa1192088b0b46efb730af43f28d52b8f04 + md5: e12673b408d1eb708adb3ecc2f621d78 + depends: + - __osx >=10.13 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libiconv >=1.18,<2.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: GD + license_family: BSD + size: 163145 + timestamp: 1766332198196 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgd-2.3.3-h05bcc79_12.conda + sha256: 269edce527e204a80d3d05673301e0207efcd0dbeebc036a118ceb52690d6341 + md5: fa4a92cfaae9570d89700a292a9ca714 + depends: + - __osx >=11.0 + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libiconv >=1.18,<2.0a0 + - libjpeg-turbo >=3.1.2,<4.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: GD + license_family: BSD + size: 159247 + timestamp: 1766331953491 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgd-2.3.3-h4974f7c_12.conda + sha256: 9ab562c718bd3fcef5f6189c8e2730c3d9321e05f13749a611630475d41207fc + md5: 3a5b40267fcd31f1ba3a24014fe92044 + depends: + - fontconfig >=2.15.0,<3.0a0 + - fonts-conda-ecosystem + - icu >=78.1,<79.0a0 + - libexpat >=2.7.3,<3.0a0 + - libfreetype >=2.14.1 + - libfreetype6 >=2.14.1 + - libjpeg-turbo >=3.1.2,<4.0a0 + - libpng >=1.6.53,<1.7.0a0 + - libtiff >=4.7.1,<4.8.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - xorg-libxpm >=3.5.17,<4.0a0 + license: GD + license_family: BSD + size: 166711 + timestamp: 1766331770351 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-15.2.0-h69a702a_18.conda + sha256: d2c9fad338fd85e4487424865da8e74006ab2e2475bd788f624d7a39b2a72aee + md5: 9063115da5bc35fdc3e1002e69b9ef6e + depends: + - libgfortran5 15.2.0 h68bc16d_18 + constrains: + - libgfortran-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27523 + timestamp: 1771378269450 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran-15.2.0-h7e5c614_18.conda + sha256: fb06c2a2ef06716a0f2a6550f5d13cdd1d89365993068512b7ae3c34e6e665d9 + md5: 34a9f67498721abcfef00178bcf4b190 + depends: + - libgfortran5 15.2.0 hd16e46c_18 + constrains: + - libgfortran-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 139761 + timestamp: 1771378423828 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-15.2.0-h07b0088_18.conda + sha256: 63f89087c3f0c8621c5c89ecceec1e56e5e1c84f65fc9c5feca33a07c570a836 + md5: 26981599908ed2205366e8fc91b37fc6 + depends: + - libgfortran5 15.2.0 hdae7583_18 + constrains: + - libgfortran-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 138973 + timestamp: 1771379054939 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-15.2.0-h68bc16d_18.conda + sha256: 539b57cf50ec85509a94ba9949b7e30717839e4d694bc94f30d41c9d34de2d12 + md5: 646855f357199a12f02a87382d429b75 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 2482475 + timestamp: 1771378241063 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libgfortran5-15.2.0-hd16e46c_18.conda + sha256: ddaf9dcf008c031b10987991aa78643e03c24a534ad420925cbd5851b31faa11 + md5: ca52daf58cea766656266c8771d8be81 + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 1062274 + timestamp: 1771378232014 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-15.2.0-hdae7583_18.conda + sha256: 91033978ba25e6a60fb86843cf7e1f7dc8ad513f9689f991c9ddabfaf0361e7e + md5: c4a6f7989cffb0544bfd9207b6789971 + depends: + - libgcc >=15.2.0 + constrains: + - libgfortran 15.2.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 598634 + timestamp: 1771378886363 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda + sha256: dc2752241fa3d9e40ce552c1942d0a4b5eeb93740c9723873f6fcf8d39ef8d2d + md5: 928b8be80851f5d8ffb016f9c81dae7a + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - libglx 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 134712 + timestamp: 1731330998354 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgl-devel-1.7.0-ha4b6fd6_2.conda + sha256: e281356c0975751f478c53e14f3efea6cd1e23c3069406d10708d6c409525260 + md5: 53e7cbb2beb03d69a478631e23e340e9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgl 1.7.0 ha4b6fd6_2 + - libglx-devel 1.7.0 ha4b6fd6_2 + license: LicenseRef-libglvnd + size: 113911 + timestamp: 1731331012126 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.86.4-h6548e54_1.conda + sha256: a27e44168a1240b15659888ce0d9b938ed4bdb49e9ea68a7c1ff27bcea8b55ce + md5: bb26456332b07f68bf3b7622ed71c0da + depends: + - __glibc >=2.17,<3.0.a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.4 *_1 + license: LGPL-2.1-or-later + size: 4398701 + timestamp: 1771863239578 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.86.4-hec30fc1_1.conda + sha256: d45fd67e18e793aeb2485a7efe3e882df594601ed6136ed1863c56109e4ad9e3 + md5: b8437d8dc24f46da3565d7f0c5a96d45 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.25.1,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.4 *_1 + license: LGPL-2.1-or-later + size: 4186085 + timestamp: 1771863964173 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.86.4-he378b5c_1.conda + sha256: a4254a241a96198e019ced2e0d2967e4c0ef64fac32077a45c065b32dc2b15d2 + md5: 673069f6725ed7b1073f9b96094294d1 + depends: + - __osx >=11.0 + - libffi >=3.5.2,<3.6.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.25.1,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + constrains: + - glib 2.86.4 *_1 + license: LGPL-2.1-or-later + size: 4108927 + timestamp: 1771864169970 +- conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.86.4-h0c9aed9_1.conda + sha256: f035fb25f8858f201e0055c719ef91022e9465cd51fe803304b781863286fb10 + md5: 0329a7e92c8c8b61fcaaf7ad44642a96 + depends: + - libffi >=3.5.2,<3.6.0a0 + - libiconv >=1.18,<2.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.3.1,<2.0a0 + - pcre2 >=10.47,<10.48.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - glib 2.86.4 *_1 + license: LGPL-2.1-or-later + size: 4095369 + timestamp: 1771863229701 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda + sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 + md5: 434ca7e50e40f4918ab701e3facd59a0 + depends: + - __glibc >=2.17,<3.0.a0 + license: LicenseRef-libglvnd + size: 132463 + timestamp: 1731330968309 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda + sha256: 2d35a679624a93ce5b3e9dd301fff92343db609b79f0363e6d0ceb3a6478bfa7 + md5: c8013e438185f33b13814c5c488acd5c + depends: + - __glibc >=2.17,<3.0.a0 + - libglvnd 1.7.0 ha4b6fd6_2 + - xorg-libx11 >=1.8.10,<2.0a0 + license: LicenseRef-libglvnd + size: 75504 + timestamp: 1731330988898 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libglx-devel-1.7.0-ha4b6fd6_2.conda + sha256: 0a930e0148ab6e61089bbcdba25a2e17ee383e7de82e7af10cc5c12c82c580f3 + md5: 27ac5ae872a21375d980bd4a6f99edf3 + depends: + - __glibc >=2.17,<3.0.a0 + - libglx 1.7.0 ha4b6fd6_2 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-xorgproto + license: LicenseRef-libglvnd + size: 26388 + timestamp: 1731331003255 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_18.conda + sha256: 21337ab58e5e0649d869ab168d4e609b033509de22521de1bfed0c031bfc5110 + md5: 239c5e9546c38a1e884d69effcf4c882 + depends: + - __glibc >=2.17,<3.0.a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 603262 + timestamp: 1771378117851 +- conda: https://conda.anaconda.org/conda-forge/win-64/libgomp-15.2.0-h8ee18e1_18.conda + sha256: 94981bc2e42374c737750895c6fdcfc43b7126c4fc788cad0ecc7281745931da + md5: 939fb173e2a4d4e980ef689e99b35223 + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + constrains: + - msys2-conda-epoch <0.0a0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 663864 + timestamp: 1771382118742 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libhiredis-1.3.0-h5888daf_1.conda + sha256: 5638e321719590b00826d218431d5028d1a22a76f281532ce621d9a40d5e0f42 + md5: aa342fcf3bc583660dbfdb2eae6be48e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + license: BSD-3-Clause + license_family: BSD + size: 140759 + timestamp: 1748219397797 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libhiredis-1.3.0-h240833e_1.conda + sha256: ae54db888afde29109b518bdffd6a7af6b35add881242a1cdf90807d8cb33143 + md5: 5a088b358e37ccb4f4e5c573ff37a9f9 + depends: + - __osx >=10.13 + - libcxx >=18 + license: BSD-3-Clause + license_family: BSD + size: 59830 + timestamp: 1748219625377 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhiredis-1.3.0-h286801f_1.conda + sha256: 8da7c0e83c1c9d1bda3569146bb5618ef78251c5f912afa5d4f1573aef6ef6c7 + md5: 58b2c5aee0ad58549bf92baead9baead + depends: + - __osx >=11.0 + - libcxx >=18 + license: BSD-3-Clause + license_family: BSD + size: 56746 + timestamp: 1748219528586 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhiredis-1.3.0-he0c23c2_1.conda + sha256: 9234de8c29f1a3a51bd37c94752e31b19c2514103821e895f6fabaa65e74ea5a + md5: 821660830c0152d3260633b150f92b49 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 64205 + timestamp: 1748219812303 +- conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.12.2-default_h4379cf1_1000.conda + sha256: 8cdf11333a81085468d9aa536ebb155abd74adc293576f6013fc0c85a7a90da3 + md5: 3b576f6860f838f950c570f4433b086e + depends: + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - libxml2 + - libxml2-16 >=2.14.6 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + size: 2411241 + timestamp: 1765104337762 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda + sha256: c467851a7312765447155e071752d7bf9bf44d610a5687e32706f480aad2833f + md5: 915f5995e94f60e9a4826e0b0920ee88 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: LGPL-2.1-only + size: 790176 + timestamp: 1754908768807 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda + sha256: a1c8cecdf9966921e13f0ae921309a1f415dfbd2b791f2117cf7e8f5e61a48b6 + md5: 210a85a1119f97ea7887188d176db135 + depends: + - __osx >=10.13 + license: LGPL-2.1-only + size: 737846 + timestamp: 1754908900138 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda + sha256: de0336e800b2af9a40bdd694b03870ac4a848161b35c8a2325704f123f185f03 + md5: 4d5a7445f0b25b6a3ddbb56e790f5251 + depends: + - __osx >=11.0 + license: LGPL-2.1-only + size: 750379 + timestamp: 1754909073836 +- conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.18-hc1393d2_2.conda + sha256: 0dcdb1a5f01863ac4e8ba006a8b0dc1a02d2221ec3319b5915a1863254d7efa7 + md5: 64571d1dd6cdcfa25d0664a5950fdaa2 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LGPL-2.1-only + size: 696926 + timestamp: 1754909290005 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda + sha256: 8c352744517bc62d24539d1ecc813b9fdc8a785c780197c5f0b84ec5b0dfe122 + md5: a8e54eefc65645193c46e8b180f62d22 + depends: + - __osx >=10.13 + - libiconv >=1.18,<2.0a0 + license: LGPL-2.1-or-later + size: 96909 + timestamp: 1753343977382 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda + sha256: 99d2cebcd8f84961b86784451b010f5f0a795ed1c08f1e7c76fbb3c22abf021a + md5: 5103f6a6b210a3912faf8d7db516918c + depends: + - __osx >=11.0 + - libiconv >=1.18,<2.0a0 + license: LGPL-2.1-or-later + size: 90957 + timestamp: 1751558394144 +- conda: https://conda.anaconda.org/conda-forge/win-64/libintl-0.22.5-h5728263_3.conda + sha256: c7e4600f28bcada8ea81456a6530c2329312519efcf0c886030ada38976b0511 + md5: 2cf0cf76cc15d360dfa2f17fd6cf9772 + depends: + - libiconv >=1.17,<2.0a0 + license: LGPL-2.1-or-later + size: 95568 + timestamp: 1723629479451 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libjpeg-turbo-3.1.2-hb03c661_0.conda + sha256: cc9aba923eea0af8e30e0f94f2ad7156e2984d80d1e8e7fe6be5a1f257f0eb32 + md5: 8397539e3a0bbd1695584fb4f927485a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + size: 633710 + timestamp: 1762094827865 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libjpeg-turbo-3.1.2-h8616949_0.conda + sha256: ebe2877abc046688d6ea299e80d8322d10c69763f13a102010f90f7168cc5f54 + md5: 48dda187f169f5a8f1e5e07701d5cdd9 + depends: + - __osx >=10.13 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + size: 586189 + timestamp: 1762095332781 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libjpeg-turbo-3.1.2-hc919400_0.conda + sha256: 6c061c56058bb10374daaef50e81b39cf43e8aee21f0037022c0c39c4f31872f + md5: f0695fbecf1006f27f4395d64bd0c4b8 + depends: + - __osx >=11.0 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + size: 551197 + timestamp: 1762095054358 +- conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.1.2-hfd05255_0.conda + sha256: 795e2d4feb2f7fc4a2c6e921871575feb32b8082b5760726791f080d1e2c2597 + md5: 56a686f92ac0273c0f6af58858a3f013 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - jpeg <0.0.0a + license: IJG AND BSD-3-Clause AND Zlib + size: 841783 + timestamp: 1762094814336 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.11.0-6_h47877c9_openblas.conda + build_number: 6 + sha256: 371f517eb7010b21c6cc882c7606daccebb943307cb9a3bf2c70456a5c024f7d + md5: 881d801569b201c2e753f03c84b85e15 + depends: + - libblas 3.11.0 6_h4a7cf45_openblas + constrains: + - blas 2.306 openblas + - liblapacke 3.11.0 6*_openblas + - libcblas 3.11.0 6*_openblas + license: BSD-3-Clause + license_family: BSD + size: 18624 + timestamp: 1774503065378 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblapack-3.11.0-6_h859234e_openblas.conda + build_number: 6 + sha256: 27aa20356e85f5fda5651866fed28e145dc98587f0bdd358a07d87bf1a68e427 + md5: 0808639f35afc076d89375aac666e8cb + depends: + - libblas 3.11.0 6_he492b99_openblas + constrains: + - libcblas 3.11.0 6*_openblas + - liblapacke 3.11.0 6*_openblas + - blas 2.306 openblas + license: BSD-3-Clause + license_family: BSD + size: 18727 + timestamp: 1774503690636 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.11.0-6_hd9741b5_openblas.conda + build_number: 6 + sha256: 21606b7346810559e259807497b86f438950cf19e71838e44ebaf4bd2b35b549 + md5: ee33d2d05a7c5ea1f67653b37eb74db1 + depends: + - libblas 3.11.0 6_h51639a9_openblas + constrains: + - liblapacke 3.11.0 6*_openblas + - libcblas 3.11.0 6*_openblas + - blas 2.306 openblas + license: BSD-3-Clause + license_family: BSD + size: 18863 + timestamp: 1774504467905 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.11.0-6_hf9ab0e9_mkl.conda + build_number: 6 + sha256: 2e6ac39e456ba13ec8f02fc0787b8a22c89780e24bd5556eaf642177463ffb36 + md5: 7e9cdaf6f302142bc363bbab3b5e7074 + depends: + - libblas 3.11.0 6_hf2e6a31_mkl + constrains: + - blas 2.306 mkl + - liblapacke 3.11.0 6*_mkl + - libcblas 3.11.0 6*_mkl + license: BSD-3-Clause + license_family: BSD + size: 80571 + timestamp: 1774503757128 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm19-19.1.7-h56e7563_2.conda + sha256: 375a634873b7441d5101e6e2a9d3a42fec51be392306a03a2fa12ae8edecec1a + md5: 05a54b479099676e75f80ad0ddd38eff + depends: + - __osx >=10.13 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 28801374 + timestamp: 1757354631264 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm19-19.1.7-h8e0c9ce_2.conda + sha256: 46f8ff3d86438c0af1bebe0c18261ce5de9878d58b4fe399a3a125670e4f0af5 + md5: d1d9b233830f6631800acc1e081a9444 + depends: + - __osx >=11.0 + - libcxx >=19 + - libxml2 + - libxml2-16 >=2.14.5 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 26914852 + timestamp: 1757353228286 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.2-hb03c661_0.conda + sha256: 755c55ebab181d678c12e49cced893598f2bab22d582fbbf4d8b83c18be207eb + md5: c7c83eecbb72d88b940c249af56c8b17 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - xz 5.8.2.* + license: 0BSD + size: 113207 + timestamp: 1768752626120 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.2-h11316ed_0.conda + sha256: 7ab3c98abd3b5d5ec72faa8d9f5d4b50dcee4970ed05339bc381861199dabb41 + md5: 688a0c3d57fa118b9c97bf7e471ab46c + depends: + - __osx >=10.13 + constrains: + - xz 5.8.2.* + license: 0BSD + size: 105482 + timestamp: 1768753411348 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.2-h8088a28_0.conda + sha256: 7bfc7ffb2d6a9629357a70d4eadeadb6f88fa26ebc28f606b1c1e5e5ed99dc7e + md5: 009f0d956d7bfb00de86901d16e486c7 + depends: + - __osx >=11.0 + constrains: + - xz 5.8.2.* + license: 0BSD + size: 92242 + timestamp: 1768752982486 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.2-hfd05255_0.conda + sha256: f25bf293f550c8ed2e0c7145eb404324611cfccff37660869d97abf526eb957c + md5: ba0bfd4c3cf73f299ffe46ff0eaeb8e3 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - xz 5.8.2.* + license: 0BSD + size: 106169 + timestamp: 1768752763559 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmatio-1.5.30-he0a2e19_0.conda + sha256: c9ac2d45e7504a4844f3b56dbac2c78330d67a64432b1ae47de9d7059548edf9 + md5: c253b59cce00f8d6a7588500ff3597b7 + depends: + - __glibc >=2.17,<3.0.a0 + - hdf5 >=1.14.6,<1.14.7.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + - zlib + license: BSD-2-Clause + license_family: BSD + size: 202346 + timestamp: 1767753592345 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmatio-1.5.30-h0881fde_0.conda + sha256: 833c5ed61d6dc4896c2d7cc65484c9b0858365c03dbe49f55d7b86816386ceea + md5: 3ba5a3b1713109406ead5793ffc9c088 + depends: + - __osx >=10.13 + - hdf5 >=1.14.6,<1.14.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - zlib + license: BSD-2-Clause + license_family: BSD + size: 195363 + timestamp: 1767754723797 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmatio-1.5.30-h8eade5c_0.conda + sha256: 80b60a764c75bd3153d29751403142a7254376fa02ce6035f36f64134d24b784 + md5: 5bea68d5a5e10226b130f456921a1a57 + depends: + - __osx >=11.0 + - hdf5 >=1.14.6,<1.14.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - zlib + license: BSD-2-Clause + license_family: BSD + size: 174283 + timestamp: 1767753950525 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmatio-1.5.30-hbeb426f_0.conda + sha256: 733183c1dc37501af50a6e32afaac287e5aa3383d0829faaaa45c3b4993bf325 + md5: 379cd16225411177a51f9bab3619f145 + depends: + - hdf5 >=1.14.6,<1.14.7.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zlib + license: BSD-2-Clause + license_family: BSD + size: 186697 + timestamp: 1767753708811 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda + sha256: fe171ed5cf5959993d43ff72de7596e8ac2853e9021dec0344e583734f1e0843 + md5: 2c21e66f50753a083cbe6b80f38268fa + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: BSD-2-Clause + license_family: BSD + size: 92400 + timestamp: 1769482286018 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hf3981d6_1.conda + sha256: 1096c740109386607938ab9f09a7e9bca06d86770a284777586d6c378b8fb3fd + md5: ec88ba8a245855935b871a7324373105 + depends: + - __osx >=10.13 + license: BSD-2-Clause + license_family: BSD + size: 79899 + timestamp: 1769482558610 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda + sha256: 1089c7f15d5b62c622625ec6700732ece83be8b705da8c6607f4dabb0c4bd6d2 + md5: 57c4be259f5e0b99a5983799a228ae55 + depends: + - __osx >=11.0 + license: BSD-2-Clause + license_family: BSD + size: 73690 + timestamp: 1769482560514 +- conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-hfd05255_1.conda + sha256: 40dcd0b9522a6e0af72a9db0ced619176e7cfdb114855c7a64f278e73f8a7514 + md5: e4a9fc2bba3b022dad998c78856afe47 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-2-Clause + license_family: BSD + size: 89411 + timestamp: 1769482314283 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.68.1-h877daf1_0.conda + sha256: 663444d77a42f2265f54fb8b48c5450bfff4388d9c0f8253dd7855f0d993153f + md5: 2a45e7f8af083626f009645a6481f12d + depends: + - __glibc >=2.17,<3.0.a0 + - c-ares >=1.34.6,<2.0a0 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libgcc >=14 + - libstdcxx >=14 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 663344 + timestamp: 1773854035739 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.68.1-h70048d4_0.conda + sha256: 899551e16aac9dfb85bfc2fd98b655f4d1b7fea45720ec04ccb93d95b4d24798 + md5: dba4c95e2fe24adcae4b77ebf33559ae + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 606749 + timestamp: 1773854765508 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.68.1-h8f3e76b_0.conda + sha256: 2bc7bc3978066f2c274ebcbf711850cc9ab92e023e433b9631958a098d11e10a + md5: 6ea18834adbc3b33df9bd9fb45eaf95b + depends: + - __osx >=11.0 + - c-ares >=1.34.6,<2.0a0 + - libcxx >=19 + - libev >=4.33,<4.34.0a0 + - libev >=4.33,<5.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + license: MIT + license_family: MIT + size: 576526 + timestamp: 1773854624224 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.32-pthreads_h94d23a6_0.conda + sha256: 6dc30b28f32737a1c52dada10c8f3a41bc9e021854215efca04a7f00487d09d9 + md5: 89d61bc91d3f39fda0ca10fcd3c68594 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + constrains: + - openblas >=0.3.32,<0.3.33.0a0 + license: BSD-3-Clause + license_family: BSD + size: 5928890 + timestamp: 1774471724897 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.32-openmp_h9e49c7b_0.conda + sha256: 6764229359cd927c9efc036930ba28f83436b8d6759c5ac4ea9242fc29a7184e + md5: 4058c5f8dbef6d28cb069f96b95ae6df + depends: + - __osx >=11.0 + - libgfortran + - libgfortran5 >=14.3.0 + - llvm-openmp >=19.1.7 + constrains: + - openblas >=0.3.32,<0.3.33.0a0 + license: BSD-3-Clause + license_family: BSD + size: 6289730 + timestamp: 1774474444702 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.32-openmp_he657e61_0.conda + sha256: 713e453bde3531c22a660577e59bf91ef578dcdfd5edb1253a399fa23514949a + md5: 3a1111a4b6626abebe8b978bb5a323bf + depends: + - __osx >=11.0 + - libgfortran + - libgfortran5 >=14.3.0 + - llvm-openmp >=19.1.7 + constrains: + - openblas >=0.3.32,<0.3.33.0a0 + license: BSD-3-Clause + license_family: BSD + size: 4308797 + timestamp: 1774472508546 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda + sha256: 0bd91de9b447a2991e666f284ae8c722ffb1d84acb594dbd0c031bd656fa32b2 + md5: 70e3400cbbfa03e96dcde7fc13e38c7b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 28424 + timestamp: 1749901812541 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.56-h421ea60_0.conda + sha256: 4f9fca3bc21e485ec0b3eb88db108b6cf9ab9a481cdf7d2ac6f9d30350b45ead + md5: 97169784f0775c85683c3d8badcea2c3 + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + size: 317540 + timestamp: 1774513272700 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libpng-1.6.56-he930e7c_0.conda + sha256: aa1f03701b8d6e22d1caea2c4a368cf0c35b3f9edb01fa78cc87b673d7d76f5a + md5: 635ddc7697d405386dcb64d777c545b5 + depends: + - __osx >=11.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + size: 299085 + timestamp: 1774513337570 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.56-h132b30e_0.conda + sha256: 3aac73e6c8b2d6dc38f8918c8de3354ed920db00fd9234c000b20fd66323c463 + md5: ce25ae471d213f9dd5edb0fe8e0b102a + depends: + - __osx >=11.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + size: 289288 + timestamp: 1774513431937 +- conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.56-h7351971_0.conda + sha256: 0ab8890b7551bae4fc2a1aada8937789a6205c9ba9f322552a24e97b2d9b33b8 + md5: bedc0fc6a8fb31b8013878ea20c76bae + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.2,<2.0a0 + license: zlib-acknowledgement + size: 383766 + timestamp: 1774513353959 +- conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.62.1-h4c96295_0.conda + sha256: dc4698b32b2ca3fc0715d7d307476a71622bee0f2f708f9dadec8af21e1047c8 + md5: a4b87f1fbcdbb8ad32e99c2611120f2e + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.5,<3.0a0 + - harfbuzz >=13.1.1 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + constrains: + - __glibc >=2.17 + license: LGPL-2.1-or-later + size: 3474421 + timestamp: 1773814909137 +- conda: https://conda.anaconda.org/conda-forge/osx-64/librsvg-2.62.1-h7321050_0.conda + sha256: ef63983208a0037d5eef331ea157bf892c73e0a73e41692fd02471fb48a7f920 + md5: 471e8234c120e51c76dada4f86fc8ed5 + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.5,<3.0a0 + - harfbuzz >=13.1.1 + - libglib >=2.86.4,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + constrains: + - __osx >=10.13 + license: LGPL-2.1-or-later + size: 2517667 + timestamp: 1773816126648 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.62.1-he8aa2a2_0.conda + sha256: 4d28ad0213fca6f93624c27f13493b986ce63e05386d2ff7a2ad723c4e7c7cec + md5: 4766fd69e64e477b500eb901dbe7bb6b + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - gdk-pixbuf >=2.44.5,<3.0a0 + - harfbuzz >=13.1.1 + - libglib >=2.86.4,<3.0a0 + - libxml2-16 >=2.14.6 + - pango >=1.56.4,<2.0a0 + constrains: + - __osx >=11.0 + license: LGPL-2.1-or-later + size: 2402915 + timestamp: 1773816188394 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsanitizer-14.3.0-h8f1669f_18.conda + sha256: e03ed186eefb46d7800224ad34bad1268c9d19ecb8f621380a50601c6221a4a7 + md5: ad3a0e2dc4cce549b2860e2ef0e6d75b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14.3.0 + - libstdcxx >=14.3.0 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 7949259 + timestamp: 1771377982207 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsigtool-0.1.3-hc0f2934_0.conda + sha256: f87b743d5ab11c1a8ddd800dd9357fc0fabe47686068232ddc1d1eed0d7321ec + md5: 3576aba85ce5e9ab15aa0ea376ab864b + depends: + - __osx >=10.13 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + size: 38085 + timestamp: 1767044977731 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsigtool-0.1.3-h98dc951_0.conda + sha256: 421f7bd7caaa945d9cd5d374cc3f01e75637ca7372a32d5e7695c825a48a30d1 + md5: c08557d00807785decafb932b5be7ef5 + depends: + - __osx >=11.0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + size: 36416 + timestamp: 1767045062496 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.52.0-hf4e2dac_0.conda + sha256: d716847b7deca293d2e49ed1c8ab9e4b9e04b9d780aea49a97c26925b28a7993 + md5: fd893f6a3002a635b5e50ceb9dd2c0f4 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.2,<79.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: blessing + size: 951405 + timestamp: 1772818874251 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.52.0-h77d7759_0.conda + sha256: f500d1cd50cfcd288d02b8fc3c3b7ecf8de6fec7b86e57ea058def02908e4231 + md5: d553eb96758e038b04027b30fe314b2d + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: blessing + size: 996526 + timestamp: 1772819669038 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.52.0-h1ae2325_0.conda + sha256: beb0fd5594d6d7c7cd42c992b6bb4d66cbb39d6c94a8234f15956da99a04306c + md5: f6233a3fddc35a2ec9f617f79d6f3d71 + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libzlib >=1.3.1,<2.0a0 + license: blessing + size: 918420 + timestamp: 1772819478684 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.52.0-hf5d6505_0.conda + sha256: 5fccf1e4e4062f8b9a554abf4f9735a98e70f82e2865d0bfdb47b9de94887583 + md5: 8830689d537fda55f990620680934bb1 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + size: 1297302 + timestamp: 1772818899033 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.1-hcf80075_0.conda + sha256: fa39bfd69228a13e553bd24601332b7cfeb30ca11a3ca50bb028108fe90a7661 + md5: eecce068c7e4eddeb169591baac20ac4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 304790 + timestamp: 1745608545575 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.1-hed3591d_0.conda + sha256: 00654ba9e5f73aa1f75c1f69db34a19029e970a4aeb0fa8615934d8e9c369c3c + md5: a6cb15db1c2dc4d3a5f6cf3772e09e81 + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 284216 + timestamp: 1745608575796 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.1-h1590b86_0.conda + sha256: 8bfe837221390ffc6f111ecca24fa12d4a6325da0c8d131333d63d6c37f27e0a + md5: b68e8f66b94b44aaa8de4583d3d4cc40 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 279193 + timestamp: 1745608793272 +- conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.1-h9aa295b_0.conda + sha256: cbdf93898f2e27cefca5f3fe46519335d1fab25c4ea2a11b11502ff63e602c09 + md5: 9dce2f112bfd3400f4f432b3d0ac07b2 + depends: + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 292785 + timestamp: 1745608759342 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_18.conda + sha256: 78668020064fdaa27e9ab65cd2997e2c837b564ab26ce3bf0e58a2ce1a525c6e + md5: 1b08cd684f34175e4514474793d44bcb + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_18 + constrains: + - libstdcxx-ng ==15.2.0=*_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 5852330 + timestamp: 1771378262446 +- conda: https://conda.anaconda.org/conda-forge/noarch/libstdcxx-devel_linux-64-14.3.0-h9f08a49_118.conda + sha256: b1c3824769b92a1486bf3e2cc5f13304d83ae613ea061b7bc47bb6080d6dfdba + md5: 865a399bce236119301ebd1532fced8d + depends: + - __unix + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 20171098 + timestamp: 1771377827750 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-15.2.0-hdf11a46_18.conda + sha256: 3c902ffd673cb3c6ddde624cdb80f870b6c835f8bf28384b0016e7d444dd0145 + md5: 6235adb93d064ecdf3d44faee6f468de + depends: + - libstdcxx 15.2.0 h934c35e_18 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 27575 + timestamp: 1771378314494 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.7.1-h9d88235_1.conda + sha256: e5f8c38625aa6d567809733ae04bb71c161a42e44a9fa8227abe61fa5c60ebe0 + md5: cd5a90476766d53e901500df9215e927 + depends: + - __glibc >=2.17,<3.0.a0 + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.25,<1.26.0a0 + - libgcc >=14 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libstdcxx >=14 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 435273 + timestamp: 1762022005702 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.7.1-ha0a348c_1.conda + sha256: e53424c34147301beae2cd9223ebf593720d94c038b3f03cacd0535e12c9668e + md5: 9d4344f94de4ab1330cdc41c40152ea6 + depends: + - __osx >=10.13 + - lerc >=4.0.0,<5.0a0 + - libcxx >=19 + - libdeflate >=1.25,<1.26.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 404591 + timestamp: 1762022511178 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.7.1-h4030677_1.conda + sha256: e9248077b3fa63db94caca42c8dbc6949c6f32f94d1cafad127f9005d9b1507f + md5: e2a72ab2fa54ecb6abab2b26cde93500 + depends: + - __osx >=11.0 + - lerc >=4.0.0,<5.0a0 + - libcxx >=19 + - libdeflate >=1.25,<1.26.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libwebp-base >=1.6.0,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 373892 + timestamp: 1762022345545 +- conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.7.1-h8f73337_1.conda + sha256: f1b8cccaaeea38a28b9cd496694b2e3d372bb5be0e9377c9e3d14b330d1cba8a + md5: 549845d5133100142452812feb9ba2e8 + depends: + - lerc >=4.0.0,<5.0a0 + - libdeflate >=1.25,<1.26.0a0 + - libjpeg-turbo >=3.1.0,<4.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: HPND + size: 993166 + timestamp: 1762022118895 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.4-h5347b49_0.conda + sha256: eeadbc59678103a9405bae26f5251d744a114fcab79e79d9b68fec36c4cdb43b + md5: 2b4d2e6978dd06af374b50abca6d374b + depends: + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: BSD-3-Clause + size: 40283 + timestamp: 1775040819467 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuv-1.51.0-hb03c661_1.conda + sha256: c180f4124a889ac343fc59d15558e93667d894a966ec6fdb61da1604481be26b + md5: 0f03292cc56bf91a077a134ea8747118 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 895108 + timestamp: 1753948278280 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libuv-1.51.0-h58003a5_1.conda + sha256: d90dd0eee6f195a5bd14edab4c5b33be3635b674b0b6c010fb942b956aa2254c + md5: fbfc6cf607ae1e1e498734e256561dc3 + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 422612 + timestamp: 1753948458902 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libuv-1.51.0-h6caf38d_1.conda + sha256: 042c7488ad97a5629ec0a991a8b2a3345599401ecc75ad6a5af73b60e6db9689 + md5: c0d87c3c8e075daf1daf6c31b53e8083 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 421195 + timestamp: 1753948426421 +- conda: https://conda.anaconda.org/conda-forge/win-64/libuv-1.51.0-hfd05255_1.conda + sha256: f03dc82e6fb1725788e73ae97f0cd3d820d5af0d351a274104a0767035444c59 + md5: 31e1545994c48efc3e6ea32ca02a8724 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: MIT + license_family: MIT + size: 297087 + timestamp: 1753948490874 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.6.0-hd42ef1d_0.conda + sha256: 3aed21ab28eddffdaf7f804f49be7a7d701e8f0e46c856d801270b470820a37b + md5: aea31d2e5b1091feca96fcfe945c3cf9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + size: 429011 + timestamp: 1752159441324 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.6.0-hb807250_0.conda + sha256: 00dbfe574b5d9b9b2b519acb07545380a6bc98d1f76a02695be4995d4ec91391 + md5: 7bb6608cf1f83578587297a158a6630b + depends: + - __osx >=10.13 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + size: 365086 + timestamp: 1752159528504 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.6.0-h07db88b_0.conda + sha256: a4de3f371bb7ada325e1f27a4ef7bcc81b2b6a330e46fac9c2f78ac0755ea3dd + md5: e5e7d467f80da752be17796b87fe6385 + depends: + - __osx >=11.0 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + size: 294974 + timestamp: 1752159906788 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.6.0-h4d5522a_0.conda + sha256: 7b6316abfea1007e100922760e9b8c820d6fc19df3f42fb5aca684cfacb31843 + md5: f9bbae5e2537e3b06e0f7310ba76c893 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libwebp 1.6.0 + license: BSD-3-Clause + license_family: BSD + size: 279176 + timestamp: 1752159543911 +- conda: https://conda.anaconda.org/conda-forge/win-64/libwinpthread-12.0.0.r4.gg4f2fc60ca-h57928b3_10.conda + sha256: 0fccf2d17026255b6e10ace1f191d0a2a18f2d65088fd02430be17c701f8ffe0 + md5: 8a86073cf3b343b87d03f41790d8b4e5 + depends: + - ucrt + constrains: + - pthreads-win32 <0.0a0 + - msys2-conda-epoch <0.0a0 + license: MIT AND BSD-3-Clause-Clear + size: 36621 + timestamp: 1759768399557 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda + sha256: 666c0c431b23c6cec6e492840b176dde533d48b7e6fb8883f5071223433776aa + md5: 92ed62436b625154323d40d5f2f11dd7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - pthread-stubs + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + size: 395888 + timestamp: 1727278577118 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.17.0-h0e4246c_0.conda + sha256: 08dec73df0e161c96765468847298a420933a36bc4f09b50e062df8793290737 + md5: a69bbf778a462da324489976c84cfc8c + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - pthread-stubs + - ucrt >=10.0.20348.0 + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxdmcp + license: MIT + license_family: MIT + size: 1208687 + timestamp: 1727279378819 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.13.1-hca5e8e5_0.conda + sha256: d2195b5fbcb0af1ff7b345efdf89290c279b8d1d74f325ae0ac98148c375863c + md5: 2bca1fbb221d9c3c8e3a155784bbc2e9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - libxcb >=1.17.0,<2.0a0 + - libxml2 + - libxml2-16 >=2.14.6 + - xkeyboard-config + - xorg-libxau >=1.0.12,<2.0a0 + license: MIT/X11 Derivative + license_family: MIT + size: 837922 + timestamp: 1764794163823 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.15.2-he237659_0.conda + sha256: 275c324f87bda1a3b67d2f4fcc3555eeff9e228a37655aa001284a7ceb6b0392 + md5: e49238a1609f9a4a844b09d9926f2c3d + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.2,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libxml2-16 2.15.2 hca6bf5a_0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 45968 + timestamp: 1772704614539 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.15.2-hd552753_0.conda + sha256: 5b9e8a5146275ac0539231f646ee51a9e4629e730026ff69dadff35bfb745911 + md5: eea3155f3b4a3b75af504c871ec23858 + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libxml2-16 2.15.2 h7a90416_0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 41106 + timestamp: 1772705465931 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.15.2-h8d039ee_0.conda + sha256: 99cb32dd06a2e58c12981b71a84b052293f27b5ab042e3f21d895f5d7ee13eff + md5: e476ba84e57f2bd2004a27381812ad4e + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libxml2-16 2.15.2 h5ef1a60_0 + - libzlib >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 41206 + timestamp: 1772704982288 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.15.2-h5d26750_0.conda + sha256: f905eb7046987c336122121759e7f09144729f6898f48cd06df2a945b86998d8 + md5: 1007e1bfe181a2aee214779ee7f13d30 + depends: + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libxml2-16 2.15.2 h692994f_0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - icu <0.0a0 + license: MIT + license_family: MIT + size: 43681 + timestamp: 1772704748950 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-16-2.15.2-hca6bf5a_0.conda + sha256: 08d2b34b49bec9613784f868209bb7c3bb8840d6cf835ff692e036b09745188c + md5: f3bc152cb4f86babe30f3a4bf0dbef69 + depends: + - __glibc >=2.17,<3.0.a0 + - icu >=78.2,<79.0a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.2 + license: MIT + license_family: MIT + size: 557492 + timestamp: 1772704601644 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-16-2.15.2-h7a90416_0.conda + sha256: f67e4b7d7f97e57ecd611a42e42d5f6c047fd3d1eb8270813b888924440c8a59 + md5: 0c8bdbfd118f5963ab343846094932a3 + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.2 + license: MIT + license_family: MIT + size: 495922 + timestamp: 1772705426323 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-16-2.15.2-h5ef1a60_0.conda + sha256: 6432259204e78c8a8a815afae987fbf60bd722605fe2c4b022e65196b17d4537 + md5: b284e2b02d53ef7981613839fb86beee + depends: + - __osx >=11.0 + - icu >=78.2,<79.0a0 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.2 + license: MIT + license_family: MIT + size: 466220 + timestamp: 1772704950232 +- conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-16-2.15.2-h692994f_0.conda + sha256: b8c71b3b609c7cfe17f3f2a47c75394d7b30acfb8b34ad7a049ea8757b4d33df + md5: e365238134188e42ed36ee996159d482 + depends: + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.2,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - libxml2 2.15.2 + - icu <0.0a0 + license: MIT + license_family: MIT + size: 520078 + timestamp: 1772704728534 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda + sha256: 55044c403570f0dc26e6364de4dc5368e5f3fc7ff103e867c487e2b5ab2bcda9 + md5: d87ff7921124eccd67248aa483c23fec + depends: + - __glibc >=2.17,<3.0.a0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + size: 63629 + timestamp: 1774072609062 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.2-hbb4bfdb_2.conda + sha256: 4c6da089952b2d70150c74234679d6f7ac04f4a98f9432dec724968f912691e7 + md5: 30439ff30578e504ee5e0b390afc8c65 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + size: 59000 + timestamp: 1774073052242 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda + sha256: 361415a698514b19a852f5d1123c5da746d4642139904156ddfca7c922d23a05 + md5: bc5a5721b6439f2f62a84f2548136082 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + size: 47759 + timestamp: 1774072956767 +- conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.2-hfd05255_2.conda + sha256: 88609816e0cc7452bac637aaf65783e5edf4fee8a9f8e22bdc3a75882c536061 + md5: dbabbd6234dea34040e631f87676292f + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - zlib 1.3.2 *_2 + license: Zlib + license_family: Other + size: 58347 + timestamp: 1774072851498 +- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-22.1.2-h0d3cbff_0.conda + sha256: 5dc4c6f21d97d608d5889227e36f77e3316be63464000df4b23194a9b10d1017 + md5: 2f82b78f43520355ae2d297fecde25fd + depends: + - __osx >=11.0 + constrains: + - openmp 22.1.2|22.1.2.* + - intel-openmp <0.0a0 + license: Apache-2.0 WITH LLVM-exception + size: 310956 + timestamp: 1774732996355 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-22.1.2-hc7d1edf_0.conda + sha256: d8acb8e790312346a286f7168380ca3ce86d5982fb073df6e0fbec1e51fa47a1 + md5: 9c162044093d8d689836dafe3c27fe06 + depends: + - __osx >=11.0 + constrains: + - intel-openmp <0.0a0 + - openmp 22.1.2|22.1.2.* + license: Apache-2.0 WITH LLVM-exception + size: 285695 + timestamp: 1774733561929 +- conda: https://conda.anaconda.org/conda-forge/win-64/llvm-openmp-22.1.2-h4fa8253_0.conda + sha256: fa8bd542624507309cbdfc620bdfe546ed823d418e6ba878977d48da7a0f6212 + md5: 29407a30bd93dc8c11c03ca60249a340 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + constrains: + - intel-openmp <0.0a0 + - openmp 22.1.2|22.1.2.* + license: Apache-2.0 WITH LLVM-exception + size: 348400 + timestamp: 1774733045609 +- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19.1.7-hb0207f0_2.conda + sha256: 8d042ee522bc9eb12c061f5f7e53052aeb4f13e576e624c8bebaf493725b95a0 + md5: 0f79b23c03d80f22ce4fe0022d12f6d2 + depends: + - __osx >=10.13 + - libllvm19 19.1.7 h56e7563_2 + - llvm-tools-19 19.1.7 h879f4bc_2 + constrains: + - llvmdev 19.1.7 + - llvm 19.1.7 + - clang 19.1.7 + - clang-tools 19.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 87962 + timestamp: 1757355027273 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19.1.7-h855ad52_2.conda + sha256: 09750c33b5d694c494cad9eafda56c61a62622264173d760341b49fb001afe82 + md5: 3e3ac06efc5fdc1aa675ca30bf7d53df + depends: + - __osx >=11.0 + - libllvm19 19.1.7 h8e0c9ce_2 + - llvm-tools-19 19.1.7 h91fd4e7_2 + constrains: + - llvm 19.1.7 + - llvmdev 19.1.7 + - clang-tools 19.1.7 + - clang 19.1.7 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 88390 + timestamp: 1757353535760 +- conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-tools-19-19.1.7-h879f4bc_2.conda + sha256: fd281acb243323087ce672139f03a1b35ceb0e864a3b4e8113b9c23ca1f83bf0 + md5: bf644c6f69854656aa02d1520175840e + depends: + - __osx >=10.13 + - libcxx >=19 + - libllvm19 19.1.7 h56e7563_2 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 17198870 + timestamp: 1757354915882 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-tools-19-19.1.7-h91fd4e7_2.conda + sha256: 73f9506f7c32a448071340e73a0e8461e349082d63ecc4849e3eb2d1efc357dd + md5: 8237b150fcd7baf65258eef9a0fc76ef + depends: + - __osx >=11.0 + - libcxx >=19 + - libllvm19 19.1.7 h8e0c9ce_2 + - libzlib >=1.3.1,<2.0a0 + - zstd >=1.5.7,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 16376095 + timestamp: 1757353442671 +- conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2025.3.1-hac47afa_11.conda + sha256: f2c2b2a3c2e7d08d78c10bef7c135a4262c80d1d48c85fb5902ca30d61d645f4 + md5: 3fd3009cef89c36e9898a6feeb0f5530 + depends: + - llvm-openmp >=22.1.1 + - tbb >=2022.3.0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 + license_family: Proprietary + size: 99997309 + timestamp: 1774449747739 +- conda: https://conda.anaconda.org/conda-forge/noarch/nanobind-2.12.0-pyhd8ed1ab_0.conda + sha256: 1f8af3e0763f767ace08781ca2666abf8d583b22256cc9e24563a2a1b35f3256 + md5: 923dda44fad6020b9ebf1496f8acf759 + depends: + - python >=3.10 + constrains: + - nanobind-abi ==19 + license: BSD-3-Clause + license_family: BSD + size: 185194 + timestamp: 1772060965521 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 + md5: 47e340acb35de30501a76c7c799c41d7 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: X11 AND BSD-3-Clause + size: 891641 + timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + sha256: ea4a5d27ded18443749aefa49dc79f6356da8506d508b5296f60b8d51e0c4bd9 + md5: ced34dd9929f491ca6dab6a2927aff25 + depends: + - __osx >=10.13 + license: X11 AND BSD-3-Clause + size: 822259 + timestamp: 1738196181298 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 + md5: 068d497125e4bf8a66bf707254fff5ae + depends: + - __osx >=11.0 + license: X11 AND BSD-3-Clause + size: 797030 + timestamp: 1738196177597 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ninja-1.13.2-h171cf75_0.conda + sha256: 6f7d59dbec0a7b00bf5d103a4306e8886678b796ff2151b62452d4582b2a53fb + md5: b518e9e92493721281a60fa975bddc65 + depends: + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: Apache-2.0 + license_family: APACHE + size: 186323 + timestamp: 1763688260928 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ninja-1.13.2-hfc0b2d5_0.conda + sha256: 1646832e3c2389595569ab9a6234c119a4dedf6f4e55532a8bf07edab7f8037d + md5: afda563484aa0017278866707807a335 + depends: + - libcxx >=19 + - __osx >=10.13 + license: Apache-2.0 + license_family: APACHE + size: 178071 + timestamp: 1763688235442 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ninja-1.13.2-h49c215f_0.conda + sha256: 18d33c17b28d4771fc0b91b7b963c9ce31aca0a9af7dc8e9ee7c974bb207192c + md5: 175809cc57b2c67f27a0f238bd7f069d + depends: + - __osx >=11.0 + - libcxx >=19 + license: Apache-2.0 + license_family: APACHE + size: 164450 + timestamp: 1763688228613 +- conda: https://conda.anaconda.org/conda-forge/win-64/ninja-1.13.2-h477610d_0.conda + sha256: e41a945c34a5f0bd2109b73a65486cd93023fa0a9bcba3ef98f9a3da40ba1180 + md5: 7ecb9f2f112c66f959d2bb7dbdb89b67 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: Apache-2.0 + license_family: APACHE + size: 309417 + timestamp: 1763688227932 +- conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-2.4.3-py314h2b28147_0.conda + sha256: f2ba8cb0d86a6461a6bcf0d315c80c7076083f72c6733c9290086640723f79ec + md5: 36f5b7eb328bdc204954a2225cf908e2 + depends: + - python + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + - python_abi 3.14.* *_cp314 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - libblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 8927860 + timestamp: 1773839233468 +- conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-2.4.3-py314h7b24d9b_0.conda + sha256: cbe5563bf8d7350647db7004871ebcdac38905f87dcdfc059ec5d73d1f27ddfd + md5: 3d8057ab97e4c8fd1f781356e7be9b40 + depends: + - python + - libcxx >=19 + - __osx >=11.0 + - liblapack >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - libblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 8153757 + timestamp: 1773839141840 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-2.4.3-py314h1569ea8_0.conda + sha256: fe565b09011e8b8edb11bc20564ab130b107d4717590c2464d6d7c2a5a53c6da + md5: 0fab9cf4fc5163131387f36742b50c79 + depends: + - python + - libcxx >=19 + - python 3.14.* *_cp314 + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - libcblas >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 6993182 + timestamp: 1773839150339 +- conda: https://conda.anaconda.org/conda-forge/win-64/numpy-2.4.3-py314h02f10f6_0.conda + sha256: e4afa67a7350836a1d652f8e7351fe4cb853f8eb8b5c86c9203cefff67669083 + md5: 54355aaff5c94c602b7b9540fbc3ca1d + depends: + - python + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - python_abi 3.14.* *_cp314 + - liblapack >=3.9.0,<4.0a0 + constrains: + - numpy-base <0a0 + license: BSD-3-Clause + license_family: BSD + size: 7311362 + timestamp: 1773839141373 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.1-h35e630c_1.conda + sha256: 44c877f8af015332a5d12f5ff0fb20ca32f896526a7d0cdb30c769df1144fb5c + md5: f61eb8cd60ff9057122a3d338b99c00f + depends: + - __glibc >=2.17,<3.0.a0 + - ca-certificates + - libgcc >=14 + license: Apache-2.0 + license_family: Apache + size: 3164551 + timestamp: 1769555830639 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.1-hb6871ef_1.conda + sha256: e02e5639b0e4d6d4fcf0f3b082642844fb5a37316f5b0a1126c6271347462e90 + md5: 30bb8d08b99b9a7600d39efb3559fff0 + depends: + - __osx >=10.13 + - ca-certificates + license: Apache-2.0 + license_family: Apache + size: 2777136 + timestamp: 1769557662405 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.1-hd24854e_1.conda + sha256: 361f5c5e60052abc12bdd1b50d7a1a43e6a6653aab99a2263bf2288d709dcf67 + md5: f4f6ad63f98f64191c3e77c5f5f29d76 + depends: + - __osx >=11.0 + - ca-certificates + license: Apache-2.0 + license_family: Apache + size: 3104268 + timestamp: 1769556384749 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.1-hf411b9b_1.conda + sha256: 53a5ad2e5553b8157a91bb8aa375f78c5958f77cb80e9d2ce59471ea8e5c0bd6 + md5: eb585509b815415bc964b2c7e11c7eb3 + depends: + - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: Apache + size: 9343023 + timestamp: 1769557547888 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.56.4-hda50119_1.conda + sha256: 315b52bfa6d1a820f4806f6490d472581438a28e21df175290477caec18972b0 + md5: d53ffc0edc8eabf4253508008493c5bc + depends: + - __glibc >=2.17,<3.0.a0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libgcc >=14 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + license: LGPL-2.1-or-later + size: 458036 + timestamp: 1774281947855 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pango-1.56.4-hf280016_1.conda + sha256: c1150e6a405985b25830c18f896d5e89b9777ef7e420bc0b1d88634f9a614769 + md5: 591f9fcbb36fbd50caef590d9b1de614 + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + license: LGPL-2.1-or-later + size: 431801 + timestamp: 1774282435173 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.56.4-hf80efc4_1.conda + sha256: b57c59cf5abb06d407b3a79017b990ca5bfb10c15a10c62fc29e113f2b12d9a9 + md5: 4b433508ebb295c05dd3d03daf27f7bb + depends: + - __osx >=11.0 + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + license: LGPL-2.1-or-later + size: 425743 + timestamp: 1774282709773 +- conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.56.4-h13911b6_1.conda + sha256: 3d4e6e541e633f6fd22fc2c1d79ad5ec39503dea3ba04fc3e01d5be904ec7cea + md5: 1f1cf3772ba7d4eef989e4679ddf97f7 + depends: + - cairo >=1.18.4,<2.0a0 + - fontconfig >=2.17.1,<3.0a0 + - fonts-conda-ecosystem + - fribidi >=1.0.16,<2.0a0 + - harfbuzz >=13.2.1 + - libexpat >=2.7.4,<3.0a0 + - libfreetype >=2.14.2 + - libfreetype6 >=2.14.2 + - libglib >=2.86.4,<3.0a0 + - libpng >=1.6.55,<1.7.0a0 + - libzlib >=1.3.2,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.1-or-later + size: 454919 + timestamp: 1774282149607 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.47-haa7fec5_0.conda + sha256: 5e6f7d161356fefd981948bea5139c5aa0436767751a6930cb1ca801ebb113ff + md5: 7a3bff861a6583f1889021facefc08b1 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 1222481 + timestamp: 1763655398280 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pcre2-10.47-h13923f0_0.conda + sha256: 8d64a9d36073346542e5ea042ef8207a45a0069a2e65ce3323ee3146db78134c + md5: 08f970fb2b75f5be27678e077ebedd46 + depends: + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 1106584 + timestamp: 1763655837207 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.47-h30297fc_0.conda + sha256: 5e2e443f796f2fd92adf7978286a525fb768c34e12b1ee9ded4000a41b2894ba + md5: 9b4190c4055435ca3502070186eba53a + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 850231 + timestamp: 1763655726735 +- conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.47-hd2b5f0e_0.conda + sha256: 3e9e02174edf02cb4bcdd75668ad7b74b8061791a3bc8bdb8a52ae336761ba3e + md5: 77eaf2336f3ae749e712f63e36b0f0a1 + depends: + - bzip2 >=1.0.8,<2.0a0 + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + size: 995992 + timestamp: 1763655708300 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.46.4-h54a6638_1.conda + sha256: 43d37bc9ca3b257c5dd7bf76a8426addbdec381f6786ff441dc90b1a49143b6a + md5: c01af13bdc553d1a8fbfff6e8db075f0 + depends: + - libgcc >=14 + - libstdcxx >=14 + - libgcc >=14 + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + size: 450960 + timestamp: 1754665235234 +- conda: https://conda.anaconda.org/conda-forge/osx-64/pixman-0.46.4-ha059160_1.conda + sha256: ff8b679079df25aa3ed5daf3f4e3a9c7ee79e7d4b2bd8a21de0f8e7ec7207806 + md5: 742a8552e51029585a32b6024e9f57b4 + depends: + - __osx >=10.13 + - libcxx >=19 + license: MIT + license_family: MIT + size: 390942 + timestamp: 1754665233989 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/pixman-0.46.4-h81086ad_1.conda + sha256: 29c9b08a9b8b7810f9d4f159aecfd205fce051633169040005c0b7efad4bc718 + md5: 17c3d745db6ea72ae2fce17e7338547f + depends: + - __osx >=11.0 + - libcxx >=19 + license: MIT + license_family: MIT + size: 248045 + timestamp: 1754665282033 +- conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.46.4-h5112557_1.conda + sha256: 246fce4706b3f8b247a7d6142ba8d732c95263d3c96e212b9d63d6a4ab4aff35 + md5: 08c8fa3b419df480d985e304f7884d35 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 542795 + timestamp: 1754665193489 +- conda: https://conda.anaconda.org/conda-forge/linux-64/prek-0.3.8-hb17b654_0.conda + sha256: 9755922189b0d6c8129f1773684c8849691182b97703ecc7e0e63cd8ee4ac63b + md5: 328007e11a0622fa4cc6b4e4e1e92a8b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + constrains: + - __glibc >=2.17 + license: MIT + license_family: MIT + size: 5767848 + timestamp: 1774264043122 +- conda: https://conda.anaconda.org/conda-forge/osx-64/prek-0.3.8-h19f9e61_0.conda + sha256: be0e3cefd4b7da69d31ebf88bbefd5625859029ee2722ccb273e25139c967dff + md5: 552445ea32f6ff48fe736cda194308ac + depends: + - __osx >=11.0 + constrains: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 5726167 + timestamp: 1774264306862 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/prek-0.3.8-h6fdd925_0.conda + sha256: 7820b6ae045abed2dfd8009165bbc37d63b9a5bf647b7a6f5d202dedc034a5c2 + md5: f48cabb96953d995d6ee1be00f88ecfb + depends: + - __osx >=11.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 5313464 + timestamp: 1774264329151 +- conda: https://conda.anaconda.org/conda-forge/win-64/prek-0.3.8-h18a1a76_0.conda + sha256: aef57d11a8e39424fe19f81ab61169ce841dd5d65cc6e28c46b407acfa886328 + md5: 19a1b9c19eec34da51d3919846cd2d1a + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 6084659 + timestamp: 1774264097526 +- conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda + sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 + md5: b3c17d95b5a10c6e64a21fa17573e70e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 8252 + timestamp: 1726802366959 +- conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-h0e40799_1002.conda + sha256: 7e446bafb4d692792310ed022fe284e848c6a868c861655a92435af7368bae7b + md5: 3c8f2573569bb816483e5cf57efbbe29 + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 9389 + timestamp: 1726802555076 +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.3-h32b2ec7_101_cp314.conda + build_number: 101 + sha256: cb0628c5f1732f889f53a877484da98f5a0e0f47326622671396fb4f2b0cd6bd + md5: c014ad06e60441661737121d3eae8a60 + depends: + - __glibc >=2.17,<3.0.a0 + - bzip2 >=1.0.8,<2.0a0 + - ld_impl_linux-64 >=2.36.1 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libuuid >=2.41.3,<3.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + size: 36702440 + timestamp: 1770675584356 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.3-h4f44bb5_101_cp314.conda + build_number: 101 + sha256: f64e357aa0168a201c9b3eedf500d89a8550d6631d26a95590b12de61f8fd660 + md5: 030ec23658b941438ac42303aff0db2b + depends: + - __osx >=10.13 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + size: 14387288 + timestamp: 1770676578632 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.3-h4c637c5_101_cp314.conda + build_number: 101 + sha256: fccce2af62d11328d232df9f6bbf63464fd45f81f718c661757f9c628c4378ce + md5: 753c8d0447677acb7ddbcc6e03e82661 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - ncurses >=6.5,<7.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - readline >=8.3,<9.0a0 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + size: 13522698 + timestamp: 1770675365241 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.3-h4b44e0e_101_cp314.conda + build_number: 101 + sha256: 3f99d83bfd95b9bdae64a42a1e4bf5131dc20b724be5ac8a9a7e1ac2c0f006d7 + md5: 7ec2be7eaf59f83f3e5617665f3fbb2e + depends: + - bzip2 >=1.0.8,<2.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.2,<6.0a0 + - libmpdec >=4.0.0,<5.0a0 + - libsqlite >=3.51.2,<4.0a0 + - libzlib >=1.3.1,<2.0a0 + - openssl >=3.5.5,<4.0a0 + - python_abi 3.14.* *_cp314 + - tk >=8.6.13,<8.7.0a0 + - tzdata + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 + license: Python-2.0 + size: 18273230 + timestamp: 1770675442998 + python_site_packages_path: Lib/site-packages +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + build_number: 8 + sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 + md5: 0539938c55b6b1a59b560e843ad864a4 + constrains: + - python 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + size: 6989 + timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 + md5: eefd65452dfe7cce476a519bece46704 + depends: + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + size: 317819 + timestamp: 1765813692798 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 + depends: + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: GPL-3.0-only + license_family: GPL + size: 313930 + timestamp: 1765813902568 +- conda: https://conda.anaconda.org/conda-forge/linux-64/rhash-1.4.6-hb9d3cd8_1.conda + sha256: d5c73079c1dd2c2a313c3bfd81c73dbd066b7eb08d213778c8bff520091ae894 + md5: c1c9b02933fdb2cfb791d936c20e887e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 193775 + timestamp: 1748644872902 +- conda: https://conda.anaconda.org/conda-forge/osx-64/rhash-1.4.6-h6e16a3a_1.conda + sha256: 65c946fc5a9bb71772a7ac9bad64ff08ac07f7d5311306c2dcc1647157b96706 + md5: d0fcaaeff83dd4b6fb035c2f36df198b + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 185180 + timestamp: 1748644989546 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/rhash-1.4.6-h5505292_1.conda + sha256: f4957c05f4fbcd99577de8838ca4b5b1ae4b400a44be647a0159c14f85b9bfc0 + md5: 029e812c8ae4e0d4cf6ff4f7d8dc9366 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 185448 + timestamp: 1748645057503 +- conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.17.1-py314hf07bd8e_0.conda + sha256: 1ae427836d7979779c9005388a05993a3addabcc66c4422694639a4272d7d972 + md5: d0510124f87c75403090e220db1e9d41 + depends: + - __glibc >=2.17,<3.0.a0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libgcc >=14 + - libgfortran + - libgfortran5 >=14.3.0 + - liblapack >=3.9.0,<4.0a0 + - libstdcxx >=14 + - numpy <2.7 + - numpy >=1.23,<3 + - numpy >=1.25.2 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + size: 17225275 + timestamp: 1771880751368 +- conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.17.1-py314h5727af0_0.conda + sha256: 115267259f529f1539c6ab1098a18ca488fac02542fa9ca657a7dd46bd9ea675 + md5: adbed17bd17ac00193e6dce1f1a37781 + depends: + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=19 + - libgfortran + - libgfortran5 >=14.3.0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.7 + - numpy >=1.23,<3 + - numpy >=1.25.2 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + size: 15400833 + timestamp: 1771881194227 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.17.1-py314hfc1f868_0.conda + sha256: 6ca2abcaff2cd071aabaabd82b10a87fc7de3a4619f6c98820cc28e90cc2cb20 + md5: 7806ce54b78b0b11517b465a3398e910 + depends: + - __osx >=11.0 + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - libcxx >=19 + - libgfortran + - libgfortran5 >=14.3.0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.7 + - numpy >=1.23,<3 + - numpy >=1.25.2 + - python >=3.14,<3.15.0a0 + - python >=3.14,<3.15.0a0 *_cp314 + - python_abi 3.14.* *_cp314 + license: BSD-3-Clause + license_family: BSD + size: 13986990 + timestamp: 1771881110844 +- conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.17.1-py314h221f224_0.conda + sha256: d9a7b6d3a306195eef4db814614a74746aae4b63e570f6db15769bd28d19a957 + md5: cfcd38938ee0137f4bf0ca824dfb0887 + depends: + - libblas >=3.9.0,<4.0a0 + - libcblas >=3.9.0,<4.0a0 + - liblapack >=3.9.0,<4.0a0 + - numpy <2.7 + - numpy >=1.23,<3 + - numpy >=1.25.2 + - python >=3.14,<3.15.0a0 + - python_abi 3.14.* *_cp314 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: BSD-3-Clause + license_family: BSD + size: 14970549 + timestamp: 1771881565717 +- conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-64-26.0-h62b880e_7.conda + sha256: 7e7e2556978bc9bd9628c6e39138c684082320014d708fbca0c9050df98c0968 + md5: 68a978f77c0ba6ca10ce55e188a21857 + license: BSD-3-Clause + license_family: BSD + size: 4948 + timestamp: 1771434185960 +- conda: https://conda.anaconda.org/conda-forge/noarch/sdkroot_env_osx-arm64-26.0-ha3f98da_7.conda + sha256: fabfe031ede99898cb2b0b805f6c0d64fcc24ecdb444de3a83002d8135bf4804 + md5: 5f0ebbfea12d8e5bddff157e271fdb2f + license: BSD-3-Clause + license_family: BSD + size: 4971 + timestamp: 1771434195389 +- conda: https://conda.anaconda.org/conda-forge/osx-64/sigtool-codesign-0.1.3-hc0f2934_0.conda + sha256: b89d89d0b62e0a84093205607d071932cca228d4d6982a5b073eec7e765b146d + md5: 1261fc730f1d8af7eeea8a0024b23493 + depends: + - __osx >=10.13 + - libsigtool 0.1.3 hc0f2934_0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + size: 123083 + timestamp: 1767045007433 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/sigtool-codesign-0.1.3-h98dc951_0.conda + sha256: f3d006e2441f110160a684744d90921bbedbffa247d7599d7e76b5cd048116dc + md5: ade77ad7513177297b1d75e351e136ce + depends: + - __osx >=11.0 + - libsigtool 0.1.3 h98dc951_0 + - openssl >=3.5.4,<4.0a0 + license: MIT + license_family: MIT + size: 114331 + timestamp: 1767045086274 +- conda: https://conda.anaconda.org/conda-forge/linux-64/simde-0.8.2-h84d6215_0.conda + sha256: c055f966ebd72a768e25994ea7bdea0f0eecf481128c01e26f68c4ab11ae21b7 + md5: aa4dd437f90aa209a0309313af213964 + depends: + - __glibc >=2.17,<3.0.a0 + license: MIT + license_family: MIT + size: 480387 + timestamp: 1724439702451 +- conda: https://conda.anaconda.org/conda-forge/osx-64/simde-0.8.2-h37c8870_0.conda + sha256: fc44261e4a4e8f4bdab010d7788fa2d90d8bef51d37e1b8ec61ece047443e037 + md5: e456c3a390b37a3192eb460bfe33587f + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + size: 483653 + timestamp: 1724439763303 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/simde-0.8.2-h7b3277c_0.conda + sha256: 282929ab21b49577fd81c5a8d2d461c028086a4be6044762f6a5f546e423f299 + md5: fc5b5caefb2778064799b76751a69b69 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 482908 + timestamp: 1724439819598 +- conda: https://conda.anaconda.org/conda-forge/win-64/simde-0.8.2-hc790b64_0.conda + sha256: 518995344f4ac4c94c2eb207fb806af960a82fca5f87cab066de6ada20a974c0 + md5: 3dc81609aedcf489d8c2abe82c9ceb46 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 483090 + timestamp: 1714665491492 +- conda: https://conda.anaconda.org/conda-forge/noarch/sysroot_linux-64-2.28-h4ee821c_9.conda + sha256: c47299fe37aebb0fcf674b3be588e67e4afb86225be4b0d452c7eb75c086b851 + md5: 13dc3adbc692664cd3beabd216434749 + depends: + - __glibc >=2.28 + - kernel-headers_linux-64 4.18.0 he073ed8_9 + - tzdata + license: LGPL-2.0-or-later AND LGPL-2.0-or-later WITH exceptions AND GPL-2.0-or-later + license_family: GPL + size: 24008591 + timestamp: 1765578833462 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tapi-1600.0.11.8-h8d8e812_1.conda + sha256: 35eff895faad6e3255da015d8b269cf333577c30d5277b6030f8bf094592056b + md5: 525e2d1714c8bc8f96e9f03c75cf2366 + depends: + - libcxx >=19.0.0.a0 + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 + license: NCSA + size: 213957 + timestamp: 1774947623947 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tapi-1600.0.11.8-h997e182_1.conda + sha256: 0072a50a204dc6a309ea61e01315caee86cf82879ce5254bb8feb04a3e0de762 + md5: ddd7d9cd7e3c3f184867e92ed1c7d394 + depends: + - libcxx >=19.0.0.a0 + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 + license: NCSA + size: 200231 + timestamp: 1774947735492 +- conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2022.3.0-h3155e25_2.conda + sha256: abd9a489f059fba85c8ffa1abdaa4d515d6de6a3325238b8e81203b913cf65a9 + md5: 0f9817ffbe25f9e69ceba5ea70c52606 + depends: + - libhwloc >=2.12.2,<2.12.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Apache-2.0 + license_family: APACHE + size: 155869 + timestamp: 1767886839029 +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda + sha256: cafeec44494f842ffeca27e9c8b0c27ed714f93ac77ddadc6aaf726b5554ebac + md5: cffd3bdd58090148f4cfcd831f4b26ab + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libzlib >=1.3.1,<2.0a0 + constrains: + - xorg-libx11 >=1.8.12,<2.0a0 + license: TCL + license_family: BSD + size: 3301196 + timestamp: 1769460227866 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h7142dee_3.conda + sha256: 7f0d9c320288532873e2d8486c331ec6d87919c9028208d3f6ac91dc8f99a67b + md5: 6e6efb7463f8cef69dbcb4c2205bf60e + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + size: 3282953 + timestamp: 1769460532442 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda + sha256: 799cab4b6cde62f91f750149995d149bc9db525ec12595e8a1d91b9317f038b3 + md5: a9d86bc62f39b94c4661716624eb21b0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: TCL + license_family: BSD + size: 3127137 + timestamp: 1769460817696 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h6ed50ae_3.conda + sha256: 0e79810fae28f3b69fe7391b0d43f5474d6bd91d451d5f2bde02f55ae481d5e3 + md5: 0481bfd9814bf525bd4b3ee4b51494c4 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: TCL + license_family: BSD + size: 3526350 + timestamp: 1769460339384 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 + license: LicenseRef-Public-Domain + size: 119135 + timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 + constrains: + - vc14_runtime >=14.29.30037 + - vs2015_runtime >=14.29.30037 + license: LicenseRef-MicrosoftWindowsSDK10 + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f + depends: + - vc14_runtime >=14.44.35208 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 + depends: + - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_34 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + size: 115235 + timestamp: 1767320173250 +- conda: https://conda.anaconda.org/conda-forge/win-64/vs2022_win-64-19.44.35207-ha74f236_34.conda + sha256: 05bc657625b58159bcea039a35cc89d1f8baf54bf4060019c2b559a03ba4a45e + md5: 1d699ffd41c140b98e199ddd9787e1e1 + depends: + - vswhere + constrains: + - vs_win-64 2022.14 + track_features: + - vc14 + license: BSD-3-Clause + license_family: BSD + size: 23060 + timestamp: 1767320175868 +- conda: https://conda.anaconda.org/conda-forge/noarch/vswhere-3.1.7-h40126e0_1.conda + sha256: b72270395326dc56de9bd6ca82f63791b3c8c9e2b98e25242a9869a4ca821895 + md5: f622897afff347b715d046178ad745a5 + depends: + - __win + license: MIT + license_family: MIT + size: 238764 + timestamp: 1745560912727 +- conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.25.0-hd6090a7_0.conda + sha256: ea374d57a8fcda281a0a89af0ee49a2c2e99cc4ac97cf2e2db7064e74e764bdb + md5: 996583ea9c796e5b915f7d7580b51ea6 + depends: + - __glibc >=2.17,<3.0.a0 + - libexpat >=2.7.4,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + size: 334139 + timestamp: 1773959575393 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.47-hb03c661_0.conda + sha256: 19c2bb14bec84b0e995b56b752369775c75f1589314b43733948bb5f471a6915 + md5: b56e0c8432b56decafae7e78c5f29ba5 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.13,<2.0a0 + license: MIT + license_family: MIT + size: 399291 + timestamp: 1772021302485 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.2-hb9d3cd8_0.conda + sha256: c12396aabb21244c212e488bbdc4abcdef0b7404b15761d9329f5a4a39113c4b + md5: fb901ff28063514abb6046c9ec2c4a45 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: MIT + license_family: MIT + size: 58628 + timestamp: 1734227592886 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libice-1.1.2-h0e40799_0.conda + sha256: bf1d34142b1bf9b5a4eed96bcc77bc4364c0e191405fd30d2f9b48a04d783fd3 + md5: 105cb93a47df9c548e88048dc9cbdbc9 + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 236306 + timestamp: 1734228116846 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.6-he73a12e_0.conda + sha256: 277841c43a39f738927145930ff963c5ce4c4dacf66637a3d95d802a64173250 + md5: 1c74ff8c35dcadf952a16f752ca5aa49 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libuuid >=2.38.1,<3.0a0 + - xorg-libice >=1.1.2,<2.0a0 + license: MIT + license_family: MIT + size: 27590 + timestamp: 1741896361728 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libsm-1.2.6-h0e40799_0.conda + sha256: 065d49b0d1e6873ed1238e962f56cb8204c585cdc5c9bd4ae2bf385cadb5bd65 + md5: 570c9a6d9b4909e45d49e9a5daa528de + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + - xorg-libice >=1.1.2,<2.0a0 + license: MIT + license_family: MIT + size: 97096 + timestamp: 1741896840170 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.8.13-he1eb515_0.conda + sha256: 516d4060139dbb4de49a4dcdc6317a9353fb39ebd47789c14e6fe52de0deee42 + md5: 861fb6ccbc677bb9a9fb2468430b9c6a + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libxcb >=1.17.0,<2.0a0 + license: MIT + license_family: MIT + size: 839652 + timestamp: 1770819209719 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libx11-1.8.13-hfa52320_0.conda + sha256: eadb12d4597b577cf9bde82a8a2a502a331bd5bfdd60ce508cea93912478e255 + md5: 5a823e21e090f8bc43dbfba00cd2f0e2 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - libxcb >=1.17.0,<2.0a0 + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 954604 + timestamp: 1770819901886 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxau-1.0.12-hb03c661_1.conda + sha256: 6bc6ab7a90a5d8ac94c7e300cc10beb0500eeba4b99822768ca2f2ef356f731b + md5: b2895afaf55bf96a8c8282a2e47a5de0 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 15321 + timestamp: 1762976464266 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxau-1.0.12-hba3369d_1.conda + sha256: 156a583fa43609507146de1c4926172286d92458c307bb90871579601f6bc568 + md5: 8436cab9a76015dfe7208d3c9f97c156 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 109246 + timestamp: 1762977105140 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcomposite-0.4.7-hb03c661_0.conda + sha256: 048c103000af9541c919deef03ae7c5e9c570ffb4024b42ecb58dbde402e373a + md5: f2ba4192d38b6cef2bb2c25029071d90 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxfixes >=6.0.2,<7.0a0 + license: MIT + license_family: MIT + size: 14415 + timestamp: 1770044404696 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda + sha256: 832f538ade441b1eee863c8c91af9e69b356cd3e9e1350fff4fe36cc573fc91a + md5: 2ccd714aa2242315acaf0a67faea780b + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + - xorg-libxrender >=0.9.11,<0.10.0a0 + license: MIT + license_family: MIT + size: 32533 + timestamp: 1730908305254 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdamage-1.1.6-hb9d3cd8_0.conda + sha256: 43b9772fd6582bf401846642c4635c47a9b0e36ca08116b3ec3df36ab96e0ec0 + md5: b5fcc7172d22516e1f965490e65e33a4 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + size: 13217 + timestamp: 1727891438799 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxdmcp-1.1.5-hb03c661_1.conda + sha256: 25d255fb2eef929d21ff660a0c687d38a6d2ccfbcbf0cc6aa738b12af6e9d142 + md5: 1dafce8548e38671bea82e3f5c6ce22f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 20591 + timestamp: 1762976546182 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxdmcp-1.1.5-hba3369d_1.conda + sha256: 366b8ae202c3b48958f0b8784bbfdc37243d3ee1b1cd4b8e76c10abe41fa258b + md5: a7c03e38aa9c0e84d41881b9236eacfb + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + license: MIT + license_family: MIT + size: 70691 + timestamp: 1762977015220 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.7-hb03c661_0.conda + sha256: 79c60fc6acfd3d713d6340d3b4e296836a0f8c51602327b32794625826bd052f + md5: 34e54f03dfea3e7a2dcf1453a85f1085 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + size: 50326 + timestamp: 1769445253162 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxext-1.3.7-hba3369d_0.conda + sha256: 5966dff3ea3f805e11b5fb466107d64704eb94f00d28818f6891a3ecd075d08e + md5: 74bc8e26c2716e9b1542bef908887b82 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + size: 286083 + timestamp: 1769445495320 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxfixes-6.0.2-hb03c661_0.conda + sha256: 83c4c99d60b8784a611351220452a0a85b080668188dce5dfa394b723d7b64f4 + md5: ba231da7fccf9ea1e768caf5c7099b84 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + license: MIT + license_family: MIT + size: 20071 + timestamp: 1759282564045 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxi-1.8.2-hb9d3cd8_0.conda + sha256: 1a724b47d98d7880f26da40e45f01728e7638e6ec69f35a3e11f92acd05f9e7a + md5: 17dcc85db3c7886650b8908b183d6876 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxfixes >=6.0.1,<7.0a0 + license: MIT + license_family: MIT + size: 47179 + timestamp: 1727799254088 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxinerama-1.1.6-hecca717_0.conda + sha256: 3a9da41aac6dca9d3ff1b53ee18b9d314de88add76bafad9ca2287a494abcd86 + md5: 93f5d4b5c17c8540479ad65f206fea51 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + license: MIT + license_family: MIT + size: 14818 + timestamp: 1769432261050 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxpm-3.5.18-hba3369d_0.conda + sha256: 2004ebe53ce5e7288f148f2d92dd52526fd6ee0f5435bf95cf48de808028cd68 + md5: 52105b90eaf5b859cb383348e99cbac2 + depends: + - libgcc >=14 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxt >=1.3.1,<2.0a0 + license: MIT + license_family: MIT + size: 237697 + timestamp: 1769445545101 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrandr-1.5.5-hb03c661_0.conda + sha256: 80ed047a5cb30632c3dc5804c7716131d767089f65877813d4ae855ee5c9d343 + md5: e192019153591938acf7322b6459d36e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxrender >=0.9.12,<0.10.0a0 + license: MIT + license_family: MIT + size: 30456 + timestamp: 1769445263457 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.12-hb9d3cd8_0.conda + sha256: 044c7b3153c224c6cedd4484dd91b389d2d7fd9c776ad0f4a34f099b3389f4a1 + md5: 96d57aba173e878a2089d5638016dc5e + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 33005 + timestamp: 1734229037766 +- conda: https://conda.anaconda.org/conda-forge/win-64/xorg-libxt-1.3.1-h0e40799_0.conda + sha256: c940a6b71a1e59450b01ebfb3e21f3bbf0a8e611e5fbfc7982145736b0f20133 + md5: 31baf0ce8ef19f5617be73aee0527618 + depends: + - libgcc >=13 + - libwinpthread >=12.0.0.r4.gg4f2fc60ca + - ucrt >=10.0.20348.0 + - xorg-libice >=1.1.1,<2.0a0 + - xorg-libsm >=1.2.4,<2.0a0 + - xorg-libx11 >=1.8.10,<2.0a0 + license: MIT + license_family: MIT + size: 918674 + timestamp: 1731861024233 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxtst-1.2.5-hb9d3cd8_3.conda + sha256: 752fdaac5d58ed863bbf685bb6f98092fe1a488ea8ebb7ed7b606ccfce08637a + md5: 7bbe9a0cc0df0ac5f5a8ad6d6a11af2f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - xorg-libx11 >=1.8.10,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + - xorg-libxi >=1.7.10,<2.0a0 + license: MIT + license_family: MIT + size: 32808 + timestamp: 1727964811275 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libxxf86vm-1.1.7-hb03c661_0.conda + sha256: 64db17baaf36fa03ed8fae105e2e671a7383e22df4077486646f7dbf12842c9f + md5: 665d152b9c6e78da404086088077c844 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - xorg-libx11 >=1.8.12,<2.0a0 + - xorg-libxext >=1.3.6,<2.0a0 + license: MIT + license_family: MIT + size: 18701 + timestamp: 1769434732453 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xorgproto-2025.1-hb03c661_0.conda + sha256: 7a8c64938428c2bfd016359f9cb3c44f94acc256c6167dbdade9f2a1f5ca7a36 + md5: aa8d21be4b461ce612d8f5fb791decae + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + license: MIT + license_family: MIT + size: 570010 + timestamp: 1766154256151 +- conda: https://conda.anaconda.org/conda-forge/linux-64/xxhash-0.8.3-hb47aa4a_0.conda + sha256: 08e12f140b1af540a6de03dd49173c0e5ae4ebc563cabdd35ead0679835baf6f + md5: 607e13a8caac17f9a664bcab5302ce06 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + license: BSD-2-Clause + license_family: BSD + size: 108219 + timestamp: 1746457673761 +- conda: https://conda.anaconda.org/conda-forge/osx-64/xxhash-0.8.3-h13e91ac_0.conda + sha256: 66745c92f34e20e559e1004ce0f2440ff8b511589a1ac16ebf1aca7e310003da + md5: 3e1f33316570709dac5d04bc4ad1b6d0 + depends: + - __osx >=10.13 + license: BSD-2-Clause + license_family: BSD + size: 108449 + timestamp: 1746457796808 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/xxhash-0.8.3-haa4e116_0.conda + sha256: 5e2e58fbaa00eeab721a86cb163a54023b3b260e91293dde7e5334962c5c96e3 + md5: 54a24201d62fc17c73523e4b86f71ae8 + depends: + - __osx >=11.0 + license: BSD-2-Clause + license_family: BSD + size: 98913 + timestamp: 1746457827085 +- conda: https://conda.anaconda.org/conda-forge/win-64/xxhash-0.8.3-hbba6f48_0.conda + sha256: 5500076adee2f73fe771320b73dc21296675658ce49a972dd84dc40c7fff5974 + md5: 2de9e5bd94ae9c32ac604ec8ce7c90eb + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-2-Clause + license_family: BSD + size: 105768 + timestamp: 1746458183583 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.3.2-h25fd6f3_2.conda + sha256: 245c9ee8d688e23661b95e3c6dd7272ca936fabc03d423cdb3cdee1bbcf9f2f2 + md5: c2a01a08fc991620a74b32420e97868a + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib 1.3.2 h25fd6f3_2 + license: Zlib + license_family: Other + size: 95931 + timestamp: 1774072620848 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.3.2-hbb4bfdb_2.conda + sha256: 5dd728cebca2e96fa48d41661f1a35ed0ee3cb722669eee4e2d854c6745655eb + md5: 6276aa61ffc361cbf130d78cfb88a237 + depends: + - __osx >=11.0 + - libzlib 1.3.2 hbb4bfdb_2 + license: Zlib + license_family: Other + size: 92411 + timestamp: 1774073075482 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.3.2-h8088a28_2.conda + sha256: 8dd2ac25f0ba714263aac5832d46985648f4bfb9b305b5021d702079badc08d2 + md5: f1c0bce276210bed45a04949cfe8dc20 + depends: + - __osx >=11.0 + - libzlib 1.3.2 h8088a28_2 + license: Zlib + license_family: Other + size: 81123 + timestamp: 1774072974535 +- conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.3.2-hfd05255_2.conda + sha256: ef408f85f664a4b9c9dac3cb2e36154d9baa15a88984ea800e11060e0f2394a1 + md5: 5187ecf958be3c39110fe691cbd6873e + depends: + - libzlib 1.3.2 hfd05255_2 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: Zlib + license_family: Other + size: 850351 + timestamp: 1774072891049 +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f + md5: 727109b184d680772e3122f40136d5ca + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 528148 + timestamp: 1764777156963 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 388453 + timestamp: 1764777142545 diff --git a/pixi.toml b/pixi.toml new file mode 100644 index 000000000..3e00f7e07 --- /dev/null +++ b/pixi.toml @@ -0,0 +1,296 @@ +[workspace] +name = "proxsuite" +version = "0.7.2" +description = "The Advanced Proximal Optimization Toolbox" +channels = ["conda-forge"] +platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"] +preview = ["pixi-build"] + +[dependencies] +ccache = ">=4.12.0" +cmake = ">=3.22" +cxx-compiler = ">=1.11.0" +ninja = ">=1.13.0" +eigen = ">=3.4.0" +simde = ">=0.8.2" + +[activation.env] +# Setup ccache +CMAKE_C_COMPILER_LAUNCHER = "ccache" +CMAKE_CXX_COMPILER_LAUNCHER = "ccache" +# Create compile_commands.json for language server +CMAKE_EXPORT_COMPILE_COMMANDS = "ON" +# Activate color output with Ninja +CMAKE_COLOR_DIAGNOSTICS = "ON" +# Help ccache manage generated files and PCH (https://ccache.dev/manual/latest.html#_precompiled_headers) +CCACHE_SLOPPINESS = "include_file_ctime,include_file_mtime,pch_defines,time_macros" + +[tasks] +configure = { cmd = [ + "cmake", + "-S", + ".", + "-B", + "build", + "-G", + "Ninja", + "-DJRL_CMAKEMODULES_SOURCE_DIR=$JRL_CMAKEMODULES_SOURCE_DIR", + "-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX", + "-DCMAKE_BUILD_TYPE=Release", + "-DPROXSUITE_CXX_STANDARD=$PROXSUITE_CXX_STANDARD", + "-DBUILD_WITH_VECTORIZATION_SUPPORT=ON", + "-DBUILD_MAROS_MESZAROS_TESTS=$BUILD_MAROS_MESZAROS_TESTS", + "-DBUILD_EXAMPLES=ON", + "-DBUILD_BENCHMARKS=ON", + "-DBUILD_TESTING=$BUILD_TESTING", + "-DBUILD_PYTHON_INTERFACE=$BUILD_PYTHON_INTERFACE", +] } +build = { depends-on = ["configure"], cmd = "cmake --build build" } +install = { depends-on = ["build"], cmd = "cmake --install build" } +uninstall = { depends-on = [ + "install", +], cmd = "cmake --build build --target uninstall" } +clean = { cmd = "rm -rf build" } + +# --- Features --- +# Each feature groups optional dependencies and tasks. +# They are composed together via environments (see [environments] below). + +# --- Python Feature --- +# Adds Python bindings support with nanobind. +# Enables building and testing Python wrappers for the C++ library. +[feature.python.dependencies] +python = ">=3.10" +numpy = ">=1.24.0" +nanobind = ">=2.5.0" + +[feature.python.activation.env] +BUILD_PYTHON_INTERFACE = "ON" + +[feature.python.tasks] +test-import-python = { depends-on = [ + "install", +], cmd = [ + "python", + "-c", + "import proxsuite; print(proxsuite.helpers.printVersion())", +] } + +# --- Test Feature --- +# Adds C++ testing dependencies and test runners. +# Includes support for Maros-Meszaros benchmark tests (very slow, excluded by default). +# Use `test` task for regular tests, `test_maros_meszaros` for benchmark tests. +[feature.test.dependencies] +catch2 = ">=3.4.0" +cereal = ">=1.3.0" +scipy = ">=1.7.0" +libmatio = ">=1.5.0" + +[feature.test.activation.env] +BUILD_TESTING = "ON" +BUILD_MAROS_MESZAROS_TESTS = "ON" + +[feature.test.tasks] +test = { depends-on = [ + "build", +], cmd = [ + "ctest", + "--test-dir", + "build", + "-LE", + "maros_meszaros", + "--output-on-failure", +] } +test_maros_meszaros = { depends-on = [ + "build", +], cmd = [ + "ctest", + "--test-dir", + "build", + "-L", + "maros_meszaros", + "--output-on-failure", +] } +_test-packaging-simple-configure = { depends-on = [ + "install", +], cmd = [ + "cmake", + "-G", + "Ninja", + "-S", + "test/packaging/cmake", + "-B", + "build/packaging", + "-DJRL_CMAKEMODULES_SOURCE_DIR=$JRL_CMAKEMODULES_SOURCE_DIR", + "--log-level=DEBUG", +] } +_test-packaging-simple = { depends-on = [ + "_test-packaging-simple-configure", +], cmd = [ + "cmake", + "--build", + "build/packaging", + "--verbose", +] } +_test-packaging-components-configure = { depends-on = [ + "install", +], cmd = [ + "cmake", + "-G", + "Ninja", + "-S", + "test/packaging/cmake-components", + "-B", + "build/packaging-components", + "-DJRL_CMAKEMODULES_SOURCE_DIR=$JRL_CMAKEMODULES_SOURCE_DIR", + "--log-level=DEBUG", +] } +_test-packaging-components = { depends-on = [ + "_test-packaging-components-configure", +], cmd = [ + "cmake", + "--build", + "build/packaging-components", + "--verbose", +] } +_test-packaging-fetchcontent-configure = { cmd = [ + "cmake", + "-G", + "Ninja", + "-S", + "test/packaging/fetchcontent", + "-B", + "build/packaging-fetchcontent", + "-DJRL_CMAKEMODULES_SOURCE_DIR=$JRL_CMAKEMODULES_SOURCE_DIR", + "-DPROXSUITE_FETCHCONTENT_SOURCE_DIR=$PIXI_PROJECT_ROOT", + "--log-level=DEBUG", +] } +_test-packaging-fetchcontent = { depends-on = [ + "_test-packaging-fetchcontent-configure", +], cmd = [ + "cmake", + "--build", + "build/packaging-fetchcontent", + "--verbose", +] } +test-packaging = { depends-on = [ + "_test-packaging-simple", + "_test-packaging-components", + "_test-packaging-fetchcontent", +] } + +# --- Documentation Feature --- +# Standalone environment for building documentation with Doxygen. +# Use `build_documentation` to generate docs, `install_documentation` to install them. +[feature.doc.dependencies] +doxygen = ">=1.10.0" +graphviz = ">=10.0.0" + +[feature.doc.tasks] +_configure_documentation = { cmd = [ + "cmake", + "-S", + ".", + "-B", + "build/doc_build", + "-G", + "Ninja", + "-DJRL_CMAKEMODULES_SOURCE_DIR=$JRL_CMAKEMODULES_SOURCE_DIR", + "-DCMAKE_INSTALL_PREFIX=build/doc_install", + "-DCMAKE_BUILD_TYPE=Release", + "-DBUILD_DOCUMENTATION=ON", + "-DINSTALL_DOCUMENTATION=ON", +] } +build_documentation = { depends-on = [ + "_configure_documentation", +], cmd = [ + "cmake", + "--build", + "build/doc_build", + "--target", + "doc", +] } +install_documentation = { depends-on = [ + "build_documentation", +], cmd = [ + "cmake", + "--install", + "build/doc_build", + "--component", + "doc", +] } + +# --- Environments --- +# Environments compose features together for different use cases. +[environments.default] +features = ["python", "test"] + +[environments.doc] +features = ["doc"] + +# --- Prek Feature --- +# Standalone pre-commit environment using prek. +# Minimal dependencies - only includes prek. +[feature.prek.dependencies] +prek = ">=0.2.21" + +[feature.prek.tasks] +prek = { cmd = "prek run -a" } + +[environments.prek] +features = ["prek"] +no-default-feature = true + +# --- Pixi Build Feature --- +# Standalone environment for building with Pixi. +[package] +name = { workspace = true } +version = { workspace = true } + +[package.build] +backend = { name = "pixi-build-cmake", version = "*" } + +[package.build.config] +extra-args = [ + "--log-level=DEBUG", + "-DBUILD_WITH_VECTORIZATION_SUPPORT=ON", + "-DBUILD_EXAMPLES=OFF", + "-DBUILD_BENCHMARKS=OFF", + "-DBUILD_TESTING=OFF", + "-DBUILD_MAROS_MESZAROS_TESTS=OFF", + "-DBUILD_PYTHON_INTERFACE=ON", +] + +[package.build-dependencies] +ccache = ">=4.12.0" +cmake = ">=3.22" +cxx-compiler = ">=1.11.0" +ninja = ">=1.13.0" + +[package.host-dependencies] +eigen = ">=3.4.0" +simde = ">=0.8.2" +python = ">=3.10" +numpy = ">=1.24.0" +nanobind = ">=2.5.0" +cereal = ">=1.3.0" + +[package.run-dependencies] +eigen = ">=3.4.0" +simde = ">=0.8.2" +cereal = ">=1.3.0" + +# [feature.test-pixi-build.dependencies] +# proxsuite = { path = "." } +# cmake = ">=3.22" +# python = ">=3.10" +# cxx-compiler = ">=1.11.0" + +# [feature.test-pixi-build.tasks] +# test-cmake = "cmake -S test/packaging/cmake -B build/test_pixi_build --log-level=DEBUG" +# test-python = "python -c 'import proxsuite; print(proxsuite.__version__)'" +# test = { depends-on = ["test-cmake", "test-python"] } + +# [environments.test-pixi-build] +# features = ["test-pixi-build"] +# no-default-feature = true diff --git a/pyproject.toml b/pyproject.toml index 65ef76517..aa1abff03 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,26 +3,30 @@ name = "proxsuite" version = "0.7.2" description = "Quadratic Programming Solver for Robotics and beyond." readme = "README.md" -requires-python = ">= 3.8" +requires-python = ">=3.10" license = "BSD-2-Clause" -dependencies = ["numpy","scipy"] +dependencies = ["numpy>=1.24.0", "scipy>=1.8.0"] [project.urls] homepage = "https://github.com/Simple-Robotics/proxsuite" repository = "https://github.com/Simple-Robotics/proxsuite.git" [build-system] -requires = [ - "cmeel[build]", - "cmeel-eigen", - "cmeel-simde", - "typing-extensions", - ] +requires = ["cmeel[build]", "cmeel-eigen", "cmeel-simde", "typing-extensions"] build-backend = "cmeel.build" [tool.cmeel] -configure-args = ["-DBUILD_TESTING:BOOL=OFF","-DBUILD_PYTHON_INTERFACE:BOOL=ON","-DBUILD_WITH_VECTORIZATION_SUPPORT:BOOL=ON","-DINSTALL_DOCUMENTATION:BOOL=OFF","-DBUILD_WITH_OPENMP_SUPPORT=OFF"] +run-tests = false +log-level = "DEBUG" +configure-args = [ + "--log-level=DEBUG", + "-GNinja", + "-DBUILD_TESTING:BOOL=OFF", + "-DBUILD_PYTHON_INTERFACE:BOOL=ON", + "-DBUILD_WITH_VECTORIZATION_SUPPORT:BOOL=ON", + "-DINSTALL_DOCUMENTATION:BOOL=OFF", + "-DBUILD_WITH_OPENMP_SUPPORT:BOOL=OFF", +] [tool.ruff.lint] -ignore = [ "E741" ] -exclude = [ "cmake-module/*", "bindings/python/external/nanobind/*" ] +ignore = ["E741"] diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dbea3694d..0963552ce 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,116 +1,12 @@ -include(../cmake-external/doctest.cmake) -find_package(Matio REQUIRED) - -add_library(${PROJECT_NAME}-doctest STATIC doctest/doctest.cpp) -target_include_directories(${PROJECT_NAME}-doctest PUBLIC ./doctest) -add_library(cnpy OBJECT src/cnpy.cpp) -target_link_libraries(cnpy Eigen3::Eigen) -target_include_directories(cnpy PUBLIC ./include) - -file(GLOB_RECURSE TEST_HEADERS ./include/*.hpp) -ADD_HEADER_GROUP(TEST_HEADERS) - -add_library( - proxsuite-test-util - STATIC - ./src/util_f64.cpp - ./src/util_f32.cpp - ${TEST_HEADERS} -) -target_include_directories(proxsuite-test-util PUBLIC ./include) -if(BUILD_WITH_VECTORIZATION_SUPPORT) - target_link_libraries(proxsuite-test-util proxsuite-vectorized matio) -else() - target_link_libraries(proxsuite-test-util proxsuite matio) -endif() - -macro(proxsuite_test name path) - set(target_name ${PROJECT_NAME}-test-cpp-${name}) - add_executable(${target_name} ${path}) - doctest_discover_tests(${target_name}) - target_link_libraries( - ${target_name} - PUBLIC proxsuite ${PROJECT_NAME}-doctest proxsuite-test-util - ) - target_compile_definitions( - ${target_name} - PRIVATE PROBLEM_PATH="${CMAKE_CURRENT_SOURCE_DIR}" - ) - add_dependencies(build_tests ${target_name}) -endmacro() - -proxsuite_test(dense_ruiz_equilibration src/dense_ruiz_equilibration.cpp) -proxsuite_test(dense_qp_eq src/dense_qp_eq.cpp) -proxsuite_test(dense_qp_with_eq_and_in src/dense_qp_with_eq_and_in.cpp) -proxsuite_test(dense_qp_unconstrained src/dense_unconstrained_qp.cpp) -proxsuite_test(dense_backward src/dense_backward.cpp) -proxsuite_test(dense_qp_wrapper src/dense_qp_wrapper.cpp) -proxsuite_test(dense_qp_solve src/dense_qp_solve.cpp) -proxsuite_test(sparse_ruiz_equilibration src/sparse_ruiz_equilibration.cpp) -proxsuite_test(sparse_qp src/sparse_qp.cpp) -proxsuite_test(sparse_qp_wrapper src/sparse_qp_wrapper.cpp) -proxsuite_test(sparse_qp_solve src/sparse_qp_solve.cpp) -proxsuite_test(sparse_factorization src/sparse_factorization.cpp) -proxsuite_test(cvxpy src/cvxpy.cpp) - -if(BUILD_WITH_OPENMP_SUPPORT) - proxsuite_test(parallel src/parallel_qp_solve.cpp) - target_link_libraries( - ${PROJECT_NAME}-test-cpp-parallel - PRIVATE OpenMP::OpenMP_CXX - ) -endif() - -# Test serialization -macro(ADD_TEST_CFLAGS target flag) - set_property(TARGET ${target} APPEND_STRING PROPERTY COMPILE_FLAGS " ${flag}") -endmacro() - -make_directory("${CMAKE_CURRENT_BINARY_DIR}/serialization-data") -proxsuite_test(serialization src/serialization.cpp) -add_test_cflags( - ${PROJECT_NAME}-test-cpp-serialization - "-DTEST_SERIALIZATION_FOLDER=\\\\\"${CMAKE_CURRENT_BINARY_DIR}/serialization-data\\\\\"" +find_path( + MAROS_MESZAROS_DIR + NAMES AUG2D.mat QPCBOEI1.mat + PATHS ${CMAKE_CURRENT_SOURCE_DIR}/data/maros_meszaros_data + REQUIRED ) -if(cereal_FOUND) - target_link_libraries( - ${PROJECT_NAME}-test-cpp-serialization - PRIVATE cereal::cereal - ) -else() - target_include_directories( - ${PROJECT_NAME}-test-cpp-serialization - SYSTEM - PRIVATE ${PROJECT_SOURCE_DIR}/external/cereal/include - ) -endif() -if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT MSVC) - proxsuite_test(dense_maros_meszaros src/dense_maros_meszaros.cpp) - proxsuite_test(sparse_maros_meszaros src/sparse_maros_meszaros.cpp) -endif() +add_subdirectory(cpp) if(BUILD_PYTHON_INTERFACE) - file(GLOB_RECURSE ${PROJECT_NAME}_PYTHON_UNITTEST *.py) - - if( - (CMAKE_BUILD_TYPE STREQUAL "Debug" AND MSVC) - OR NOT BUILD_WITH_OPENMP_SUPPORT - ) - list_filter( - "${${PROJECT_NAME}_PYTHON_UNITTEST}" - "parallel_qp_solve" - ${PROJECT_NAME}_PYTHON_UNITTEST - ) - endif() - - foreach(TEST_FILE ${${PROJECT_NAME}_PYTHON_UNITTEST}) - get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE) - string(REGEX REPLACE "${PROJECT_SOURCE_DIR}/" "" TEST_FILE ${TEST_FILE}) - ADD_PYTHON_UNIT_TEST( - "${PROJECT_NAME}-test-py-${TEST_NAME}" - "${TEST_FILE}" - "bindings/python" - ) - endforeach() -endif(BUILD_PYTHON_INTERFACE) + add_subdirectory(python) +endif() diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt new file mode 100644 index 000000000..4c9653ba4 --- /dev/null +++ b/test/cpp/CMakeLists.txt @@ -0,0 +1,92 @@ +add_library(proxsuite-test-util STATIC util_f64.cpp util_f32.cpp) +target_link_libraries(proxsuite-test-util PUBLIC proxsuite) + +if(BUILD_WITH_VECTORIZATION_SUPPORT) + add_library(proxsuite-test-util-vectorized STATIC util_f64.cpp util_f32.cpp) + target_include_directories(proxsuite-test-util-vectorized PRIVATE include) + target_link_libraries(proxsuite-test-util-vectorized PUBLIC proxsuite-vectorized) +endif() + +function(proxsuite_add_test name) + set(options) + set(oneValueArgs) + set(multiValueArgs COMPILE_DEFINITIONS LINK_LIBRARIES LABELS) + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + add_executable(proxsuite-test-cpp-${name} ${name}.cpp) + target_link_libraries( + proxsuite-test-cpp-${name} + PRIVATE proxsuite-test-util Catch2::Catch2WithMain ${arg_LINK_LIBRARIES} + ) + target_compile_definitions(proxsuite-test-cpp-${name} PRIVATE ${arg_COMPILE_DEFINITIONS}) + add_test(NAME proxsuite-test-cpp.${name} COMMAND proxsuite-test-cpp-${name}) + + if(arg_LABELS) + set_tests_properties(proxsuite-test-cpp.${name} PROPERTIES LABELS "${arg_LABELS}") + endif() + + if(BUILD_WITH_VECTORIZATION_SUPPORT) + add_executable(proxsuite-vectorized-test-cpp-${name} ${name}.cpp) + target_link_libraries( + proxsuite-vectorized-test-cpp-${name} + PRIVATE proxsuite-test-util-vectorized Catch2::Catch2WithMain ${arg_LINK_LIBRARIES} + ) + target_compile_definitions( + proxsuite-vectorized-test-cpp-${name} + PRIVATE ${arg_COMPILE_DEFINITIONS} + ) + add_test( + NAME proxsuite-test-cpp.vectorized.${name} + COMMAND proxsuite-vectorized-test-cpp-${name} + ) + if(arg_LABELS) + set_tests_properties( + proxsuite-test-cpp.vectorized.${name} + PROPERTIES LABELS "vectorized;${arg_LABELS}" + ) + endif() + endif() +endfunction() + +proxsuite_add_test(uint128) +proxsuite_add_test(cvxpy) +proxsuite_add_test(dense_backward) +proxsuite_add_test(dense_qp_eq) +proxsuite_add_test(dense_qp_solve) +proxsuite_add_test(dense_qp_with_eq_and_in) +proxsuite_add_test(dense_qp_wrapper) +proxsuite_add_test(dense_ruiz_equilibration) +proxsuite_add_test(dense_unconstrained_qp) +proxsuite_add_test(sparse_factorization) +proxsuite_add_test(sparse_qp_solve) +proxsuite_add_test(sparse_qp_wrapper) +proxsuite_add_test(sparse_qp) +proxsuite_add_test(sparse_ruiz_equilibration) + +if(BUILD_WITH_OPENMP_SUPPORT) + proxsuite_add_test(parallel_qp_solve) +endif() + +if(BUILD_WITH_SERIALIZATION) + # We have to create the folder for the output data, tests don't do that. + make_directory(${CMAKE_BINARY_DIR}/serialization-data) + proxsuite_add_test( + serialization + COMPILE_DEFINITIONS TEST_SERIALIZATION_FOLDER="${CMAKE_BINARY_DIR}/serialization-data" + ) +endif() + +if(BUILD_MAROS_MESZAROS_TESTS) + proxsuite_add_test( + dense_maros_meszaros + COMPILE_DEFINITIONS MAROS_MESZAROS_DIR="${MAROS_MESZAROS_DIR}" + LINK_LIBRARIES matio::matio + LABELS maros_meszaros + ) + proxsuite_add_test( + sparse_maros_meszaros + COMPILE_DEFINITIONS MAROS_MESZAROS_DIR="${MAROS_MESZAROS_DIR}" + LINK_LIBRARIES matio::matio + LABELS maros_meszaros + ) +endif() diff --git a/test/src/cvxpy.cpp b/test/cpp/cvxpy.cpp similarity index 86% rename from test/src/cvxpy.cpp rename to test/cpp/cvxpy.cpp index dfdb6df2e..437badc2b 100644 --- a/test/src/cvxpy.cpp +++ b/test/cpp/cvxpy.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include @@ -19,7 +19,7 @@ using Mat = template using Vec = Eigen::Matrix; -DOCTEST_TEST_CASE("3 dim test case from cvxpy, check feasibility") +TEST_CASE("3 dim test case from cvxpy, check feasibility") { std::cout << "---3 dim test case from cvxpy, check feasibility " << std::endl; @@ -48,8 +48,8 @@ DOCTEST_TEST_CASE("3 dim test case from cvxpy, check feasibility") .lpNorm(); T dua_res = (H * results.x + g + C.transpose() * results.z).lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "primal residual: " << pri_res << std::endl; std::cout << "dual residual: " << dua_res << std::endl; @@ -58,7 +58,7 @@ DOCTEST_TEST_CASE("3 dim test case from cvxpy, check feasibility") << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("simple test case from cvxpy, check feasibility") +TEST_CASE("simple test case from cvxpy, check feasibility") { std::cout << "---simple test case from cvxpy, check feasibility " @@ -90,9 +90,9 @@ DOCTEST_TEST_CASE("simple test case from cvxpy, check feasibility") (H * results.x + g + C.transpose() * results.z).lpNorm(); T x_sol = 0.5; - DOCTEST_CHECK((x_sol - results.x.coeff(0, 0)) <= eps_abs); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK((x_sol - results.x.coeff(0, 0)) <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "primal residual: " << pri_res << std::endl; std::cout << "dual residual: " << dua_res << std::endl; @@ -101,8 +101,8 @@ DOCTEST_TEST_CASE("simple test case from cvxpy, check feasibility") << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("simple test case from cvxpy, init with solution, check that " - "solver stays there") +TEST_CASE("simple test case from cvxpy, init with solution, check that " + "solver stays there") { std::cout << "---simple test case from cvxpy, init with solution, check that " @@ -147,10 +147,10 @@ DOCTEST_TEST_CASE("simple test case from cvxpy, init with solution, check that " T dua_res = (H * qp.results.x + g + C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(qp.results.info.iter <= 0); - DOCTEST_CHECK((x_sol - qp.results.x.coeff(0, 0)) <= eps_abs); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(qp.results.info.iter <= 0); + CHECK((x_sol - qp.results.x.coeff(0, 0)) <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "primal residual: " << pri_res << std::endl; std::cout << "dual residual: " << dua_res << std::endl; diff --git a/test/src/dense_backward.cpp b/test/cpp/dense_backward.cpp similarity index 92% rename from test/src/dense_backward.cpp rename to test/cpp/dense_backward.cpp index 346275161..9a70aaeac 100644 --- a/test/src/dense_backward.cpp +++ b/test/cpp/dense_backward.cpp @@ -2,9 +2,7 @@ // Copyright (c) 2023 INRIA // #include -#include -#include -#include +#include #include #include #include @@ -13,7 +11,7 @@ using T = double; using namespace proxsuite; using namespace proxsuite::proxqp; -DOCTEST_TEST_CASE("proxqp::dense: test compute backward for g (feasible QP)") +TEST_CASE("proxqp::dense: test compute backward for g (feasible QP)") { double sparsity_factor = 0.85; T eps_abs = T(1e-9); @@ -74,12 +72,12 @@ DOCTEST_TEST_CASE("proxqp::dense: test compute backward for g (feasible QP)") // Compare dx_dg_fd with the result from the backward function for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { - DOCTEST_CHECK(std::abs(dx_dg_fd(i, j) - dx_dg(i, j)) < 1e-5); + CHECK(std::abs(dx_dg_fd(i, j) - dx_dg(i, j)) < 1e-5); } } } -DOCTEST_TEST_CASE("proxqp::dense: test compute backward for b (feasible QP)") +TEST_CASE("proxqp::dense: test compute backward for b (feasible QP)") { double sparsity_factor = 0.85; T eps_abs = T(1e-9); @@ -140,13 +138,13 @@ DOCTEST_TEST_CASE("proxqp::dense: test compute backward for b (feasible QP)") // Compare dx_db_fd with the result from the backward function for (int i = 0; i < dim; i++) { for (int j = 0; j < n_eq; j++) { - DOCTEST_CHECK(std::abs(dx_db_fd(i, j) - dx_db(i, j)) < 1e-5); + CHECK(std::abs(dx_db_fd(i, j) - dx_db(i, j)) < 1e-5); } } } -DOCTEST_TEST_CASE("proxqp::dense: test compute backward for g (QP with " - "saturating inequality constraints)") +TEST_CASE("proxqp::dense: test compute backward for g (QP with " + "saturating inequality constraints)") { double sparsity_factor = 0.85; T eps_abs = T(1e-9); @@ -216,7 +214,7 @@ DOCTEST_TEST_CASE("proxqp::dense: test compute backward for g (QP with " // Compare dx_dg_fd with the result from the backward function for (int i = 0; i < dim; i++) { for (int j = 0; j < dim; j++) { - DOCTEST_CHECK(std::abs(dx_dg_fd(i, j) - dx_dg(i, j)) < 1e-5); + CHECK(std::abs(dx_dg_fd(i, j) - dx_dg(i, j)) < 1e-5); } } } \ No newline at end of file diff --git a/test/src/dense_maros_meszaros.cpp b/test/cpp/dense_maros_meszaros.cpp similarity index 98% rename from test/src/dense_maros_meszaros.cpp rename to test/cpp/dense_maros_meszaros.cpp index 9fcc4a88e..d3a5017df 100644 --- a/test/src/dense_maros_meszaros.cpp +++ b/test/cpp/dense_maros_meszaros.cpp @@ -1,15 +1,13 @@ // // Copyright (c) 2022 INRIA // -#include -#include +#include +#include "maros_meszaros.hpp" #include #include using namespace proxsuite; -#define MAROS_MESZAROS_DIR PROBLEM_PATH "/data/maros_meszaros_data/" - char const* files[] = { MAROS_MESZAROS_DIR "AUG2D.mat", MAROS_MESZAROS_DIR "AUG2DC.mat", MAROS_MESZAROS_DIR "AUG2DCQP.mat", MAROS_MESZAROS_DIR "AUG2DQP.mat", diff --git a/test/src/dense_qp_eq.cpp b/test/cpp/dense_qp_eq.cpp similarity index 87% rename from test/src/dense_qp_eq.cpp rename to test/cpp/dense_qp_eq.cpp index 2a6aa2541..2d707e60a 100644 --- a/test/src/dense_qp_eq.cpp +++ b/test/cpp/dense_qp_eq.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 - 2024 INRIA // #include -#include +#include #include #include #include @@ -11,7 +11,7 @@ using T = double; using namespace proxsuite; -DOCTEST_TEST_CASE("qp: start from solution using the wrapper framework") +TEST_CASE("qp: start from solution using the wrapper framework") { proxqp::isize dim = 30; proxqp::isize n_eq = 6; @@ -49,12 +49,12 @@ DOCTEST_TEST_CASE("qp: start from solution using the wrapper framework") qp.init(H, g, A, b, C, l, u); qp.solve(primal_solution, dual_solution, dual_init_in); - DOCTEST_CHECK((A * qp.results.x - b).lpNorm() <= eps_abs); - DOCTEST_CHECK((H * qp.results.x + g + A.transpose() * qp.results.y) - .lpNorm() <= eps_abs); + CHECK((A * qp.results.x - b).lpNorm() <= eps_abs); + CHECK((H * qp.results.x + g + A.transpose() * qp.results.y) + .lpNorm() <= eps_abs); } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality constraints " - "and increasing dimension with the wrapper API") +TEST_CASE("sparse random strongly convex qp with equality constraints " + "and increasing dimension with the wrapper API") { std::cout << "---testing sparse random strongly convex qp with equality " @@ -89,8 +89,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality constraints " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using wrapper API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -100,8 +100,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality constraints " << std::endl; } } -DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " - "linar cost and increasing dimension using wrapper API") +TEST_CASE("linear problem with equality with equality constraints and " + "linar cost and increasing dimension using wrapper API") { std::cout << "---testing linear problem with equality constraints and " @@ -143,8 +143,8 @@ DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using wrapper API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -155,9 +155,9 @@ DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " } } -DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " - "linear cost and increasing dimension using wrapper API and " - "the dedicated LP interface") +TEST_CASE("linear problem with equality with equality constraints and " + "linear cost and increasing dimension using wrapper API and " + "the dedicated LP interface") { std::cout @@ -202,8 +202,8 @@ DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using wrapper API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -214,7 +214,7 @@ DOCTEST_TEST_CASE("linear problem with equality with equality constraints and " } } -DOCTEST_TEST_CASE("infeasible qp") +TEST_CASE("infeasible qp") { // (x1- 9)^2 + (x2-6)^2 // s.t. @@ -251,6 +251,6 @@ DOCTEST_TEST_CASE("infeasible qp") qp.solve(); - DOCTEST_CHECK(qp.results.info.status == - proxsuite::proxqp::QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE); + CHECK(qp.results.info.status == + proxsuite::proxqp::QPSolverOutput::PROXQP_PRIMAL_INFEASIBLE); } \ No newline at end of file diff --git a/test/src/dense_qp_solve.cpp b/test/cpp/dense_qp_solve.cpp similarity index 91% rename from test/src/dense_qp_solve.cpp rename to test/cpp/dense_qp_solve.cpp index 012bcb4c5..9da18ebac 100644 --- a/test/src/dense_qp_solve.cpp +++ b/test/cpp/dense_qp_solve.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include #include @@ -13,7 +13,7 @@ using T = double; using namespace proxsuite; using namespace proxsuite::proxqp; -DOCTEST_TEST_CASE("proxqp::dense: test init with fixed sizes matrices") +TEST_CASE("proxqp::dense: test init with fixed sizes matrices") { double sparsity_factor = 0.15; T eps_abs = T(1e-9); @@ -44,8 +44,8 @@ DOCTEST_TEST_CASE("proxqp::dense: test init with fixed sizes matrices") T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -68,8 +68,8 @@ DOCTEST_TEST_CASE("proxqp::dense: test init with fixed sizes matrices") T pri_res = (qp.A * results.x - qp.b).lpNorm(); T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -82,8 +82,8 @@ DOCTEST_TEST_CASE("proxqp::dense: test init with fixed sizes matrices") } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test solve function") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test solve function") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -119,8 +119,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -131,8 +131,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test solve with different rho value") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test solve with different rho value") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -161,7 +161,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " eps_abs, 0, T(1.E-7)); - DOCTEST_CHECK(results.info.rho == T(1.E-7)); + CHECK(results.info.rho == T(1.E-7)); T pri_res = std::max((qp.A * results.x - qp.b).lpNorm(), (helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l)) @@ -169,8 +169,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -181,7 +181,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test solve with different mu_eq and mu_in values") { @@ -222,8 +222,8 @@ DOCTEST_TEST_CASE( T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -234,8 +234,8 @@ DOCTEST_TEST_CASE( << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test warm starting") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test warm starting") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -263,8 +263,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -275,8 +275,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test verbose = true") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test verbose = true") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -316,8 +316,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -328,8 +328,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " << results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test no initial guess") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -373,8 +373,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " T dua_res = (qp.H * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; diff --git a/test/src/dense_qp_with_eq_and_in.cpp b/test/cpp/dense_qp_with_eq_and_in.cpp similarity index 89% rename from test/src/dense_qp_with_eq_and_in.cpp rename to test/cpp/dense_qp_with_eq_and_in.cpp index cb7e1d808..b77be02a8 100644 --- a/test/src/dense_qp_with_eq_and_in.cpp +++ b/test/cpp/dense_qp_with_eq_and_in.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include #include @@ -11,7 +11,7 @@ using T = double; using namespace proxsuite; -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and inequality constraints " "and increasing dimension using wrapper API") { @@ -52,8 +52,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -64,8 +64,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with box inequality " - "constraints and increasing dimension using the API") +TEST_CASE("sparse random strongly convex qp with box inequality " + "constraints and increasing dimension using the API") { std::cout @@ -102,8 +102,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with box inequality " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -114,8 +114,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with box inequality " } } -DOCTEST_TEST_CASE("sparse random not strongly convex qp with inequality " - "constraints and increasing dimension using the API") +TEST_CASE("sparse random not strongly convex qp with inequality " + "constraints and increasing dimension using the API") { std::cout @@ -152,8 +152,8 @@ DOCTEST_TEST_CASE("sparse random not strongly convex qp with inequality " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -164,8 +164,8 @@ DOCTEST_TEST_CASE("sparse random not strongly convex qp with inequality " } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " - "constraints and increasing dimension using the API") +TEST_CASE("sparse random strongly convex qp with degenerate inequality " + "constraints and increasing dimension using the API") { std::cout @@ -197,8 +197,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " qp_random.l, qp_random.u); qp.solve(); - DOCTEST_CHECK(qp.results.info.status == - proxqp::QPSolverOutput::PROXQP_SOLVED); + CHECK(qp.results.info.status == proxqp::QPSolverOutput::PROXQP_SOLVED); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -208,8 +207,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -220,8 +219,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with degenerate inequality " } } -DOCTEST_TEST_CASE("linear problem with equality inequality constraints and " - "increasing dimension using the API") +TEST_CASE("linear problem with equality inequality constraints and " + "increasing dimension using the API") { srand(1); std::cout << "---testing linear problem with inequality constraints and " @@ -263,8 +262,8 @@ DOCTEST_TEST_CASE("linear problem with equality inequality constraints and " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; diff --git a/test/src/dense_qp_wrapper.cpp b/test/cpp/dense_qp_wrapper.cpp similarity index 87% rename from test/src/dense_qp_wrapper.cpp rename to test/cpp/dense_qp_wrapper.cpp index 353fb7dce..0f0d1cffc 100644 --- a/test/src/dense_qp_wrapper.cpp +++ b/test/cpp/dense_qp_wrapper.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022-2024 INRIA // #include -#include +#include #include #include #include @@ -13,7 +13,7 @@ using T = double; using namespace proxsuite; using namespace proxsuite::proxqp; -DOCTEST_TEST_CASE( +TEST_CASE( "ProxQP::dense: sparse random strongly convex qp with inequality constraints" "and empty equality constraints") { @@ -67,8 +67,8 @@ DOCTEST_TEST_CASE( T dua_res = (qp_random.H * qp.results.x + qp_random.g + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -116,8 +116,8 @@ DOCTEST_TEST_CASE( dua_res = (qp_random.H * qp.results.x + qp_random.g + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -148,8 +148,8 @@ DOCTEST_TEST_CASE( dua_res = (qp_random.H * qp.results.x + qp_random.g + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -160,9 +160,8 @@ DOCTEST_TEST_CASE( std::cout << "setup timing " << qp.results.info.setup_time << " solve time " << qp.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update H") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update H") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test update H---" @@ -199,8 +198,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -243,8 +242,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -277,8 +276,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -291,9 +290,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update A") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update A") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -331,8 +329,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -377,8 +375,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -410,8 +408,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -424,9 +422,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update C") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update C") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -464,8 +461,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -510,8 +507,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -543,8 +540,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -557,9 +554,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update b") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update b") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -597,8 +593,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -643,8 +639,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -676,8 +672,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -690,9 +686,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update u") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update u") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -728,8 +723,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -779,8 +774,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -812,8 +807,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -826,9 +821,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update g") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update g") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -864,8 +858,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -911,8 +905,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -944,8 +938,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -958,9 +952,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "sparse random strongly convex qp with equality and inequality " - "constraints: test update H and A and b and u and l") +TEST_CASE("sparse random strongly convex qp with equality and inequality " + "constraints: test update H and A and b and u and l") { std::cout @@ -997,8 +990,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1059,8 +1052,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1092,8 +1085,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -1106,9 +1099,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update rho") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update rho") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1144,8 +1136,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1184,8 +1176,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1222,8 +1214,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -1236,9 +1228,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test update mu_eq and mu_in") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test update mu_eq and mu_in") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1274,8 +1265,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1317,8 +1308,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1355,8 +1346,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -1369,9 +1360,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test warm starting") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test warm starting") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1408,8 +1398,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1439,8 +1429,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim after updating: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -1474,8 +1464,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------ conter factual check with another QP object starting at " "the updated model : " @@ -1488,9 +1478,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test dense init") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test dense init") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1532,13 +1521,12 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test with no initial guess") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test with no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1577,8 +1565,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1610,8 +1598,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1622,7 +1610,7 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test with equality constrained initial guess") { @@ -1665,8 +1653,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1699,8 +1687,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1711,9 +1699,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test with warm start with previous result") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test with warm start with previous result") { std::cout @@ -1754,8 +1741,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1822,8 +1809,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1834,9 +1821,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test with cold start option") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test with cold start option") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1876,8 +1862,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1944,8 +1930,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with cold start option: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1956,7 +1942,7 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test equilibration options at initialization") { @@ -2000,8 +1986,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp with " "preconditioner derived: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -2037,8 +2023,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp without preconditioner derivation: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -2051,9 +2037,8 @@ DOCTEST_TEST_CASE( << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test equilibration options at update") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test equilibration options at update") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -2093,8 +2078,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp with " "preconditioner derived: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -2124,8 +2109,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with preconditioner re derived " "after an update (should get exact same results): " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -2179,8 +2164,8 @@ DOCTEST_TEST_CASE( nullopt, false); // use previous preconditioner: should get same result as well qp2.solve(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp without preconditioner derivation: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -2445,7 +2430,7 @@ TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " "inequality constraints: test multiple solve at once with equality " - "constrained initial guess") + "constrained initial guess and warm start") { double sparsity_factor = 0.15; @@ -2572,9 +2557,9 @@ TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " << qp.results.info.solve_time << std::endl; } -TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test multiple solve at once with no initial guess") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test multiple solve at once with no initial " + "guess and warm start") { double sparsity_factor = 0.15; @@ -3467,146 +3452,6 @@ TEST_CASE( << qp.results.info.solve_time << std::endl; } -TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test multiple solve at once with no initial guess") -{ - - double sparsity_factor = 0.15; - T eps_abs = T(1e-9); - utils::rand::set_seed(1); - dense::isize dim = 10; - - dense::isize n_eq(dim / 4); - dense::isize n_in(dim / 4); - T strong_convexity_factor(1.e-2); - proxqp::dense::Model qp_random = proxqp::utils::dense_strongly_convex_qp( - dim, n_eq, n_in, sparsity_factor, strong_convexity_factor); - - dense::QP qp(dim, n_eq, n_in); - - qp.settings.eps_abs = eps_abs; - qp.settings.eps_rel = 0; - qp.settings.initial_guess = InitialGuessStatus::NO_INITIAL_GUESS; - - std::cout << "Test with warm start with previous result and first solve with " - "no initial guess" - << std::endl; - std::cout << "dirty workspace before any solving: " << qp.work.dirty - << std::endl; - - qp.init(qp_random.H, - qp_random.g, - qp_random.A, - qp_random.b, - qp_random.C, - qp_random.l, - qp_random.u); - qp.solve(); - - T pri_res = std::max( - (qp_random.A * qp.results.x - qp_random.b).lpNorm(), - (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + - helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) - .lpNorm()); - T dua_res = (qp_random.H * qp.results.x + qp_random.g + - qp_random.A.transpose() * qp.results.y + - qp_random.C.transpose() * qp.results.z) - .lpNorm(); - CHECK(dua_res <= eps_abs); - CHECK(pri_res <= eps_abs); - std::cout << "--n = " << dim << " n_eq " << n_eq << " n_in " << n_in - << std::endl; - std::cout << "; dual residual " << dua_res << "; primal residual " << pri_res - << std::endl; - std::cout << "total number of iteration: " << qp.results.info.iter - << std::endl; - std::cout << "setup timing " << qp.results.info.setup_time << " solve time " - << qp.results.info.solve_time << std::endl; - - qp.settings.initial_guess = - InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - std::cout << "dirty workspace : " << qp.work.dirty << std::endl; - qp_random.H *= 2.; - qp_random.g = utils::rand::vector_rand(dim); - bool update_preconditioner = true; - qp.update(qp_random.H, - qp_random.g, - qp_random.A, - qp_random.b, - qp_random.C, - qp_random.l, - qp_random.u, - update_preconditioner); - qp.solve(); - pri_res = std::max( - (qp_random.A * qp.results.x - qp_random.b).lpNorm(), - (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + - helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) - .lpNorm()); - dua_res = (qp_random.H * qp.results.x + qp_random.g + - qp_random.A.transpose() * qp.results.y + - qp_random.C.transpose() * qp.results.z) - .lpNorm(); - CHECK(dua_res <= eps_abs); - CHECK(pri_res <= eps_abs); - std::cout << "Second solve " << std::endl; - std::cout << "--n = " << dim << " n_eq " << n_eq << " n_in " << n_in - << std::endl; - std::cout << "; dual residual " << dua_res << "; primal residual " << pri_res - << std::endl; - std::cout << "total number of iteration: " << qp.results.info.iter - << std::endl; - std::cout << "setup timing " << qp.results.info.setup_time << " solve time " - << qp.results.info.solve_time << std::endl; - - std::cout << "dirty workspace : " << qp.work.dirty << std::endl; - qp.solve(); - pri_res = std::max( - (qp_random.A * qp.results.x - qp_random.b).lpNorm(), - (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + - helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) - .lpNorm()); - dua_res = (qp_random.H * qp.results.x + qp_random.g + - qp_random.A.transpose() * qp.results.y + - qp_random.C.transpose() * qp.results.z) - .lpNorm(); - CHECK(dua_res <= eps_abs); - CHECK(pri_res <= eps_abs); - std::cout << "Third solve " << std::endl; - std::cout << "--n = " << dim << " n_eq " << n_eq << " n_in " << n_in - << std::endl; - std::cout << "; dual residual " << dua_res << "; primal residual " << pri_res - << std::endl; - std::cout << "total number of iteration: " << qp.results.info.iter - << std::endl; - std::cout << "setup timing " << qp.results.info.setup_time << " solve time " - << qp.results.info.solve_time << std::endl; - - std::cout << "dirty workspace : " << qp.work.dirty << std::endl; - qp.solve(); - pri_res = std::max( - (qp_random.A * qp.results.x - qp_random.b).lpNorm(), - (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + - helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) - .lpNorm()); - dua_res = (qp_random.H * qp.results.x + qp_random.g + - qp_random.A.transpose() * qp.results.y + - qp_random.C.transpose() * qp.results.z) - .lpNorm(); - CHECK(dua_res <= eps_abs); - CHECK(pri_res <= eps_abs); - std::cout << "Fourth solve " << std::endl; - std::cout << "--n = " << dim << " n_eq " << n_eq << " n_in " << n_in - << std::endl; - std::cout << "; dual residual " << dua_res << "; primal residual " << pri_res - << std::endl; - std::cout << "total number of iteration: " << qp.results.info.iter - << std::endl; - std::cout << "setup timing " << qp.results.info.setup_time << " solve time " - << qp.results.info.solve_time << std::endl; -} - TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " "inequality constraints: test update + multiple solve at once with " "cold start initial guess and then cold start option") @@ -5049,10 +4894,9 @@ TEST_CASE("ProxQP::dense: Test g update for different warm start with previous " << qp2.results.info.solve_time << std::endl; } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using warm start with previous results") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using warm start with previous results") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5074,8 +4918,8 @@ DOCTEST_TEST_CASE( bool compute_preconditioner = true; dense::QP qp{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -5087,11 +4931,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5102,8 +4946,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -5117,11 +4961,11 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5132,12 +4976,12 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5150,13 +4994,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -5167,13 +5011,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5186,17 +5030,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5207,8 +5051,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -5221,11 +5065,11 @@ DOCTEST_TEST_CASE( 1.e-3); qp3.settings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5236,14 +5080,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using cold start with previous results") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using cold start with previous results") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5267,8 +5110,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -5280,11 +5123,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5295,8 +5138,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -5307,11 +5150,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5322,14 +5165,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5342,13 +5185,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -5359,15 +5202,15 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5380,17 +5223,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5401,8 +5244,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -5413,11 +5256,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5428,14 +5271,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using equality constrained initial guess") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using equality constrained initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5459,8 +5301,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -5472,11 +5314,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5487,8 +5329,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -5499,11 +5341,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5514,14 +5356,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5534,13 +5376,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -5551,15 +5393,15 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5572,17 +5414,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5593,8 +5435,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -5605,11 +5447,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5620,14 +5462,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using no initial guess") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5650,8 +5491,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -5663,11 +5504,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5678,8 +5519,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -5690,11 +5531,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5705,13 +5546,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5724,13 +5565,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -5741,14 +5582,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5761,17 +5602,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5782,8 +5623,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -5794,11 +5635,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5809,14 +5650,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using warm start with previous results") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using warm start with previous results") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5838,8 +5678,8 @@ DOCTEST_TEST_CASE( bool compute_preconditioner = true; dense::QP qp{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -5851,11 +5691,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5866,15 +5706,15 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.settings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5884,8 +5724,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -5899,8 +5739,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5910,14 +5750,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5930,13 +5770,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.settings.initial_guess = proxsuite::proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; @@ -5944,13 +5784,13 @@ DOCTEST_TEST_CASE( // warm start with previous result used, hence if the qp is small and // simple, the parameters should not changed during first solve, and also // after as we start at the solution - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp2.results.x - qp_random.u) + @@ -5960,14 +5800,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.settings.verbose = true; @@ -5986,17 +5826,17 @@ DOCTEST_TEST_CASE( // warm start with previous result used, hence if the qp is small and // simple, the parameters should not changed during first solve, and also // after as we start at the solution - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6006,8 +5846,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -6024,17 +5864,17 @@ DOCTEST_TEST_CASE( // warm start with previous result used, hence if the qp is small and // simple, the parameters should not changed during first solve, and also // after as we start at the solution - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6044,15 +5884,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using cold start with previous results") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using cold start with previous results") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -6076,8 +5915,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -6089,11 +5928,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -6104,13 +5943,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6120,8 +5959,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -6135,8 +5974,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6146,16 +5985,16 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -6168,22 +6007,22 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp2.results.x - qp_random.u) + @@ -6193,16 +6032,16 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -6217,17 +6056,17 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6237,8 +6076,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -6252,17 +6091,17 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6272,12 +6111,12 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after several solves " "using equality constrained initial guess") @@ -6304,8 +6143,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -6317,11 +6156,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -6332,13 +6171,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6348,8 +6187,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -6363,8 +6202,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6374,16 +6213,16 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -6396,22 +6235,22 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp2.results.x - qp_random.u) + @@ -6421,16 +6260,16 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -6445,17 +6284,17 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6465,8 +6304,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -6480,17 +6319,17 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6500,15 +6339,14 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( - "ProxQP::dense: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using no initial guess") +TEST_CASE("ProxQP::dense: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -6531,8 +6369,8 @@ DOCTEST_TEST_CASE( dense::QP qp{ dim, n_eq, n_in }; // creating QP object qp.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -6544,11 +6382,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -6559,13 +6397,13 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6575,8 +6413,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -6590,8 +6428,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -6601,15 +6439,15 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp2{ dim, n_eq, n_in }; // creating QP object qp2.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -6622,22 +6460,22 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp2.results.x - qp_random.u) + @@ -6647,15 +6485,15 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model dense::QP qp3{ dim, n_eq, n_in }; // creating QP object qp3.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -6670,17 +6508,17 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6690,8 +6528,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -6705,17 +6543,17 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp3.results.x - qp_random.u) + @@ -6725,8 +6563,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } @@ -7204,8 +7042,8 @@ TEST_CASE("ProxQP::dense: test primal infeasibility solving") qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= scaled_eps); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= scaled_eps); + CHECK(dua_res <= eps_abs); } } @@ -7249,8 +7087,7 @@ TEST_CASE("ProxQP::dense: estimate of minimal eigenvalues using Eigen") nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 1) <= - tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 1) <= tol); } dim = 50; n_eq = dim; @@ -7285,8 +7122,8 @@ TEST_CASE("ProxQP::dense: estimate of minimal eigenvalues using Eigen") nullopt, nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } dim = 50; n_eq = dim; @@ -7323,8 +7160,8 @@ TEST_CASE("ProxQP::dense: estimate of minimal eigenvalues using Eigen") nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } } @@ -7365,8 +7202,7 @@ TEST_CASE( nullopt, -1); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 1) <= - tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 1) <= tol); } dim = 50; n_eq = dim; @@ -7397,8 +7233,8 @@ TEST_CASE( nullopt, nullopt, minimal_eigenvalue); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } dim = 50; n_eq = dim; @@ -7431,8 +7267,8 @@ TEST_CASE( nullopt, minimal_eigenvalue); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } } @@ -7480,8 +7316,7 @@ TEST_CASE( nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK( - std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 0.5) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate + 0.5) <= tol); } dim = 50; n_eq = dim; @@ -7519,8 +7354,8 @@ TEST_CASE( nullopt, nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } dim = 50; n_eq = dim; @@ -7561,13 +7396,13 @@ TEST_CASE( nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } } -DOCTEST_TEST_CASE("check that model.is_valid function for symmetric matrices " - "works for epsilon precision") +TEST_CASE("check that model.is_valid function for symmetric matrices " + "works for epsilon precision") { Eigen::Matrix matrix = Eigen::Matrix::Random(); Eigen::Matrix symmetric_mat = matrix + matrix.transpose(); @@ -7581,8 +7416,8 @@ DOCTEST_TEST_CASE("check that model.is_valid function for symmetric matrices " bool is_symmetric_with_tolerance = symmetric_mat.isApprox( symmetric_mat.transpose(), std::numeric_limits::epsilon()); - DOCTEST_CHECK(is_symmetric_without_tolerance == false); - DOCTEST_CHECK(is_symmetric_with_tolerance == true); + CHECK(is_symmetric_without_tolerance == false); + CHECK(is_symmetric_with_tolerance == true); // initialize a model with a symmetric matrix as Hessian, this runs // model.is_valid() that performs the check above @@ -7652,15 +7487,15 @@ TEST_CASE("ProxQP::dense: sparse random strongly convex qp with" qp_random.u); qp.solve(); - DOCTEST_CHECK(qp.results.info.mu_updates > 0); + CHECK(qp.results.info.mu_updates > 0); T pri_res = (helpers::negative_part(qp_random.C * qp.results.x - qp_random.l)) .lpNorm(); T dua_res = (qp_random.H * qp.results.x + qp_random.g + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; diff --git a/test/src/dense_ruiz_equilibration.cpp b/test/cpp/dense_ruiz_equilibration.cpp similarity index 84% rename from test/src/dense_ruiz_equilibration.cpp rename to test/cpp/dense_ruiz_equilibration.cpp index d1bff6479..4861e24ed 100644 --- a/test/src/dense_ruiz_equilibration.cpp +++ b/test/cpp/dense_ruiz_equilibration.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022-2023 INRIA // #include -#include +#include #include #include #include @@ -12,7 +12,7 @@ using namespace proxsuite; using Scalar = double; -DOCTEST_TEST_CASE("ruiz preconditioner") +TEST_CASE("ruiz preconditioner") { int dim = 5; int n_eq = 6; @@ -65,8 +65,8 @@ DOCTEST_TEST_CASE("ruiz preconditioner") auto A_new = (tail * A * head).eval(); auto b_new = (tail * b).eval(); - DOCTEST_CHECK((H_new - qp.work.H_scaled).norm() <= Scalar(1e-10)); - DOCTEST_CHECK((g_new - qp.work.g_scaled).norm() <= Scalar(1e-10)); - DOCTEST_CHECK((A_new - qp.work.A_scaled).norm() <= Scalar(1e-10)); - DOCTEST_CHECK((b_new - qp.work.b_scaled).norm() <= Scalar(1e-10)); + CHECK((H_new - qp.work.H_scaled).norm() <= Scalar(1e-10)); + CHECK((g_new - qp.work.g_scaled).norm() <= Scalar(1e-10)); + CHECK((A_new - qp.work.A_scaled).norm() <= Scalar(1e-10)); + CHECK((b_new - qp.work.b_scaled).norm() <= Scalar(1e-10)); } diff --git a/test/src/dense_unconstrained_qp.cpp b/test/cpp/dense_unconstrained_qp.cpp similarity index 92% rename from test/src/dense_unconstrained_qp.cpp rename to test/cpp/dense_unconstrained_qp.cpp index eed71aecc..1ac37ef88 100644 --- a/test/src/dense_unconstrained_qp.cpp +++ b/test/cpp/dense_unconstrained_qp.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include #include @@ -12,7 +12,7 @@ using namespace proxsuite; using T = double; -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex unconstrained qp and increasing dimension") { @@ -48,8 +48,8 @@ DOCTEST_TEST_CASE( qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -60,8 +60,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE("sparse random not strongly convex unconstrained qp and " - "increasing dimension") +TEST_CASE("sparse random not strongly convex unconstrained qp and " + "increasing dimension") { std::cout << "---testing sparse random not strongly convex unconstrained qp " @@ -101,8 +101,8 @@ DOCTEST_TEST_CASE("sparse random not strongly convex unconstrained qp and " qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -113,7 +113,7 @@ DOCTEST_TEST_CASE("sparse random not strongly convex unconstrained qp and " } } -DOCTEST_TEST_CASE("unconstrained qp with H = Id and g random") +TEST_CASE("unconstrained qp with H = Id and g random") { std::cout << "---unconstrained qp with H = Id and g random---" << std::endl; @@ -149,8 +149,8 @@ DOCTEST_TEST_CASE("unconstrained qp with H = Id and g random") qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -160,7 +160,7 @@ DOCTEST_TEST_CASE("unconstrained qp with H = Id and g random") << std::endl; } -DOCTEST_TEST_CASE("unconstrained qp with H = Id and g = 0") +TEST_CASE("unconstrained qp with H = Id and g = 0") { std::cout << "---unconstrained qp with H = Id and g = 0---" << std::endl; @@ -197,8 +197,8 @@ DOCTEST_TEST_CASE("unconstrained qp with H = Id and g = 0") qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------solving qp with dim: " << dim << " neq: " << n_eq << " nin: " << n_in << std::endl; diff --git a/test/include/maros_meszaros.hpp b/test/cpp/maros_meszaros.hpp similarity index 100% rename from test/include/maros_meszaros.hpp rename to test/cpp/maros_meszaros.hpp diff --git a/test/src/parallel_qp_solve.cpp b/test/cpp/parallel_qp_solve.cpp similarity index 96% rename from test/src/parallel_qp_solve.cpp rename to test/cpp/parallel_qp_solve.cpp index b60d25f53..ab271d948 100644 --- a/test/src/parallel_qp_solve.cpp +++ b/test/cpp/parallel_qp_solve.cpp @@ -1,7 +1,7 @@ // // Copyright (c) 2023 INRIA // -#include +#include #include #include #include @@ -16,7 +16,7 @@ using T = double; using I = c_int; using namespace proxsuite::linalg::sparse::tags; -DOCTEST_TEST_CASE("test parallel qp_solve for dense qps") +TEST_CASE("test parallel qp_solve for dense qps") { double sparsity_factor = 0.15; T eps_abs = T(1e-9); @@ -76,7 +76,7 @@ DOCTEST_TEST_CASE("test parallel qp_solve for dense qps") } } -DOCTEST_TEST_CASE("test dense BatchQP and optional NUM_THREADS") +TEST_CASE("test dense BatchQP and optional NUM_THREADS") { double sparsity_factor = 0.15; T eps_abs = T(1e-9); @@ -132,7 +132,7 @@ DOCTEST_TEST_CASE("test dense BatchQP and optional NUM_THREADS") } } -DOCTEST_TEST_CASE("test parallel qp_solve for sparse qps") +TEST_CASE("test parallel qp_solve for sparse qps") { sparse::isize dim = 500; sparse::isize n_eq(10); @@ -193,7 +193,7 @@ DOCTEST_TEST_CASE("test parallel qp_solve for sparse qps") } } -DOCTEST_TEST_CASE("test sparse BatchQP") +TEST_CASE("test sparse BatchQP") { sparse::isize dim = 500; sparse::isize n_eq(10); diff --git a/test/src/serialization.cpp b/test/cpp/serialization.cpp similarity index 89% rename from test/src/serialization.cpp rename to test/cpp/serialization.cpp index d9fe67693..506b2af3b 100644 --- a/test/src/serialization.cpp +++ b/test/cpp/serialization.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include #include @@ -78,7 +78,7 @@ generic_test(const T& object, const std::string& filename) loadFromXML(object_loaded, xml_filename); // Check - DOCTEST_CHECK(object_loaded == object); + CHECK(object_loaded == object); } // Load and save as json @@ -90,7 +90,7 @@ generic_test(const T& object, const std::string& filename) loadFromJSON(object_loaded, json_filename); // Check - DOCTEST_CHECK(object_loaded == object); + CHECK(object_loaded == object); } // Load and save as binary @@ -102,7 +102,7 @@ generic_test(const T& object, const std::string& filename) loadFromBinary(object_loaded, bin_filename); // Check - DOCTEST_CHECK(object_loaded == object); + CHECK(object_loaded == object); } } @@ -110,7 +110,7 @@ using T = double; using namespace proxsuite; using namespace proxsuite::proxqp; -DOCTEST_TEST_CASE("test serialization of qp model, results and settings") +TEST_CASE("test serialization of qp model, results and settings") { std::cout << "--- serialization ---" << std::endl; double sparsity_factor = 0.15; @@ -140,8 +140,7 @@ DOCTEST_TEST_CASE("test serialization of qp model, results and settings") generic_test(qp, TEST_SERIALIZATION_FOLDER "/qp_wrapper"); } -DOCTEST_TEST_CASE( - "test serialization of eigen matrices with different storage orders") +TEST_CASE("test serialization of eigen matrices with different storage orders") { Eigen::Matrix row_matrix; Eigen::Matrix row_matrix_loaded; @@ -153,6 +152,6 @@ DOCTEST_TEST_CASE( proxsuite::serialization::loadFromJSON(row_matrix_loaded, "row_matrix"); proxsuite::serialization::loadFromJSON(col_matrix_loaded, "row_matrix"); - DOCTEST_CHECK(row_matrix_loaded == row_matrix); - DOCTEST_CHECK(col_matrix_loaded == row_matrix); + CHECK(row_matrix_loaded == row_matrix); + CHECK(col_matrix_loaded == row_matrix); } \ No newline at end of file diff --git a/test/src/sparse_factorization.cpp b/test/cpp/sparse_factorization.cpp similarity index 99% rename from test/src/sparse_factorization.cpp rename to test/cpp/sparse_factorization.cpp index d60e00fba..7f7b82e81 100644 --- a/test/src/sparse_factorization.cpp +++ b/test/cpp/sparse_factorization.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include template diff --git a/test/src/sparse_maros_meszaros.cpp b/test/cpp/sparse_maros_meszaros.cpp similarity index 98% rename from test/src/sparse_maros_meszaros.cpp rename to test/cpp/sparse_maros_meszaros.cpp index 01f701e79..8f2baa342 100644 --- a/test/src/sparse_maros_meszaros.cpp +++ b/test/cpp/sparse_maros_meszaros.cpp @@ -3,14 +3,12 @@ // #include -#include -#include +#include +#include "maros_meszaros.hpp" #include using namespace proxsuite; -#define MAROS_MESZAROS_DIR PROBLEM_PATH "/data/maros_meszaros_data/" - template void compute_primal_dual_feasibility(const PreprocessedQpSparse& preprocessed, diff --git a/test/src/sparse_qp.cpp b/test/cpp/sparse_qp.cpp similarity index 99% rename from test/src/sparse_qp.cpp rename to test/cpp/sparse_qp.cpp index 6aec4a872..8598f6305 100644 --- a/test/src/sparse_qp.cpp +++ b/test/cpp/sparse_qp.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include using namespace proxsuite; diff --git a/test/src/sparse_qp_solve.cpp b/test/cpp/sparse_qp_solve.cpp similarity index 93% rename from test/src/sparse_qp_solve.cpp rename to test/cpp/sparse_qp_solve.cpp index 112fca202..fb3238ec5 100644 --- a/test/src/sparse_qp_solve.cpp +++ b/test/cpp/sparse_qp_solve.cpp @@ -2,7 +2,7 @@ // Copyright (c) 2022 INRIA // #include -#include +#include #include #include #include @@ -14,8 +14,8 @@ using T = double; using I = c_int; using namespace proxsuite::linalg::sparse::tags; -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test solve function") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test solve function") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -82,8 +82,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -96,8 +96,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test solve with different rho value") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test solve with different rho value") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -131,7 +131,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " eps_abs, nullopt, T(1.E-7)); - DOCTEST_CHECK(results.info.rho == T(1.E-7)); + CHECK(results.info.rho == T(1.E-7)); T dua_res = proxqp::dense::infty_norm( qp.H.selfadjointView() * results.x + qp.g + qp.A.transpose() * results.y + qp.C.transpose() * results.z); @@ -139,8 +139,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -153,7 +153,7 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " } } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test solve with different mu_eq and mu_in values") { @@ -199,8 +199,8 @@ DOCTEST_TEST_CASE( proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -213,9 +213,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test setting specific sparse backend") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test setting specific sparse backend") { std::cout @@ -269,9 +268,9 @@ DOCTEST_TEST_CASE( proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); - DOCTEST_CHECK(results.info.sparse_backend == SparseBackend::MatrixFree); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); + CHECK(results.info.sparse_backend == SparseBackend::MatrixFree); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -284,8 +283,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test warm starting") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test warm starting") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -318,8 +317,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -332,8 +331,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test verbose = true") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test verbose = true") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -378,8 +377,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; @@ -392,8 +391,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " } } -DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " - "inequality constraints: test no initial guess") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -443,8 +442,8 @@ DOCTEST_TEST_CASE("sparse random strongly convex qp with equality and " proxqp::dense::infty_norm( helpers::positive_part(qp.C * results.x - qp.u) + helpers::negative_part(qp.C * results.x - qp.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; diff --git a/test/src/sparse_qp_wrapper.cpp b/test/cpp/sparse_qp_wrapper.cpp similarity index 90% rename from test/src/sparse_qp_wrapper.cpp rename to test/cpp/sparse_qp_wrapper.cpp index f8d07398a..154323893 100644 --- a/test/src/sparse_qp_wrapper.cpp +++ b/test/cpp/sparse_qp_wrapper.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include using namespace proxsuite; @@ -14,7 +14,7 @@ using T = double; using I = c_int; using namespace proxsuite::linalg::sparse::tags; -DOCTEST_TEST_CASE( +TEST_CASE( "ProxQP::sparse: sparse random strongly convex qp with inequality constraints" "and empty equality constraints") { @@ -727,9 +727,8 @@ TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " } } -DOCTEST_TEST_CASE( - "sparse random strongly convex qp with equality and " - "inequality constraints: test with warm start with previous result") +TEST_CASE("sparse random strongly convex qp with equality and " + "inequality constraints: test with warm start with previous result") { std::cout @@ -774,8 +773,8 @@ DOCTEST_TEST_CASE( proxqp::dense::infty_norm( helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + helpers::negative_part(qp_random.C * qp.results.x - qp_random.l))); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -832,8 +831,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -845,9 +844,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test with cold start option") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test with cold start option") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -891,8 +889,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -956,8 +954,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with cold start option: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -969,9 +967,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test equilibration option") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test equilibration option") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1016,8 +1013,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1047,8 +1044,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1060,9 +1057,8 @@ DOCTEST_TEST_CASE( } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test equilibration option at update") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test equilibration option at update") { std::cout << "---testing sparse random strongly convex qp with equality and " @@ -1106,8 +1102,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1127,8 +1123,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1159,8 +1155,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1182,8 +1178,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); std::cout << "------using API solving qp with dim with qp2: " << n << " neq: " << n_eq << " nin: " << n_in << std::endl; std::cout << "primal residual: " << pri_res << std::endl; @@ -1256,7 +1252,7 @@ TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " } TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test new init") + "inequality constraints: test new init 2") { for (auto const& dims : { // proxsuite::linalg::veg::tuplify(50, 0, 0), @@ -1604,7 +1600,7 @@ TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " "inequality constraints: test multiple solve at once with equality " - "constrained initial guess") + "constrained initial guess 2") { for (auto const& dims : { // proxsuite::linalg::veg::tuplify(50, 0, 0), @@ -1738,7 +1734,7 @@ TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " } TEST_CASE( "sparse random strongly convex qp with equality and " - "inequality constraints: test multiple solve at once with no initial guess") + "inequality constraints: test multiple solve at once with no initial guess 2") { for (auto const& dims : { // proxsuite::linalg::veg::tuplify(50, 0, 0), @@ -2677,7 +2673,7 @@ TEST_CASE( } TEST_CASE( "sparse random strongly convex qp with equality and " - "inequality constraints: test multiple solve at once with no initial guess") + "inequality constraints: test multiple solve at once with no initial guess 3") { for (auto const& dims : { // proxsuite::linalg::veg::tuplify(50, 0, 0), @@ -4239,10 +4235,9 @@ TEST_CASE("ProxQP::sparse: Test rho update for different initial guess") } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using no initial guess") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -4269,8 +4264,8 @@ DOCTEST_TEST_CASE( bool compute_preconditioner = true; qp.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -4282,11 +4277,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4297,8 +4292,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -4309,11 +4304,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4324,15 +4319,15 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp2(qp_random.H.cast(), qp_random.A.cast(), qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; @@ -4346,13 +4341,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -4363,16 +4358,16 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp3(qp_random.H.cast(), qp_random.A.cast(), qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -4385,17 +4380,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4406,8 +4401,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -4418,11 +4413,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4433,13 +4428,12 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using EQUALITY_CONSTRAINED_INITIAL_GUESS") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using EQUALITY_CONSTRAINED_INITIAL_GUESS") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -4467,8 +4461,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -4480,11 +4474,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4495,8 +4489,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -4507,11 +4501,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4522,16 +4516,16 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp2(qp_random.H.cast(), qp_random.A.cast(), qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -4545,9 +4539,9 @@ DOCTEST_TEST_CASE( nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -4558,8 +4552,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp3(qp_random.H.cast(), @@ -4567,8 +4561,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -4581,17 +4575,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4602,8 +4596,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -4614,11 +4608,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4629,13 +4623,12 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using COLD_START_WITH_PREVIOUS_RESULT") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using COLD_START_WITH_PREVIOUS_RESULT") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -4663,8 +4656,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -4676,11 +4669,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4691,8 +4684,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -4703,11 +4696,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4718,16 +4711,16 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp2(qp_random.H.cast(), qp_random.A.cast(), qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; @@ -4741,13 +4734,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -4758,8 +4751,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp3(qp_random.H.cast(), @@ -4767,8 +4760,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -4781,17 +4774,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4802,8 +4795,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -4814,11 +4807,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -4829,14 +4822,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after updates using WARM_START_WITH_PREVIOUS_RESULT") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after updates using WARM_START_WITH_PREVIOUS_RESULT") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -4864,8 +4856,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; qp.init(qp_random.H, @@ -4877,11 +4869,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4892,8 +4884,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp.update(nullopt, nullopt, @@ -4904,11 +4896,11 @@ DOCTEST_TEST_CASE( nullopt, compute_preconditioner, 1.e-6); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -4919,16 +4911,16 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp2(qp_random.H.cast(), qp_random.A.cast(), qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; @@ -4942,13 +4934,13 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), @@ -4959,8 +4951,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); // conter factual check with another QP object starting at the updated model proxqp::sparse::QP qp3(qp_random.H.cast(), @@ -4968,8 +4960,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -4982,17 +4974,17 @@ DOCTEST_TEST_CASE( compute_preconditioner, rho, mu_eq); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5003,8 +4995,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp3.update(nullopt, nullopt, nullopt, @@ -5015,11 +5007,11 @@ DOCTEST_TEST_CASE( compute_preconditioner, 1.e-6, 1.e-3); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), @@ -5030,14 +5022,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using no initial guess") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using no initial guess") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5071,8 +5062,8 @@ DOCTEST_TEST_CASE( bool compute_preconditioner = true; qp.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; // qp.settings.verbose = true; @@ -5085,11 +5076,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5100,13 +5091,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5116,8 +5107,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -5131,8 +5122,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5142,8 +5133,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5151,8 +5142,8 @@ DOCTEST_TEST_CASE( qp_random.A.cast(), qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5165,16 +5156,16 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5184,8 +5175,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5193,8 +5184,8 @@ DOCTEST_TEST_CASE( qp_random.A.cast(), qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::NO_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::NO_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::NO_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5209,13 +5200,13 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5225,8 +5216,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -5240,13 +5231,13 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5256,12 +5247,12 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( +TEST_CASE( "sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after several solves " "using equality constrained initial guess") @@ -5299,8 +5290,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; // qp.settings.verbose = true; @@ -5313,11 +5304,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5328,13 +5319,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5344,8 +5335,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -5359,8 +5350,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5370,8 +5361,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5380,8 +5371,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5394,16 +5385,16 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5413,8 +5404,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5423,8 +5414,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::EQUALITY_CONSTRAINED_INITIAL_GUESS); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5439,12 +5430,12 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5454,8 +5445,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -5469,13 +5460,13 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5485,15 +5476,14 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using cold start with previous result") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using cold start with previous result") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5528,8 +5518,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; // qp.settings.verbose = true; @@ -5542,11 +5532,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5557,13 +5547,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5573,8 +5563,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -5588,8 +5578,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5599,8 +5589,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5609,8 +5599,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5623,22 +5613,22 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5648,8 +5638,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5658,8 +5648,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::COLD_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5674,17 +5664,17 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5694,8 +5684,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -5709,17 +5699,17 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5729,15 +5719,14 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } -DOCTEST_TEST_CASE( - "ProxQP::sparse: sparse random strongly convex qp with equality and " - "inequality constraints: test changing default settings " - "after several solves using warm start with previous result") +TEST_CASE("ProxQP::sparse: sparse random strongly convex qp with equality and " + "inequality constraints: test changing default settings " + "after several solves using warm start with previous result") { std::cout << "---testing sparse random strongly convex qp with equality and " "inequality constraints: test changing default settings after " @@ -5772,8 +5761,8 @@ DOCTEST_TEST_CASE( qp.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp.settings.eps_abs = eps_abs; qp.settings.eps_rel = 0; // qp.settings.verbose = true; @@ -5786,11 +5775,11 @@ DOCTEST_TEST_CASE( qp_random.u, compute_preconditioner, rho); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); + CHECK(std::abs(rho - qp.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp.results.info.rho) <= 1.E-9); T pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), @@ -5801,13 +5790,13 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(rho - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(rho - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5817,8 +5806,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp.update(nullopt, @@ -5832,8 +5821,8 @@ DOCTEST_TEST_CASE( 1.e-6); for (isize iter = 0; iter < 10; ++iter) { qp.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.settings.default_rho) < 1.e-9); + CHECK(std::abs(1.e-6 - qp.results.info.rho) < 1.e-9); pri_res = std::max( (qp_random.A * qp.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5843,8 +5832,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5853,8 +5842,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp2.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp2.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp2.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp2.settings.eps_abs = eps_abs; qp2.settings.eps_rel = 0; qp2.init(qp_random.H, @@ -5867,22 +5856,22 @@ DOCTEST_TEST_CASE( compute_preconditioner, nullopt, mu_eq); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); qp2.solve(); - DOCTEST_CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp2.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp2.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp2.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5892,8 +5881,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp2.results.y + qp_random.C.transpose() * qp2.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } // conter factual check with another QP object starting at the updated model @@ -5902,8 +5891,8 @@ DOCTEST_TEST_CASE( qp_random.C.cast()); qp3.settings.initial_guess = proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT; - DOCTEST_CHECK(qp3.settings.initial_guess == - proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); + CHECK(qp3.settings.initial_guess == + proxqp::InitialGuessStatus::WARM_START_WITH_PREVIOUS_RESULT); qp3.settings.eps_abs = eps_abs; qp3.settings.eps_rel = 0; qp3.init(qp_random.H, @@ -5918,17 +5907,17 @@ DOCTEST_TEST_CASE( mu_eq); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(rho - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(rho - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(mu_eq - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(T(1) / mu_eq - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5938,8 +5927,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } qp3.update(nullopt, @@ -5953,17 +5942,17 @@ DOCTEST_TEST_CASE( 1.e-6, 1.e-3); for (isize iter = 0; iter < 10; ++iter) { - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); qp3.solve(); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); - DOCTEST_CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.settings.default_rho) <= 1.E-9); + CHECK(std::abs(1.e-6 - qp3.results.info.rho) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.settings.default_mu_eq) <= 1.E-9); + CHECK(std::abs(1.e-3 - qp3.results.info.mu_eq) <= 1.E-9); + CHECK(std::abs(1.e3 - qp3.results.info.mu_eq_inv) <= 1.E-9); pri_res = std::max( (qp_random.A * qp3.results.x - qp_random.b).lpNorm(), (helpers::positive_part(qp_random.C * qp.results.x - qp_random.u) + @@ -5973,8 +5962,8 @@ DOCTEST_TEST_CASE( qp_random.g + qp_random.A.transpose() * qp3.results.y + qp_random.C.transpose() * qp3.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } } @@ -6022,8 +6011,8 @@ TEST_CASE("ProxQP::sparse: init must be called before update") qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); qp_random.H = 2 * qp_random.H; // keep same sparsity structure qp_random.g = utils::rand::vector_rand(dim); @@ -6047,8 +6036,8 @@ TEST_CASE("ProxQP::sparse: init must be called before update") qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= eps_abs); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= eps_abs); + CHECK(dua_res <= eps_abs); } TEST_CASE("ProxQP::sparse: test primal infeasibility solving") @@ -6107,8 +6096,8 @@ TEST_CASE("ProxQP::sparse: test primal infeasibility solving") qp_random.g + qp_random.A.transpose() * qp.results.y + qp_random.C.transpose() * qp.results.z) .lpNorm(); - DOCTEST_CHECK(pri_res <= scaled_eps); - DOCTEST_CHECK(dua_res <= eps_abs); + CHECK(pri_res <= scaled_eps); + CHECK(dua_res <= eps_abs); } } // TEST_CASE("ProxQP::sparse: estimate of minimal eigenvalues using Eigen") @@ -6153,7 +6142,7 @@ TEST_CASE("ProxQP::sparse: test primal infeasibility solving") // C_sparse, // qp_random.l, // qp_random.u); -// DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - +// CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - // minimal_eigenvalue) <= tol); // } // dim = 50; @@ -6187,7 +6176,7 @@ TEST_CASE("ProxQP::sparse: test primal infeasibility solving") // C_sparse, // qp_random.l, // qp_random.u); -// DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - +// CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - // minimal_eigenvalue) <= 1.); // } // } @@ -6235,8 +6224,8 @@ TEST_CASE("ProxQP::sparse: estimate of minimal eigenvalues using manual choice") nullopt, nullopt, minimal_eigenvalue); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } dim = 50; n_eq = dim; @@ -6271,8 +6260,8 @@ TEST_CASE("ProxQP::sparse: estimate of minimal eigenvalues using manual choice") nullopt, nullopt, minimal_eigenvalue); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= 1.); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= 1.); } } @@ -6326,8 +6315,8 @@ TEST_CASE( nullopt, nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= tol); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= tol); } dim = 50; n_eq = dim; @@ -6365,7 +6354,7 @@ TEST_CASE( nullopt, nullopt, estimate_minimal_eigen_value); - DOCTEST_CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - - minimal_eigenvalue) <= 1.); + CHECK(std::abs(qp.results.info.minimal_H_eigenvalue_estimate - + minimal_eigenvalue) <= 1.); } } diff --git a/test/src/sparse_ruiz_equilibration.cpp b/test/cpp/sparse_ruiz_equilibration.cpp similarity index 99% rename from test/src/sparse_ruiz_equilibration.cpp rename to test/cpp/sparse_ruiz_equilibration.cpp index 04f6b67f4..7c92feafc 100644 --- a/test/src/sparse_ruiz_equilibration.cpp +++ b/test/cpp/sparse_ruiz_equilibration.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include using namespace proxsuite; diff --git a/test/cpp/uint128.cpp b/test/cpp/uint128.cpp new file mode 100644 index 000000000..1c8cf163f --- /dev/null +++ b/test/cpp/uint128.cpp @@ -0,0 +1,204 @@ +// +// Copyright (c) 2023 INRIA +// +#include +#include +#include +#include + +#if defined(_MSC_VER) +#include +using u128 = uint128_t; +#define MAKE_U128(low, high) u128(low, high) +#define CHECK_HIGH(val, expected) CHECK((val).high == (expected)) +#define CHECK_LOW(val, expected) CHECK((val).low == (expected)) +#else +using u128 = __uint128_t; +#define MAKE_U128(low, high) ((u128(high) << 64) | low) +#define CHECK_HIGH(val, expected) \ + CHECK(static_cast(val >> 64) == (expected)) +#define CHECK_LOW(val, expected) CHECK(static_cast(val) == (expected)) +#endif + +std::ostream& +operator<<(std::ostream& os, u128 n) +{ + if (n == u128(0)) { + return os << "0"; + } + std::string s; + while (n > u128(0)) { + // Cast remainder to uint64_t for char addition. + // Works for both custom struct (via explicit operator) and built-in type. + u128 rem = n % u128(10); + s += (char)('0' + static_cast(rem)); + n = n / u128(10); + } + std::reverse(s.begin(), s.end()); + return os << s; +} + +TEST_CASE("Constructors and Equality", "[uint128]") +{ + u128 zero(0); + CHECK_LOW(zero, 0); + CHECK_HIGH(zero, 0); + + u128 val(12345); + CHECK_LOW(val, 12345); + CHECK_HIGH(val, 0); + + u128 big = MAKE_U128(0xFFFFFFFFFFFFFFFF, 0x1); + CHECK_LOW(big, 0xFFFFFFFFFFFFFFFF); + CHECK_HIGH(big, 1); + + REQUIRE(u128(10) == u128(10)); + REQUIRE(u128(10) != u128(11)); +} + +TEST_CASE("Bitwise Shifts with u128 (The Fix)", "[uint128][shift]") +{ + // This is the specific case you asked for: u128 >> u128 + u128 val = u128(0); + u128 shift_amt = u128(64); + + REQUIRE((val >> shift_amt) == u128(0)); + + // Test shifting a real value by a u128 + u128 one(1); + u128 two(2); + REQUIRE((one << one) == u128(2)); // 1 << 1 = 2 + + // Test large shift via u128 + u128 large_shift(100); + u128 shifted = one << large_shift; + + // 1 << 100 results in high bit (1 << (100-64)) = 1 << 36 + CHECK_HIGH(shifted, (1ULL << 36)); + CHECK_LOW(shifted, 0); + +#if defined(_MSC_VER) + // Test over-shift (>= 128) via u128 + // Now MSVC behaves like __uint128_t (modulo 128 shift) + u128 huge_shift(128); + u128 pattern = MAKE_U128(0xFF, 0xFF); + // pattern >> 128 is effectively pattern >> 0, which is pattern + REQUIRE((pattern >> huge_shift) == pattern); +#endif +} + +TEST_CASE("Standard Bitwise Shifts (int)", "[uint128][shift]") +{ + u128 val = MAKE_U128(1, 0); // low=1, high=0 + + // Shift left crossing boundary + u128 res = val << 64; + CHECK_HIGH(res, 1); + CHECK_LOW(res, 0); + + // Shift right crossing boundary + u128 high_val = MAKE_U128(0, 1); // low=0, high=1 + res = high_val >> 64; + CHECK_HIGH(res, 0); + CHECK_LOW(res, 1); + + // Shift within high part + u128 mix = MAKE_U128(0, 2); + REQUIRE((mix << 1) == MAKE_U128(0, 4)); +} + +TEST_CASE("Arithmetic Operations", "[uint128][math]") +{ + SECTION("Addition") + { + u128 max_low = MAKE_U128(0xFFFFFFFFFFFFFFFF, 0); + u128 one(1); + u128 result = max_low + one; + + // Should carry over to high + CHECK_HIGH(result, 1); + CHECK_LOW(result, 0); + } + + SECTION("Subtraction") + { + u128 zero = MAKE_U128(0, 0); + u128 one(1); + u128 result = zero - one; + + // Underflow checks + CHECK_HIGH(result, 0xFFFFFFFFFFFFFFFF); + CHECK_LOW(result, 0xFFFFFFFFFFFFFFFF); + } + + SECTION("Multiplication") + { + u128 a(2); + u128 b(3); + REQUIRE((a * b) == u128(6)); + + // Test overflow into high + // 2^64 * 2 = 2^65 + // Construct 2^64 using the struct (low=0, high=1) + u128 two_64 = MAKE_U128(0, 1); + u128 two(2); + u128 res = two_64 * two; + CHECK_HIGH(res, 2); + CHECK_LOW(res, 0); + } + + SECTION("Division (Decimal Printing Helper)") + { + u128 a(100); + u128 b(10); + REQUIRE((a / b) == u128(10)); + + // Test the optimize 64-bit divisor path + u128 large = MAKE_U128(0, 1); // 2^64 + u128 two(2); + u128 half_large = large / two; // 2^63 + CHECK_HIGH(half_large, 0); + CHECK_LOW(half_large, (1ULL << 63)); + } +} + +TEST_CASE("Comparison Operators", "[uint128][compare]") +{ + u128 small(10); + u128 big(20); + u128 huge = MAKE_U128(0, 1); // 2^64 + + REQUIRE(small < big); + REQUIRE(big > small); + REQUIRE(huge > big); + REQUIRE(small <= u128(10)); + REQUIRE(big >= u128(20)); +} + +TEST_CASE("Lehmer Constant Generation", "[uint128][lehmer]") +{ + constexpr u128 lehmer64_constant(0xda942042e4dd58b5); + CHECK_LOW(lehmer64_constant, 0xda942042e4dd58b5); + CHECK_HIGH(lehmer64_constant, 0); +} + +TEST_CASE("String Output (Decimal)", "[uint128][print]") +{ + std::stringstream ss; + + u128 val(12345); + ss << val; + REQUIRE(ss.str() == "12345"); + + ss.str(""); // Clear + u128 zero(0); + ss << zero; + REQUIRE(ss.str() == "0"); + + // Test value larger than uint64_t max (18446744073709551615) + // 18446744073709551616 is 2^64 (high=1, low=0) + ss.str(""); + u128 big = MAKE_U128(0, 1); + ss << big; + REQUIRE(ss.str() == "18446744073709551616"); +} diff --git a/test/src/util_f32.cpp b/test/cpp/util_f32.cpp similarity index 97% rename from test/src/util_f32.cpp rename to test/cpp/util_f32.cpp index 06afe7ffa..f4cbfd19d 100644 --- a/test/src/util_f32.cpp +++ b/test/cpp/util_f32.cpp @@ -1,4 +1,4 @@ -#include "util_f64.hpp" +#include "util_f32.hpp" namespace proxsuite { namespace proxqp { diff --git a/test/include/util_f32.hpp b/test/cpp/util_f32.hpp similarity index 99% rename from test/include/util_f32.hpp rename to test/cpp/util_f32.hpp index c8415220c..740a0ad97 100644 --- a/test/include/util_f32.hpp +++ b/test/cpp/util_f32.hpp @@ -12,6 +12,7 @@ LDLT_EXPLICIT_TPL_DECL(2, ldlt_compute>); LDLT_EXPLICIT_TPL_DECL(2, llt_compute>); LDLT_EXPLICIT_TPL_DECL(2, ldlt_compute>); } // namespace eigen + namespace rand { LDLT_EXPLICIT_TPL_DECL(2, matrix_rand); LDLT_EXPLICIT_TPL_DECL(1, vector_rand); diff --git a/test/src/util_f64.cpp b/test/cpp/util_f64.cpp similarity index 100% rename from test/src/util_f64.cpp rename to test/cpp/util_f64.cpp diff --git a/test/include/util_f64.hpp b/test/cpp/util_f64.hpp similarity index 100% rename from test/include/util_f64.hpp rename to test/cpp/util_f64.hpp diff --git a/test/cpp/utils.hpp b/test/cpp/utils.hpp new file mode 100644 index 000000000..c7a9b791a --- /dev/null +++ b/test/cpp/utils.hpp @@ -0,0 +1,4 @@ +#pragma once + +#include "utils/util_f32.hpp" +#include "utils/util_f64.hpp" diff --git a/test/doctest/doctest.cpp b/test/doctest/doctest.cpp deleted file mode 100644 index 6a4a5dba9..000000000 --- a/test/doctest/doctest.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#include "doctest.hpp" diff --git a/test/doctest/doctest.hpp b/test/doctest/doctest.hpp deleted file mode 100644 index fd4072374..000000000 --- a/test/doctest/doctest.hpp +++ /dev/null @@ -1,8694 +0,0 @@ -// ====================================================================== lgtm -// [cpp/missing-header-guard] -// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == -// ====================================================================== -// -// doctest.h - the lightest feature-rich C++ single-header testing framework for -// unit tests and TDD -// -// Copyright (c) 2016-2021 Viktor Kirilov -// -// Distributed under the MIT Software License -// See accompanying file LICENSE.txt or copy at -// https://opensource.org/licenses/MIT -// -// The documentation can be found at the library's page: -// https://github.com/doctest/doctest/blob/master/doc/markdown/readme.md -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= -// -// The library is heavily influenced by Catch - -// https://github.com/catchorg/Catch2 which uses the Boost Software License - -// Version 1.0 see here - -// https://github.com/catchorg/Catch2/blob/master/LICENSE.txt -// -// The concept of subcases (sections in Catch) and expression decomposition are -// from there. Some parts of the code are taken directly: -// - stringification - the detection of "ostream& operator<<(ostream&, const -// T&)" and StringMaker<> -// - the Approx() helper class for floating point comparison -// - colors in the console -// - breaking into a debugger -// - signal / SEH handling -// - timer -// - XmlWriter class - thanks to Phil Nash for allowing the direct reuse (AKA -// copy/paste) -// -// The expression decomposing templates are taken from lest - -// https://github.com/martinmoene/lest which uses the Boost Software License - -// Version 1.0 see here - -// https://github.com/martinmoene/lest/blob/master/LICENSE.txt -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= - -#ifndef DOCTEST_LIBRARY_INCLUDED -#define DOCTEST_LIBRARY_INCLUDED - -// ================================================================================================= -// == VERSION -// ====================================================================================== -// ================================================================================================= - -#define DOCTEST_VERSION_MAJOR 2 -#define DOCTEST_VERSION_MINOR 4 -#define DOCTEST_VERSION_PATCH 9 - -// util we need here -#define DOCTEST_TOSTR_IMPL(x) #x -#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x) - -#define DOCTEST_VERSION_STR \ - DOCTEST_TOSTR(DOCTEST_VERSION_MAJOR) \ - "." DOCTEST_TOSTR(DOCTEST_VERSION_MINOR) "." DOCTEST_TOSTR( \ - DOCTEST_VERSION_PATCH) - -#define DOCTEST_VERSION \ - (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + \ - DOCTEST_VERSION_PATCH) - -// ================================================================================================= -// == COMPILER VERSION -// ============================================================================= -// ================================================================================================= - -// ideas for the version stuff are taken from here: -// https://github.com/cxxstuff/cxx_detect - -#ifdef _MSC_VER -#define DOCTEST_CPLUSPLUS _MSVC_LANG -#else -#define DOCTEST_CPLUSPLUS __cplusplus -#endif - -#define DOCTEST_COMPILER(MAJOR, MINOR, PATCH) \ - ((MAJOR) * 10000000 + (MINOR) * 100000 + (PATCH)) - -// GCC/Clang and GCC/MSVC are mutually exclusive, but Clang/MSVC are not because -// of clang-cl... -#if defined(_MSC_VER) && defined(_MSC_FULL_VER) -#if _MSC_VER == _MSC_FULL_VER / 10000 -#define DOCTEST_MSVC \ - DOCTEST_COMPILER(_MSC_VER / 100, _MSC_VER % 100, _MSC_FULL_VER % 10000) -#else // MSVC -#define DOCTEST_MSVC \ - DOCTEST_COMPILER( \ - _MSC_VER / 100, (_MSC_FULL_VER / 100000) % 100, _MSC_FULL_VER % 100000) -#endif // MSVC -#endif // MSVC -#if defined(__clang__) && defined(__clang_minor__) -#define DOCTEST_CLANG \ - DOCTEST_COMPILER(__clang_major__, __clang_minor__, __clang_patchlevel__) -#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && \ - defined(__GNUC_PATCHLEVEL__) && !defined(__INTEL_COMPILER) -#define DOCTEST_GCC \ - DOCTEST_COMPILER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#endif // GCC - -#ifndef DOCTEST_MSVC -#define DOCTEST_MSVC 0 -#endif // DOCTEST_MSVC -#ifndef DOCTEST_CLANG -#define DOCTEST_CLANG 0 -#endif // DOCTEST_CLANG -#ifndef DOCTEST_GCC -#define DOCTEST_GCC 0 -#endif // DOCTEST_GCC - -// ================================================================================================= -// == COMPILER WARNINGS HELPERS -// ==================================================================== -// ================================================================================================= - -#if DOCTEST_CLANG -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH _Pragma("clang diagnostic push") -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) \ - DOCTEST_PRAGMA_TO_STR(clang diagnostic ignored w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP _Pragma("clang diagnostic pop") -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH DOCTEST_CLANG_SUPPRESS_WARNING(w) -#else // DOCTEST_CLANG -#define DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -#define DOCTEST_CLANG_SUPPRESS_WARNING(w) -#define DOCTEST_CLANG_SUPPRESS_WARNING_POP -#define DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_CLANG - -#if DOCTEST_GCC -#define DOCTEST_PRAGMA_TO_STR(x) _Pragma(#x) -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH _Pragma("GCC diagnostic push") -#define DOCTEST_GCC_SUPPRESS_WARNING(w) \ - DOCTEST_PRAGMA_TO_STR(GCC diagnostic ignored w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP _Pragma("GCC diagnostic pop") -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_GCC_SUPPRESS_WARNING_PUSH DOCTEST_GCC_SUPPRESS_WARNING(w) -#else // DOCTEST_GCC -#define DOCTEST_GCC_SUPPRESS_WARNING_PUSH -#define DOCTEST_GCC_SUPPRESS_WARNING(w) -#define DOCTEST_GCC_SUPPRESS_WARNING_POP -#define DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_GCC - -#if DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH __pragma(warning(push)) -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) __pragma(warning(disable : w)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP __pragma(warning(pop)) -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH DOCTEST_MSVC_SUPPRESS_WARNING(w) -#else // DOCTEST_MSVC -#define DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -#define DOCTEST_MSVC_SUPPRESS_WARNING(w) -#define DOCTEST_MSVC_SUPPRESS_WARNING_POP -#define DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(w) -#endif // DOCTEST_MSVC - -// ================================================================================================= -// == COMPILER WARNINGS -// ============================================================================ -// ================================================================================================= - -// both the header and the implementation suppress all of these, -// so it only makes sense to aggregrate them like so -#define DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH \ - DOCTEST_CLANG_SUPPRESS_WARNING_PUSH \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wunknown-pragmas") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wweak-vtables") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wpadded") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat") \ - DOCTEST_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic") \ - \ - DOCTEST_GCC_SUPPRESS_WARNING_PUSH \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wunknown-pragmas") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wpragmas") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Weffc++") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-overflow") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wstrict-aliasing") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wuseless-cast") \ - DOCTEST_GCC_SUPPRESS_WARNING("-Wnoexcept") \ - \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ - /* these 4 also disabled globally via cmake: */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4514) /* unreferenced inline function has been removed */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4571) /* SEH related */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4710) /* function not inlined */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4711) /* function selected for inline expansion*/ \ - /* */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4616) /* invalid compiler warning */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4619) /* invalid compiler warning */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4996) /* The compiler encountered a deprecated declaration */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4706) /* assignment within conditional expression */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4512) /* 'class' : assignment operator could not be generated */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4127) /* conditional expression is constant */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4625) /* copy constructor was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4626) /* assignment operator was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5027) /* move assignment operator implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5026) /* move constructor was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4640) /* construction of local static object not thread-safe */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \ - /* static analysis */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 26439) /* Function may not throw. Declare it 'noexcept' */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 26495) /* Always initialize a member variable */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(26451) /* Arithmetic overflow ... */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 26444) /* Avoid unnamed objects with custom ctor and dtor... */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(26812) /* Prefer 'enum class' over 'enum' */ - -#define DOCTEST_SUPPRESS_COMMON_WARNINGS_POP \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP \ - DOCTEST_GCC_SUPPRESS_WARNING_POP \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP - -DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdeprecated") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wctor-dtor-privacy") -DOCTEST_GCC_SUPPRESS_WARNING("-Wnon-virtual-dtor") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-promo") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING( - 4623) // default constructor was implicitly defined as deleted - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN \ - DOCTEST_MSVC_SUPPRESS_WARNING_PUSH \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4548) /* before comma no effect; expected side - effect */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4265) /* virtual functions, but destructor is not virtual */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4986) /* exception specification does not match previous */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4350) /* 'member1' called instead of 'member2' */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4668) /* not defined as a preprocessor macro */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4365) /* signed/unsigned mismatch */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4774) /* format string not a string literal */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(4820) /* padding */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4625) /* copy constructor was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4626) /* assignment operator was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5027) /* move assignment operator implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5026) /* move constructor was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4623) /* default constructor was implicitly deleted */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5039) /* pointer to pot. throwing function passed to extern C */ \ - DOCTEST_MSVC_SUPPRESS_WARNING(5045) /* Spectre mitigation for memory load */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 5105) /* macro producing 'defined' has undefined behavior */ \ - DOCTEST_MSVC_SUPPRESS_WARNING( \ - 4738) /* storing float result in memory, loss of performance */ - -#define DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP - -// ================================================================================================= -// == FEATURE DETECTION -// ============================================================================ -// ================================================================================================= - -// general compiler feature support table: -// https://en.cppreference.com/w/cpp/compiler_support MSVC C++11 feature support -// table: https://msdn.microsoft.com/en-us/library/hh567368.aspx GCC C++11 -// feature support table: https://gcc.gnu.org/projects/cxx-status.html MSVC -// version table: -// https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering -// MSVC++ 14.3 (17) _MSC_VER == 1930 (Visual Studio 2022) -// MSVC++ 14.2 (16) _MSC_VER == 1920 (Visual Studio 2019) -// MSVC++ 14.1 (15) _MSC_VER == 1910 (Visual Studio 2017) -// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) -// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) -// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) -// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) -// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) -// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) - -// Universal Windows Platform support -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -#define DOCTEST_CONFIG_NO_WINDOWS_SEH -#endif // WINAPI_FAMILY -#if DOCTEST_MSVC && !defined(DOCTEST_CONFIG_WINDOWS_SEH) -#define DOCTEST_CONFIG_WINDOWS_SEH -#endif // MSVC -#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && \ - defined(DOCTEST_CONFIG_WINDOWS_SEH) -#undef DOCTEST_CONFIG_WINDOWS_SEH -#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH - -#if !defined(_WIN32) && !defined(__QNX__) && \ - !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(__EMSCRIPTEN__) && \ - !defined(__wasi__) -#define DOCTEST_CONFIG_POSIX_SIGNALS -#endif // _WIN32 -#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && \ - defined(DOCTEST_CONFIG_POSIX_SIGNALS) -#undef DOCTEST_CONFIG_POSIX_SIGNALS -#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#if !defined(__cpp_exceptions) && !defined(__EXCEPTIONS) && \ - !defined(_CPPUNWIND) || \ - defined(__wasi__) -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // no exceptions -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && \ - !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS) -#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && - // !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#ifdef __wasi__ -#define DOCTEST_CONFIG_NO_MULTITHREADING -#endif - -#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && \ - !defined(DOCTEST_CONFIG_IMPLEMENT) -#define DOCTEST_CONFIG_IMPLEMENT -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#if defined(_WIN32) || defined(__CYGWIN__) -#if DOCTEST_MSVC -#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport) -#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport) -#else // MSVC -#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport)) -#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport)) -#endif // MSVC -#else // _WIN32 -#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default"))) -#define DOCTEST_SYMBOL_IMPORT -#endif // _WIN32 - -#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#ifdef DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT -#else // DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT -#endif // DOCTEST_CONFIG_IMPLEMENT -#else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#define DOCTEST_INTERFACE -#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL - -// needed for extern template instantiations -// see https://github.com/fmtlib/fmt/issues/2228 -#if DOCTEST_MSVC -#define DOCTEST_INTERFACE_DECL -#define DOCTEST_INTERFACE_DEF DOCTEST_INTERFACE -#else // DOCTEST_MSVC -#define DOCTEST_INTERFACE_DECL DOCTEST_INTERFACE -#define DOCTEST_INTERFACE_DEF -#endif // DOCTEST_MSVC - -#define DOCTEST_EMPTY - -#if DOCTEST_MSVC -#define DOCTEST_NOINLINE __declspec(noinline) -#define DOCTEST_UNUSED -#define DOCTEST_ALIGNMENT(x) -#elif DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 5, 0) -#define DOCTEST_NOINLINE -#define DOCTEST_UNUSED -#define DOCTEST_ALIGNMENT(x) -#else -#define DOCTEST_NOINLINE __attribute__((noinline)) -#define DOCTEST_UNUSED __attribute__((unused)) -#define DOCTEST_ALIGNMENT(x) __attribute__((aligned(x))) -#endif - -#ifndef DOCTEST_NORETURN -#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) -#define DOCTEST_NORETURN -#else // DOCTEST_MSVC -#define DOCTEST_NORETURN [[noreturn]] -#endif // DOCTEST_MSVC -#endif // DOCTEST_NORETURN - -#ifndef DOCTEST_NOEXCEPT -#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) -#define DOCTEST_NOEXCEPT -#else // DOCTEST_MSVC -#define DOCTEST_NOEXCEPT noexcept -#endif // DOCTEST_MSVC -#endif // DOCTEST_NOEXCEPT - -#ifndef DOCTEST_CONSTEXPR -#if DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) -#define DOCTEST_CONSTEXPR const -#define DOCTEST_CONSTEXPR_FUNC inline -#else // DOCTEST_MSVC -#define DOCTEST_CONSTEXPR constexpr -#define DOCTEST_CONSTEXPR_FUNC constexpr -#endif // DOCTEST_MSVC -#endif // DOCTEST_CONSTEXPR - -// ================================================================================================= -// == FEATURE DETECTION END -// ======================================================================== -// ================================================================================================= - -#define DOCTEST_DECLARE_INTERFACE(name) \ - virtual ~name(); \ - name() = default; \ - name(const name&) = delete; \ - name(name&&) = delete; \ - name& operator=(const name&) = delete; \ - name& operator=(name&&) = delete; - -#define DOCTEST_DEFINE_INTERFACE(name) name::~name() = default; - -// internal macros for string concatenation and anonymous variable name -// generation -#define DOCTEST_CAT_IMPL(s1, s2) s1##s2 -#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) -#ifdef __COUNTER__ // not standard and may be missing for some compilers -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) -#else // __COUNTER__ -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) -#endif // __COUNTER__ - -#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x& -#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x -#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE - -// not using __APPLE__ because... this is how Catch does it -#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED -#define DOCTEST_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define DOCTEST_PLATFORM_IPHONE -#elif defined(_WIN32) -#define DOCTEST_PLATFORM_WINDOWS -#elif defined(__wasi__) -#define DOCTEST_PLATFORM_WASI -#else // DOCTEST_PLATFORM -#define DOCTEST_PLATFORM_LINUX -#endif // DOCTEST_PLATFORM - -namespace doctest { -namespace detail { -static DOCTEST_CONSTEXPR int -consume(const int*, int) noexcept -{ - return 0; -} -} -} - -#define DOCTEST_GLOBAL_NO_WARNINGS(var, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wglobal-constructors") \ - static const int var = doctest::detail::consume(&var, __VA_ARGS__); \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#ifndef DOCTEST_BREAK_INTO_DEBUGGER -// should probably take a look at https://github.com/scottt/debugbreak -#ifdef DOCTEST_PLATFORM_LINUX -#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) -// Break at the location of the failing check if possible -#define DOCTEST_BREAK_INTO_DEBUGGER() \ - __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler) -#else -#include -#define DOCTEST_BREAK_INTO_DEBUGGER() raise(SIGTRAP) -#endif -#elif defined(DOCTEST_PLATFORM_MAC) -#if defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || \ - defined(__i386) -#define DOCTEST_BREAK_INTO_DEBUGGER() \ - __asm__("int $3\n" : :) // NOLINT(hicpp-no-assembler) -#elif defined(__ppc__) || defined(__ppc64__) -// https://www.cocoawithlove.com/2008/03/break-into-debugger.html -#define DOCTEST_BREAK_INTO_DEBUGGER() \ - __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ - : \ - : \ - : "memory", "r0", "r3", "r4") // NOLINT(hicpp-no-assembler) -#else -#define DOCTEST_BREAK_INTO_DEBUGGER() \ - __asm__("brk #0"); // NOLINT(hicpp-no-assembler) -#endif -#elif DOCTEST_MSVC -#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() -#elif defined(__MINGW32__) -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wredundant-decls") -extern "C" __declspec(dllimport) void __stdcall -DebugBreak(); -DOCTEST_GCC_SUPPRESS_WARNING_POP -#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() -#else // linux -#define DOCTEST_BREAK_INTO_DEBUGGER() (static_cast(0)) -#endif // linux -#endif // DOCTEST_BREAK_INTO_DEBUGGER - -// this is kept here for backwards compatibility since the config option was -// changed -#ifdef DOCTEST_CONFIG_USE_IOSFWD -#ifndef DOCTEST_CONFIG_USE_STD_HEADERS -#define DOCTEST_CONFIG_USE_STD_HEADERS -#endif -#endif // DOCTEST_CONFIG_USE_IOSFWD - -// for clang - always include ciso646 (which drags some std stuff) because -// we want to check if we are using libc++ with the _LIBCPP_VERSION macro in -// which case we don't want to forward declare stuff from std - for reference: -// https://github.com/doctest/doctest/issues/126 -// https://github.com/doctest/doctest/issues/356 -#if DOCTEST_CLANG -#include -#ifdef _LIBCPP_VERSION -#ifndef DOCTEST_CONFIG_USE_STD_HEADERS -#define DOCTEST_CONFIG_USE_STD_HEADERS -#endif -#endif // _LIBCPP_VERSION -#endif // clang - -#ifdef DOCTEST_CONFIG_USE_STD_HEADERS -#ifndef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#define DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN -#include -#include -#include -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END -#else // DOCTEST_CONFIG_USE_STD_HEADERS - -// Forward declaring 'X' in namespace std is not permitted by the C++ Standard. -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4643) - -namespace std { // NOLINT(cert-dcl58-cpp) -typedef decltype(nullptr) nullptr_t; // NOLINT(modernize-use-using) -typedef decltype(sizeof(void*)) size_t; // NOLINT(modernize-use-using) -template -struct char_traits; -template<> -struct char_traits; -template -class basic_ostream; // NOLINT(fuchsia-virtual-inheritance) -typedef basic_ostream> - ostream; // NOLINT(modernize-use-using) -template -// NOLINTNEXTLINE -basic_ostream& -operator<<(basic_ostream&, const char*); -template -class basic_istream; -typedef basic_istream> - istream; // NOLINT(modernize-use-using) -template -class tuple; -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: -// https://github.com/doctest/doctest/issues/183 -template -class allocator; -template -class basic_string; -using string = basic_string, allocator>; -#endif // VS 2019 -} // namespace std - -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_USE_STD_HEADERS - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#include -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - -namespace doctest { - -using std::size_t; - -DOCTEST_INTERFACE extern bool is_running_in_test; - -#ifndef DOCTEST_CONFIG_STRING_SIZE_TYPE -#define DOCTEST_CONFIG_STRING_SIZE_TYPE unsigned -#endif - -// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that -// can hold strings with length of up to 23 chars on the stack before going on -// the heap - the last byte of the buffer is used for: -// - "is small" bit - the highest bit - if "0" then it is small - otherwise its -// "1" (128) -// - if small - capacity left before going on the heap - using the lowest 5 bits -// - if small - 2 bits are left unused - the second and third highest ones -// - if small - acts as a null terminator if strlen() is 23 (24 including the -// null terminator) -// and the "is small" bit remains "0" ("as well as the capacity -// left") so its OK -// Idea taken from this lecture about the string implementation of -// facebook/folly - fbstring https://www.youtube.com/watch?v=kPR8h4-qZdk -// TODO: -// - optimizations - like not deleting memory unnecessarily in operator= and -// etc. -// - resize/reserve/clear -// - replace -// - back/front -// - iterator stuff -// - find & friends -// - push_back/pop_back -// - assign/insert/erase -// - relational operators as free functions - taking const char* as one of the -// params -class DOCTEST_INTERFACE String -{ -public: - using size_type = DOCTEST_CONFIG_STRING_SIZE_TYPE; - -private: - static DOCTEST_CONSTEXPR size_type len = - 24; //! OCLINT avoid private static members - static DOCTEST_CONSTEXPR size_type last = - len - 1; //! OCLINT avoid private static members - - struct view // len should be more than sizeof(view) - because of the final - // byte for flags - { - char* ptr; - size_type size; - size_type capacity; - }; - - union - { - char buf[len]; // NOLINT(*-avoid-c-arrays) - view data; - }; - - char* allocate(size_type sz); - - bool isOnStack() const noexcept { return (buf[last] & 128) == 0; } - void setOnHeap() noexcept; - void setLast(size_type in = last) noexcept; - void setSize(size_type sz) noexcept; - - void copy(const String& other); - -public: - static DOCTEST_CONSTEXPR size_type npos = static_cast(-1); - - String() noexcept; - ~String(); - - // cppcheck-suppress noExplicitConstructor - String(const char* in); - String(const char* in, size_type in_size); - - String(std::istream& in, size_type in_size); - - String(const String& other); - String& operator=(const String& other); - - String& operator+=(const String& other); - - String(String&& other) noexcept; - String& operator=(String&& other) noexcept; - - char operator[](size_type i) const; - char& operator[](size_type i); - - // the only functions I'm willing to leave in the interface - available for - // inlining - const char* c_str() const - { - return const_cast(this)->c_str(); - } // NOLINT - char* c_str() - { - if (isOnStack()) { - return reinterpret_cast(buf); - } - return data.ptr; - } - - size_type size() const; - size_type capacity() const; - - String substr(size_type pos, size_type cnt = npos) &&; - String substr(size_type pos, size_type cnt = npos) const&; - - size_type find(char ch, size_type pos = 0) const; - size_type rfind(char ch, size_type pos = npos) const; - - int compare(const char* other, bool no_case = false) const; - int compare(const String& other, bool no_case = false) const; - - friend DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& s, - const String& in); -}; - -DOCTEST_INTERFACE String -operator+(const String& lhs, const String& rhs); - -DOCTEST_INTERFACE bool -operator==(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator!=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator<(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator>(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator<=(const String& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator>=(const String& lhs, const String& rhs); - -class DOCTEST_INTERFACE Contains -{ -public: - explicit Contains(const String& string); - - bool checkWith(const String& other) const; - - String string; -}; - -DOCTEST_INTERFACE String -toString(const Contains& in); - -DOCTEST_INTERFACE bool -operator==(const String& lhs, const Contains& rhs); -DOCTEST_INTERFACE bool -operator==(const Contains& lhs, const String& rhs); -DOCTEST_INTERFACE bool -operator!=(const String& lhs, const Contains& rhs); -DOCTEST_INTERFACE bool -operator!=(const Contains& lhs, const String& rhs); - -namespace Color { -enum Enum -{ - None = 0, - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White -}; - -DOCTEST_INTERFACE std::ostream& -operator<<(std::ostream& s, Color::Enum code); -} // namespace Color - -namespace assertType { -enum Enum -{ - // macro traits - - is_warn = 1, - is_check = 2 * is_warn, - is_require = 2 * is_check, - - is_normal = 2 * is_require, - is_throws = 2 * is_normal, - is_throws_as = 2 * is_throws, - is_throws_with = 2 * is_throws_as, - is_nothrow = 2 * is_throws_with, - - is_false = 2 * is_nothrow, - is_unary = - 2 * is_false, // not checked anywhere - used just to distinguish the types - - is_eq = 2 * is_unary, - is_ne = 2 * is_eq, - - is_lt = 2 * is_ne, - is_gt = 2 * is_lt, - - is_ge = 2 * is_gt, - is_le = 2 * is_ge, - - // macro types - - DT_WARN = is_normal | is_warn, - DT_CHECK = is_normal | is_check, - DT_REQUIRE = is_normal | is_require, - - DT_WARN_FALSE = is_normal | is_false | is_warn, - DT_CHECK_FALSE = is_normal | is_false | is_check, - DT_REQUIRE_FALSE = is_normal | is_false | is_require, - - DT_WARN_THROWS = is_throws | is_warn, - DT_CHECK_THROWS = is_throws | is_check, - DT_REQUIRE_THROWS = is_throws | is_require, - - DT_WARN_THROWS_AS = is_throws_as | is_warn, - DT_CHECK_THROWS_AS = is_throws_as | is_check, - DT_REQUIRE_THROWS_AS = is_throws_as | is_require, - - DT_WARN_THROWS_WITH = is_throws_with | is_warn, - DT_CHECK_THROWS_WITH = is_throws_with | is_check, - DT_REQUIRE_THROWS_WITH = is_throws_with | is_require, - - DT_WARN_THROWS_WITH_AS = is_throws_with | is_throws_as | is_warn, - DT_CHECK_THROWS_WITH_AS = is_throws_with | is_throws_as | is_check, - DT_REQUIRE_THROWS_WITH_AS = is_throws_with | is_throws_as | is_require, - - DT_WARN_NOTHROW = is_nothrow | is_warn, - DT_CHECK_NOTHROW = is_nothrow | is_check, - DT_REQUIRE_NOTHROW = is_nothrow | is_require, - - DT_WARN_EQ = is_normal | is_eq | is_warn, - DT_CHECK_EQ = is_normal | is_eq | is_check, - DT_REQUIRE_EQ = is_normal | is_eq | is_require, - - DT_WARN_NE = is_normal | is_ne | is_warn, - DT_CHECK_NE = is_normal | is_ne | is_check, - DT_REQUIRE_NE = is_normal | is_ne | is_require, - - DT_WARN_GT = is_normal | is_gt | is_warn, - DT_CHECK_GT = is_normal | is_gt | is_check, - DT_REQUIRE_GT = is_normal | is_gt | is_require, - - DT_WARN_LT = is_normal | is_lt | is_warn, - DT_CHECK_LT = is_normal | is_lt | is_check, - DT_REQUIRE_LT = is_normal | is_lt | is_require, - - DT_WARN_GE = is_normal | is_ge | is_warn, - DT_CHECK_GE = is_normal | is_ge | is_check, - DT_REQUIRE_GE = is_normal | is_ge | is_require, - - DT_WARN_LE = is_normal | is_le | is_warn, - DT_CHECK_LE = is_normal | is_le | is_check, - DT_REQUIRE_LE = is_normal | is_le | is_require, - - DT_WARN_UNARY = is_normal | is_unary | is_warn, - DT_CHECK_UNARY = is_normal | is_unary | is_check, - DT_REQUIRE_UNARY = is_normal | is_unary | is_require, - - DT_WARN_UNARY_FALSE = is_normal | is_false | is_unary | is_warn, - DT_CHECK_UNARY_FALSE = is_normal | is_false | is_unary | is_check, - DT_REQUIRE_UNARY_FALSE = is_normal | is_false | is_unary | is_require, -}; -} // namespace assertType - -DOCTEST_INTERFACE const char* -assertString(assertType::Enum at); -DOCTEST_INTERFACE const char* -failureString(assertType::Enum at); -DOCTEST_INTERFACE const char* -skipPathFromFilename(const char* file); - -struct DOCTEST_INTERFACE TestCaseData -{ - String m_file; // the file in which the test was registered (using String - - // see #350) - unsigned m_line; // the line where the test was registered - const char* m_name; // name of the test case - const char* m_test_suite; // the test suite in which the test was added - const char* m_description; - bool m_skip; - bool m_no_breaks; - bool m_no_output; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; -}; - -struct DOCTEST_INTERFACE AssertData -{ - // common - for all asserts - const TestCaseData* m_test_case; - assertType::Enum m_at; - const char* m_file; - int m_line; - const char* m_expr; - bool m_failed; - - // exception-related - for all asserts - bool m_threw; - String m_exception; - - // for normal asserts - String m_decomp; - - // for specific exception-related asserts - bool m_threw_as; - const char* m_exception_type; - - class DOCTEST_INTERFACE StringContains - { - private: - Contains content; - bool isContains; - - public: - StringContains(const String& str) - : content(str) - , isContains(false) - { - } - StringContains(Contains cntn) - : content(static_cast(cntn)) - , isContains(true) - { - } - - bool check(const String& str) - { - return isContains ? (content == str) : (content.string == str); - } - - operator const String&() const { return content.string; } - - const char* c_str() const { return content.string.c_str(); } - } m_exception_string; - - AssertData(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type, - const StringContains& exception_string); -}; - -struct DOCTEST_INTERFACE MessageData -{ - String m_string; - const char* m_file; - int m_line; - assertType::Enum m_severity; -}; - -struct DOCTEST_INTERFACE SubcaseSignature -{ - String m_name; - const char* m_file; - int m_line; - - bool operator==(const SubcaseSignature& other) const; - bool operator<(const SubcaseSignature& other) const; -}; - -struct DOCTEST_INTERFACE IContextScope -{ - DOCTEST_DECLARE_INTERFACE(IContextScope) - virtual void stringify(std::ostream*) const = 0; -}; - -namespace detail { -struct DOCTEST_INTERFACE TestCase; -} // namespace detail - -struct ContextOptions //! OCLINT too many fields -{ - std::ostream* cout = nullptr; // stdout stream - String binary_name; // the test binary name - - const detail::TestCase* currentTest = nullptr; - - // == parameters from the command line - String out; // output filename - String order_by; // how tests should be ordered - unsigned rand_seed; // the seed for rand ordering - - unsigned first; // the first (matching) test to be executed - unsigned last; // the last (matching) test to be executed - - int abort_after; // stop tests after this many failed assertions - int subcase_filter_levels; // apply the subcase filters for the first N levels - - bool success; // include successful assertions in output - bool case_sensitive; // if filtering should be case sensitive - bool exit; // if the program should be exited after the tests are ran/whatever - bool duration; // print the time duration of each test case - bool minimal; // minimal console output (only test failures) - bool quiet; // no console output - bool no_throw; // to skip exceptions-related assertion macros - bool no_exitcode; // if the framework should return 0 as the exitcode - bool no_run; // to not run the tests at all (can be done with an "*" exclude) - bool no_intro; // to not print the intro of the framework - bool no_version; // to not print the version of the framework - bool no_colors; // if output to the console should be colorized - bool - force_colors; // forces the use of colors even when a tty cannot be detected - bool no_breaks; // to not break into the debugger - bool no_skip; // don't skip test cases which are marked to be skipped - bool - gnu_file_line; // if line numbers should be surrounded with :x: and not (x): - bool no_path_in_filenames; // if the path to files should be removed from the - // output - bool no_line_numbers; // if source code line numbers should be omitted from - // the output - bool no_debug_output; // no output in the debug console when a debugger is - // attached - bool no_skipped_summary; // don't print "skipped" in the summary !!! - // UNDOCUMENTED !!! - bool no_time_in_output; // omit any time/timestamps from output !!! - // UNDOCUMENTED !!! - - bool help; // to print the help - bool version; // to print the version - bool count; // if only the count of matching tests is to be retrieved - bool list_test_cases; // to list all tests matching the filters - bool list_test_suites; // to list all suites matching the filters - bool list_reporters; // lists all registered reporters -}; - -namespace detail { -namespace types { -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -using namespace std; -#else -template -struct enable_if -{}; - -template -struct enable_if -{ - using type = T; -}; - -struct true_type -{ - static DOCTEST_CONSTEXPR bool value = true; -}; -struct false_type -{ - static DOCTEST_CONSTEXPR bool value = false; -}; - -template -struct remove_reference -{ - using type = T; -}; -template -struct remove_reference -{ - using type = T; -}; -template -struct remove_reference -{ - using type = T; -}; - -template -struct is_rvalue_reference : false_type -{}; -template -struct is_rvalue_reference : true_type -{}; - -template -struct remove_const -{ - using type = T; -}; -template -struct remove_const -{ - using type = T; -}; - -// Compiler intrinsics -template -struct is_enum -{ - static DOCTEST_CONSTEXPR bool value = __is_enum(T); -}; -template -struct underlying_type -{ - using type = __underlying_type(T); -}; - -template -struct is_pointer : false_type -{}; -template -struct is_pointer : true_type -{}; - -template -struct is_array : false_type -{}; -// NOLINTNEXTLINE(*-avoid-c-arrays) -template -struct is_array : true_type -{}; -#endif -} - -// -template -T&& -declval(); - -template -DOCTEST_CONSTEXPR_FUNC T&& -forward(typename types::remove_reference::type& t) DOCTEST_NOEXCEPT -{ - return static_cast(t); -} - -template -DOCTEST_CONSTEXPR_FUNC T&& -forward(typename types::remove_reference::type&& t) DOCTEST_NOEXCEPT -{ - return static_cast(t); -} - -template -struct deferred_false : types::false_type -{}; - -// MSVS 2015 :( -#if defined(_MSC_VER) && _MSC_VER <= 1900 -template -struct has_global_insertion_operator : types::false_type -{}; - -template -struct has_global_insertion_operator< - T, - decltype(::operator<<(declval(), declval()), void())> - : types::true_type -{}; - -template -struct has_insertion_operator -{ - static DOCTEST_CONSTEXPR bool value = has_global_insertion_operator::value; -}; - -template -struct insert_hack; - -template -struct insert_hack -{ - static void insert(std::ostream& os, const T& t) { ::operator<<(os, t); } -}; - -template -struct insert_hack -{ - static void insert(std::ostream& os, const T& t) { operator<<(os, t); } -}; - -template -using insert_hack_t = insert_hack::value>; -#else -template -struct has_insertion_operator : types::false_type -{}; -#endif - -template -struct has_insertion_operator< - T, - decltype(operator<<(declval(), declval()), void())> - : types::true_type -{}; - -DOCTEST_INTERFACE std::ostream* -tlssPush(); -DOCTEST_INTERFACE String -tlssPop(); - -template -struct StringMakerBase -{ - template - static String convert(const DOCTEST_REF_WRAP(T)) - { -#ifdef DOCTEST_CONFIG_REQUIRE_STRINGIFICATION_FOR_ALL_USED_TYPES - static_assert( - deferred_false::value, - "No stringification detected for type T. See string conversion manual"); -#endif - return "{?}"; - } -}; - -template -struct filldata; - -template -void -filloss(std::ostream* stream, const T& in) -{ - filldata::fill(stream, in); -} - -template -void -filloss(std::ostream* stream, const T (&in)[N]) -{ // NOLINT(*-avoid-c-arrays) - // T[N], T(&)[N], T(&&)[N] have same behaviour. - // Hence remove reference. - filloss::type>(stream, in); -} - -template -String -toStream(const T& in) -{ - std::ostream* stream = tlssPush(); - filloss(stream, in); - return tlssPop(); -} - -template<> -struct StringMakerBase -{ - template - static String convert(const DOCTEST_REF_WRAP(T) in) - { - return toStream(in); - } -}; -} // namespace detail - -template -struct StringMaker - : public detail::StringMakerBase::value || - detail::types::is_pointer::value || - detail::types::is_array::value> -{}; - -#ifndef DOCTEST_STRINGIFY -#ifdef DOCTEST_CONFIG_DOUBLE_STRINGIFY -#define DOCTEST_STRINGIFY(...) toString(toString(__VA_ARGS__)) -#else -#define DOCTEST_STRINGIFY(...) toString(__VA_ARGS__) -#endif -#endif - -template -String -toString() -{ -#if DOCTEST_MSVC >= 0 && DOCTEST_CLANG == 0 && DOCTEST_GCC == 0 - String ret = - __FUNCSIG__; // class doctest::String __cdecl doctest::toString(void) - String::size_type beginPos = ret.find('<'); - return ret.substr(beginPos + 1, - ret.size() - beginPos - - static_cast(sizeof(">(void)"))); -#else - String ret = - __PRETTY_FUNCTION__; // doctest::String toString() [with T = TYPE] - String::size_type begin = ret.find('=') + 2; - return ret.substr(begin, ret.size() - begin - 1); -#endif -} - -template::value, - bool>::type = true> -String -toString(const DOCTEST_REF_WRAP(T) value) -{ - return StringMaker::convert(value); -} - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String -toString(const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: -// https://github.com/doctest/doctest/issues/183 -DOCTEST_INTERFACE String -toString(const std::string& in); -#endif // VS 2019 - -DOCTEST_INTERFACE String -toString(String in); - -DOCTEST_INTERFACE String toString(std::nullptr_t); - -DOCTEST_INTERFACE String -toString(bool in); - -DOCTEST_INTERFACE String -toString(float in); -DOCTEST_INTERFACE String -toString(double in); -DOCTEST_INTERFACE String -toString(double long in); - -DOCTEST_INTERFACE String -toString(char in); -DOCTEST_INTERFACE String -toString(char signed in); -DOCTEST_INTERFACE String -toString(char unsigned in); -DOCTEST_INTERFACE String -toString(short in); -DOCTEST_INTERFACE String -toString(short unsigned in); -DOCTEST_INTERFACE String -toString(signed in); -DOCTEST_INTERFACE String -toString(unsigned in); -DOCTEST_INTERFACE String -toString(long in); -DOCTEST_INTERFACE String -toString(long unsigned in); -DOCTEST_INTERFACE String -toString(long long in); -DOCTEST_INTERFACE String -toString(long long unsigned in); - -template::value, - bool>::type = true> -String -toString(const DOCTEST_REF_WRAP(T) value) -{ - using UT = typename detail::types::underlying_type::type; - return (DOCTEST_STRINGIFY(static_cast(value))); -} - -namespace detail { -template -struct filldata -{ - static void fill(std::ostream* stream, const T& in) - { -#if defined(_MSC_VER) && _MSC_VER <= 1900 - insert_hack_t::insert(*stream, in); -#else - operator<<(*stream, in); -#endif - } -}; - -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866) -// NOLINTBEGIN(*-avoid-c-arrays) -template -struct filldata -{ - static void fill(std::ostream* stream, const T (&in)[N]) - { - *stream << "["; - for (size_t i = 0; i < N; i++) { - if (i != 0) { - *stream << ", "; - } - *stream << (DOCTEST_STRINGIFY(in[i])); - } - *stream << "]"; - } -}; -// NOLINTEND(*-avoid-c-arrays) -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -// Specialized since we don't want the terminating null byte! -// NOLINTBEGIN(*-avoid-c-arrays) -template -struct filldata -{ - static void fill(std::ostream* stream, const char (&in)[N]) - { - *stream << String(in, in[N - 1] ? N : N - 1); - } // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) -}; -// NOLINTEND(*-avoid-c-arrays) - -template<> -struct filldata -{ - static void fill(std::ostream* stream, const void* in); -}; - -template -struct filldata -{ - static void fill(std::ostream* stream, const T* in) - { - filldata::fill(stream, in); - } -}; -} - -struct DOCTEST_INTERFACE Approx -{ - Approx(double value); - - Approx operator()(double value) const; - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - explicit Approx(const T& value, - typename detail::types::enable_if< - std::is_constructible::value>::type* = - static_cast(nullptr)) - { - *this = static_cast(value); - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& epsilon(double newEpsilon); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename std::enable_if::value, - Approx&>::type epsilon(const T& newEpsilon) - { - m_epsilon = static_cast(newEpsilon); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - Approx& scale(double newScale); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - template - typename std::enable_if::value, - Approx&>::type scale(const T& newScale) - { - m_scale = static_cast(newScale); - return *this; - } -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format off - DOCTEST_INTERFACE friend bool operator==(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator==(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator!=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator!=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator<=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator<=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator>=(double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator>=(const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator< (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator< (const Approx & lhs, double rhs); - DOCTEST_INTERFACE friend bool operator> (double lhs, const Approx & rhs); - DOCTEST_INTERFACE friend bool operator> (const Approx & lhs, double rhs); - -#ifdef DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS -#define DOCTEST_APPROX_PREFIX \ - template friend typename std::enable_if::value, bool>::type - - DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(static_cast(lhs), rhs); } - DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); } - DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return static_cast(lhs) < rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return static_cast(lhs) > rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return static_cast(lhs) < rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < static_cast(rhs) && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return static_cast(lhs) > rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > static_cast(rhs) && lhs != rhs; } -#undef DOCTEST_APPROX_PREFIX -#endif // DOCTEST_CONFIG_INCLUDE_TYPE_TRAITS - - // clang-format on - - double m_epsilon; - double m_scale; - double m_value; -}; - -DOCTEST_INTERFACE String -toString(const Approx& in); - -DOCTEST_INTERFACE const ContextOptions* -getContextOptions(); - -template -struct DOCTEST_INTERFACE_DECL IsNaN -{ - F value; - bool flipped; - IsNaN(F f, bool flip = false) - : value(f) - , flipped(flip) - { - } - IsNaN operator!() const { return { value, !flipped }; } - operator bool() const; -}; -#ifndef __MINGW32__ -extern template struct DOCTEST_INTERFACE_DECL IsNaN; -extern template struct DOCTEST_INTERFACE_DECL IsNaN; -extern template struct DOCTEST_INTERFACE_DECL IsNaN; -#endif -DOCTEST_INTERFACE String -toString(IsNaN in); -DOCTEST_INTERFACE String -toString(IsNaN in); -DOCTEST_INTERFACE String -toString(IsNaN in); - -#ifndef DOCTEST_CONFIG_DISABLE - -namespace detail { -// clang-format off -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - template struct decay_array { using type = T; }; - template struct decay_array { using type = T*; }; - template struct decay_array { using type = T*; }; - - template struct not_char_pointer { static DOCTEST_CONSTEXPR value = 1; }; - template<> struct not_char_pointer { static DOCTEST_CONSTEXPR value = 0; }; - template<> struct not_char_pointer { static DOCTEST_CONSTEXPR value = 0; }; - - template struct can_use_op : public not_char_pointer::type> {}; -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -// clang-format on - -struct DOCTEST_INTERFACE TestFailureException -{}; - -DOCTEST_INTERFACE bool -checkIfShouldThrow(assertType::Enum at); - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -DOCTEST_NORETURN -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -DOCTEST_INTERFACE void -throwException(); - -struct DOCTEST_INTERFACE Subcase -{ - SubcaseSignature m_signature; - bool m_entered = false; - - Subcase(const String& name, const char* file, int line); - Subcase(const Subcase&) = delete; - Subcase(Subcase&&) = delete; - Subcase& operator=(const Subcase&) = delete; - Subcase& operator=(Subcase&&) = delete; - ~Subcase(); - - operator bool() const; - -private: - bool checkFilters(); -}; - -template -String -stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, - const char* op, - const DOCTEST_REF_WRAP(R) rhs) -{ - return (DOCTEST_STRINGIFY(lhs)) + op + (DOCTEST_STRINGIFY(rhs)); -} - -#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-comparison") -#endif - -// This will check if there is any way it could find a operator like member or -// friend and uses it. If not it doesn't find the operator or if the operator at -// global scope is defined after this template, the template won't be -// instantiated due to SFINAE. Once the template is not instantiated it can look -// for global operator using normal conversions. -#define SFINAE_OP(ret, op) \ - decltype((void)(doctest::detail::declval() \ - op doctest::detail::declval()), \ - ret{}) - -#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ - template \ - DOCTEST_NOINLINE SFINAE_OP(Result, op) operator op(R&& rhs) \ - { \ - bool res = op_macro(doctest::detail::forward(lhs), \ - doctest::detail::forward(rhs)); \ - if (m_at & assertType::is_false) \ - res = !res; \ - if (!res || doctest::getContextOptions()->success) \ - return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \ - return Result(res); \ - } - -// more checks could be added - like in Catch: -// https://github.com/catchorg/Catch2/pull/1480/files -// https://github.com/catchorg/Catch2/pull/1481/files -#define DOCTEST_FORBIT_EXPRESSION(rt, op) \ - template \ - rt& operator op(const R&) \ - { \ - static_assert( \ - deferred_false::value, \ - "Expression Too Complex Please Rewrite As Binary Comparison!"); \ - return *this; \ - } - -struct DOCTEST_INTERFACE Result // NOLINT(*-member-init) -{ - bool m_passed; - String m_decomp; - - Result() = default; // TODO: Why do we need this? (To remove NOLINT) - Result(bool passed, const String& decomposition = String()); - - // forbidding some expressions based on this table: - // https://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Result, &) - DOCTEST_FORBIT_EXPRESSION(Result, ^) - DOCTEST_FORBIT_EXPRESSION(Result, |) - DOCTEST_FORBIT_EXPRESSION(Result, &&) - DOCTEST_FORBIT_EXPRESSION(Result, ||) - DOCTEST_FORBIT_EXPRESSION(Result, ==) - DOCTEST_FORBIT_EXPRESSION(Result, !=) - DOCTEST_FORBIT_EXPRESSION(Result, <) - DOCTEST_FORBIT_EXPRESSION(Result, >) - DOCTEST_FORBIT_EXPRESSION(Result, <=) - DOCTEST_FORBIT_EXPRESSION(Result, >=) - DOCTEST_FORBIT_EXPRESSION(Result, =) - DOCTEST_FORBIT_EXPRESSION(Result, +=) - DOCTEST_FORBIT_EXPRESSION(Result, -=) - DOCTEST_FORBIT_EXPRESSION(Result, *=) - DOCTEST_FORBIT_EXPRESSION(Result, /=) - DOCTEST_FORBIT_EXPRESSION(Result, %=) - DOCTEST_FORBIT_EXPRESSION(Result, <<=) - DOCTEST_FORBIT_EXPRESSION(Result, >>=) - DOCTEST_FORBIT_EXPRESSION(Result, &=) - DOCTEST_FORBIT_EXPRESSION(Result, ^=) - DOCTEST_FORBIT_EXPRESSION(Result, |=) -}; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-compare") -// DOCTEST_CLANG_SUPPRESS_WARNING("-Wdouble-promotion") -// DOCTEST_CLANG_SUPPRESS_WARNING("-Wconversion") -// DOCTEST_CLANG_SUPPRESS_WARNING("-Wfloat-equal") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-compare") -// DOCTEST_GCC_SUPPRESS_WARNING("-Wdouble-promotion") -// DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") -// DOCTEST_GCC_SUPPRESS_WARNING("-Wfloat-equal") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -// https://stackoverflow.com/questions/39479163 what's the difference between -// 4018 and 4389 -DOCTEST_MSVC_SUPPRESS_WARNING(4388) // signed/unsigned mismatch -DOCTEST_MSVC_SUPPRESS_WARNING(4389) // 'operator' : signed/unsigned mismatch -DOCTEST_MSVC_SUPPRESS_WARNING(4018) // 'expression' : signed/unsigned mismatch -// DOCTEST_MSVC_SUPPRESS_WARNING(4805) // 'operation' : unsafe mix of type -// 'type' and type 'type' in operation - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -// clang-format off -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE bool -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE typename types::enable_if::value || can_use_op::value, bool>::type - inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } - inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } - inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } - inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } - inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } - inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -// clang-format on - -#define DOCTEST_RELATIONAL_OP(name, op) \ - template \ - DOCTEST_COMPARISON_RETURN_TYPE name(const DOCTEST_REF_WRAP(L) lhs, \ - const DOCTEST_REF_WRAP(R) rhs) \ - { \ - return lhs op rhs; \ - } - -DOCTEST_RELATIONAL_OP(eq, ==) -DOCTEST_RELATIONAL_OP(ne, !=) -DOCTEST_RELATIONAL_OP(lt, <) -DOCTEST_RELATIONAL_OP(gt, >) -DOCTEST_RELATIONAL_OP(le, <=) -DOCTEST_RELATIONAL_OP(ge, >=) - -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) l == r -#define DOCTEST_CMP_NE(l, r) l != r -#define DOCTEST_CMP_GT(l, r) l > r -#define DOCTEST_CMP_LT(l, r) l < r -#define DOCTEST_CMP_GE(l, r) l >= r -#define DOCTEST_CMP_LE(l, r) l <= r -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) eq(l, r) -#define DOCTEST_CMP_NE(l, r) ne(l, r) -#define DOCTEST_CMP_GT(l, r) gt(l, r) -#define DOCTEST_CMP_LT(l, r) lt(l, r) -#define DOCTEST_CMP_GE(l, r) ge(l, r) -#define DOCTEST_CMP_LE(l, r) le(l, r) -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - -template -// cppcheck-suppress copyCtorAndEqOperator -struct Expression_lhs -{ - L lhs; - assertType::Enum m_at; - - explicit Expression_lhs(L&& in, assertType::Enum at) - : lhs(static_cast(in)) - , m_at(at) - { - } - - DOCTEST_NOINLINE operator Result() - { - // this is needed only for MSVC 2015 - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH( - 4800) // 'int': forcing value to bool - bool res = static_cast(lhs); - DOCTEST_MSVC_SUPPRESS_WARNING_POP - if (m_at & assertType::is_false) { //! OCLINT bitwise operator in - //! conditional - res = !res; - } - - if (!res || getContextOptions()->success) { - return { res, (DOCTEST_STRINGIFY(lhs)) }; - } - return { res }; - } - - /* This is required for user-defined conversions from Expression_lhs to L */ - operator L() const { return lhs; } - - // clang-format off - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional - // clang-format on - - // forbidding some expressions based on this table: - // https://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &&) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ||) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, =) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, +=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, -=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, *=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, /=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, %=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, &=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, ^=) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, |=) - // these 2 are unfortunate because they should be allowed - they have higher - // precedence over the comparisons, but the ExpressionDecomposer class uses - // the left shift operator to capture the left operand of the binary - // expression... - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, <<) - DOCTEST_FORBIT_EXPRESSION(Expression_lhs, >>) -}; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -#if DOCTEST_CLANG && DOCTEST_CLANG < DOCTEST_COMPILER(3, 6, 0) -DOCTEST_CLANG_SUPPRESS_WARNING_POP -#endif - -struct DOCTEST_INTERFACE ExpressionDecomposer -{ - assertType::Enum m_at; - - ExpressionDecomposer(assertType::Enum at); - - // The right operator for capturing expressions is "<=" instead of "<<" (based - // on the operator precedence table) but then there will be warnings from GCC - // about "-Wparentheses" and since "_Pragma()" is problematic this will stay - // for now... https://github.com/catchorg/Catch2/issues/870 - // https://github.com/catchorg/Catch2/issues/565 - template - Expression_lhs operator<<(L&& operand) - { - return Expression_lhs(static_cast(operand), m_at); - } - - template::value, - void>::type* = nullptr> - Expression_lhs operator<<(const L& operand) - { - return Expression_lhs(operand, m_at); - } -}; - -struct DOCTEST_INTERFACE TestSuite -{ - const char* m_test_suite = nullptr; - const char* m_description = nullptr; - bool m_skip = false; - bool m_no_breaks = false; - bool m_no_output = false; - bool m_may_fail = false; - bool m_should_fail = false; - int m_expected_failures = 0; - double m_timeout = 0; - - TestSuite& operator*(const char* in); - - template - TestSuite& operator*(const T& in) - { - in.fill(*this); - return *this; - } -}; - -using funcType = void (*)(); - -struct DOCTEST_INTERFACE TestCase : public TestCaseData -{ - funcType m_test; // a function pointer to the test case - - String m_type; // for templated test cases - gets appended to the real name - int m_template_id; // an ID used to distinguish between the different versions - // of a templated test case - String m_full_name; // contains the name (only for templated test cases!) + - // the template type - - TestCase(funcType test, - const char* file, - unsigned line, - const TestSuite& test_suite, - const String& type = String(), - int template_id = -1); - - TestCase(const TestCase& other); - TestCase(TestCase&&) = delete; - - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function - TestCase& operator=(const TestCase& other); - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - TestCase& operator=(TestCase&&) = delete; - - TestCase& operator*(const char* in); - - template - TestCase& operator*(const T& in) - { - in.fill(*this); - return *this; - } - - bool operator<(const TestCase& other) const; - - ~TestCase() = default; -}; - -// forward declarations of functions used by the macros -DOCTEST_INTERFACE int -regTest(const TestCase& tc); -DOCTEST_INTERFACE int -setTestSuite(const TestSuite& ts); -DOCTEST_INTERFACE bool -isDebuggerActive(); - -template -int -instantiationHelper(const T&) -{ - return 0; -} - -namespace binaryAssertComparison { -enum Enum -{ - eq = 0, - ne, - gt, - lt, - ge, - le -}; -} // namespace binaryAssertComparison - -// clang-format off - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; - -#define DOCTEST_BINARY_RELATIONAL_OP(n, op) \ - template struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return op(lhs, rhs); } }; -// clang-format on - -DOCTEST_BINARY_RELATIONAL_OP(0, doctest::detail::eq) -DOCTEST_BINARY_RELATIONAL_OP(1, doctest::detail::ne) -DOCTEST_BINARY_RELATIONAL_OP(2, doctest::detail::gt) -DOCTEST_BINARY_RELATIONAL_OP(3, doctest::detail::lt) -DOCTEST_BINARY_RELATIONAL_OP(4, doctest::detail::ge) -DOCTEST_BINARY_RELATIONAL_OP(5, doctest::detail::le) - -struct DOCTEST_INTERFACE ResultBuilder : public AssertData -{ - ResultBuilder(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type = "", - const String& exception_string = ""); - - ResultBuilder(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type, - const Contains& exception_string); - - void setResult(const Result& res); - - template - DOCTEST_NOINLINE bool binary_assert(const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) - { - m_failed = !RelationalComparator()(lhs, rhs); - if (m_failed || getContextOptions()->success) { - m_decomp = stringifyBinaryExpr(lhs, ", ", rhs); - } - return !m_failed; - } - - template - DOCTEST_NOINLINE bool unary_assert(const DOCTEST_REF_WRAP(L) val) - { - m_failed = !val; - - if (m_at & assertType::is_false) { //! OCLINT bitwise operator in - //! conditional - m_failed = !m_failed; - } - - if (m_failed || getContextOptions()->success) { - m_decomp = (DOCTEST_STRINGIFY(val)); - } - - return !m_failed; - } - - void translateException(); - - bool log(); - void react() const; -}; - -namespace assertAction { -enum Enum -{ - nothing = 0, - dbgbreak = 1, - shouldthrow = 2 -}; -} // namespace assertAction - -DOCTEST_INTERFACE void -failed_out_of_a_testing_context(const AssertData& ad); - -DOCTEST_INTERFACE bool -decomp_assert(assertType::Enum at, - const char* file, - int line, - const char* expr, - const Result& result); - -#define DOCTEST_ASSERT_OUT_OF_TESTS(decomp) \ - do { \ - if (!is_running_in_test) { \ - if (failed) { \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - rb.m_decomp = decomp; \ - failed_out_of_a_testing_context(rb); \ - if (isDebuggerActive() && !getContextOptions()->no_breaks) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if (checkIfShouldThrow(at)) \ - throwException(); \ - } \ - return !failed; \ - } \ - } while (false) - -#define DOCTEST_ASSERT_IN_TESTS(decomp) \ - ResultBuilder rb(at, file, line, expr); \ - rb.m_failed = failed; \ - if (rb.m_failed || getContextOptions()->success) \ - rb.m_decomp = decomp; \ - if (rb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - if (rb.m_failed && checkIfShouldThrow(at)) \ - throwException() - -template -DOCTEST_NOINLINE bool -binary_assert(assertType::Enum at, - const char* file, - int line, - const char* expr, - const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) -{ - bool failed = !RelationalComparator()(lhs, rhs); - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE - // FAILING ASSERT THIS IS THE EFFECT OF HAVING - // 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - DOCTEST_ASSERT_IN_TESTS(stringifyBinaryExpr(lhs, ", ", rhs)); - return !failed; -} - -template -DOCTEST_NOINLINE bool -unary_assert(assertType::Enum at, - const char* file, - int line, - const char* expr, - const DOCTEST_REF_WRAP(L) val) -{ - bool failed = !val; - - if (at & assertType::is_false) //! OCLINT bitwise operator in conditional - failed = !failed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE - // FAILING ASSERT THIS IS THE EFFECT OF HAVING - // 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS((DOCTEST_STRINGIFY(val))); - DOCTEST_ASSERT_IN_TESTS((DOCTEST_STRINGIFY(val))); - return !failed; -} - -struct DOCTEST_INTERFACE IExceptionTranslator -{ - DOCTEST_DECLARE_INTERFACE(IExceptionTranslator) - virtual bool translate(String&) const = 0; -}; - -template -class ExceptionTranslator - : public IExceptionTranslator //! OCLINT destructor of virtual class -{ -public: - explicit ExceptionTranslator(String (*translateFunction)(T)) - : m_translateFunction(translateFunction) - { - } - - bool translate(String& res) const override - { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { - throw; // lgtm [cpp/rethrow-no-exception] - // cppcheck-suppress catchExceptionByValue - } catch (const T& ex) { - res = m_translateFunction(ex); //! OCLINT parameter reassignment - return true; - } catch (...) { - } //! OCLINT - empty catch statement -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - static_cast(res); // to silence -Wunused-parameter - return false; - } - -private: - String (*m_translateFunction)(T); -}; - -DOCTEST_INTERFACE void -registerExceptionTranslatorImpl(const IExceptionTranslator* et); - -// ContextScope base class used to allow implementing methods of ContextScope -// that don't depend on the template parameter in doctest.cpp. -struct DOCTEST_INTERFACE ContextScopeBase : public IContextScope -{ - ContextScopeBase(const ContextScopeBase&) = delete; - - ContextScopeBase& operator=(const ContextScopeBase&) = delete; - ContextScopeBase& operator=(ContextScopeBase&&) = delete; - - ~ContextScopeBase() override = default; - -protected: - ContextScopeBase(); - ContextScopeBase(ContextScopeBase&& other) noexcept; - - void destroy(); - bool need_to_destroy{ true }; -}; - -template -class ContextScope : public ContextScopeBase -{ - L lambda_; - -public: - explicit ContextScope(const L& lambda) - : lambda_(lambda) - { - } - explicit ContextScope(L&& lambda) - : lambda_(static_cast(lambda)) - { - } - - ContextScope(const ContextScope&) = delete; - ContextScope(ContextScope&&) noexcept = default; - - ContextScope& operator=(const ContextScope&) = delete; - ContextScope& operator=(ContextScope&&) = delete; - - void stringify(std::ostream* s) const override { lambda_(s); } - - ~ContextScope() override - { - if (need_to_destroy) { - destroy(); - } - } -}; - -struct DOCTEST_INTERFACE MessageBuilder : public MessageData -{ - std::ostream* m_stream; - bool logged = false; - - MessageBuilder(const char* file, int line, assertType::Enum severity); - - MessageBuilder(const MessageBuilder&) = delete; - MessageBuilder(MessageBuilder&&) = delete; - - MessageBuilder& operator=(const MessageBuilder&) = delete; - MessageBuilder& operator=(MessageBuilder&&) = delete; - - ~MessageBuilder(); - - // the preferred way of chaining parameters for stringification - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4866) - template - MessageBuilder& operator,(const T& in) - { - *m_stream << (DOCTEST_STRINGIFY(in)); - return *this; - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP - - // kept here just for backwards-compatibility - the comma operator should be - // preferred now - template - MessageBuilder& operator<<(const T& in) - { - return this->operator,(in); - } - - // the `,` operator has the lowest operator precedence - if `<<` is used by - // the user then the `,` operator will be called last which is not what we - // want and thus the `*` operator is used first (has higher operator - // precedence compared to `<<`) so that we guarantee that an operator of the - // MessageBuilder class is called first before the rest of the parameters - template - MessageBuilder& operator*(const T& in) - { - return this->operator,(in); - } - - bool log(); - void react(); -}; - -template -ContextScope -MakeContextScope(const L& lambda) -{ - return ContextScope(lambda); -} -} // namespace detail - -#define DOCTEST_DEFINE_DECORATOR(name, type, def) \ - struct name \ - { \ - type data; \ - name(type in = def) \ - : data(in) \ - { \ - } \ - void fill(detail::TestCase& state) const \ - { \ - state.DOCTEST_CAT(m_, name) = data; \ - } \ - void fill(detail::TestSuite& state) const \ - { \ - state.DOCTEST_CAT(m_, name) = data; \ - } \ - } - -DOCTEST_DEFINE_DECORATOR(test_suite, const char*, ""); -DOCTEST_DEFINE_DECORATOR(description, const char*, ""); -DOCTEST_DEFINE_DECORATOR(skip, bool, true); -DOCTEST_DEFINE_DECORATOR(no_breaks, bool, true); -DOCTEST_DEFINE_DECORATOR(no_output, bool, true); -DOCTEST_DEFINE_DECORATOR(timeout, double, 0); -DOCTEST_DEFINE_DECORATOR(may_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(should_fail, bool, true); -DOCTEST_DEFINE_DECORATOR(expected_failures, int, 0); - -template -int -registerExceptionTranslator(String (*translateFunction)(T)) -{ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") - static detail::ExceptionTranslator exceptionTranslator(translateFunction); - DOCTEST_CLANG_SUPPRESS_WARNING_POP - detail::registerExceptionTranslatorImpl(&exceptionTranslator); - return 0; -} - -} // namespace doctest - -// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE -// macro introduces an anonymous namespace in which getCurrentTestSuite gets -// overridden -namespace doctest_detail_test_suite_ns { -DOCTEST_INTERFACE doctest::detail::TestSuite& -getCurrentTestSuite(); -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -#else // DOCTEST_CONFIG_DISABLE -template -int -registerExceptionTranslator(String (*)(T)) -{ - return 0; -} -#endif // DOCTEST_CONFIG_DISABLE - -namespace detail { -using assert_handler = void (*)(const AssertData&); -struct ContextState; -} // namespace detail - -class DOCTEST_INTERFACE Context -{ - detail::ContextState* p; - - void parseArgs(int argc, const char* const* argv, bool withDefaults = false); - -public: - explicit Context(int argc = 0, const char* const* argv = nullptr); - - Context(const Context&) = delete; - Context(Context&&) = delete; - - Context& operator=(const Context&) = delete; - Context& operator=(Context&&) = delete; - - ~Context(); // NOLINT(performance-trivially-destructible) - - void applyCommandLine(int argc, const char* const* argv); - - void addFilter(const char* filter, const char* value); - void clearFilters(); - void setOption(const char* option, bool value); - void setOption(const char* option, int value); - void setOption(const char* option, const char* value); - - bool shouldExit(); - - void setAsDefaultForAssertsOutOfTestCases(); - - void setAssertHandler(detail::assert_handler ah); - - void setCout(std::ostream* out); - - int run(); -}; - -namespace TestCaseFailureReason { -enum Enum -{ - None = 0, - AssertFailure = 1, // an assertion has failed in the test case - Exception = 2, // test case threw an exception - Crash = 4, // a crash... - TooManyFailedAsserts = 8, // the abort-after option - Timeout = 16, // see the timeout decorator - ShouldHaveFailedButDidnt = 32, // see the should_fail decorator - ShouldHaveFailedAndDid = 64, // see the should_fail decorator - DidntFailExactlyNumTimes = 128, // see the expected_failures decorator - FailedExactlyNumTimes = 256, // see the expected_failures decorator - CouldHaveFailedAndDid = 512 // see the may_fail decorator -}; -} // namespace TestCaseFailureReason - -struct DOCTEST_INTERFACE CurrentTestCaseStats -{ - int numAssertsCurrentTest; - int numAssertsFailedCurrentTest; - double seconds; - int failure_flags; // use TestCaseFailureReason::Enum - bool testCaseSuccess; -}; - -struct DOCTEST_INTERFACE TestCaseException -{ - String error_string; - bool is_crash; -}; - -struct DOCTEST_INTERFACE TestRunStats -{ - unsigned numTestCases; - unsigned numTestCasesPassingFilters; - unsigned numTestSuitesPassingFilters; - unsigned numTestCasesFailed; - int numAsserts; - int numAssertsFailed; -}; - -struct QueryData -{ - const TestRunStats* run_stats = nullptr; - const TestCaseData** data = nullptr; - unsigned num_data = 0; -}; - -struct DOCTEST_INTERFACE IReporter -{ - // The constructor has to accept "const ContextOptions&" as a single argument - // which has most of the options for the run + a pointer to the stdout stream - // Reporter(const ContextOptions& in) - - // called when a query should be reported (listing test cases, printing the - // version, etc.) - virtual void report_query(const QueryData&) = 0; - - // called when the whole test run starts - virtual void test_run_start() = 0; - // called when the whole test run ends (caching a pointer to the input doesn't - // make sense here) - virtual void test_run_end(const TestRunStats&) = 0; - - // called when a test case is started (safe to cache a pointer to the input) - virtual void test_case_start(const TestCaseData&) = 0; - // called when a test case is reentered because of unfinished subcases (safe - // to cache a pointer to the input) - virtual void test_case_reenter(const TestCaseData&) = 0; - // called when a test case has ended - virtual void test_case_end(const CurrentTestCaseStats&) = 0; - - // called when an exception is thrown from the test case (or it crashes) - virtual void test_case_exception(const TestCaseException&) = 0; - - // called whenever a subcase is entered (don't cache pointers to the input) - virtual void subcase_start(const SubcaseSignature&) = 0; - // called whenever a subcase is exited (don't cache pointers to the input) - virtual void subcase_end() = 0; - - // called for each assert (don't cache pointers to the input) - virtual void log_assert(const AssertData&) = 0; - // called for each message (don't cache pointers to the input) - virtual void log_message(const MessageData&) = 0; - - // called when a test case is skipped either because it doesn't pass the - // filters, has a skip decorator or isn't in the execution range (between - // first and last) (safe to cache a pointer to the input) - virtual void test_case_skipped(const TestCaseData&) = 0; - - DOCTEST_DECLARE_INTERFACE(IReporter) - - // can obtain all currently active contexts and stringify them if one wishes - // to do so - static int get_num_active_contexts(); - static const IContextScope* const* get_active_contexts(); - - // can iterate through contexts which have been stringified automatically in - // their destructors when an exception has been thrown - static int get_num_stringified_contexts(); - static const String* get_stringified_contexts(); -}; - -namespace detail { -using reporterCreatorFunc = IReporter* (*)(const ContextOptions&); - -DOCTEST_INTERFACE void -registerReporterImpl(const char* name, - int prio, - reporterCreatorFunc c, - bool isReporter); - -template -IReporter* -reporterCreator(const ContextOptions& o) -{ - return new Reporter(o); -} -} // namespace detail - -template -int -registerReporter(const char* name, int priority, bool isReporter) -{ - detail::registerReporterImpl( - name, priority, detail::reporterCreator, isReporter); - return 0; -} -} // namespace doctest - -#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES -#define DOCTEST_FUNC_EMPTY [] { return false; }() -#else -#define DOCTEST_FUNC_EMPTY (void)0 -#endif - -// if registering is not disabled -#ifndef DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_ASSERTS_RETURN_VALUES -#define DOCTEST_FUNC_SCOPE_BEGIN [&] -#define DOCTEST_FUNC_SCOPE_END () -#define DOCTEST_FUNC_SCOPE_RET(v) return v -#else -#define DOCTEST_FUNC_SCOPE_BEGIN do -#define DOCTEST_FUNC_SCOPE_END while (false) -#define DOCTEST_FUNC_SCOPE_RET(v) (void)0 -#endif - -// common code in asserts - for convenience -#define DOCTEST_ASSERT_LOG_REACT_RETURN(b) \ - if (b.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - b.react(); \ - DOCTEST_FUNC_SCOPE_RET(!b.m_failed) - -#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) x; -#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) \ - try { \ - x; \ - } catch (...) { \ - DOCTEST_RB.translateException(); \ - } -#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#ifdef DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS -#define DOCTEST_CAST_TO_VOID(...) \ - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wuseless-cast") \ - static_cast(__VA_ARGS__); \ - DOCTEST_GCC_SUPPRESS_WARNING_POP -#else // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS -#define DOCTEST_CAST_TO_VOID(...) __VA_ARGS__; -#endif // DOCTEST_CONFIG_VOID_CAST_EXPRESSIONS - -// registers the test by initializing a dummy var with a function -#define DOCTEST_REGISTER_FUNCTION(global_prefix, f, decorators) \ - global_prefix DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT */ \ - doctest::detail::regTest( \ - doctest::detail::TestCase( \ - f, \ - __FILE__, \ - __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite()) * \ - decorators)) - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \ - namespace { /* NOLINT */ \ - struct der : public base \ - { \ - void f(); \ - }; \ - static inline DOCTEST_NOINLINE void func() \ - { \ - der v; \ - v.f(); \ - } \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, func, decorators) \ - } \ - inline DOCTEST_NOINLINE void der::f() // NOLINT(misc-definitions-in-headers) - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \ - static void f(); \ - DOCTEST_REGISTER_FUNCTION(DOCTEST_EMPTY, f, decorators) \ - static void f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS(f, proxy, decorators) \ - static doctest::detail::funcType proxy() \ - { \ - return f; \ - } \ - DOCTEST_REGISTER_FUNCTION(inline, proxy(), decorators) \ - static void f() - -// for registering tests -#define DOCTEST_TEST_CASE(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - decorators) - -// for registering tests in classes - requires C++17 for inline variables! -#if DOCTEST_CPLUSPLUS >= 201703L -#define DOCTEST_TEST_CASE_CLASS(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION_IN_CLASS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_PROXY_), \ - decorators) -#else // DOCTEST_TEST_CASE_CLASS -#define DOCTEST_TEST_CASE_CLASS(...) \ - TEST_CASES_CAN_BE_REGISTERED_IN_CLASSES_ONLY_IN_CPP17_MODE_OR_WITH_VS_2017_OR_NEWER -#endif // DOCTEST_TEST_CASE_CLASS - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), \ - c, \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - decorators) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING_AS(str, ...) \ - namespace doctest { \ - template<> \ - inline String toString<__VA_ARGS__>() \ - { \ - return str; \ - } \ - } \ - static_assert(true, "") - -#define DOCTEST_TYPE_TO_STRING(...) \ - DOCTEST_TYPE_TO_STRING_AS(#__VA_ARGS__, __VA_ARGS__) - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(dec, T, iter, func) \ - template \ - static void func(); \ - namespace { /* NOLINT */ \ - template \ - struct iter; \ - template \ - struct iter> \ - { \ - iter(const char* file, unsigned line, int index) \ - { \ - doctest::detail::regTest( \ - doctest::detail::TestCase( \ - func, \ - file, \ - line, \ - doctest_detail_test_suite_ns::getCurrentTestSuite(), \ - doctest::toString(), \ - int(line) * 1000 + index) * \ - dec); \ - iter>(file, line, index + 1); \ - } \ - }; \ - template<> \ - struct iter> \ - { \ - iter(const char*, unsigned, int) {} \ - }; \ - } \ - template \ - static void func() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(dec, T, id) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL( \ - dec, T, DOCTEST_CAT(id, ITERATOR), DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)) - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, anon, ...) \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_CAT(anon, DUMMY), /* NOLINT(cert-err58-cpp, \ - fuchsia-statically-constructed-objects) */ \ - doctest::detail::instantiationHelper( \ - DOCTEST_CAT(id, ITERATOR) < __VA_ARGS__ > (__FILE__, __LINE__, 0))) - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL( \ - id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), std::tuple<__VA_ARGS__>) \ - static_assert(true, "") - -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL( \ - id, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) \ - static_assert(true, "") - -#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(dec, T, anon, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL( \ - dec, T, DOCTEST_CAT(anon, ITERATOR), anon); \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL( \ - anon, anon, std::tuple<__VA_ARGS__>) \ - template \ - static void anon() - -#define DOCTEST_TEST_CASE_TEMPLATE(dec, T, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_IMPL( \ - dec, T, DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_), __VA_ARGS__) - -// for subcases -#define DOCTEST_SUBCASE(name) \ - if (const doctest::detail::Subcase& DOCTEST_ANONYMOUS(DOCTEST_ANON_SUBCASE_) \ - DOCTEST_UNUSED = doctest::detail::Subcase(name, __FILE__, __LINE__)) - -// for grouping tests in test suites by using code blocks -#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \ - namespace ns_name { \ - namespace doctest_detail_test_suite_ns { \ - static DOCTEST_NOINLINE doctest::detail::TestSuite& \ - getCurrentTestSuite() noexcept \ - { \ - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4640) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wexit-time-destructors") \ - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmissing-field-initializers") \ - static doctest::detail::TestSuite data{}; \ - static bool inited = false; \ - DOCTEST_MSVC_SUPPRESS_WARNING_POP \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP \ - DOCTEST_GCC_SUPPRESS_WARNING_POP \ - if (!inited) { \ - data* decorators; \ - inited = true; \ - } \ - return data; \ - } \ - } \ - } \ - namespace ns_name - -#define DOCTEST_TEST_SUITE(decorators) \ - DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(DOCTEST_ANON_SUITE_)) - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(decorators) \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators)) \ - static_assert(true, "") - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_VAR_), /* NOLINT(cert-err58-cpp) */ \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * "")) \ - using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int - -// for registering exception translators -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \ - inline doctest::String translatorName(signature); \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), /* NOLINT(cert-err58-cpp) */ \ - doctest::registerExceptionTranslator(translatorName)) \ - doctest::String translatorName(signature) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_), signature) - -// for registering reporters -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \ - doctest::registerReporter(name, priority, true)) \ - static_assert(true, "") - -// for registering listeners -#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) \ - DOCTEST_GLOBAL_NO_WARNINGS( \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_REPORTER_), /* NOLINT(cert-err58-cpp) */ \ - doctest::registerReporter(name, priority, false)) \ - static_assert(true, "") - -// clang-format off -// for logging - disabling formatting because it's important to have these on 2 separate lines - see PR #557 -#define DOCTEST_INFO(...) \ - DOCTEST_INFO_IMPL(DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_), \ - DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_OTHER_), \ - __VA_ARGS__) -// clang-format on - -#define DOCTEST_INFO_IMPL(mb_name, s_name, ...) \ - auto DOCTEST_ANONYMOUS(DOCTEST_CAPTURE_) = \ - doctest::detail::MakeContextScope([&](std::ostream* s_name) { \ - doctest::detail::MessageBuilder mb_name( \ - __FILE__, __LINE__, doctest::assertType::is_warn); \ - mb_name.m_stream = s_name; \ - mb_name* __VA_ARGS__; \ - }) - -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := ", x) - -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - doctest::detail::MessageBuilder mb(file, line, doctest::assertType::type); \ - mb* __VA_ARGS__; \ - if (mb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - mb.react(); \ - } \ - DOCTEST_FUNC_SCOPE_END - -// clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) -#define DOCTEST_ADD_FAIL_AT(file, line, ...) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(DOCTEST_MESSAGE_), __VA_ARGS__) -// clang-format on - -#define DOCTEST_MESSAGE(...) \ - DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, __VA_ARGS__) -#define DOCTEST_FAIL_CHECK(...) \ - DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, __VA_ARGS__) -#define DOCTEST_FAIL(...) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, __VA_ARGS__) - -#define DOCTEST_TO_LVALUE(...) \ - __VA_ARGS__ // Not removed to keep backwards compatibility. - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_ASSERT_IMPLEMENT_2(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH( \ - "-Woverloaded-shift-op-parentheses") \ - /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) */ \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(DOCTEST_RB.setResult( \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__)) /* NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) \ - */ \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB) \ - DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - DOCTEST_ASSERT_IMPLEMENT_2(assert_type, __VA_ARGS__); \ - } \ - DOCTEST_FUNC_SCOPE_END // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) - -#define DOCTEST_BINARY_ASSERT(assert_type, comp, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY( \ - DOCTEST_RB.binary_assert( \ - __VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ - } \ - DOCTEST_FUNC_SCOPE_END - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__); \ - DOCTEST_WRAP_IN_TRY(DOCTEST_RB.unary_assert(__VA_ARGS__)) \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ - } \ - DOCTEST_FUNC_SCOPE_END - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -// necessary for _MESSAGE -#define DOCTEST_ASSERT_IMPLEMENT_2 DOCTEST_ASSERT_IMPLEMENT_1 - -#define DOCTEST_ASSERT_IMPLEMENT_1(assert_type, ...) \ - DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH( \ - "-Woverloaded-shift-op-parentheses") \ - doctest::detail::decomp_assert( \ - doctest::assertType::assert_type, \ - __FILE__, \ - __LINE__, \ - #__VA_ARGS__, \ - doctest::detail::ExpressionDecomposer(doctest::assertType::assert_type) \ - << __VA_ARGS__) DOCTEST_CLANG_SUPPRESS_WARNING_POP - -#define DOCTEST_BINARY_ASSERT(assert_type, comparison, ...) \ - doctest::detail::binary_assert< \ - doctest::detail::binaryAssertComparison::comparison>( \ - doctest::assertType::assert_type, \ - __FILE__, \ - __LINE__, \ - #__VA_ARGS__, \ - __VA_ARGS__) - -#define DOCTEST_UNARY_ASSERT(assert_type, ...) \ - doctest::detail::unary_assert(doctest::assertType::assert_type, \ - __FILE__, \ - __LINE__, \ - #__VA_ARGS__, \ - __VA_ARGS__) - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN, __VA_ARGS__) -#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK, __VA_ARGS__) -#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE, __VA_ARGS__) -#define DOCTEST_WARN_FALSE(...) \ - DOCTEST_ASSERT_IMPLEMENT_1(DT_WARN_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_FALSE(...) \ - DOCTEST_ASSERT_IMPLEMENT_1(DT_CHECK_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_FALSE(...) \ - DOCTEST_ASSERT_IMPLEMENT_1(DT_REQUIRE_FALSE, __VA_ARGS__) - -// clang-format off -#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN, cond); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK, cond); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE, cond); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_WARN_FALSE, cond); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_CHECK_FALSE, cond); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_ASSERT_IMPLEMENT_2(DT_REQUIRE_FALSE, cond); } DOCTEST_FUNC_SCOPE_END -// clang-format on - -#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, eq, __VA_ARGS__) -#define DOCTEST_CHECK_EQ(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, eq, __VA_ARGS__) -#define DOCTEST_REQUIRE_EQ(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, eq, __VA_ARGS__) -#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, ne, __VA_ARGS__) -#define DOCTEST_CHECK_NE(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_NE, ne, __VA_ARGS__) -#define DOCTEST_REQUIRE_NE(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, ne, __VA_ARGS__) -#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, gt, __VA_ARGS__) -#define DOCTEST_CHECK_GT(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_GT, gt, __VA_ARGS__) -#define DOCTEST_REQUIRE_GT(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, gt, __VA_ARGS__) -#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lt, __VA_ARGS__) -#define DOCTEST_CHECK_LT(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lt, __VA_ARGS__) -#define DOCTEST_REQUIRE_LT(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lt, __VA_ARGS__) -#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, ge, __VA_ARGS__) -#define DOCTEST_CHECK_GE(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_GE, ge, __VA_ARGS__) -#define DOCTEST_REQUIRE_GE(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, ge, __VA_ARGS__) -#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, le, __VA_ARGS__) -#define DOCTEST_CHECK_LE(...) \ - DOCTEST_BINARY_ASSERT(DT_CHECK_LE, le, __VA_ARGS__) -#define DOCTEST_REQUIRE_LE(...) \ - DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, le, __VA_ARGS__) - -#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY(...) \ - DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY(...) \ - DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, __VA_ARGS__) -#define DOCTEST_WARN_UNARY_FALSE(...) \ - DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_CHECK_UNARY_FALSE(...) \ - DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, __VA_ARGS__) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) \ - DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, __VA_ARGS__) - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - -#define DOCTEST_ASSERT_THROWS_AS(expr, assert_type, message, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - if (!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, \ - __FILE__, \ - __LINE__, \ - #expr, \ - #__VA_ARGS__, \ - message); \ - try { \ - DOCTEST_CAST_TO_VOID(expr) \ - } catch (const typename doctest::detail::types::remove_const< \ - typename doctest::detail::types::remove_reference< \ - __VA_ARGS__>::type>::type&) { \ - DOCTEST_RB.translateException(); \ - DOCTEST_RB.m_threw_as = true; \ - } catch (...) { \ - DOCTEST_RB.translateException(); \ - } \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ - } else { /* NOLINT(*-else-after-return) */ \ - DOCTEST_FUNC_SCOPE_RET(false); \ - } \ - } \ - DOCTEST_FUNC_SCOPE_END - -#define DOCTEST_ASSERT_THROWS_WITH(expr, expr_str, assert_type, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - if (!doctest::getContextOptions()->no_throw) { \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, \ - __FILE__, \ - __LINE__, \ - expr_str, \ - "", \ - __VA_ARGS__); \ - try { \ - DOCTEST_CAST_TO_VOID(expr) \ - } catch (...) { \ - DOCTEST_RB.translateException(); \ - } \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ - } else { /* NOLINT(*-else-after-return) */ \ - DOCTEST_FUNC_SCOPE_RET(false); \ - } \ - } \ - DOCTEST_FUNC_SCOPE_END - -#define DOCTEST_ASSERT_NOTHROW(assert_type, ...) \ - DOCTEST_FUNC_SCOPE_BEGIN \ - { \ - doctest::detail::ResultBuilder DOCTEST_RB( \ - doctest::assertType::assert_type, __FILE__, __LINE__, #__VA_ARGS__); \ - try { \ - DOCTEST_CAST_TO_VOID(__VA_ARGS__) \ - } catch (...) { \ - DOCTEST_RB.translateException(); \ - } \ - DOCTEST_ASSERT_LOG_REACT_RETURN(DOCTEST_RB); \ - } \ - DOCTEST_FUNC_SCOPE_END - -// clang-format off -#define DOCTEST_WARN_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_WARN_THROWS, "") -#define DOCTEST_CHECK_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_CHECK_THROWS, "") -#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_ASSERT_THROWS_WITH((__VA_ARGS__), #__VA_ARGS__, DT_REQUIRE_THROWS, "") - -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_AS, "", __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_AS, "", __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_AS, "", __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_WARN_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_CHECK_THROWS_WITH, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_ASSERT_THROWS_WITH(expr, #expr, DT_REQUIRE_THROWS_WITH, __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_WARN_THROWS_WITH_AS, message, __VA_ARGS__) -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_CHECK_THROWS_WITH_AS, message, __VA_ARGS__) -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, message, ...) DOCTEST_ASSERT_THROWS_AS(expr, DT_REQUIRE_THROWS_WITH_AS, message, __VA_ARGS__) - -#define DOCTEST_WARN_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_WARN_NOTHROW, __VA_ARGS__) -#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_CHECK_NOTHROW, __VA_ARGS__) -#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_ASSERT_NOTHROW(DT_REQUIRE_NOTHROW, __VA_ARGS__) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS(expr); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS(expr); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS(expr); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH(expr, with); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_WARN_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_CHECK_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_SCOPE_BEGIN { DOCTEST_INFO(__VA_ARGS__); DOCTEST_REQUIRE_NOTHROW(expr); } DOCTEST_FUNC_SCOPE_END -// clang-format on - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -// ================================================================================================= -// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == -// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == -// ================================================================================================= -#else // DOCTEST_CONFIG_DISABLE - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ - namespace /* NOLINT */ { \ - template \ - struct der : public base \ - { \ - void f(); \ - }; \ - } \ - template \ - inline void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ - template \ - static inline void f() - -// for registering tests -#define DOCTEST_TEST_CASE(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - name) - -// for registering tests in classes -#define DOCTEST_TEST_CASE_CLASS(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - name) - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(x, name) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(DOCTEST_ANON_CLASS_), \ - x, \ - DOCTEST_ANONYMOUS(DOCTEST_ANON_FUNC_), \ - name) - -// for converting types to strings without the header and demangling -#define DOCTEST_TYPE_TO_STRING_AS(str, ...) static_assert(true, "") -#define DOCTEST_TYPE_TO_STRING(...) static_assert(true, "") - -// for typed tests -#define DOCTEST_TEST_CASE_TEMPLATE(name, type, ...) \ - template \ - inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \ - template \ - inline void DOCTEST_ANONYMOUS(DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, ...) static_assert(true, "") -#define DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, ...) static_assert(true, "") - -// for subcases -#define DOCTEST_SUBCASE(name) - -// for a testsuite block -#define DOCTEST_TEST_SUITE(name) namespace // NOLINT - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(name) static_assert(true, "") - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END \ - using DOCTEST_ANONYMOUS(DOCTEST_ANON_FOR_SEMICOLON_) = int - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - template \ - static inline doctest::String DOCTEST_ANONYMOUS(DOCTEST_ANON_TRANSLATOR_)( \ - signature) - -#define DOCTEST_REGISTER_REPORTER(name, priority, reporter) -#define DOCTEST_REGISTER_LISTENER(name, priority, reporter) - -#define DOCTEST_INFO(...) (static_cast(0)) -#define DOCTEST_CAPTURE(x) (static_cast(0)) -#define DOCTEST_ADD_MESSAGE_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_ADD_FAIL_AT(file, line, ...) (static_cast(0)) -#define DOCTEST_MESSAGE(...) (static_cast(0)) -#define DOCTEST_FAIL_CHECK(...) (static_cast(0)) -#define DOCTEST_FAIL(...) (static_cast(0)) - -#if defined(DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED) && \ - defined(DOCTEST_CONFIG_ASSERTS_RETURN_VALUES) - -#define DOCTEST_WARN(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_CHECK(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_REQUIRE(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_WARN_FALSE(...) [&] { return !(__VA_ARGS__); }() -#define DOCTEST_CHECK_FALSE(...) [&] { return !(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_FALSE(...) [&] { return !(__VA_ARGS__); }() - -#define DOCTEST_WARN_MESSAGE(cond, ...) [&] { return cond; }() -#define DOCTEST_CHECK_MESSAGE(cond, ...) [&] { return cond; }() -#define DOCTEST_REQUIRE_MESSAGE(cond, ...) [&] { return cond; }() -#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) [&] { return !(cond); }() - -namespace doctest { -namespace detail { -#define DOCTEST_RELATIONAL_OP(name, op) \ - template \ - bool name(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) \ - { \ - return lhs op rhs; \ - } - -DOCTEST_RELATIONAL_OP(eq, ==) -DOCTEST_RELATIONAL_OP(ne, !=) -DOCTEST_RELATIONAL_OP(lt, <) -DOCTEST_RELATIONAL_OP(gt, >) -DOCTEST_RELATIONAL_OP(le, <=) -DOCTEST_RELATIONAL_OP(ge, >=) -} // namespace detail -} // namespace doctest - -#define DOCTEST_WARN_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }() -#define DOCTEST_CHECK_EQ(...) [&] { return doctest::detail::eq(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_EQ(...) \ - [&] { return doctest::detail::eq(__VA_ARGS__); }() -#define DOCTEST_WARN_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }() -#define DOCTEST_CHECK_NE(...) [&] { return doctest::detail::ne(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_NE(...) \ - [&] { return doctest::detail::ne(__VA_ARGS__); }() -#define DOCTEST_WARN_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }() -#define DOCTEST_CHECK_LT(...) [&] { return doctest::detail::lt(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_LT(...) \ - [&] { return doctest::detail::lt(__VA_ARGS__); }() -#define DOCTEST_WARN_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }() -#define DOCTEST_CHECK_GT(...) [&] { return doctest::detail::gt(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_GT(...) \ - [&] { return doctest::detail::gt(__VA_ARGS__); }() -#define DOCTEST_WARN_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }() -#define DOCTEST_CHECK_LE(...) [&] { return doctest::detail::le(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_LE(...) \ - [&] { return doctest::detail::le(__VA_ARGS__); }() -#define DOCTEST_WARN_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }() -#define DOCTEST_CHECK_GE(...) [&] { return doctest::detail::ge(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_GE(...) \ - [&] { return doctest::detail::ge(__VA_ARGS__); }() -#define DOCTEST_WARN_UNARY(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_CHECK_UNARY(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_REQUIRE_UNARY(...) [&] { return __VA_ARGS__; }() -#define DOCTEST_WARN_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() -#define DOCTEST_CHECK_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() -#define DOCTEST_REQUIRE_UNARY_FALSE(...) [&] { return !(__VA_ARGS__); }() - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - -#define DOCTEST_WARN_THROWS_WITH(expr, with, ...) \ - [] { \ - static_assert( \ - false, \ - "Exception translation is not available when doctest is disabled."); \ - return false; \ - }() -#define DOCTEST_CHECK_THROWS_WITH(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_REQUIRE_THROWS_WITH(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) - -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH(, , ) - -#define DOCTEST_WARN_THROWS(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_CHECK_THROWS(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_REQUIRE_THROWS(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_WARN_THROWS_AS(expr, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_CHECK_THROWS_AS(expr, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_WARN_NOTHROW(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() -#define DOCTEST_CHECK_NOTHROW(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() -#define DOCTEST_REQUIRE_NOTHROW(...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return false; \ - } catch (...) { \ - return true; \ - } \ - }() -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) \ - [&] { \ - try { \ - expr; \ - } catch (__VA_ARGS__) { \ - return true; \ - } catch (...) { \ - } \ - return false; \ - }() -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) \ - [&] { \ - try { \ - __VA_ARGS__; \ - return true; \ - } catch (...) { \ - return false; \ - } \ - }() - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#else // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED - -#define DOCTEST_WARN(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_FALSE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_FALSE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_FUNC_EMPTY - -#define DOCTEST_WARN_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, ...) DOCTEST_FUNC_EMPTY - -#define DOCTEST_WARN_EQ(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_EQ(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_EQ(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_NE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_NE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_NE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_GT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_GT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_GT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_LT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_LT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_LT(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_GE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_GE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_GE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_LE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_LE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_LE(...) DOCTEST_FUNC_EMPTY - -#define DOCTEST_WARN_UNARY(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_UNARY(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_FUNC_EMPTY - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - -#define DOCTEST_WARN_THROWS(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_NOTHROW(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_FUNC_EMPTY - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_FUNC_EMPTY -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_FUNC_EMPTY - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#endif // DOCTEST_CONFIG_EVALUATE_ASSERTS_EVEN_WHEN_DISABLED - -#endif // DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#define DOCTEST_EXCEPTION_EMPTY_FUNC DOCTEST_FUNC_EMPTY -#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#define DOCTEST_EXCEPTION_EMPTY_FUNC \ - [] { \ - static_assert(false, \ - "Exceptions are disabled! " \ - "Use DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS if " \ - "you want to compile with exceptions disabled."); \ - return false; \ - }() - -#undef DOCTEST_REQUIRE -#undef DOCTEST_REQUIRE_FALSE -#undef DOCTEST_REQUIRE_MESSAGE -#undef DOCTEST_REQUIRE_FALSE_MESSAGE -#undef DOCTEST_REQUIRE_EQ -#undef DOCTEST_REQUIRE_NE -#undef DOCTEST_REQUIRE_GT -#undef DOCTEST_REQUIRE_LT -#undef DOCTEST_REQUIRE_GE -#undef DOCTEST_REQUIRE_LE -#undef DOCTEST_REQUIRE_UNARY -#undef DOCTEST_REQUIRE_UNARY_FALSE - -#define DOCTEST_REQUIRE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_FALSE_MESSAGE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_EQ DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_NE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_GT DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_LT DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_GE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_LE DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_UNARY DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_UNARY_FALSE DOCTEST_EXCEPTION_EMPTY_FUNC - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#define DOCTEST_WARN_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS(...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_WITH(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_NOTHROW(...) DOCTEST_EXCEPTION_EMPTY_FUNC - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, ...) DOCTEST_EXCEPTION_EMPTY_FUNC - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -// clang-format off -// KEPT FOR BACKWARDS COMPATIBILITY - FORWARDING TO THE RIGHT MACROS -#define DOCTEST_FAST_WARN_EQ DOCTEST_WARN_EQ -#define DOCTEST_FAST_CHECK_EQ DOCTEST_CHECK_EQ -#define DOCTEST_FAST_REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define DOCTEST_FAST_WARN_NE DOCTEST_WARN_NE -#define DOCTEST_FAST_CHECK_NE DOCTEST_CHECK_NE -#define DOCTEST_FAST_REQUIRE_NE DOCTEST_REQUIRE_NE -#define DOCTEST_FAST_WARN_GT DOCTEST_WARN_GT -#define DOCTEST_FAST_CHECK_GT DOCTEST_CHECK_GT -#define DOCTEST_FAST_REQUIRE_GT DOCTEST_REQUIRE_GT -#define DOCTEST_FAST_WARN_LT DOCTEST_WARN_LT -#define DOCTEST_FAST_CHECK_LT DOCTEST_CHECK_LT -#define DOCTEST_FAST_REQUIRE_LT DOCTEST_REQUIRE_LT -#define DOCTEST_FAST_WARN_GE DOCTEST_WARN_GE -#define DOCTEST_FAST_CHECK_GE DOCTEST_CHECK_GE -#define DOCTEST_FAST_REQUIRE_GE DOCTEST_REQUIRE_GE -#define DOCTEST_FAST_WARN_LE DOCTEST_WARN_LE -#define DOCTEST_FAST_CHECK_LE DOCTEST_CHECK_LE -#define DOCTEST_FAST_REQUIRE_LE DOCTEST_REQUIRE_LE - -#define DOCTEST_FAST_WARN_UNARY DOCTEST_WARN_UNARY -#define DOCTEST_FAST_CHECK_UNARY DOCTEST_CHECK_UNARY -#define DOCTEST_FAST_REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define DOCTEST_FAST_WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define DOCTEST_FAST_CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id,__VA_ARGS__) -// clang-format on - -// BDD style macros -// clang-format off -#define DOCTEST_SCENARIO(name) DOCTEST_TEST_CASE(" Scenario: " name) -#define DOCTEST_SCENARIO_CLASS(name) DOCTEST_TEST_CASE_CLASS(" Scenario: " name) -#define DOCTEST_SCENARIO_TEMPLATE(name, T, ...) DOCTEST_TEST_CASE_TEMPLATE(" Scenario: " name, T, __VA_ARGS__) -#define DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) DOCTEST_TEST_CASE_TEMPLATE_DEFINE(" Scenario: " name, T, id) - -#define DOCTEST_GIVEN(name) DOCTEST_SUBCASE(" Given: " name) -#define DOCTEST_WHEN(name) DOCTEST_SUBCASE(" When: " name) -#define DOCTEST_AND_WHEN(name) DOCTEST_SUBCASE("And when: " name) -#define DOCTEST_THEN(name) DOCTEST_SUBCASE(" Then: " name) -#define DOCTEST_AND_THEN(name) DOCTEST_SUBCASE(" And: " name) -// clang-format on - -// == SHORT VERSIONS OF THE MACROS -#ifndef DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES - -#define TEST_CASE(name) DOCTEST_TEST_CASE(name) -#define TEST_CASE_CLASS(name) DOCTEST_TEST_CASE_CLASS(name) -#define TEST_CASE_FIXTURE(x, name) DOCTEST_TEST_CASE_FIXTURE(x, name) -#define TYPE_TO_STRING_AS(str, ...) DOCTEST_TYPE_TO_STRING_AS(str, __VA_ARGS__) -#define TYPE_TO_STRING(...) DOCTEST_TYPE_TO_STRING(__VA_ARGS__) -#define TEST_CASE_TEMPLATE(name, T, ...) \ - DOCTEST_TEST_CASE_TEMPLATE(name, T, __VA_ARGS__) -#define TEST_CASE_TEMPLATE_DEFINE(name, T, id) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, T, id) -#define TEST_CASE_TEMPLATE_INVOKE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INVOKE(id, __VA_ARGS__) -#define TEST_CASE_TEMPLATE_APPLY(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_APPLY(id, __VA_ARGS__) -#define SUBCASE(name) DOCTEST_SUBCASE(name) -#define TEST_SUITE(decorators) DOCTEST_TEST_SUITE(decorators) -#define TEST_SUITE_BEGIN(name) DOCTEST_TEST_SUITE_BEGIN(name) -#define TEST_SUITE_END DOCTEST_TEST_SUITE_END -#define REGISTER_EXCEPTION_TRANSLATOR(signature) \ - DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) -#define REGISTER_REPORTER(name, priority, reporter) \ - DOCTEST_REGISTER_REPORTER(name, priority, reporter) -#define REGISTER_LISTENER(name, priority, reporter) \ - DOCTEST_REGISTER_LISTENER(name, priority, reporter) -#define INFO(...) DOCTEST_INFO(__VA_ARGS__) -#define CAPTURE(x) DOCTEST_CAPTURE(x) -#define ADD_MESSAGE_AT(file, line, ...) \ - DOCTEST_ADD_MESSAGE_AT(file, line, __VA_ARGS__) -#define ADD_FAIL_CHECK_AT(file, line, ...) \ - DOCTEST_ADD_FAIL_CHECK_AT(file, line, __VA_ARGS__) -#define ADD_FAIL_AT(file, line, ...) \ - DOCTEST_ADD_FAIL_AT(file, line, __VA_ARGS__) -#define MESSAGE(...) DOCTEST_MESSAGE(__VA_ARGS__) -#define FAIL_CHECK(...) DOCTEST_FAIL_CHECK(__VA_ARGS__) -#define FAIL(...) DOCTEST_FAIL(__VA_ARGS__) -#define TO_LVALUE(...) DOCTEST_TO_LVALUE(__VA_ARGS__) - -#define WARN(...) DOCTEST_WARN(__VA_ARGS__) -#define WARN_FALSE(...) DOCTEST_WARN_FALSE(__VA_ARGS__) -#define WARN_THROWS(...) DOCTEST_WARN_THROWS(__VA_ARGS__) -#define WARN_THROWS_AS(expr, ...) DOCTEST_WARN_THROWS_AS(expr, __VA_ARGS__) -#define WARN_THROWS_WITH(expr, ...) DOCTEST_WARN_THROWS_WITH(expr, __VA_ARGS__) -#define WARN_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define WARN_NOTHROW(...) DOCTEST_WARN_NOTHROW(__VA_ARGS__) -#define CHECK(...) DOCTEST_CHECK(__VA_ARGS__) -#define CHECK_FALSE(...) DOCTEST_CHECK_FALSE(__VA_ARGS__) -#define CHECK_THROWS(...) DOCTEST_CHECK_THROWS(__VA_ARGS__) -#define CHECK_THROWS_AS(expr, ...) DOCTEST_CHECK_THROWS_AS(expr, __VA_ARGS__) -#define CHECK_THROWS_WITH(expr, ...) \ - DOCTEST_CHECK_THROWS_WITH(expr, __VA_ARGS__) -#define CHECK_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_CHECK_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define CHECK_NOTHROW(...) DOCTEST_CHECK_NOTHROW(__VA_ARGS__) -#define REQUIRE(...) DOCTEST_REQUIRE(__VA_ARGS__) -#define REQUIRE_FALSE(...) DOCTEST_REQUIRE_FALSE(__VA_ARGS__) -#define REQUIRE_THROWS(...) DOCTEST_REQUIRE_THROWS(__VA_ARGS__) -#define REQUIRE_THROWS_AS(expr, ...) \ - DOCTEST_REQUIRE_THROWS_AS(expr, __VA_ARGS__) -#define REQUIRE_THROWS_WITH(expr, ...) \ - DOCTEST_REQUIRE_THROWS_WITH(expr, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_AS(expr, with, ...) \ - DOCTEST_REQUIRE_THROWS_WITH_AS(expr, with, __VA_ARGS__) -#define REQUIRE_NOTHROW(...) DOCTEST_REQUIRE_NOTHROW(__VA_ARGS__) - -#define WARN_MESSAGE(cond, ...) DOCTEST_WARN_MESSAGE(cond, __VA_ARGS__) -#define WARN_FALSE_MESSAGE(cond, ...) \ - DOCTEST_WARN_FALSE_MESSAGE(cond, __VA_ARGS__) -#define WARN_THROWS_MESSAGE(expr, ...) \ - DOCTEST_WARN_THROWS_MESSAGE(expr, __VA_ARGS__) -#define WARN_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define WARN_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_WARN_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_WARN_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define WARN_NOTHROW_MESSAGE(expr, ...) \ - DOCTEST_WARN_NOTHROW_MESSAGE(expr, __VA_ARGS__) -#define CHECK_MESSAGE(cond, ...) DOCTEST_CHECK_MESSAGE(cond, __VA_ARGS__) -#define CHECK_FALSE_MESSAGE(cond, ...) \ - DOCTEST_CHECK_FALSE_MESSAGE(cond, __VA_ARGS__) -#define CHECK_THROWS_MESSAGE(expr, ...) \ - DOCTEST_CHECK_THROWS_MESSAGE(expr, __VA_ARGS__) -#define CHECK_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define CHECK_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_CHECK_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_CHECK_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define CHECK_NOTHROW_MESSAGE(expr, ...) \ - DOCTEST_CHECK_NOTHROW_MESSAGE(expr, __VA_ARGS__) -#define REQUIRE_MESSAGE(cond, ...) DOCTEST_REQUIRE_MESSAGE(cond, __VA_ARGS__) -#define REQUIRE_FALSE_MESSAGE(cond, ...) \ - DOCTEST_REQUIRE_FALSE_MESSAGE(cond, __VA_ARGS__) -#define REQUIRE_THROWS_MESSAGE(expr, ...) \ - DOCTEST_REQUIRE_THROWS_MESSAGE(expr, __VA_ARGS__) -#define REQUIRE_THROWS_AS_MESSAGE(expr, ex, ...) \ - DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_MESSAGE(expr, with, ...) \ - DOCTEST_REQUIRE_THROWS_WITH_MESSAGE(expr, with, __VA_ARGS__) -#define REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, ...) \ - DOCTEST_REQUIRE_THROWS_WITH_AS_MESSAGE(expr, with, ex, __VA_ARGS__) -#define REQUIRE_NOTHROW_MESSAGE(expr, ...) \ - DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, __VA_ARGS__) - -#define SCENARIO(name) DOCTEST_SCENARIO(name) -#define SCENARIO_CLASS(name) DOCTEST_SCENARIO_CLASS(name) -#define SCENARIO_TEMPLATE(name, T, ...) \ - DOCTEST_SCENARIO_TEMPLATE(name, T, __VA_ARGS__) -#define SCENARIO_TEMPLATE_DEFINE(name, T, id) \ - DOCTEST_SCENARIO_TEMPLATE_DEFINE(name, T, id) -#define GIVEN(name) DOCTEST_GIVEN(name) -#define WHEN(name) DOCTEST_WHEN(name) -#define AND_WHEN(name) DOCTEST_AND_WHEN(name) -#define THEN(name) DOCTEST_THEN(name) -#define AND_THEN(name) DOCTEST_AND_THEN(name) - -#define WARN_EQ(...) DOCTEST_WARN_EQ(__VA_ARGS__) -#define CHECK_EQ(...) DOCTEST_CHECK_EQ(__VA_ARGS__) -#define REQUIRE_EQ(...) DOCTEST_REQUIRE_EQ(__VA_ARGS__) -#define WARN_NE(...) DOCTEST_WARN_NE(__VA_ARGS__) -#define CHECK_NE(...) DOCTEST_CHECK_NE(__VA_ARGS__) -#define REQUIRE_NE(...) DOCTEST_REQUIRE_NE(__VA_ARGS__) -#define WARN_GT(...) DOCTEST_WARN_GT(__VA_ARGS__) -#define CHECK_GT(...) DOCTEST_CHECK_GT(__VA_ARGS__) -#define REQUIRE_GT(...) DOCTEST_REQUIRE_GT(__VA_ARGS__) -#define WARN_LT(...) DOCTEST_WARN_LT(__VA_ARGS__) -#define CHECK_LT(...) DOCTEST_CHECK_LT(__VA_ARGS__) -#define REQUIRE_LT(...) DOCTEST_REQUIRE_LT(__VA_ARGS__) -#define WARN_GE(...) DOCTEST_WARN_GE(__VA_ARGS__) -#define CHECK_GE(...) DOCTEST_CHECK_GE(__VA_ARGS__) -#define REQUIRE_GE(...) DOCTEST_REQUIRE_GE(__VA_ARGS__) -#define WARN_LE(...) DOCTEST_WARN_LE(__VA_ARGS__) -#define CHECK_LE(...) DOCTEST_CHECK_LE(__VA_ARGS__) -#define REQUIRE_LE(...) DOCTEST_REQUIRE_LE(__VA_ARGS__) -#define WARN_UNARY(...) DOCTEST_WARN_UNARY(__VA_ARGS__) -#define CHECK_UNARY(...) DOCTEST_CHECK_UNARY(__VA_ARGS__) -#define REQUIRE_UNARY(...) DOCTEST_REQUIRE_UNARY(__VA_ARGS__) -#define WARN_UNARY_FALSE(...) DOCTEST_WARN_UNARY_FALSE(__VA_ARGS__) -#define CHECK_UNARY_FALSE(...) DOCTEST_CHECK_UNARY_FALSE(__VA_ARGS__) -#define REQUIRE_UNARY_FALSE(...) DOCTEST_REQUIRE_UNARY_FALSE(__VA_ARGS__) - -// KEPT FOR BACKWARDS COMPATIBILITY -#define FAST_WARN_EQ(...) DOCTEST_FAST_WARN_EQ(__VA_ARGS__) -#define FAST_CHECK_EQ(...) DOCTEST_FAST_CHECK_EQ(__VA_ARGS__) -#define FAST_REQUIRE_EQ(...) DOCTEST_FAST_REQUIRE_EQ(__VA_ARGS__) -#define FAST_WARN_NE(...) DOCTEST_FAST_WARN_NE(__VA_ARGS__) -#define FAST_CHECK_NE(...) DOCTEST_FAST_CHECK_NE(__VA_ARGS__) -#define FAST_REQUIRE_NE(...) DOCTEST_FAST_REQUIRE_NE(__VA_ARGS__) -#define FAST_WARN_GT(...) DOCTEST_FAST_WARN_GT(__VA_ARGS__) -#define FAST_CHECK_GT(...) DOCTEST_FAST_CHECK_GT(__VA_ARGS__) -#define FAST_REQUIRE_GT(...) DOCTEST_FAST_REQUIRE_GT(__VA_ARGS__) -#define FAST_WARN_LT(...) DOCTEST_FAST_WARN_LT(__VA_ARGS__) -#define FAST_CHECK_LT(...) DOCTEST_FAST_CHECK_LT(__VA_ARGS__) -#define FAST_REQUIRE_LT(...) DOCTEST_FAST_REQUIRE_LT(__VA_ARGS__) -#define FAST_WARN_GE(...) DOCTEST_FAST_WARN_GE(__VA_ARGS__) -#define FAST_CHECK_GE(...) DOCTEST_FAST_CHECK_GE(__VA_ARGS__) -#define FAST_REQUIRE_GE(...) DOCTEST_FAST_REQUIRE_GE(__VA_ARGS__) -#define FAST_WARN_LE(...) DOCTEST_FAST_WARN_LE(__VA_ARGS__) -#define FAST_CHECK_LE(...) DOCTEST_FAST_CHECK_LE(__VA_ARGS__) -#define FAST_REQUIRE_LE(...) DOCTEST_FAST_REQUIRE_LE(__VA_ARGS__) - -#define FAST_WARN_UNARY(...) DOCTEST_FAST_WARN_UNARY(__VA_ARGS__) -#define FAST_CHECK_UNARY(...) DOCTEST_FAST_CHECK_UNARY(__VA_ARGS__) -#define FAST_REQUIRE_UNARY(...) DOCTEST_FAST_REQUIRE_UNARY(__VA_ARGS__) -#define FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_WARN_UNARY_FALSE(__VA_ARGS__) -#define FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_CHECK_UNARY_FALSE(__VA_ARGS__) -#define FAST_REQUIRE_UNARY_FALSE(...) \ - DOCTEST_FAST_REQUIRE_UNARY_FALSE(__VA_ARGS__) - -#define TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, __VA_ARGS__) - -#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES - -#ifndef DOCTEST_CONFIG_DISABLE - -// this is here to clear the 'current test suite' for the current translation -// unit - at the top -DOCTEST_TEST_SUITE_END(); - -#endif // DOCTEST_CONFIG_DISABLE - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -DOCTEST_SUPPRESS_COMMON_WARNINGS_POP - -#endif // DOCTEST_LIBRARY_INCLUDED - -#ifndef DOCTEST_SINGLE_HEADER -#define DOCTEST_SINGLE_HEADER -#endif // DOCTEST_SINGLE_HEADER - -#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER) - -#ifndef DOCTEST_SINGLE_HEADER -#include "doctest_fwd.h" -#endif // DOCTEST_SINGLE_HEADER - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wunused-macros") - -#ifndef DOCTEST_LIBRARY_IMPLEMENTATION -#define DOCTEST_LIBRARY_IMPLEMENTATION - -DOCTEST_CLANG_SUPPRESS_WARNING_POP - -DOCTEST_SUPPRESS_COMMON_WARNINGS_PUSH - -DOCTEST_CLANG_SUPPRESS_WARNING_PUSH -DOCTEST_CLANG_SUPPRESS_WARNING("-Wglobal-constructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wexit-time-destructors") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wshorten-64-to-32") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-variable-declarations") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wcovered-switch-default") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-noreturn") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wdisabled-macro-expansion") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wunused-member-function") -DOCTEST_CLANG_SUPPRESS_WARNING("-Wnonportable-system-include-path") - -DOCTEST_GCC_SUPPRESS_WARNING_PUSH -DOCTEST_GCC_SUPPRESS_WARNING("-Wconversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsign-conversion") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-field-initializers") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-braces") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-enum") -DOCTEST_GCC_SUPPRESS_WARNING("-Wswitch-default") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunsafe-loop-optimizations") -DOCTEST_GCC_SUPPRESS_WARNING("-Wold-style-cast") -DOCTEST_GCC_SUPPRESS_WARNING("-Wunused-function") -DOCTEST_GCC_SUPPRESS_WARNING("-Wmultiple-inheritance") -DOCTEST_GCC_SUPPRESS_WARNING("-Wsuggest-attribute") - -DOCTEST_MSVC_SUPPRESS_WARNING_PUSH -DOCTEST_MSVC_SUPPRESS_WARNING( - 4267) // 'var' : conversion from 'x' to 'y', possible loss of data -DOCTEST_MSVC_SUPPRESS_WARNING( - 4530) // C++ exception handler used, but unwind semantics not enabled -DOCTEST_MSVC_SUPPRESS_WARNING( - 4577) // 'noexcept' used with no exception handling mode specified -DOCTEST_MSVC_SUPPRESS_WARNING( - 4774) // format string expected in argument is not a string literal -DOCTEST_MSVC_SUPPRESS_WARNING( - 4365) // conversion from 'int' to 'unsigned', signed/unsigned mismatch -DOCTEST_MSVC_SUPPRESS_WARNING( - 5039) // pointer to potentially throwing function passed to extern C -DOCTEST_MSVC_SUPPRESS_WARNING( - 4800) // forcing value to bool 'true' or 'false' (performance warning) -DOCTEST_MSVC_SUPPRESS_WARNING( - 5245) // unreferenced function with internal linkage has been removed - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN - -// required includes - will go only in one translation unit! -#include -#include -#include -// borland (Embarcadero) compiler requires math.h and not cmath - -// https://github.com/doctest/doctest/pull/37 -#ifdef __BORLANDC__ -#include -#endif // __BORLANDC__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef DOCTEST_CONFIG_NO_MULTITHREADING -#include -#include -#define DOCTEST_DECLARE_MUTEX(name) std::mutex name; -#define DOCTEST_DECLARE_STATIC_MUTEX(name) static DOCTEST_DECLARE_MUTEX(name) -#define DOCTEST_LOCK_MUTEX(name) \ - std::lock_guard DOCTEST_ANONYMOUS(DOCTEST_ANON_LOCK_)(name); -#else // DOCTEST_CONFIG_NO_MULTITHREADING -#define DOCTEST_DECLARE_MUTEX(name) -#define DOCTEST_DECLARE_STATIC_MUTEX(name) -#define DOCTEST_LOCK_MUTEX(name) -#endif // DOCTEST_CONFIG_NO_MULTITHREADING -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef DOCTEST_PLATFORM_MAC -#include -#include -#include -#endif // DOCTEST_PLATFORM_MAC - -#ifdef DOCTEST_PLATFORM_WINDOWS - -// defines for a leaner windows.h -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif // WIN32_LEAN_AND_MEAN -#ifndef NOMINMAX -#define NOMINMAX -#endif // NOMINMAX - -// not sure what AfxWin.h is for - here I do what Catch does -#ifdef __AFXDLL -#include -#else -#include -#endif -#include - -#else // DOCTEST_PLATFORM_WINDOWS - -#include -#include - -#endif // DOCTEST_PLATFORM_WINDOWS - -// this is a fix for https://github.com/doctest/doctest/issues/348 -// https://mail.gnome.org/archives/xml/2012-January/msg00000.html -#if !defined(HAVE_UNISTD_H) && !defined(STDOUT_FILENO) -#define STDOUT_FILENO fileno(stdout) -#endif // HAVE_UNISTD_H - -DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END - -// counts the number of elements in a C array -#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) - -#ifdef DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_disabled -#else // DOCTEST_CONFIG_DISABLE -#define DOCTEST_BRANCH_ON_DISABLED(if_disabled, if_not_disabled) if_not_disabled -#endif // DOCTEST_CONFIG_DISABLE - -#ifndef DOCTEST_CONFIG_OPTIONS_PREFIX -#define DOCTEST_CONFIG_OPTIONS_PREFIX "dt-" -#endif - -#ifndef DOCTEST_THREAD_LOCAL -#if defined(DOCTEST_CONFIG_NO_MULTITHREADING) || \ - DOCTEST_MSVC && (DOCTEST_MSVC < DOCTEST_COMPILER(19, 0, 0)) -#define DOCTEST_THREAD_LOCAL -#else // DOCTEST_MSVC -#define DOCTEST_THREAD_LOCAL thread_local -#endif // DOCTEST_MSVC -#endif // DOCTEST_THREAD_LOCAL - -#ifndef DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES -#define DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES 32 -#endif - -#ifndef DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE -#define DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE 64 -#endif - -#ifdef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS -#define DOCTEST_OPTIONS_PREFIX_DISPLAY DOCTEST_CONFIG_OPTIONS_PREFIX -#else -#define DOCTEST_OPTIONS_PREFIX_DISPLAY "" -#endif - -#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) -#define DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS -#endif - -#ifndef DOCTEST_CDECL -#define DOCTEST_CDECL __cdecl -#endif - -namespace doctest { - -bool is_running_in_test = false; - -namespace { -using namespace detail; - -template -DOCTEST_NORETURN void -throw_exception(Ex const& e) -{ -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - throw e; -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - std::cerr - << "doctest will terminate because it needed to throw an exception.\n" - << "The message was: " << e.what() << '\n'; - std::terminate(); -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -} - -#ifndef DOCTEST_INTERNAL_ERROR -#define DOCTEST_INTERNAL_ERROR(msg) \ - throw_exception(std::logic_error( \ - __FILE__ ":" DOCTEST_TOSTR(__LINE__) ": Internal doctest error: " msg)) -#endif // DOCTEST_INTERNAL_ERROR - -// case insensitive strcmp -int -stricmp(const char* a, const char* b) -{ - for (;; a++, b++) { - const int d = tolower(*a) - tolower(*b); - if (d != 0 || !*a) - return d; - } -} - -struct Endianness -{ - enum Arch - { - Big, - Little - }; - - static Arch which() - { - int x = 1; - // casting any data pointer to char* is allowed - auto ptr = reinterpret_cast(&x); - if (*ptr) - return Little; - return Big; - } -}; -} // namespace - -namespace detail { -DOCTEST_THREAD_LOCAL class -{ - std::vector stack; - std::stringstream ss; - -public: - std::ostream* push() - { - stack.push_back(ss.tellp()); - return &ss; - } - - String pop() - { - if (stack.empty()) - DOCTEST_INTERNAL_ERROR("TLSS was empty when trying to pop!"); - - std::streampos pos = stack.back(); - stack.pop_back(); - unsigned sz = static_cast(ss.tellp() - pos); - ss.rdbuf()->pubseekpos(pos, std::ios::in | std::ios::out); - return String(ss, sz); - } -} g_oss; - -std::ostream* -tlssPush() -{ - return g_oss.push(); -} - -String -tlssPop() -{ - return g_oss.pop(); -} - -#ifndef DOCTEST_CONFIG_DISABLE - -namespace timer_large_integer { - -#if defined(DOCTEST_PLATFORM_WINDOWS) -using type = ULONGLONG; -#else // DOCTEST_PLATFORM_WINDOWS -using type = std::uint64_t; -#endif // DOCTEST_PLATFORM_WINDOWS -} - -using ticks_t = timer_large_integer::type; - -#ifdef DOCTEST_CONFIG_GETCURRENTTICKS -ticks_t -getCurrentTicks() -{ - return DOCTEST_CONFIG_GETCURRENTTICKS(); -} -#elif defined(DOCTEST_PLATFORM_WINDOWS) -ticks_t -getCurrentTicks() -{ - static LARGE_INTEGER hz = { { 0 } }, hzo = { { 0 } }; - if (!hz.QuadPart) { - QueryPerformanceFrequency(&hz); - QueryPerformanceCounter(&hzo); - } - LARGE_INTEGER t; - QueryPerformanceCounter(&t); - return ((t.QuadPart - hzo.QuadPart) * LONGLONG(1000000)) / hz.QuadPart; -} -#else // DOCTEST_PLATFORM_WINDOWS -ticks_t -getCurrentTicks() -{ - timeval t; - gettimeofday(&t, nullptr); - return static_cast(t.tv_sec) * 1000000 + - static_cast(t.tv_usec); -} -#endif // DOCTEST_PLATFORM_WINDOWS - -struct Timer -{ - void start() { m_ticks = getCurrentTicks(); } - unsigned int getElapsedMicroseconds() const - { - return static_cast(getCurrentTicks() - m_ticks); - } - // unsigned int getElapsedMilliseconds() const { - // return static_cast(getElapsedMicroseconds() / 1000); - // } - double getElapsedSeconds() const - { - return static_cast(getCurrentTicks() - m_ticks) / 1000000.0; - } - -private: - ticks_t m_ticks = 0; -}; - -#ifdef DOCTEST_CONFIG_NO_MULTITHREADING -template -using Atomic = T; -#else // DOCTEST_CONFIG_NO_MULTITHREADING -template -using Atomic = std::atomic; -#endif // DOCTEST_CONFIG_NO_MULTITHREADING - -#if defined(DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) || \ - defined(DOCTEST_CONFIG_NO_MULTITHREADING) -template -using MultiLaneAtomic = Atomic; -#else // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS -// Provides a multilane implementation of an atomic variable that supports add, -// sub, load, store. Instead of using a single atomic variable, this splits up -// into multiple ones, each sitting on a separate cache line. The goal is to -// provide a speedup when most operations are modifying. It achieves this with -// two properties: -// -// * Multiple atomics are used, so chance of congestion from the same atomic is -// reduced. -// * Each atomic sits on a separate cache line, so false sharing is reduced. -// -// The disadvantage is that there is a small overhead due to the use of TLS, and -// load/store is slower because all atomics have to be accessed. -template -class MultiLaneAtomic -{ - struct CacheLineAlignedAtomic - { - Atomic atomic{}; - char - padding[DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE - sizeof(Atomic)]; - }; - CacheLineAlignedAtomic m_atomics[DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES]; - - static_assert(sizeof(CacheLineAlignedAtomic) == - DOCTEST_MULTI_LANE_ATOMICS_CACHE_LINE_SIZE, - "guarantee one atomic takes exactly one cache line"); - -public: - T operator++() DOCTEST_NOEXCEPT { return fetch_add(1) + 1; } - - T operator++(int) DOCTEST_NOEXCEPT { return fetch_add(1); } - - T fetch_add(T arg, std::memory_order order = std::memory_order_seq_cst) - DOCTEST_NOEXCEPT - { - return myAtomic().fetch_add(arg, order); - } - - T fetch_sub(T arg, std::memory_order order = std::memory_order_seq_cst) - DOCTEST_NOEXCEPT - { - return myAtomic().fetch_sub(arg, order); - } - - operator T() const DOCTEST_NOEXCEPT { return load(); } - - T load(std::memory_order order = std::memory_order_seq_cst) const - DOCTEST_NOEXCEPT - { - auto result = T(); - for (auto const& c : m_atomics) { - result += c.atomic.load(order); - } - return result; - } - - T operator=(T desired) DOCTEST_NOEXCEPT - { // lgtm [cpp/assignment-does-not-return-this] - store(desired); - return desired; - } - - void store(T desired, std::memory_order order = std::memory_order_seq_cst) - DOCTEST_NOEXCEPT - { - // first value becomes desired", all others become 0. - for (auto& c : m_atomics) { - c.atomic.store(desired, order); - desired = {}; - } - } - -private: - // Each thread has a different atomic that it operates on. If more than - // NumLanes threads use this, some will use the same atomic. So performance - // will degrade a bit, but still everything will work. - // - // The logic here is a bit tricky. The call should be as fast as possible, so - // that there is minimal to no overhead in determining the correct atomic for - // the current thread. - // - // 1. A global static counter laneCounter counts continuously up. - // 2. Each successive thread will use modulo operation of that counter so it - // gets an atomic - // assigned in a round-robin fashion. - // 3. This tlsLaneIdx is stored in the thread local data, so it is directly - // available with - // little overhead. - Atomic& myAtomic() DOCTEST_NOEXCEPT - { - static Atomic laneCounter; - DOCTEST_THREAD_LOCAL size_t tlsLaneIdx = - laneCounter++ % DOCTEST_MULTI_LANE_ATOMICS_THREAD_LANES; - - return m_atomics[tlsLaneIdx].atomic; - } -}; -#endif // DOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS - -// this holds both parameters from the command line and runtime data for tests -struct ContextState - : ContextOptions - , TestRunStats - , CurrentTestCaseStats -{ - MultiLaneAtomic numAssertsCurrentTest_atomic; - MultiLaneAtomic numAssertsFailedCurrentTest_atomic; - - std::vector> filters = - decltype(filters)(9); // 9 different filters - - std::vector reporters_currently_used; - - assert_handler ah = nullptr; - - Timer timer; - - std::vector - stringifiedContexts; // logging from INFO() due to an exception - - // stuff for subcases - bool reachedLeaf; - std::vector subcaseStack; - std::vector nextSubcaseStack; - std::unordered_set fullyTraversedSubcases; - size_t currentSubcaseDepth; - Atomic shouldLogCurrentException; - - void resetRunData() - { - numTestCases = 0; - numTestCasesPassingFilters = 0; - numTestSuitesPassingFilters = 0; - numTestCasesFailed = 0; - numAsserts = 0; - numAssertsFailed = 0; - numAssertsCurrentTest = 0; - numAssertsFailedCurrentTest = 0; - } - - void finalizeTestCaseData() - { - seconds = timer.getElapsedSeconds(); - - // update the non-atomic counters - numAsserts += numAssertsCurrentTest_atomic; - numAssertsFailed += numAssertsFailedCurrentTest_atomic; - numAssertsCurrentTest = numAssertsCurrentTest_atomic; - numAssertsFailedCurrentTest = numAssertsFailedCurrentTest_atomic; - - if (numAssertsFailedCurrentTest) - failure_flags |= TestCaseFailureReason::AssertFailure; - - if (Approx(currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 && - Approx(seconds).epsilon(DBL_EPSILON) > currentTest->m_timeout) - failure_flags |= TestCaseFailureReason::Timeout; - - if (currentTest->m_should_fail) { - if (failure_flags) { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedAndDid; - } else { - failure_flags |= TestCaseFailureReason::ShouldHaveFailedButDidnt; - } - } else if (failure_flags && currentTest->m_may_fail) { - failure_flags |= TestCaseFailureReason::CouldHaveFailedAndDid; - } else if (currentTest->m_expected_failures > 0) { - if (numAssertsFailedCurrentTest == currentTest->m_expected_failures) { - failure_flags |= TestCaseFailureReason::FailedExactlyNumTimes; - } else { - failure_flags |= TestCaseFailureReason::DidntFailExactlyNumTimes; - } - } - - bool ok_to_fail = - (TestCaseFailureReason::ShouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::CouldHaveFailedAndDid & failure_flags) || - (TestCaseFailureReason::FailedExactlyNumTimes & failure_flags); - - // if any subcase has failed - the whole test case has failed - testCaseSuccess = !(failure_flags && !ok_to_fail); - if (!testCaseSuccess) - numTestCasesFailed++; - } -}; - -ContextState* g_cs = nullptr; - -// used to avoid locks for the debug output -// TODO: figure out if this is indeed necessary/correct - seems like either -// there still could be a race or that there wouldn't be a race even if using -// the context directly -DOCTEST_THREAD_LOCAL bool g_no_colors; - -#endif // DOCTEST_CONFIG_DISABLE -} // namespace detail - -char* -String::allocate(size_type sz) -{ - if (sz <= last) { - buf[sz] = '\0'; - setLast(last - sz); - return buf; - } else { - setOnHeap(); - data.size = sz; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - data.ptr[sz] = '\0'; - return data.ptr; - } -} - -void -String::setOnHeap() noexcept -{ - *reinterpret_cast(&buf[last]) = 128; -} -void -String::setLast(size_type in) noexcept -{ - buf[last] = char(in); -} -void -String::setSize(size_type sz) noexcept -{ - if (isOnStack()) { - buf[sz] = '\0'; - setLast(last - sz); - } else { - data.ptr[sz] = '\0'; - data.size = sz; - } -} - -void -String::copy(const String& other) -{ - if (other.isOnStack()) { - memcpy(buf, other.buf, len); - } else { - memcpy(allocate(other.data.size), other.data.ptr, other.data.size); - } -} - -String::String() noexcept -{ - buf[0] = '\0'; - setLast(); -} - -String::~String() -{ - if (!isOnStack()) - delete[] data.ptr; -} // NOLINT(clang-analyzer-cplusplus.NewDeleteLeaks) - -String::String(const char* in) - : String(in, strlen(in)) -{ -} - -String::String(const char* in, size_type in_size) -{ - memcpy(allocate(in_size), in, in_size); -} - -String::String(std::istream& in, size_type in_size) -{ - in.read(allocate(in_size), in_size); -} - -String::String(const String& other) -{ - copy(other); -} - -String& -String::operator=(const String& other) -{ - if (this != &other) { - if (!isOnStack()) - delete[] data.ptr; - - copy(other); - } - - return *this; -} - -String& -String::operator+=(const String& other) -{ - const size_type my_old_size = size(); - const size_type other_size = other.size(); - const size_type total_size = my_old_size + other_size; - if (isOnStack()) { - if (total_size < len) { - // append to the current stack space - memcpy(buf + my_old_size, other.c_str(), other_size + 1); - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - setLast(last - total_size); - } else { - // alloc new chunk - char* temp = new char[total_size + 1]; - // copy current data to new location before writing in the union - memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed - // update data in union - setOnHeap(); - data.size = total_size; - data.capacity = data.size + 1; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } else { - if (data.capacity > total_size) { - // append to the current heap block - data.size = total_size; - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } else { - // resize - data.capacity *= 2; - if (data.capacity <= total_size) - data.capacity = total_size + 1; - // alloc new chunk - char* temp = new char[data.capacity]; - // copy current data to new location before releasing it - memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed - // release old chunk - delete[] data.ptr; - // update the rest of the union members - data.size = total_size; - data.ptr = temp; - // transfer the rest of the data - memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } - - return *this; -} - -String::String(String&& other) noexcept -{ - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); -} - -String& -String::operator=(String&& other) noexcept -{ - if (this != &other) { - if (!isOnStack()) - delete[] data.ptr; - memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); - } - return *this; -} - -char -String::operator[](size_type i) const -{ - return const_cast(this)->operator[](i); -} - -char& -String::operator[](size_type i) -{ - if (isOnStack()) - return reinterpret_cast(buf)[i]; - return data.ptr[i]; -} - -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wmaybe-uninitialized") -String::size_type -String::size() const -{ - if (isOnStack()) - return last - (size_type(buf[last]) & - 31); // using "last" would work only if "len" is 32 - return data.size; -} -DOCTEST_GCC_SUPPRESS_WARNING_POP - -String::size_type -String::capacity() const -{ - if (isOnStack()) - return len; - return data.capacity; -} - -String -String::substr(size_type pos, size_type cnt) && -{ - cnt = std::min(cnt, size() - 1 - pos); - char* cptr = c_str(); - memmove(cptr, cptr + pos, cnt); - setSize(cnt); - return std::move(*this); -} - -String -String::substr(size_type pos, size_type cnt) const& -{ - cnt = std::min(cnt, size() - 1 - pos); - return String{ c_str() + pos, cnt }; -} - -String::size_type -String::find(char ch, size_type pos) const -{ - const char* begin = c_str(); - const char* end = begin + size(); - const char* it = begin + pos; - for (; it < end && *it != ch; it++) - ; - if (it < end) { - return static_cast(it - begin); - } else { - return npos; - } -} - -String::size_type -String::rfind(char ch, size_type pos) const -{ - const char* begin = c_str(); - const char* it = begin + std::min(pos, size() - 1); - for (; it >= begin && *it != ch; it--) - ; - if (it >= begin) { - return static_cast(it - begin); - } else { - return npos; - } -} - -int -String::compare(const char* other, bool no_case) const -{ - if (no_case) - return doctest::stricmp(c_str(), other); - return std::strcmp(c_str(), other); -} - -int -String::compare(const String& other, bool no_case) const -{ - return compare(other.c_str(), no_case); -} - -String -operator+(const String& lhs, const String& rhs) -{ - return String(lhs) += rhs; -} - -bool -operator==(const String& lhs, const String& rhs) -{ - return lhs.compare(rhs) == 0; -} -bool -operator!=(const String& lhs, const String& rhs) -{ - return lhs.compare(rhs) != 0; -} -bool -operator<(const String& lhs, const String& rhs) -{ - return lhs.compare(rhs) < 0; -} -bool -operator>(const String& lhs, const String& rhs) -{ - return lhs.compare(rhs) > 0; -} -bool -operator<=(const String& lhs, const String& rhs) -{ - return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; -} -bool -operator>=(const String& lhs, const String& rhs) -{ - return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; -} - -std::ostream& -operator<<(std::ostream& s, const String& in) -{ - return s << in.c_str(); -} - -Contains::Contains(const String& str) - : string(str) -{ -} - -bool -Contains::checkWith(const String& other) const -{ - return strstr(other.c_str(), string.c_str()) != nullptr; -} - -String -toString(const Contains& in) -{ - return "Contains( " + in.string + " )"; -} - -bool -operator==(const String& lhs, const Contains& rhs) -{ - return rhs.checkWith(lhs); -} -bool -operator==(const Contains& lhs, const String& rhs) -{ - return lhs.checkWith(rhs); -} -bool -operator!=(const String& lhs, const Contains& rhs) -{ - return !rhs.checkWith(lhs); -} -bool -operator!=(const Contains& lhs, const String& rhs) -{ - return !lhs.checkWith(rhs); -} - -namespace { -void -color_to_stream(std::ostream&, Color::Enum) DOCTEST_BRANCH_ON_DISABLED({}, ;) -} // namespace - -namespace Color { -std::ostream& -operator<<(std::ostream& s, Color::Enum code) -{ - color_to_stream(s, code); - return s; -} -} // namespace Color - -// clang-format off -const char* assertString(assertType::Enum at) { - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4061) // enum 'x' in switch of enum 'y' is not explicitely handled - #define DOCTEST_GENERATE_ASSERT_TYPE_CASE(assert_type) case assertType::DT_ ## assert_type: return #assert_type - #define DOCTEST_GENERATE_ASSERT_TYPE_CASES(assert_type) \ - DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN_ ## assert_type); \ - DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK_ ## assert_type); \ - DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE_ ## assert_type) - switch(at) { - DOCTEST_GENERATE_ASSERT_TYPE_CASE(WARN); - DOCTEST_GENERATE_ASSERT_TYPE_CASE(CHECK); - DOCTEST_GENERATE_ASSERT_TYPE_CASE(REQUIRE); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(FALSE); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_AS); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(THROWS_WITH_AS); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(NOTHROW); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(EQ); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(NE); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(GT); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(LT); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(GE); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(LE); - - DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY); - DOCTEST_GENERATE_ASSERT_TYPE_CASES(UNARY_FALSE); - - default: DOCTEST_INTERNAL_ERROR("Tried stringifying invalid assert type!"); - } - DOCTEST_MSVC_SUPPRESS_WARNING_POP -} -// clang-format on - -const char* -failureString(assertType::Enum at) -{ - if (at & assertType::is_warn) //! OCLINT bitwise operator in conditional - return "WARNING"; - if (at & assertType::is_check) //! OCLINT bitwise operator in conditional - return "ERROR"; - if (at & assertType::is_require) //! OCLINT bitwise operator in conditional - return "FATAL ERROR"; - return ""; -} - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wnull-dereference") -// depending on the current options this will remove the path of filenames -const char* -skipPathFromFilename(const char* file) -{ -#ifndef DOCTEST_CONFIG_DISABLE - if (getContextOptions()->no_path_in_filenames) { - auto back = std::strrchr(file, '\\'); - auto forward = std::strrchr(file, '/'); - if (back || forward) { - if (back > forward) - forward = back; - return forward + 1; - } - } -#endif // DOCTEST_CONFIG_DISABLE - return file; -} -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -bool -SubcaseSignature::operator==(const SubcaseSignature& other) const -{ - return m_line == other.m_line && std::strcmp(m_file, other.m_file) == 0 && - m_name == other.m_name; -} - -bool -SubcaseSignature::operator<(const SubcaseSignature& other) const -{ - if (m_line != other.m_line) - return m_line < other.m_line; - if (std::strcmp(m_file, other.m_file) != 0) - return std::strcmp(m_file, other.m_file) < 0; - return m_name.compare(other.m_name) < 0; -} - -DOCTEST_DEFINE_INTERFACE(IContextScope) - -namespace detail { -void -filldata::fill(std::ostream* stream, const void* in) -{ - if (in) { - *stream << in; - } else { - *stream << "nullptr"; - } -} - -template -String -toStreamLit(T t) -{ - std::ostream* os = tlssPush(); - os->operator<<(t); - return tlssPop(); -} -} - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String -toString(const char* in) -{ - return String("\"") + (in ? in : "{null string}") + "\""; -} -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - -#if DOCTEST_MSVC >= DOCTEST_COMPILER(19, 20, 0) -// see this issue on why this is needed: -// https://github.com/doctest/doctest/issues/183 -String -toString(const std::string& in) -{ - return in.c_str(); -} -#endif // VS 2019 - -String -toString(String in) -{ - return in; -} - -String -toString(std::nullptr_t) -{ - return "nullptr"; -} - -String -toString(bool in) -{ - return in ? "true" : "false"; -} - -String -toString(float in) -{ - return toStreamLit(in); -} -String -toString(double in) -{ - return toStreamLit(in); -} -String -toString(double long in) -{ - return toStreamLit(in); -} - -String -toString(char in) -{ - return toStreamLit(static_cast(in)); -} -String -toString(char signed in) -{ - return toStreamLit(static_cast(in)); -} -String -toString(char unsigned in) -{ - return toStreamLit(static_cast(in)); -} -String -toString(short in) -{ - return toStreamLit(in); -} -String -toString(short unsigned in) -{ - return toStreamLit(in); -} -String -toString(signed in) -{ - return toStreamLit(in); -} -String -toString(unsigned in) -{ - return toStreamLit(in); -} -String -toString(long in) -{ - return toStreamLit(in); -} -String -toString(long unsigned in) -{ - return toStreamLit(in); -} -String -toString(long long in) -{ - return toStreamLit(in); -} -String -toString(long long unsigned in) -{ - return toStreamLit(in); -} - -Approx::Approx(double value) - : m_epsilon(static_cast(std::numeric_limits::epsilon()) * 100) - , m_scale(1.0) - , m_value(value) -{ -} - -Approx -Approx::operator()(double value) const -{ - Approx approx(value); - approx.epsilon(m_epsilon); - approx.scale(m_scale); - return approx; -} - -Approx& -Approx::epsilon(double newEpsilon) -{ - m_epsilon = newEpsilon; - return *this; -} -Approx& -Approx::scale(double newScale) -{ - m_scale = newScale; - return *this; -} - -bool -operator==(double lhs, const Approx& rhs) -{ - // Thanks to Richard Harris for his help refining this formula - return std::fabs(lhs - rhs.m_value) < - rhs.m_epsilon * - (rhs.m_scale + - std::max(std::fabs(lhs), std::fabs(rhs.m_value))); -} -bool -operator==(const Approx& lhs, double rhs) -{ - return operator==(rhs, lhs); -} -bool -operator!=(double lhs, const Approx& rhs) -{ - return !operator==(lhs, rhs); -} -bool -operator!=(const Approx& lhs, double rhs) -{ - return !operator==(rhs, lhs); -} -bool -operator<=(double lhs, const Approx& rhs) -{ - return lhs < rhs.m_value || lhs == rhs; -} -bool -operator<=(const Approx& lhs, double rhs) -{ - return lhs.m_value < rhs || lhs == rhs; -} -bool -operator>=(double lhs, const Approx& rhs) -{ - return lhs > rhs.m_value || lhs == rhs; -} -bool -operator>=(const Approx& lhs, double rhs) -{ - return lhs.m_value > rhs || lhs == rhs; -} -bool -operator<(double lhs, const Approx& rhs) -{ - return lhs < rhs.m_value && lhs != rhs; -} -bool -operator<(const Approx& lhs, double rhs) -{ - return lhs.m_value < rhs && lhs != rhs; -} -bool -operator>(double lhs, const Approx& rhs) -{ - return lhs > rhs.m_value && lhs != rhs; -} -bool -operator>(const Approx& lhs, double rhs) -{ - return lhs.m_value > rhs && lhs != rhs; -} - -String -toString(const Approx& in) -{ - return "Approx( " + doctest::toString(in.m_value) + " )"; -} -const ContextOptions* -getContextOptions() -{ - return DOCTEST_BRANCH_ON_DISABLED(nullptr, g_cs); -} - -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4738) -template -IsNaN:: -operator bool() const -{ - return std::isnan(value) ^ flipped; -} -DOCTEST_MSVC_SUPPRESS_WARNING_POP -template struct DOCTEST_INTERFACE_DEF IsNaN; -template struct DOCTEST_INTERFACE_DEF IsNaN; -template struct DOCTEST_INTERFACE_DEF IsNaN; -template -String -toString(IsNaN in) -{ - return String(in.flipped ? "! " : "") + "IsNaN( " + - doctest::toString(in.value) + " )"; -} -String -toString(IsNaN in) -{ - return toString(in); -} -String -toString(IsNaN in) -{ - return toString(in); -} -String -toString(IsNaN in) -{ - return toString(in); -} - -} // namespace doctest - -#ifdef DOCTEST_CONFIG_DISABLE -namespace doctest { -Context::Context(int, const char* const*) {} -Context::~Context() = default; -void -Context::applyCommandLine(int, const char* const*) -{ -} -void -Context::addFilter(const char*, const char*) -{ -} -void -Context::clearFilters() -{ -} -void -Context::setOption(const char*, bool) -{ -} -void -Context::setOption(const char*, int) -{ -} -void -Context::setOption(const char*, const char*) -{ -} -bool -Context::shouldExit() -{ - return false; -} -void -Context::setAsDefaultForAssertsOutOfTestCases() -{ -} -void -Context::setAssertHandler(detail::assert_handler) -{ -} -void -Context::setCout(std::ostream*) -{ -} -int -Context::run() -{ - return 0; -} - -int -IReporter::get_num_active_contexts() -{ - return 0; -} -const IContextScope* const* -IReporter::get_active_contexts() -{ - return nullptr; -} -int -IReporter::get_num_stringified_contexts() -{ - return 0; -} -const String* -IReporter::get_stringified_contexts() -{ - return nullptr; -} - -int -registerReporter(const char*, int, IReporter*) -{ - return 0; -} - -} // namespace doctest -#else // DOCTEST_CONFIG_DISABLE - -#if !defined(DOCTEST_CONFIG_COLORS_NONE) -#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && \ - !defined(DOCTEST_CONFIG_COLORS_ANSI) -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_CONFIG_COLORS_WINDOWS -#else // linux -#define DOCTEST_CONFIG_COLORS_ANSI -#endif // platform -#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI -#endif // DOCTEST_CONFIG_COLORS_NONE - -namespace doctest_detail_test_suite_ns { -// holds the current test suite -doctest::detail::TestSuite& -getCurrentTestSuite() -{ - static doctest::detail::TestSuite data{}; - return data; -} -} // namespace doctest_detail_test_suite_ns - -namespace doctest { -namespace { -// the int (priority) is part of the key for automatic sorting - sadly one can -// register a reporter with a duplicate name and a different priority but -// hopefully that won't happen often :| -using reporterMap = std::map, reporterCreatorFunc>; - -reporterMap& -getReporters() -{ - static reporterMap data; - return data; -} -reporterMap& -getListeners() -{ - static reporterMap data; - return data; -} -} // namespace -namespace detail { -#define DOCTEST_ITERATE_THROUGH_REPORTERS(function, ...) \ - for (auto& curr_rep : g_cs->reporters_currently_used) \ - curr_rep->function(__VA_ARGS__) - -bool -checkIfShouldThrow(assertType::Enum at) -{ - if (at & assertType::is_require) //! OCLINT bitwise operator in conditional - return true; - - if ((at & assertType::is_check) //! OCLINT bitwise operator in conditional - && getContextOptions()->abort_after > 0 && - (g_cs->numAssertsFailed + g_cs->numAssertsFailedCurrentTest_atomic) >= - getContextOptions()->abort_after) - return true; - - return false; -} - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -DOCTEST_NORETURN void -throwException() -{ - g_cs->shouldLogCurrentException = false; - throw TestFailureException(); // NOLINT(hicpp-exception-baseclass) -} -#else // DOCTEST_CONFIG_NO_EXCEPTIONS -void -throwException() -{ -} -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -} // namespace detail - -namespace { -using namespace detail; -// matching of a string against a wildcard mask (case sensitivity configurable) -// taken from -// https://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing -int -wildcmp(const char* str, const char* wild, bool caseSensitive) -{ - const char* cp = str; - const char* mp = wild; - - while ((*str) && (*wild != '*')) { - if ((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && - (*wild != '?')) { - return 0; - } - wild++; - str++; - } - - while (*str) { - if (*wild == '*') { - if (!*++wild) { - return 1; - } - mp = wild; - cp = str + 1; - } else if ((caseSensitive ? (*wild == *str) - : (tolower(*wild) == tolower(*str))) || - (*wild == '?')) { - wild++; - str++; - } else { - wild = mp; //! OCLINT parameter reassignment - str = cp++; //! OCLINT parameter reassignment - } - } - - while (*wild == '*') { - wild++; - } - return !*wild; -} - -// checks if the name matches any of the filters (and can be configured what to -// do when empty) -bool -matchesAny(const char* name, - const std::vector& filters, - bool matchEmpty, - bool caseSensitive) -{ - if (filters.empty() && matchEmpty) - return true; - for (auto& curr : filters) - if (wildcmp(name, curr.c_str(), caseSensitive)) - return true; - return false; -} - -unsigned long long -hash(unsigned long long a, unsigned long long b) -{ - return (a << 5) + b; -} - -// C string hash function (djb2) - taken from -// http://www.cse.yorku.ca/~oz/hash.html -unsigned long long -hash(const char* str) -{ - unsigned long long hash = 5381; - char c; - while ((c = *str++)) - hash = ((hash << 5) + hash) + c; // hash * 33 + c - return hash; -} - -unsigned long long -hash(const SubcaseSignature& sig) -{ - return hash(hash(hash(sig.m_file), hash(sig.m_name.c_str())), sig.m_line); -} - -unsigned long long -hash(const std::vector& sigs, size_t count) -{ - unsigned long long running = 0; - auto end = sigs.begin() + count; - for (auto it = sigs.begin(); it != end; it++) { - running = hash(running, hash(*it)); - } - return running; -} - -unsigned long long -hash(const std::vector& sigs) -{ - unsigned long long running = 0; - for (const SubcaseSignature& sig : sigs) { - running = hash(running, hash(sig)); - } - return running; -} -} // namespace -namespace detail { -bool -Subcase::checkFilters() -{ - if (g_cs->subcaseStack.size() < size_t(g_cs->subcase_filter_levels)) { - if (!matchesAny(m_signature.m_name.c_str(), - g_cs->filters[6], - true, - g_cs->case_sensitive)) - return true; - if (matchesAny(m_signature.m_name.c_str(), - g_cs->filters[7], - false, - g_cs->case_sensitive)) - return true; - } - return false; -} - -Subcase::Subcase(const String& name, const char* file, int line) - : m_signature({ name, file, line }) -{ - if (!g_cs->reachedLeaf) { - if (g_cs->nextSubcaseStack.size() <= g_cs->subcaseStack.size() || - g_cs->nextSubcaseStack[g_cs->subcaseStack.size()] == m_signature) { - // Going down. - if (checkFilters()) { - return; - } - - g_cs->subcaseStack.push_back(m_signature); - g_cs->currentSubcaseDepth++; - m_entered = true; - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); - } - } else { - if (g_cs->subcaseStack[g_cs->currentSubcaseDepth] == m_signature) { - // This subcase is reentered via control flow. - g_cs->currentSubcaseDepth++; - m_entered = true; - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_start, m_signature); - } else if (g_cs->nextSubcaseStack.size() <= g_cs->currentSubcaseDepth && - g_cs->fullyTraversedSubcases.find(hash( - hash(g_cs->subcaseStack, g_cs->currentSubcaseDepth), - hash(m_signature))) == g_cs->fullyTraversedSubcases.end()) { - if (checkFilters()) { - return; - } - // This subcase is part of the one to be executed next. - g_cs->nextSubcaseStack.clear(); - g_cs->nextSubcaseStack.insert(g_cs->nextSubcaseStack.end(), - g_cs->subcaseStack.begin(), - g_cs->subcaseStack.begin() + - g_cs->currentSubcaseDepth); - g_cs->nextSubcaseStack.push_back(m_signature); - } - } -} - -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH( - 4996) // std::uncaught_exception is deprecated in C++17 -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - -Subcase::~Subcase() -{ - if (m_entered) { - g_cs->currentSubcaseDepth--; - - if (!g_cs->reachedLeaf) { - // Leaf. - g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack)); - g_cs->nextSubcaseStack.clear(); - g_cs->reachedLeaf = true; - } else if (g_cs->nextSubcaseStack.empty()) { - // All children are finished. - g_cs->fullyTraversedSubcases.insert(hash(g_cs->subcaseStack)); - } - -#if defined(__cpp_lib_uncaught_exceptions) && \ - __cpp_lib_uncaught_exceptions >= 201411L && \ - (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || \ - __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) - if (std::uncaught_exceptions() > 0 -#else - if (std::uncaught_exception() -#endif - && g_cs->shouldLogCurrentException) { - DOCTEST_ITERATE_THROUGH_REPORTERS( - test_case_exception, - { "exception thrown in subcase - will translate later " - "when the whole test case has been exited (cannot " - "translate while there is an active exception)", - false }); - g_cs->shouldLogCurrentException = false; - } - - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - } -} - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -Subcase:: -operator bool() const -{ - return m_entered; -} - -Result::Result(bool passed, const String& decomposition) - : m_passed(passed) - , m_decomp(decomposition) -{ -} - -ExpressionDecomposer::ExpressionDecomposer(assertType::Enum at) - : m_at(at) -{ -} - -TestSuite& -TestSuite::operator*(const char* in) -{ - m_test_suite = in; - return *this; -} - -TestCase::TestCase(funcType test, - const char* file, - unsigned line, - const TestSuite& test_suite, - const String& type, - int template_id) -{ - m_file = file; - m_line = line; - m_name = nullptr; // will be later overridden in operator* - m_test_suite = test_suite.m_test_suite; - m_description = test_suite.m_description; - m_skip = test_suite.m_skip; - m_no_breaks = test_suite.m_no_breaks; - m_no_output = test_suite.m_no_output; - m_may_fail = test_suite.m_may_fail; - m_should_fail = test_suite.m_should_fail; - m_expected_failures = test_suite.m_expected_failures; - m_timeout = test_suite.m_timeout; - - m_test = test; - m_type = type; - m_template_id = template_id; -} - -TestCase::TestCase(const TestCase& other) - : TestCaseData() -{ - *this = other; -} - -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(26434) // hides a non-virtual function -TestCase& -TestCase::operator=(const TestCase& other) -{ - TestCaseData::operator=(other); - m_test = other.m_test; - m_type = other.m_type; - m_template_id = other.m_template_id; - m_full_name = other.m_full_name; - - if (m_template_id != -1) - m_name = m_full_name.c_str(); - return *this; -} -DOCTEST_MSVC_SUPPRESS_WARNING_POP - -TestCase& -TestCase::operator*(const char* in) -{ - m_name = in; - // make a new name with an appended type for templated test case - if (m_template_id != -1) { - m_full_name = String(m_name) + "<" + m_type + ">"; - // redirect the name to point to the newly constructed full name - m_name = m_full_name.c_str(); - } - return *this; -} - -bool -TestCase::operator<(const TestCase& other) const -{ - // this will be used only to differentiate between test cases - not relevant - // for sorting - if (m_line != other.m_line) - return m_line < other.m_line; - const int name_cmp = strcmp(m_name, other.m_name); - if (name_cmp != 0) - return name_cmp < 0; - const int file_cmp = m_file.compare(other.m_file); - if (file_cmp != 0) - return file_cmp < 0; - return m_template_id < other.m_template_id; -} - -// all the registered tests -std::set& -getRegisteredTests() -{ - static std::set data; - return data; -} -} // namespace detail -namespace { -using namespace detail; -// for sorting tests by file/line -bool -fileOrderComparator(const TestCase* lhs, const TestCase* rhs) -{ - // this is needed because MSVC gives different case for drive letters - // for __FILE__ when evaluated in a header and a source file - const int res = lhs->m_file.compare(rhs->m_file, bool(DOCTEST_MSVC)); - if (res != 0) - return res < 0; - if (lhs->m_line != rhs->m_line) - return lhs->m_line < rhs->m_line; - return lhs->m_template_id < rhs->m_template_id; -} - -// for sorting tests by suite/file/line -bool -suiteOrderComparator(const TestCase* lhs, const TestCase* rhs) -{ - const int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); - if (res != 0) - return res < 0; - return fileOrderComparator(lhs, rhs); -} - -// for sorting tests by name/suite/file/line -bool -nameOrderComparator(const TestCase* lhs, const TestCase* rhs) -{ - const int res = std::strcmp(lhs->m_name, rhs->m_name); - if (res != 0) - return res < 0; - return suiteOrderComparator(lhs, rhs); -} - -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") -void -color_to_stream(std::ostream& s, Color::Enum code) -{ - static_cast( - s); // for DOCTEST_CONFIG_COLORS_NONE or DOCTEST_CONFIG_COLORS_WINDOWS - static_cast(code); // for DOCTEST_CONFIG_COLORS_NONE -#ifdef DOCTEST_CONFIG_COLORS_ANSI - if (g_no_colors || (isatty(STDOUT_FILENO) == false && - getContextOptions()->force_colors == false)) - return; - - auto col = ""; - // clang-format off - switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement - case Color::Red: col = "[0;31m"; break; - case Color::Green: col = "[0;32m"; break; - case Color::Blue: col = "[0;34m"; break; - case Color::Cyan: col = "[0;36m"; break; - case Color::Yellow: col = "[0;33m"; break; - case Color::Grey: col = "[1;30m"; break; - case Color::LightGrey: col = "[0;37m"; break; - case Color::BrightRed: col = "[1;31m"; break; - case Color::BrightGreen: col = "[1;32m"; break; - case Color::BrightWhite: col = "[1;37m"; break; - case Color::Bright: // invalid - case Color::None: - case Color::White: - default: col = "[0m"; - } - // clang-format on - s << "\033" << col; -#endif // DOCTEST_CONFIG_COLORS_ANSI - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - if (g_no_colors || (_isatty(_fileno(stdout)) == false && - getContextOptions()->force_colors == false)) - return; - - static struct ConsoleHelper - { - HANDLE stdoutHandle; - WORD origFgAttrs; - WORD origBgAttrs; - - ConsoleHelper() - { - stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo); - origFgAttrs = - csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | - BACKGROUND_BLUE | BACKGROUND_INTENSITY); - origBgAttrs = - csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | - FOREGROUND_BLUE | FOREGROUND_INTENSITY); - } - } ch; - -#define DOCTEST_SET_ATTR(x) \ - SetConsoleTextAttribute(ch.stdoutHandle, x | ch.origBgAttrs) - - // clang-format off - switch (code) { - case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; - case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; - case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; - case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; - case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; - case Color::Grey: DOCTEST_SET_ATTR(0); break; - case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; - case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; - case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; - case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::None: - case Color::Bright: // invalid - default: DOCTEST_SET_ATTR(ch.origFgAttrs); - } - // clang-format on -#endif // DOCTEST_CONFIG_COLORS_WINDOWS -} -DOCTEST_CLANG_SUPPRESS_WARNING_POP - -std::vector& -getExceptionTranslators() -{ - static std::vector data; - return data; -} - -String -translateActiveException() -{ -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - String res; - auto& translators = getExceptionTranslators(); - for (auto& curr : translators) - if (curr->translate(res)) - return res; - // clang-format off - DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wcatch-value") - try { - throw; - } catch(std::exception& ex) { - return ex.what(); - } catch(std::string& msg) { - return msg.c_str(); - } catch(const char* msg) { - return msg; - } catch(...) { - return "unknown exception"; - } - DOCTEST_GCC_SUPPRESS_WARNING_POP -// clang-format on -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - return ""; -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -} -} // namespace - -namespace detail { -// used by the macros for registering tests -int -regTest(const TestCase& tc) -{ - getRegisteredTests().insert(tc); - return 0; -} - -// sets the current test suite -int -setTestSuite(const TestSuite& ts) -{ - doctest_detail_test_suite_ns::getCurrentTestSuite() = ts; - return 0; -} - -#ifdef DOCTEST_IS_DEBUGGER_ACTIVE -bool -isDebuggerActive() -{ - return DOCTEST_IS_DEBUGGER_ACTIVE(); -} -#else // DOCTEST_IS_DEBUGGER_ACTIVE -#ifdef DOCTEST_PLATFORM_LINUX -class ErrnoGuard -{ -public: - ErrnoGuard() - : m_oldErrno(errno) - { - } - ~ErrnoGuard() { errno = m_oldErrno; } - -private: - int m_oldErrno; -}; -// See the comments in Catch2 for the reasoning behind this implementation: -// https://github.com/catchorg/Catch2/blob/v2.13.1/include/internal/catch_debugger.cpp#L79-L102 -bool -isDebuggerActive() -{ - ErrnoGuard guard; - std::ifstream in("/proc/self/status"); - for (std::string line; std::getline(in, line);) { - static const int PREFIX_LEN = 11; - if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) { - return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; - } - } - return false; -} -#elif defined(DOCTEST_PLATFORM_MAC) -// The following function is taken directly from the following technical note: -// https://developer.apple.com/library/archive/qa/qa1361/_index.html -// Returns true if the current process is being debugged (either -// running under the debugger or has a debugger attached post facto). -bool -isDebuggerActive() -{ - int mib[4]; - kinfo_proc info; - size_t size; - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - info.kp_proc.p_flag = 0; - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - // Call sysctl. - size = sizeof(info); - if (sysctl(mib, DOCTEST_COUNTOF(mib), &info, &size, 0, 0) != 0) { - std::cerr << "\nCall to sysctl failed - unable to determine if debugger is " - "active **\n"; - return false; - } - // We're being debugged if the P_TRACED flag is set. - return ((info.kp_proc.p_flag & P_TRACED) != 0); -} -#elif DOCTEST_MSVC || defined(__MINGW32__) || defined(__MINGW64__) -bool -isDebuggerActive() -{ - return ::IsDebuggerPresent() != 0; -} -#else -bool -isDebuggerActive() -{ - return false; -} -#endif // Platform -#endif // DOCTEST_IS_DEBUGGER_ACTIVE - -void -registerExceptionTranslatorImpl(const IExceptionTranslator* et) -{ - if (std::find(getExceptionTranslators().begin(), - getExceptionTranslators().end(), - et) == getExceptionTranslators().end()) - getExceptionTranslators().push_back(et); -} - -DOCTEST_THREAD_LOCAL std::vector - g_infoContexts; // for logging with INFO() - -ContextScopeBase::ContextScopeBase() -{ - g_infoContexts.push_back(this); -} - -ContextScopeBase::ContextScopeBase(ContextScopeBase&& other) noexcept -{ - if (other.need_to_destroy) { - other.destroy(); - } - other.need_to_destroy = false; - g_infoContexts.push_back(this); -} - -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH( - 4996) // std::uncaught_exception is deprecated in C++17 -DOCTEST_GCC_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") -DOCTEST_CLANG_SUPPRESS_WARNING_WITH_PUSH("-Wdeprecated-declarations") - -// destroy cannot be inlined into the destructor because that would mean calling -// stringify after ContextScope has been destroyed (base class destructors run -// after derived class destructors). Instead, ContextScope calls this method -// directly from its destructor. -void -ContextScopeBase::destroy() -{ -#if defined(__cpp_lib_uncaught_exceptions) && \ - __cpp_lib_uncaught_exceptions >= 201411L && \ - (!defined(__MAC_OS_X_VERSION_MIN_REQUIRED) || \ - __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200) - if (std::uncaught_exceptions() > 0) { -#else - if (std::uncaught_exception()) { -#endif - std::ostringstream s; - this->stringify(&s); - g_cs->stringifiedContexts.push_back(s.str().c_str()); - } - g_infoContexts.pop_back(); -} - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -} // namespace detail -namespace { -using namespace detail; - -#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && \ - !defined(DOCTEST_CONFIG_WINDOWS_SEH) -struct FatalConditionHandler -{ - static void reset() {} - static void allocateAltStackMem() {} - static void freeAltStackMem() {} -}; -#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - -void -reportFatal(const std::string&); - -#ifdef DOCTEST_PLATFORM_WINDOWS - -struct SignalDefs -{ - DWORD id; - const char* name; -}; -// There is no 1-1 mapping between signals and windows exceptions. -// Windows can easily distinguish between SO and SigSegV, -// but SigInt, SigTerm, etc are handled differently. -SignalDefs signalDefs[] = { - { static_cast(EXCEPTION_ILLEGAL_INSTRUCTION), - "SIGILL - Illegal instruction signal" }, - { static_cast(EXCEPTION_STACK_OVERFLOW), "SIGSEGV - Stack overflow" }, - { static_cast(EXCEPTION_ACCESS_VIOLATION), - "SIGSEGV - Segmentation violation signal" }, - { static_cast(EXCEPTION_INT_DIVIDE_BY_ZERO), "Divide by zero error" }, -}; - -struct FatalConditionHandler -{ - static LONG CALLBACK handleException(PEXCEPTION_POINTERS ExceptionInfo) - { - // Multiple threads may enter this filter/handler at once. We want the error - // message to be printed on the console just once no matter how many threads - // have crashed. - DOCTEST_DECLARE_STATIC_MUTEX(mutex) - static bool execute = true; - { - DOCTEST_LOCK_MUTEX(mutex) - if (execute) { - bool reported = false; - for (size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - if (ExceptionInfo->ExceptionRecord->ExceptionCode == - signalDefs[i].id) { - reportFatal(signalDefs[i].name); - reported = true; - break; - } - } - if (reported == false) - reportFatal("Unhandled SEH exception caught"); - if (isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - } - execute = false; - } - std::exit(EXIT_FAILURE); - } - - static void allocateAltStackMem() {} - static void freeAltStackMem() {} - - FatalConditionHandler() - { - isSet = true; - // 32k seems enough for doctest to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - // Register an unhandled exception filter - previousTop = SetUnhandledExceptionFilter(handleException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - - // On Windows uncaught exceptions from another thread, exceptions from - // destructors, or calls to std::terminate are not a SEH exception - - // The terminal handler gets called when: - // - std::terminate is called FROM THE TEST RUNNER THREAD - // - an exception is thrown from a destructor FROM THE TEST RUNNER THREAD - original_terminate_handler = std::get_terminate(); - std::set_terminate([]() DOCTEST_NOEXCEPT { - reportFatal("Terminate handler called"); - if (isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - std::exit(EXIT_FAILURE); // explicitly exit - otherwise the SIGABRT - // handler may be called as well - }); - - // SIGABRT is raised when: - // - std::terminate is called FROM A DIFFERENT THREAD - // - an exception is thrown from a destructor FROM A DIFFERENT THREAD - // - an uncaught exception is thrown FROM A DIFFERENT THREAD - prev_sigabrt_handler = - std::signal(SIGABRT, [](int signal) DOCTEST_NOEXCEPT { - if (signal == SIGABRT) { - reportFatal("SIGABRT - Abort (abnormal termination) signal"); - if (isDebuggerActive() && !g_cs->no_breaks) - DOCTEST_BREAK_INTO_DEBUGGER(); - std::exit(EXIT_FAILURE); - } - }); - - // The following settings are taken from google test, and more - // specifically from UnitTest::Run() inside of gtest.cc - - // the user does not want to see pop-up dialogs about crashes - prev_error_mode_1 = - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); - // This forces the abort message to go to stderr in all circumstances. - prev_error_mode_2 = _set_error_mode(_OUT_TO_STDERR); - // In the debug version, Visual Studio pops up a separate dialog - // offering a choice to debug the aborted program - we want to disable that. - prev_abort_behavior = - _set_abort_behavior(0x0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - // In debug mode, the Windows CRT can crash with an assertion over invalid - // input (e.g. passing an invalid file descriptor). The default handling - // for these assertions is to pop up a dialog and wait for user input. - // Instead ask the CRT to dump such assertions to stderr non-interactively. - prev_report_mode = - _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); - prev_report_file = _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); - } - - static void reset() - { - if (isSet) { - // Unregister handler and restore the old guarantee - SetUnhandledExceptionFilter(previousTop); - SetThreadStackGuarantee(&guaranteeSize); - std::set_terminate(original_terminate_handler); - std::signal(SIGABRT, prev_sigabrt_handler); - SetErrorMode(prev_error_mode_1); - _set_error_mode(prev_error_mode_2); - _set_abort_behavior(prev_abort_behavior, - _WRITE_ABORT_MSG | _CALL_REPORTFAULT); - static_cast(_CrtSetReportMode(_CRT_ASSERT, prev_report_mode)); - static_cast(_CrtSetReportFile(_CRT_ASSERT, prev_report_file)); - isSet = false; - } - } - - ~FatalConditionHandler() { reset(); } - -private: - static UINT prev_error_mode_1; - static int prev_error_mode_2; - static unsigned int prev_abort_behavior; - static int prev_report_mode; - static _HFILE prev_report_file; - static void(DOCTEST_CDECL* prev_sigabrt_handler)(int); - static std::terminate_handler original_terminate_handler; - static bool isSet; - static ULONG guaranteeSize; - static LPTOP_LEVEL_EXCEPTION_FILTER previousTop; -}; - -UINT FatalConditionHandler::prev_error_mode_1; -int FatalConditionHandler::prev_error_mode_2; -unsigned int FatalConditionHandler::prev_abort_behavior; -int FatalConditionHandler::prev_report_mode; -_HFILE FatalConditionHandler::prev_report_file; -void(DOCTEST_CDECL* FatalConditionHandler::prev_sigabrt_handler)(int); -std::terminate_handler FatalConditionHandler::original_terminate_handler; -bool FatalConditionHandler::isSet = false; -ULONG FatalConditionHandler::guaranteeSize = 0; -LPTOP_LEVEL_EXCEPTION_FILTER FatalConditionHandler::previousTop = nullptr; - -#else // DOCTEST_PLATFORM_WINDOWS - -struct SignalDefs -{ - int id; - const char* name; -}; -SignalDefs signalDefs[] = { - { SIGINT, "SIGINT - Terminal interrupt signal" }, - { SIGILL, "SIGILL - Illegal instruction signal" }, - { SIGFPE, "SIGFPE - Floating point error signal" }, - { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, - { SIGTERM, "SIGTERM - Termination request signal" }, - { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } -}; - -struct FatalConditionHandler -{ - static bool isSet; - static struct sigaction oldSigActions[DOCTEST_COUNTOF(signalDefs)]; - static stack_t oldSigStack; - static size_t altStackSize; - static char* altStackMem; - - static void handleSignal(int sig) - { - const char* name = ""; - for (std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - SignalDefs& def = signalDefs[i]; - if (sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise(sig); - } - - static void allocateAltStackMem() { altStackMem = new char[altStackSize]; } - - static void freeAltStackMem() { delete[] altStackMem; } - - FatalConditionHandler() - { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = altStackSize; - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = {}; - sa.sa_handler = handleSignal; - sa.sa_flags = SA_ONSTACK; - for (std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - ~FatalConditionHandler() { reset(); } - static void reset() - { - if (isSet) { - // Set signals back to previous values -- hopefully nobody overwrote them - // in the meantime - for (std::size_t i = 0; i < DOCTEST_COUNTOF(signalDefs); ++i) { - sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); - } - // Return the old stack - sigaltstack(&oldSigStack, nullptr); - isSet = false; - } - } -}; - -bool FatalConditionHandler::isSet = false; -struct sigaction - FatalConditionHandler::oldSigActions[DOCTEST_COUNTOF(signalDefs)] = {}; -stack_t FatalConditionHandler::oldSigStack = {}; -size_t FatalConditionHandler::altStackSize = 4 * SIGSTKSZ; -char* FatalConditionHandler::altStackMem = nullptr; - -#endif // DOCTEST_PLATFORM_WINDOWS -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - -} // namespace - -namespace { -using namespace detail; - -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_OUTPUT_DEBUG_STRING(text) ::OutputDebugStringA(text) -#else -// TODO: integration with XCode and other IDEs -#define DOCTEST_OUTPUT_DEBUG_STRING(text) -#endif // Platform - -void -addAssert(assertType::Enum at) -{ - if ((at & assertType::is_warn) == 0) //! OCLINT bitwise operator in - //! conditional - g_cs->numAssertsCurrentTest_atomic++; -} - -void -addFailedAssert(assertType::Enum at) -{ - if ((at & assertType::is_warn) == 0) //! OCLINT bitwise operator in - //! conditional - g_cs->numAssertsFailedCurrentTest_atomic++; -} - -#if defined(DOCTEST_CONFIG_POSIX_SIGNALS) || defined(DOCTEST_CONFIG_WINDOWS_SEH) -void -reportFatal(const std::string& message) -{ - g_cs->failure_flags |= TestCaseFailureReason::Crash; - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_exception, - { message.c_str(), true }); - - while (g_cs->subcaseStack.size()) { - g_cs->subcaseStack.pop_back(); - DOCTEST_ITERATE_THROUGH_REPORTERS(subcase_end, DOCTEST_EMPTY); - } - - g_cs->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); -} -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH -} // namespace - -AssertData::AssertData(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type, - const StringContains& exception_string) - : m_test_case(g_cs->currentTest) - , m_at(at) - , m_file(file) - , m_line(line) - , m_expr(expr) - , m_failed(true) - , m_threw(false) - , m_threw_as(false) - , m_exception_type(exception_type) - , m_exception_string(exception_string) -{ -#if DOCTEST_MSVC - if (m_expr[0] == - ' ') // this happens when variadic macros are disabled under MSVC - ++m_expr; -#endif // MSVC -} - -namespace detail { -ResultBuilder::ResultBuilder(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type, - const String& exception_string) - : AssertData(at, file, line, expr, exception_type, exception_string) -{ -} - -ResultBuilder::ResultBuilder(assertType::Enum at, - const char* file, - int line, - const char* expr, - const char* exception_type, - const Contains& exception_string) - : AssertData(at, file, line, expr, exception_type, exception_string) -{ -} - -void -ResultBuilder::setResult(const Result& res) -{ - m_decomp = res.m_decomp; - m_failed = !res.m_passed; -} - -void -ResultBuilder::translateException() -{ - m_threw = true; - m_exception = translateActiveException(); -} - -bool -ResultBuilder::log() -{ - if (m_at & assertType::is_throws) { //! OCLINT bitwise operator in conditional - m_failed = !m_threw; - } else if ((m_at & assertType::is_throws_as) && - (m_at & assertType::is_throws_with)) { //! OCLINT - m_failed = !m_threw_as || !m_exception_string.check(m_exception); - } else if (m_at & assertType::is_throws_as) { //! OCLINT bitwise operator in - //! conditional - m_failed = !m_threw_as; - } else if (m_at & assertType::is_throws_with) { //! OCLINT bitwise operator in - //! conditional - m_failed = !m_exception_string.check(m_exception); - } else if (m_at & assertType::is_nothrow) { //! OCLINT bitwise operator in - //! conditional - m_failed = m_threw; - } - - if (m_exception.size()) - m_exception = "\"" + m_exception + "\""; - - if (is_running_in_test) { - addAssert(m_at); - DOCTEST_ITERATE_THROUGH_REPORTERS(log_assert, *this); - - if (m_failed) - addFailedAssert(m_at); - } else if (m_failed) { - failed_out_of_a_testing_context(*this); - } - - return m_failed && isDebuggerActive() && !getContextOptions()->no_breaks && - (g_cs->currentTest == nullptr || - !g_cs->currentTest->m_no_breaks); // break into debugger -} - -void -ResultBuilder::react() const -{ - if (m_failed && checkIfShouldThrow(m_at)) - throwException(); -} - -void -failed_out_of_a_testing_context(const AssertData& ad) -{ - if (g_cs->ah) - g_cs->ah(ad); - else - std::abort(); -} - -bool -decomp_assert(assertType::Enum at, - const char* file, - int line, - const char* expr, - const Result& result) -{ - bool failed = !result.m_passed; - - // ################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK FOR THE - // FAILING ASSERT THIS IS THE EFFECT OF HAVING - // 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ################################################################################### - DOCTEST_ASSERT_OUT_OF_TESTS(result.m_decomp); - DOCTEST_ASSERT_IN_TESTS(result.m_decomp); - return !failed; -} - -MessageBuilder::MessageBuilder(const char* file, - int line, - assertType::Enum severity) -{ - m_stream = tlssPush(); - m_file = file; - m_line = line; - m_severity = severity; -} - -MessageBuilder::~MessageBuilder() -{ - if (!logged) - tlssPop(); -} - -DOCTEST_DEFINE_INTERFACE(IExceptionTranslator) - -bool -MessageBuilder::log() -{ - if (!logged) { - m_string = tlssPop(); - logged = true; - } - - DOCTEST_ITERATE_THROUGH_REPORTERS(log_message, *this); - - const bool isWarn = m_severity & assertType::is_warn; - - // warn is just a message in this context so we don't treat it as an assert - if (!isWarn) { - addAssert(m_severity); - addFailedAssert(m_severity); - } - - return isDebuggerActive() && !getContextOptions()->no_breaks && !isWarn && - (g_cs->currentTest == nullptr || - !g_cs->currentTest->m_no_breaks); // break into debugger -} - -void -MessageBuilder::react() -{ - if (m_severity & - assertType::is_require) //! OCLINT bitwise operator in conditional - throwException(); -} -} // namespace detail -namespace { -using namespace detail; - -// clang-format off - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - - class XmlEncode { - public: - enum ForWhat { ForTextNodes, ForAttributes }; - - XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes ); - - void encodeTo( std::ostream& os ) const; - - friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ); - - private: - std::string m_str; - ForWhat m_forWhat; - }; - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ); - - ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT; - ScopedElement& operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT; - - ~ScopedElement(); - - ScopedElement& writeText( std::string const& text, bool indent = true ); - - template - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer = nullptr; - }; - - XmlWriter( std::ostream& os = std::cout ); - ~XmlWriter(); - - XmlWriter( XmlWriter const& ) = delete; - XmlWriter& operator=( XmlWriter const& ) = delete; - - XmlWriter& startElement( std::string const& name ); - - ScopedElement scopedElement( std::string const& name ); - - XmlWriter& endElement(); - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ); - - XmlWriter& writeAttribute( std::string const& name, const char* attribute ); - - XmlWriter& writeAttribute( std::string const& name, bool attribute ); - - template - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - std::stringstream rss; - rss << attribute; - return writeAttribute( name, rss.str() ); - } - - XmlWriter& writeText( std::string const& text, bool indent = true ); - - //XmlWriter& writeComment( std::string const& text ); - - //void writeStylesheetRef( std::string const& url ); - - //XmlWriter& writeBlankLine(); - - void ensureTagClosed(); - - void writeDeclaration(); - - private: - - void newlineIfNecessary(); - - bool m_tagIsOpen = false; - bool m_needsNewline = false; - std::vector m_tags; - std::string m_indent; - std::ostream& m_os; - }; - -// ================================================================================================= -// The following code has been taken verbatim from Catch2/include/internal/catch_xmlwriter.h/cpp -// This is done so cherry-picking bug fixes is trivial - even the style/formatting is untouched. -// ================================================================================================= - -using uchar = unsigned char; - -namespace { - - size_t trailingBytes(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return 2; - } - if ((c & 0xF0) == 0xE0) { - return 3; - } - if ((c & 0xF8) == 0xF0) { - return 4; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - uint32_t headerValue(unsigned char c) { - if ((c & 0xE0) == 0xC0) { - return c & 0x1F; - } - if ((c & 0xF0) == 0xE0) { - return c & 0x0F; - } - if ((c & 0xF8) == 0xF0) { - return c & 0x07; - } - DOCTEST_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); - } - - void hexEscapeChar(std::ostream& os, unsigned char c) { - std::ios_base::fmtflags f(os.flags()); - os << "\\x" - << std::uppercase << std::hex << std::setfill('0') << std::setw(2) - << static_cast(c); - os.flags(f); - } - -} // anonymous namespace - - XmlEncode::XmlEncode( std::string const& str, ForWhat forWhat ) - : m_str( str ), - m_forWhat( forWhat ) - {} - - void XmlEncode::encodeTo( std::ostream& os ) const { - // Apostrophe escaping not necessary if we always use " to write attributes - // (see: https://www.w3.org/TR/xml/#syntax) - - for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) { - uchar c = m_str[idx]; - switch (c) { - case '<': os << "<"; break; - case '&': os << "&"; break; - - case '>': - // See: https://www.w3.org/TR/xml/#syntax - if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') - os << ">"; - else - os << c; - break; - - case '\"': - if (m_forWhat == ForAttributes) - os << """; - else - os << c; - break; - - default: - // Check for control characters and invalid utf-8 - - // Escape control characters in standard ascii - // see https://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 - if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { - hexEscapeChar(os, c); - break; - } - - // Plain ASCII: Write it to stream - if (c < 0x7F) { - os << c; - break; - } - - // UTF-8 territory - // Check if the encoding is valid and if it is not, hex escape bytes. - // Important: We do not check the exact decoded values for validity, only the encoding format - // First check that this bytes is a valid lead byte: - // This means that it is not encoded as 1111 1XXX - // Or as 10XX XXXX - if (c < 0xC0 || - c >= 0xF8) { - hexEscapeChar(os, c); - break; - } - - auto encBytes = trailingBytes(c); - // Are there enough bytes left to avoid accessing out-of-bounds memory? - if (idx + encBytes - 1 >= m_str.size()) { - hexEscapeChar(os, c); - break; - } - // The header is valid, check data - // The next encBytes bytes must together be a valid utf-8 - // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) - bool valid = true; - uint32_t value = headerValue(c); - for (std::size_t n = 1; n < encBytes; ++n) { - uchar nc = m_str[idx + n]; - valid &= ((nc & 0xC0) == 0x80); - value = (value << 6) | (nc & 0x3F); - } - - if ( - // Wrong bit pattern of following bytes - (!valid) || - // Overlong encodings - (value < 0x80) || - ( value < 0x800 && encBytes > 2) || // removed "0x80 <= value &&" because redundant - (0x800 < value && value < 0x10000 && encBytes > 3) || - // Encoded value out of range - (value >= 0x110000) - ) { - hexEscapeChar(os, c); - break; - } - - // If we got here, this is in fact a valid(ish) utf-8 sequence - for (std::size_t n = 0; n < encBytes; ++n) { - os << m_str[idx + n]; - } - idx += encBytes - 1; - break; - } - } - } - - std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode ) { - xmlEncode.encodeTo( os ); - return os; - } - - XmlWriter::ScopedElement::ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - XmlWriter::ScopedElement::ScopedElement( ScopedElement&& other ) DOCTEST_NOEXCEPT - : m_writer( other.m_writer ){ - other.m_writer = nullptr; - } - XmlWriter::ScopedElement& XmlWriter::ScopedElement::operator=( ScopedElement&& other ) DOCTEST_NOEXCEPT { - if ( m_writer ) { - m_writer->endElement(); - } - m_writer = other.m_writer; - other.m_writer = nullptr; - return *this; - } - - - XmlWriter::ScopedElement::~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - XmlWriter::ScopedElement& XmlWriter::ScopedElement::writeText( std::string const& text, bool indent ) { - m_writer->writeText( text, indent ); - return *this; - } - - XmlWriter::XmlWriter( std::ostream& os ) : m_os( os ) - { - // writeDeclaration(); // called explicitly by the reporters that use the writer class - see issue #627 - } - - XmlWriter::~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& XmlWriter::startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - m_os << m_indent << '<' << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - XmlWriter::ScopedElement XmlWriter::scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& XmlWriter::endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - m_os << "/>"; - m_tagIsOpen = false; - } - else { - m_os << m_indent << ""; - } - m_os << std::endl; - m_tags.pop_back(); - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, const char* attribute ) { - if( !name.empty() && attribute && attribute[0] != '\0' ) - m_os << ' ' << name << "=\"" << XmlEncode( attribute, XmlEncode::ForAttributes ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeAttribute( std::string const& name, bool attribute ) { - m_os << ' ' << name << "=\"" << ( attribute ? "true" : "false" ) << '"'; - return *this; - } - - XmlWriter& XmlWriter::writeText( std::string const& text, bool indent ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - m_os << m_indent; - m_os << XmlEncode( text ); - m_needsNewline = true; - } - return *this; - } - - //XmlWriter& XmlWriter::writeComment( std::string const& text ) { - // ensureTagClosed(); - // m_os << m_indent << ""; - // m_needsNewline = true; - // return *this; - //} - - //void XmlWriter::writeStylesheetRef( std::string const& url ) { - // m_os << "\n"; - //} - - //XmlWriter& XmlWriter::writeBlankLine() { - // ensureTagClosed(); - // m_os << '\n'; - // return *this; - //} - - void XmlWriter::ensureTagClosed() { - if( m_tagIsOpen ) { - m_os << ">" << std::endl; - m_tagIsOpen = false; - } - } - - void XmlWriter::writeDeclaration() { - m_os << "\n"; - } - - void XmlWriter::newlineIfNecessary() { - if( m_needsNewline ) { - m_os << std::endl; - m_needsNewline = false; - } - } - -// ================================================================================================= -// End of copy-pasted code from Catch -// ================================================================================================= - -// clang-format on - -struct XmlReporter : public IReporter -{ - XmlWriter xml; - DOCTEST_DECLARE_MUTEX(mutex) - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc = nullptr; - - XmlReporter(const ContextOptions& co) - : xml(*co.cout) - , opt(co) - { - } - - void log_contexts() - { - int num_contexts = get_num_active_contexts(); - if (num_contexts) { - auto contexts = get_active_contexts(); - std::stringstream ss; - for (int i = 0; i < num_contexts; ++i) { - contexts[i]->stringify(&ss); - xml.scopedElement("Info").writeText(ss.str()); - ss.str(""); - } - } - } - - unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } - - void test_case_start_impl(const TestCaseData& in) - { - bool open_ts_tag = false; - if (tc != nullptr) { // we have already opened a test suite - if (std::strcmp(tc->m_test_suite, in.m_test_suite) != 0) { - xml.endElement(); - open_ts_tag = true; - } - } else { - open_ts_tag = true; // first test case ==> first test suite - } - - if (open_ts_tag) { - xml.startElement("TestSuite"); - xml.writeAttribute("name", in.m_test_suite); - } - - tc = ∈ - xml.startElement("TestCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file.c_str())) - .writeAttribute("line", line(in.m_line)) - .writeAttribute("description", in.m_description); - - if (Approx(in.m_timeout) != 0) - xml.writeAttribute("timeout", in.m_timeout); - if (in.m_may_fail) - xml.writeAttribute("may_fail", true); - if (in.m_should_fail) - xml.writeAttribute("should_fail", true); - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override - { - test_run_start(); - if (opt.list_reporters) { - for (auto& curr : getListeners()) - xml.scopedElement("Listener") - .writeAttribute("priority", curr.first.first) - .writeAttribute("name", curr.first.second); - for (auto& curr : getReporters()) - xml.scopedElement("Reporter") - .writeAttribute("priority", curr.first.first) - .writeAttribute("name", curr.first.second); - } else if (opt.count || opt.list_test_cases) { - for (unsigned i = 0; i < in.num_data; ++i) { - xml.scopedElement("TestCase") - .writeAttribute("name", in.data[i]->m_name) - .writeAttribute("testsuite", in.data[i]->m_test_suite) - .writeAttribute("filename", - skipPathFromFilename(in.data[i]->m_file.c_str())) - .writeAttribute("line", line(in.data[i]->m_line)) - .writeAttribute("skipped", in.data[i]->m_skip); - } - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - } else if (opt.list_test_suites) { - for (unsigned i = 0; i < in.num_data; ++i) - xml.scopedElement("TestSuite") - .writeAttribute("name", in.data[i]->m_test_suite); - xml.scopedElement("OverallResultsTestCases") - .writeAttribute("unskipped", in.run_stats->numTestCasesPassingFilters); - xml.scopedElement("OverallResultsTestSuites") - .writeAttribute("unskipped", in.run_stats->numTestSuitesPassingFilters); - } - xml.endElement(); - } - - void test_run_start() override - { - xml.writeDeclaration(); - - // remove .exe extension - mainly to have the same output on UNIX and - // Windows - std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); -#ifdef DOCTEST_PLATFORM_WINDOWS - if (binary_name.rfind(".exe") != std::string::npos) - binary_name = binary_name.substr(0, binary_name.length() - 4); -#endif // DOCTEST_PLATFORM_WINDOWS - - xml.startElement("doctest").writeAttribute("binary", binary_name); - if (opt.no_version == false) - xml.writeAttribute("version", DOCTEST_VERSION_STR); - - // only the consequential ones (TODO: filters) - xml.scopedElement("Options") - .writeAttribute("order_by", opt.order_by.c_str()) - .writeAttribute("rand_seed", opt.rand_seed) - .writeAttribute("first", opt.first) - .writeAttribute("last", opt.last) - .writeAttribute("abort_after", opt.abort_after) - .writeAttribute("subcase_filter_levels", opt.subcase_filter_levels) - .writeAttribute("case_sensitive", opt.case_sensitive) - .writeAttribute("no_throw", opt.no_throw) - .writeAttribute("no_skip", opt.no_skip); - } - - void test_run_end(const TestRunStats& p) override - { - if (tc) // the TestSuite tag - only if there has been at least 1 test case - xml.endElement(); - - xml.scopedElement("OverallResultsAsserts") - .writeAttribute("successes", p.numAsserts - p.numAssertsFailed) - .writeAttribute("failures", p.numAssertsFailed); - - xml.startElement("OverallResultsTestCases") - .writeAttribute("successes", - p.numTestCasesPassingFilters - p.numTestCasesFailed) - .writeAttribute("failures", p.numTestCasesFailed); - if (opt.no_skipped_summary == false) - xml.writeAttribute("skipped", - p.numTestCases - p.numTestCasesPassingFilters); - xml.endElement(); - - xml.endElement(); - } - - void test_case_start(const TestCaseData& in) override - { - test_case_start_impl(in); - xml.ensureTagClosed(); - } - - void test_case_reenter(const TestCaseData&) override {} - - void test_case_end(const CurrentTestCaseStats& st) override - { - xml.startElement("OverallResultsAsserts") - .writeAttribute("successes", - st.numAssertsCurrentTest - st.numAssertsFailedCurrentTest) - .writeAttribute("failures", st.numAssertsFailedCurrentTest) - .writeAttribute("test_case_success", st.testCaseSuccess); - if (opt.duration) - xml.writeAttribute("duration", st.seconds); - if (tc->m_expected_failures) - xml.writeAttribute("expected_failures", tc->m_expected_failures); - xml.endElement(); - - xml.endElement(); - } - - void test_case_exception(const TestCaseException& e) override - { - DOCTEST_LOCK_MUTEX(mutex) - - xml.scopedElement("Exception") - .writeAttribute("crash", e.is_crash) - .writeText(e.error_string.c_str()); - } - - void subcase_start(const SubcaseSignature& in) override - { - xml.startElement("SubCase") - .writeAttribute("name", in.m_name) - .writeAttribute("filename", skipPathFromFilename(in.m_file)) - .writeAttribute("line", line(in.m_line)); - xml.ensureTagClosed(); - } - - void subcase_end() override { xml.endElement(); } - - void log_assert(const AssertData& rb) override - { - if (!rb.m_failed && !opt.success) - return; - - DOCTEST_LOCK_MUTEX(mutex) - - xml.startElement("Expression") - .writeAttribute("success", !rb.m_failed) - .writeAttribute("type", assertString(rb.m_at)) - .writeAttribute("filename", skipPathFromFilename(rb.m_file)) - .writeAttribute("line", line(rb.m_line)); - - xml.scopedElement("Original").writeText(rb.m_expr); - - if (rb.m_threw) - xml.scopedElement("Exception").writeText(rb.m_exception.c_str()); - - if (rb.m_at & assertType::is_throws_as) - xml.scopedElement("ExpectedException").writeText(rb.m_exception_type); - if (rb.m_at & assertType::is_throws_with) - xml.scopedElement("ExpectedExceptionString") - .writeText(rb.m_exception_string.c_str()); - if ((rb.m_at & assertType::is_normal) && !rb.m_threw) - xml.scopedElement("Expanded").writeText(rb.m_decomp.c_str()); - - log_contexts(); - - xml.endElement(); - } - - void log_message(const MessageData& mb) override - { - DOCTEST_LOCK_MUTEX(mutex) - - xml.startElement("Message") - .writeAttribute("type", failureString(mb.m_severity)) - .writeAttribute("filename", skipPathFromFilename(mb.m_file)) - .writeAttribute("line", line(mb.m_line)); - - xml.scopedElement("Text").writeText(mb.m_string.c_str()); - - log_contexts(); - - xml.endElement(); - } - - void test_case_skipped(const TestCaseData& in) override - { - if (opt.no_skipped_summary == false) { - test_case_start_impl(in); - xml.writeAttribute("skipped", "true"); - xml.endElement(); - } - } -}; - -DOCTEST_REGISTER_REPORTER("xml", 0, XmlReporter); - -void -fulltext_log_assert_to_stream(std::ostream& s, const AssertData& rb) -{ - if ((rb.m_at & (assertType::is_throws_as | assertType::is_throws_with)) == - 0) //! OCLINT bitwise operator in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << " ) " - << Color::None; - - if (rb.m_at & - assertType::is_throws) { //! OCLINT bitwise operator in conditional - s << (rb.m_threw ? "threw as expected!" : "did NOT throw at all!") << "\n"; - } else if ((rb.m_at & assertType::is_throws_as) && - (rb.m_at & assertType::is_throws_with)) { //! OCLINT - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" - << rb.m_exception_string.c_str() << "\", " << rb.m_exception_type << " ) " - << Color::None; - if (rb.m_threw) { - if (!rb.m_failed) { - s << "threw as expected!\n"; - } else { - s << "threw a DIFFERENT exception! (contents: " << rb.m_exception - << ")\n"; - } - } else { - s << "did NOT throw at all!\n"; - } - } else if (rb.m_at & assertType::is_throws_as) { //! OCLINT bitwise operator - //! in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", " - << rb.m_exception_type << " ) " << Color::None - << (rb.m_threw ? (rb.m_threw_as ? "threw as expected!" - : "threw a DIFFERENT exception: ") - : "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if (rb.m_at & assertType::is_throws_with) { //! OCLINT bitwise operator - //! in conditional - s << Color::Cyan << assertString(rb.m_at) << "( " << rb.m_expr << ", \"" - << rb.m_exception_string.c_str() << "\" ) " << Color::None - << (rb.m_threw ? (!rb.m_failed ? "threw as expected!" - : "threw a DIFFERENT exception: ") - : "did NOT throw at all!") - << Color::Cyan << rb.m_exception << "\n"; - } else if (rb.m_at & assertType::is_nothrow) { //! OCLINT bitwise operator in - //! conditional - s << (rb.m_threw ? "THREW exception: " : "didn't throw!") << Color::Cyan - << rb.m_exception << "\n"; - } else { - s << (rb.m_threw ? "THREW exception: " - : (!rb.m_failed ? "is correct!\n" : "is NOT correct!\n")); - if (rb.m_threw) - s << rb.m_exception << "\n"; - else - s << " values: " << assertString(rb.m_at) << "( " << rb.m_decomp - << " )\n"; - } -} - -// TODO: -// - log_message() -// - respond to queries -// - honor remaining options -// - more attributes in tags -struct JUnitReporter : public IReporter -{ - XmlWriter xml; - DOCTEST_DECLARE_MUTEX(mutex) - Timer timer; - std::vector deepestSubcaseStackNames; - - struct JUnitTestCaseData - { - static std::string getCurrentTimestamp() - { - // Beware, this is not reentrant because of backward compatibility issues - // Also, UTC only, again because of backward compatibility (%z is C++11) - time_t rawtime; - std::time(&rawtime); - auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); - - std::tm timeInfo; -#ifdef DOCTEST_PLATFORM_WINDOWS - gmtime_s(&timeInfo, &rawtime); -#else // DOCTEST_PLATFORM_WINDOWS - gmtime_r(&rawtime, &timeInfo); -#endif // DOCTEST_PLATFORM_WINDOWS - - char timeStamp[timeStampSize]; - const char* const fmt = "%Y-%m-%dT%H:%M:%SZ"; - - std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); - return std::string(timeStamp); - } - - struct JUnitTestMessage - { - JUnitTestMessage(const std::string& _message, - const std::string& _type, - const std::string& _details) - : message(_message) - , type(_type) - , details(_details) - { - } - - JUnitTestMessage(const std::string& _message, const std::string& _details) - : message(_message) - , type() - , details(_details) - { - } - - std::string message, type, details; - }; - - struct JUnitTestCase - { - JUnitTestCase(const std::string& _classname, const std::string& _name) - : classname(_classname) - , name(_name) - , time(0) - , failures() - { - } - - std::string classname, name; - double time; - std::vector failures, errors; - }; - - void add(const std::string& classname, const std::string& name) - { - testcases.emplace_back(classname, name); - } - - void appendSubcaseNamesToLastTestcase(std::vector nameStack) - { - for (auto& curr : nameStack) - if (curr.size()) - testcases.back().name += std::string("/") + curr.c_str(); - } - - void addTime(double time) - { - if (time < 1e-4) - time = 0; - testcases.back().time = time; - totalSeconds += time; - } - - void addFailure(const std::string& message, - const std::string& type, - const std::string& details) - { - testcases.back().failures.emplace_back(message, type, details); - ++totalFailures; - } - - void addError(const std::string& message, const std::string& details) - { - testcases.back().errors.emplace_back(message, details); - ++totalErrors; - } - - std::vector testcases; - double totalSeconds = 0; - int totalErrors = 0, totalFailures = 0; - }; - - JUnitTestCaseData testCaseData; - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc = nullptr; - - JUnitReporter(const ContextOptions& co) - : xml(*co.cout) - , opt(co) - { - } - - unsigned line(unsigned l) const { return opt.no_line_numbers ? 0 : l; } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData&) override { xml.writeDeclaration(); } - - void test_run_start() override { xml.writeDeclaration(); } - - void test_run_end(const TestRunStats& p) override - { - // remove .exe extension - mainly to have the same output on UNIX and - // Windows - std::string binary_name = skipPathFromFilename(opt.binary_name.c_str()); -#ifdef DOCTEST_PLATFORM_WINDOWS - if (binary_name.rfind(".exe") != std::string::npos) - binary_name = binary_name.substr(0, binary_name.length() - 4); -#endif // DOCTEST_PLATFORM_WINDOWS - xml.startElement("testsuites"); - xml.startElement("testsuite") - .writeAttribute("name", binary_name) - .writeAttribute("errors", testCaseData.totalErrors) - .writeAttribute("failures", testCaseData.totalFailures) - .writeAttribute("tests", p.numAsserts); - if (opt.no_time_in_output == false) { - xml.writeAttribute("time", testCaseData.totalSeconds); - xml.writeAttribute("timestamp", JUnitTestCaseData::getCurrentTimestamp()); - } - if (opt.no_version == false) - xml.writeAttribute("doctest_version", DOCTEST_VERSION_STR); - - for (const auto& testCase : testCaseData.testcases) { - xml.startElement("testcase") - .writeAttribute("classname", testCase.classname) - .writeAttribute("name", testCase.name); - if (opt.no_time_in_output == false) - xml.writeAttribute("time", testCase.time); - // This is not ideal, but it should be enough to mimic gtest's junit - // output. - xml.writeAttribute("status", "run"); - - for (const auto& failure : testCase.failures) { - xml.scopedElement("failure") - .writeAttribute("message", failure.message) - .writeAttribute("type", failure.type) - .writeText(failure.details, false); - } - - for (const auto& error : testCase.errors) { - xml.scopedElement("error") - .writeAttribute("message", error.message) - .writeText(error.details); - } - - xml.endElement(); - } - xml.endElement(); - xml.endElement(); - } - - void test_case_start(const TestCaseData& in) override - { - testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); - timer.start(); - } - - void test_case_reenter(const TestCaseData& in) override - { - testCaseData.addTime(timer.getElapsedSeconds()); - testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); - deepestSubcaseStackNames.clear(); - - timer.start(); - testCaseData.add(skipPathFromFilename(in.m_file.c_str()), in.m_name); - } - - void test_case_end(const CurrentTestCaseStats&) override - { - testCaseData.addTime(timer.getElapsedSeconds()); - testCaseData.appendSubcaseNamesToLastTestcase(deepestSubcaseStackNames); - deepestSubcaseStackNames.clear(); - } - - void test_case_exception(const TestCaseException& e) override - { - DOCTEST_LOCK_MUTEX(mutex) - testCaseData.addError("exception", e.error_string.c_str()); - } - - void subcase_start(const SubcaseSignature& in) override - { - deepestSubcaseStackNames.push_back(in.m_name); - } - - void subcase_end() override {} - - void log_assert(const AssertData& rb) override - { - if (!rb.m_failed) // report only failures & ignore the `success` option - return; - - DOCTEST_LOCK_MUTEX(mutex) - - std::ostringstream os; - os << skipPathFromFilename(rb.m_file) << (opt.gnu_file_line ? ":" : "(") - << line(rb.m_line) << (opt.gnu_file_line ? ":" : "):") << std::endl; - - fulltext_log_assert_to_stream(os, rb); - log_contexts(os); - testCaseData.addFailure( - rb.m_decomp.c_str(), assertString(rb.m_at), os.str()); - } - - void log_message(const MessageData&) override {} - - void test_case_skipped(const TestCaseData&) override {} - - void log_contexts(std::ostringstream& s) - { - int num_contexts = get_num_active_contexts(); - if (num_contexts) { - auto contexts = get_active_contexts(); - - s << " logged: "; - for (int i = 0; i < num_contexts; ++i) { - s << (i == 0 ? "" : " "); - contexts[i]->stringify(&s); - s << std::endl; - } - } - } -}; - -DOCTEST_REGISTER_REPORTER("junit", 0, JUnitReporter); - -struct Whitespace -{ - int nrSpaces; - explicit Whitespace(int nr) - : nrSpaces(nr) - { - } -}; - -std::ostream& -operator<<(std::ostream& out, const Whitespace& ws) -{ - if (ws.nrSpaces != 0) - out << std::setw(ws.nrSpaces) << ' '; - return out; -} - -struct ConsoleReporter : public IReporter -{ - std::ostream& s; - bool hasLoggedCurrentTestStart; - std::vector subcasesStack; - size_t currentSubcaseLevel; - DOCTEST_DECLARE_MUTEX(mutex) - - // caching pointers/references to objects of these types - safe to do - const ContextOptions& opt; - const TestCaseData* tc; - - ConsoleReporter(const ContextOptions& co) - : s(*co.cout) - , opt(co) - { - } - - ConsoleReporter(const ContextOptions& co, std::ostream& ostr) - : s(ostr) - , opt(co) - { - } - - // ========================================================================================= - // WHAT FOLLOWS ARE HELPERS USED BY THE OVERRIDES OF THE VIRTUAL METHODS OF - // THE INTERFACE - // ========================================================================================= - - void separator_to_stream() - { - s << Color::Yellow - << "=====================================================================" - "==========" - "\n"; - } - - const char* getSuccessOrFailString(bool success, - assertType::Enum at, - const char* success_str) - { - if (success) - return success_str; - return failureString(at); - } - - Color::Enum getSuccessOrFailColor(bool success, assertType::Enum at) - { - return success ? Color::BrightGreen - : (at & assertType::is_warn) ? Color::Yellow - : Color::Red; - } - - void successOrFailColoredStringToStream(bool success, - assertType::Enum at, - const char* success_str = "SUCCESS") - { - s << getSuccessOrFailColor(success, at) - << getSuccessOrFailString(success, at, success_str) << ": "; - } - - void log_contexts() - { - int num_contexts = get_num_active_contexts(); - if (num_contexts) { - auto contexts = get_active_contexts(); - - s << Color::None << " logged: "; - for (int i = 0; i < num_contexts; ++i) { - s << (i == 0 ? "" : " "); - contexts[i]->stringify(&s); - s << "\n"; - } - } - - s << "\n"; - } - - // this was requested to be made virtual so users could override it - virtual void file_line_to_stream(const char* file, - int line, - const char* tail = "") - { - s << Color::LightGrey << skipPathFromFilename(file) - << (opt.gnu_file_line ? ":" : "(") - << (opt.no_line_numbers - ? 0 - : line) // 0 or the real num depending on the option - << (opt.gnu_file_line ? ":" : "):") << tail; - } - - void logTestStart() - { - if (hasLoggedCurrentTestStart) - return; - - separator_to_stream(); - file_line_to_stream(tc->m_file.c_str(), tc->m_line, "\n"); - if (tc->m_description) - s << Color::Yellow << "DESCRIPTION: " << Color::None << tc->m_description - << "\n"; - if (tc->m_test_suite && tc->m_test_suite[0] != '\0') - s << Color::Yellow << "TEST SUITE: " << Color::None << tc->m_test_suite - << "\n"; - if (strncmp(tc->m_name, " Scenario:", 11) != 0) - s << Color::Yellow << "TEST CASE: "; - s << Color::None << tc->m_name << "\n"; - - for (size_t i = 0; i < currentSubcaseLevel; ++i) { - if (subcasesStack[i].m_name[0] != '\0') - s << " " << subcasesStack[i].m_name << "\n"; - } - - if (currentSubcaseLevel != subcasesStack.size()) { - s << Color::Yellow - << "\nDEEPEST SUBCASE STACK REACHED (DIFFERENT FROM THE CURRENT ONE):\n" - << Color::None; - for (size_t i = 0; i < subcasesStack.size(); ++i) { - if (subcasesStack[i].m_name[0] != '\0') - s << " " << subcasesStack[i].m_name << "\n"; - } - } - - s << "\n"; - - hasLoggedCurrentTestStart = true; - } - - void printVersion() - { - if (opt.no_version == false) - s << Color::Cyan << "[doctest] " << Color::None << "doctest version is \"" - << DOCTEST_VERSION_STR << "\"\n"; - } - - void printIntro() - { - if (opt.no_intro == false) { - printVersion(); - s << Color::Cyan << "[doctest] " << Color::None - << "run with \"--" DOCTEST_OPTIONS_PREFIX_DISPLAY - "help\" for options\n"; - } - } - - void printHelp() - { - int sizePrefixDisplay = - static_cast(strlen(DOCTEST_OPTIONS_PREFIX_DISPLAY)); - printVersion(); - // clang-format off - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filter values: \"str1,str2,str3\" (comma separated strings)\n"; - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "filters use wildcards for matching strings\n"; - s << Color::Cyan << "[doctest] " << Color::None; - s << "something passes a filter if any of the strings in a filter matches\n"; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"" DOCTEST_CONFIG_OPTIONS_PREFIX "\" PREFIX!!!\n"; -#endif - s << Color::Cyan << "[doctest]\n" << Color::None; - s << Color::Cyan << "[doctest] " << Color::None; - s << "Query flags - the program quits after them. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "?, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "help, -" DOCTEST_OPTIONS_PREFIX_DISPLAY "h " - << Whitespace(sizePrefixDisplay*0) << "prints this message\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "v, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "version " - << Whitespace(sizePrefixDisplay*1) << "prints the version\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "c, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "count " - << Whitespace(sizePrefixDisplay*1) << "prints the number of matching tests\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ltc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-cases " - << Whitespace(sizePrefixDisplay*1) << "lists all matching tests by name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-test-suites " - << Whitespace(sizePrefixDisplay*1) << "lists all matching test suites\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "lr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "list-reporters " - << Whitespace(sizePrefixDisplay*1) << "lists all registered reporters\n\n"; - // ================================================================================== << 79 - s << Color::Cyan << "[doctest] " << Color::None; - s << "The available / options/filters are:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-case-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sfe, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "source-file-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their file\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ts, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite= " - << Whitespace(sizePrefixDisplay*1) << "filters tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "tse, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "test-suite-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT tests by their test suite\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase= " - << Whitespace(sizePrefixDisplay*1) << "filters subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "sce, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-exclude= " - << Whitespace(sizePrefixDisplay*1) << "filters OUT subcases by their name\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "r, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "reporters= " - << Whitespace(sizePrefixDisplay*1) << "reporters to use (console is default)\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "o, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "out= " - << Whitespace(sizePrefixDisplay*1) << "output filename\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ob, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "order-by= " - << Whitespace(sizePrefixDisplay*1) << "how the tests should be ordered\n"; - s << Whitespace(sizePrefixDisplay*3) << " - [file/suite/name/rand/none]\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "rs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "rand-seed= " - << Whitespace(sizePrefixDisplay*1) << "seed for random ordering\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "f, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "first= " - << Whitespace(sizePrefixDisplay*1) << "the first test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "l, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "last= " - << Whitespace(sizePrefixDisplay*1) << "the last test passing the filters to\n"; - s << Whitespace(sizePrefixDisplay*3) << " execute - for range-based execution\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "aa, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "abort-after= " - << Whitespace(sizePrefixDisplay*1) << "stop after failed assertions\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "scfl,--" DOCTEST_OPTIONS_PREFIX_DISPLAY "subcase-filter-levels= " - << Whitespace(sizePrefixDisplay*1) << "apply filters for the first levels\n"; - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "Bool options - can be used like flags and true is assumed. Available:\n\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "s, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "success= " - << Whitespace(sizePrefixDisplay*1) << "include successful assertions in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "cs, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "case-sensitive= " - << Whitespace(sizePrefixDisplay*1) << "filters being treated as case sensitive\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "e, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "exit= " - << Whitespace(sizePrefixDisplay*1) << "exits after the tests finish\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "d, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "duration= " - << Whitespace(sizePrefixDisplay*1) << "prints the time duration of each test\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "m, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "minimal= " - << Whitespace(sizePrefixDisplay*1) << "minimal console output (only failures)\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "q, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "quiet= " - << Whitespace(sizePrefixDisplay*1) << "no console output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nt, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-throw= " - << Whitespace(sizePrefixDisplay*1) << "skips exceptions-related assert checks\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ne, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-exitcode= " - << Whitespace(sizePrefixDisplay*1) << "returns (or exits) always with success\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nr, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-run= " - << Whitespace(sizePrefixDisplay*1) << "skips all runtime doctest operations\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ni, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-intro= " - << Whitespace(sizePrefixDisplay*1) << "omit the framework intro in the output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nv, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-version= " - << Whitespace(sizePrefixDisplay*1) << "omit the framework version in the output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-colors= " - << Whitespace(sizePrefixDisplay*1) << "disables colors in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "fc, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "force-colors= " - << Whitespace(sizePrefixDisplay*1) << "use colors even when not in a tty\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nb, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-breaks= " - << Whitespace(sizePrefixDisplay*1) << "disables breakpoints in debuggers\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "ns, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-skip= " - << Whitespace(sizePrefixDisplay*1) << "don't skip test cases marked as skip\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "gfl, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "gnu-file-line= " - << Whitespace(sizePrefixDisplay*1) << ":n: vs (n): for line numbers in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "npf, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-path-filenames= " - << Whitespace(sizePrefixDisplay*1) << "only filenames and no paths in output\n"; - s << " -" DOCTEST_OPTIONS_PREFIX_DISPLAY "nln, --" DOCTEST_OPTIONS_PREFIX_DISPLAY "no-line-numbers= " - << Whitespace(sizePrefixDisplay*1) << "0 instead of real line numbers in output\n"; - // ================================================================================== << 79 - // clang-format on - - s << Color::Cyan << "\n[doctest] " << Color::None; - s << "for more information visit the project documentation\n\n"; - } - - void printRegisteredReporters() - { - printVersion(); - auto printReporters = [this](const reporterMap& reporters, - const char* type) { - if (reporters.size()) { - s << Color::Cyan << "[doctest] " << Color::None - << "listing all registered " << type << "\n"; - for (auto& curr : reporters) - s << "priority: " << std::setw(5) << curr.first.first - << " name: " << curr.first.second << "\n"; - } - }; - printReporters(getListeners(), "listeners"); - printReporters(getReporters(), "reporters"); - } - - // ========================================================================================= - // WHAT FOLLOWS ARE OVERRIDES OF THE VIRTUAL METHODS OF THE REPORTER INTERFACE - // ========================================================================================= - - void report_query(const QueryData& in) override - { - if (opt.version) { - printVersion(); - } else if (opt.help) { - printHelp(); - } else if (opt.list_reporters) { - printRegisteredReporters(); - } else if (opt.count || opt.list_test_cases) { - if (opt.list_test_cases) { - s << Color::Cyan << "[doctest] " << Color::None - << "listing all test case names\n"; - separator_to_stream(); - } - - for (unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i]->m_name << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - - } else if (opt.list_test_suites) { - s << Color::Cyan << "[doctest] " << Color::None - << "listing all test suites\n"; - separator_to_stream(); - - for (unsigned i = 0; i < in.num_data; ++i) - s << Color::None << in.data[i]->m_test_suite << "\n"; - - separator_to_stream(); - - s << Color::Cyan << "[doctest] " << Color::None - << "unskipped test cases passing the current filters: " - << g_cs->numTestCasesPassingFilters << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "test suites with unskipped test cases passing the current filters: " - << g_cs->numTestSuitesPassingFilters << "\n"; - } - } - - void test_run_start() override - { - if (!opt.minimal) - printIntro(); - } - - void test_run_end(const TestRunStats& p) override - { - if (opt.minimal && p.numTestCasesFailed == 0) - return; - - separator_to_stream(); - s << std::dec; - - auto totwidth = - int(std::ceil(log10((std::max(p.numTestCasesPassingFilters, - static_cast(p.numAsserts))) + - 1))); - auto passwidth = int(std::ceil(log10( - (std::max(p.numTestCasesPassingFilters - p.numTestCasesFailed, - static_cast(p.numAsserts - p.numAssertsFailed))) + - 1))); - auto failwidth = int( - std::ceil(log10((std::max(p.numTestCasesFailed, - static_cast(p.numAssertsFailed))) + - 1))); - const bool anythingFailed = - p.numTestCasesFailed > 0 || p.numAssertsFailed > 0; - s << Color::Cyan << "[doctest] " << Color::None - << "test cases: " << std::setw(totwidth) << p.numTestCasesPassingFilters - << " | " - << ((p.numTestCasesPassingFilters == 0 || anythingFailed) ? Color::None - : Color::Green) - << std::setw(passwidth) - << p.numTestCasesPassingFilters - p.numTestCasesFailed << " passed" - << Color::None << " | " - << (p.numTestCasesFailed > 0 ? Color::Red : Color::None) - << std::setw(failwidth) << p.numTestCasesFailed << " failed" - << Color::None << " |"; - if (opt.no_skipped_summary == false) { - const int numSkipped = p.numTestCases - p.numTestCasesPassingFilters; - s << " " << (numSkipped == 0 ? Color::None : Color::Yellow) << numSkipped - << " skipped" << Color::None; - } - s << "\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "assertions: " << std::setw(totwidth) << p.numAsserts << " | " - << ((p.numAsserts == 0 || anythingFailed) ? Color::None : Color::Green) - << std::setw(passwidth) << (p.numAsserts - p.numAssertsFailed) - << " passed" << Color::None << " | " - << (p.numAssertsFailed > 0 ? Color::Red : Color::None) - << std::setw(failwidth) << p.numAssertsFailed << " failed" << Color::None - << " |\n"; - s << Color::Cyan << "[doctest] " << Color::None - << "Status: " << (p.numTestCasesFailed > 0 ? Color::Red : Color::Green) - << ((p.numTestCasesFailed > 0) ? "FAILURE!" : "SUCCESS!") << Color::None - << std::endl; - } - - void test_case_start(const TestCaseData& in) override - { - hasLoggedCurrentTestStart = false; - tc = ∈ - subcasesStack.clear(); - currentSubcaseLevel = 0; - } - - void test_case_reenter(const TestCaseData&) override - { - subcasesStack.clear(); - } - - void test_case_end(const CurrentTestCaseStats& st) override - { - if (tc->m_no_output) - return; - - // log the preamble of the test case only if there is something - // else to print - something other than that an assert has failed - if (opt.duration || - (st.failure_flags && - st.failure_flags != - static_cast(TestCaseFailureReason::AssertFailure))) - logTestStart(); - - if (opt.duration) - s << Color::None << std::setprecision(6) << std::fixed << st.seconds - << " s: " << tc->m_name << "\n"; - - if (st.failure_flags & TestCaseFailureReason::Timeout) - s << Color::Red << "Test case exceeded time limit of " - << std::setprecision(6) << std::fixed << tc->m_timeout << "!\n"; - - if (st.failure_flags & TestCaseFailureReason::ShouldHaveFailedButDidnt) { - s << Color::Red - << "Should have failed but didn't! Marking it as failed!\n"; - } else if (st.failure_flags & - TestCaseFailureReason::ShouldHaveFailedAndDid) { - s << Color::Yellow << "Failed as expected so marking it as not failed\n"; - } else if (st.failure_flags & - TestCaseFailureReason::CouldHaveFailedAndDid) { - s << Color::Yellow << "Allowed to fail so marking it as not failed\n"; - } else if (st.failure_flags & - TestCaseFailureReason::DidntFailExactlyNumTimes) { - s << Color::Red << "Didn't fail exactly " << tc->m_expected_failures - << " times so marking it as failed!\n"; - } else if (st.failure_flags & - TestCaseFailureReason::FailedExactlyNumTimes) { - s << Color::Yellow << "Failed exactly " << tc->m_expected_failures - << " times as expected so marking it as not failed!\n"; - } - if (st.failure_flags & TestCaseFailureReason::TooManyFailedAsserts) { - s << Color::Red << "Aborting - too many failed asserts!\n"; - } - s << Color::None; // lgtm [cpp/useless-expression] - } - - void test_case_exception(const TestCaseException& e) override - { - DOCTEST_LOCK_MUTEX(mutex) - if (tc->m_no_output) - return; - - logTestStart(); - - file_line_to_stream(tc->m_file.c_str(), tc->m_line, " "); - successOrFailColoredStringToStream( - false, e.is_crash ? assertType::is_require : assertType::is_check); - s << Color::Red - << (e.is_crash ? "test case CRASHED: " : "test case THREW exception: ") - << Color::Cyan << e.error_string << "\n"; - - int num_stringified_contexts = get_num_stringified_contexts(); - if (num_stringified_contexts) { - auto stringified_contexts = get_stringified_contexts(); - s << Color::None << " logged: "; - for (int i = num_stringified_contexts; i > 0; --i) { - s << (i == num_stringified_contexts ? "" : " ") - << stringified_contexts[i - 1] << "\n"; - } - } - s << "\n" << Color::None; - } - - void subcase_start(const SubcaseSignature& subc) override - { - subcasesStack.push_back(subc); - ++currentSubcaseLevel; - hasLoggedCurrentTestStart = false; - } - - void subcase_end() override - { - --currentSubcaseLevel; - hasLoggedCurrentTestStart = false; - } - - void log_assert(const AssertData& rb) override - { - if ((!rb.m_failed && !opt.success) || tc->m_no_output) - return; - - DOCTEST_LOCK_MUTEX(mutex) - - logTestStart(); - - file_line_to_stream(rb.m_file, rb.m_line, " "); - successOrFailColoredStringToStream(!rb.m_failed, rb.m_at); - - fulltext_log_assert_to_stream(s, rb); - - log_contexts(); - } - - void log_message(const MessageData& mb) override - { - if (tc->m_no_output) - return; - - DOCTEST_LOCK_MUTEX(mutex) - - logTestStart(); - - file_line_to_stream(mb.m_file, mb.m_line, " "); - s << getSuccessOrFailColor(false, mb.m_severity) - << getSuccessOrFailString( - mb.m_severity & assertType::is_warn, mb.m_severity, "MESSAGE") - << ": "; - s << Color::None << mb.m_string << "\n"; - log_contexts(); - } - - void test_case_skipped(const TestCaseData&) override {} -}; - -DOCTEST_REGISTER_REPORTER("console", 0, ConsoleReporter); - -#ifdef DOCTEST_PLATFORM_WINDOWS -struct DebugOutputWindowReporter : public ConsoleReporter -{ - DOCTEST_THREAD_LOCAL static std::ostringstream oss; - - DebugOutputWindowReporter(const ContextOptions& co) - : ConsoleReporter(co, oss) - { - } - -#define DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(func, type, arg) \ - void func(type arg) override \ - { \ - bool with_col = g_no_colors; \ - g_no_colors = false; \ - ConsoleReporter::func(arg); \ - if (oss.tellp() != std::streampos{}) { \ - DOCTEST_OUTPUT_DEBUG_STRING(oss.str().c_str()); \ - oss.str(""); \ - } \ - g_no_colors = with_col; \ - } - - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_start, - DOCTEST_EMPTY, - DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_run_end, const TestRunStats&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_start, - const TestCaseData&, - in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_reenter, - const TestCaseData&, - in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_end, - const CurrentTestCaseStats&, - in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_exception, - const TestCaseException&, - in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_start, - const SubcaseSignature&, - in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(subcase_end, - DOCTEST_EMPTY, - DOCTEST_EMPTY) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_assert, const AssertData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(log_message, const MessageData&, in) - DOCTEST_DEBUG_OUTPUT_REPORTER_OVERRIDE(test_case_skipped, - const TestCaseData&, - in) -}; - -DOCTEST_THREAD_LOCAL std::ostringstream DebugOutputWindowReporter::oss; -#endif // DOCTEST_PLATFORM_WINDOWS - -// the implementation of parseOption() -bool -parseOptionImpl(int argc, - const char* const* argv, - const char* pattern, - String* value) -{ - // going from the end to the beginning and stopping on the first occurrence - // from the end - for (int i = argc; i > 0; --i) { - auto index = i - 1; - auto temp = std::strstr(argv[index], pattern); - if (temp && - (value || - strlen(temp) == - strlen(pattern))) { //! OCLINT prefer early exits and continue - // eliminate matches in which the chars before the option are not '-' - bool noBadCharsFound = true; - auto curr = argv[index]; - while (curr != temp) { - if (*curr++ != '-') { - noBadCharsFound = false; - break; - } - } - if (noBadCharsFound && argv[index][0] == '-') { - if (value) { - // parsing the value of an option - temp += strlen(pattern); - const unsigned len = strlen(temp); - if (len) { - *value = temp; - return true; - } - } else { - // just a flag - no value - return true; - } - } - } - } - return false; -} - -// parses an option and returns the string after the '=' character -bool -parseOption(int argc, - const char* const* argv, - const char* pattern, - String* value = nullptr, - const String& defaultVal = String()) -{ - if (value) - *value = defaultVal; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - // offset (normally 3 for "dt-") to skip prefix - if (parseOptionImpl( - argc, argv, pattern + strlen(DOCTEST_CONFIG_OPTIONS_PREFIX), value)) - return true; -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseOptionImpl(argc, argv, pattern, value); -} - -// locates a flag on the command line -bool -parseFlag(int argc, const char* const* argv, const char* pattern) -{ - return parseOption(argc, argv, pattern); -} - -// parses a comma separated list of words after a pattern in one of the -// arguments in argv -bool -parseCommaSepArgs(int argc, - const char* const* argv, - const char* pattern, - std::vector& res) -{ - String filtersString; - if (parseOption(argc, argv, pattern, &filtersString)) { - // tokenize with "," as a separator, unless escaped with backslash - std::ostringstream s; - auto flush = [&s, &res]() { - auto string = s.str(); - if (string.size() > 0) { - res.push_back(string.c_str()); - } - s.str(""); - }; - - bool seenBackslash = false; - const char* current = filtersString.c_str(); - const char* end = current + strlen(current); - while (current != end) { - char character = *current++; - if (seenBackslash) { - seenBackslash = false; - if (character == ',' || character == '\\') { - s.put(character); - continue; - } - s.put('\\'); - } - if (character == '\\') { - seenBackslash = true; - } else if (character == ',') { - flush(); - } else { - s.put(character); - } - } - - if (seenBackslash) { - s.put('\\'); - } - flush(); - return true; - } - return false; -} - -enum optionType -{ - option_bool, - option_int -}; - -// parses an int/bool option from the command line -bool -parseIntOption(int argc, - const char* const* argv, - const char* pattern, - optionType type, - int& res) -{ - String parsedValue; - if (!parseOption(argc, argv, pattern, &parsedValue)) - return false; - - if (type) { - // integer - // TODO: change this to use std::stoi or something else! currently it uses - // undefined behavior - assumes '0' on failed parse... - int theInt = std::atoi(parsedValue.c_str()); - if (theInt != 0) { - res = theInt; //! OCLINT parameter reassignment - return true; - } - } else { - // boolean - const char positive[][5] = { - "1", "true", "on", "yes" - }; // 5 - strlen("true") + 1 - const char negative[][6] = { - "0", "false", "off", "no" - }; // 6 - strlen("false") + 1 - - // if the value matches any of the positive/negative possibilities - for (unsigned i = 0; i < 4; i++) { - if (parsedValue.compare(positive[i], true) == 0) { - res = 1; //! OCLINT parameter reassignment - return true; - } - if (parsedValue.compare(negative[i], true) == 0) { - res = 0; //! OCLINT parameter reassignment - return true; - } - } - } - return false; -} -} // namespace - -Context::Context(int argc, const char* const* argv) - : p(new detail::ContextState) -{ - parseArgs(argc, argv, true); - if (argc) - p->binary_name = argv[0]; -} - -Context::~Context() -{ - if (g_cs == p) - g_cs = nullptr; - delete p; -} - -void -Context::applyCommandLine(int argc, const char* const* argv) -{ - parseArgs(argc, argv); - if (argc) - p->binary_name = argv[0]; -} - -// parses args -void -Context::parseArgs(int argc, const char* const* argv, bool withDefaults) -{ - using namespace detail; - - // clang-format off - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sf=", p->filters[0]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "source-file-exclude=",p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sfe=", p->filters[1]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ts=", p->filters[2]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-suite-exclude=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tse=", p->filters[3]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tc=", p->filters[4]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "test-case-exclude=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "tce=", p->filters[5]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sc=", p->filters[6]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "subcase-exclude=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "sce=", p->filters[7]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "reporters=", p->filters[8]); - parseCommaSepArgs(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "r=", p->filters[8]); - // clang-format on - - int intRes = 0; - String strRes; - -#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ - if (parseIntOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX name "=", \ - option_bool, \ - intRes) || \ - parseIntOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", \ - option_bool, \ - intRes)) \ - p->var = static_cast(intRes); \ - else if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX name) || \ - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX sname)) \ - p->var = true; \ - else if (withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ - if (parseIntOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX name "=", \ - option_int, \ - intRes) || \ - parseIntOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", \ - option_int, \ - intRes)) \ - p->var = intRes; \ - else if (withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ - if (parseOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX name "=", \ - &strRes, \ - default) || \ - parseOption(argc, \ - argv, \ - DOCTEST_CONFIG_OPTIONS_PREFIX sname "=", \ - &strRes, \ - default) || \ - withDefaults) \ - p->var = strRes - - // clang-format off - DOCTEST_PARSE_STR_OPTION("out", "o", out, ""); - DOCTEST_PARSE_STR_OPTION("order-by", "ob", order_by, "file"); - DOCTEST_PARSE_INT_OPTION("rand-seed", "rs", rand_seed, 0); - - DOCTEST_PARSE_INT_OPTION("first", "f", first, 0); - DOCTEST_PARSE_INT_OPTION("last", "l", last, UINT_MAX); - - DOCTEST_PARSE_INT_OPTION("abort-after", "aa", abort_after, 0); - DOCTEST_PARSE_INT_OPTION("subcase-filter-levels", "scfl", subcase_filter_levels, INT_MAX); - - DOCTEST_PARSE_AS_BOOL_OR_FLAG("success", "s", success, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("case-sensitive", "cs", case_sensitive, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("exit", "e", exit, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("duration", "d", duration, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("minimal", "m", minimal, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("quiet", "q", quiet, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-throw", "nt", no_throw, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-exitcode", "ne", no_exitcode, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-run", "nr", no_run, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-intro", "ni", no_intro, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-version", "nv", no_version, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-colors", "nc", no_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("force-colors", "fc", force_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-breaks", "nb", no_breaks, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skip", "ns", no_skip, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("gnu-file-line", "gfl", gnu_file_line, !bool(DOCTEST_MSVC)); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-path-filenames", "npf", no_path_in_filenames, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-line-numbers", "nln", no_line_numbers, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-debug-output", "ndo", no_debug_output, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-skipped-summary", "nss", no_skipped_summary, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG("no-time-in-output", "ntio", no_time_in_output, false); - // clang-format on - - if (withDefaults) { - p->help = false; - p->version = false; - p->count = false; - p->list_test_cases = false; - p->list_test_suites = false; - p->list_reporters = false; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "help") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "h") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "?")) { - p->help = true; - p->exit = true; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "version") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "v")) { - p->version = true; - p->exit = true; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "count") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "c")) { - p->count = true; - p->exit = true; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-cases") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "ltc")) { - p->list_test_cases = true; - p->exit = true; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-test-suites") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lts")) { - p->list_test_suites = true; - p->exit = true; - } - if (parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "list-reporters") || - parseFlag(argc, argv, DOCTEST_CONFIG_OPTIONS_PREFIX "lr")) { - p->list_reporters = true; - p->exit = true; - } -} - -// allows the user to add procedurally to the filters from the command line -void -Context::addFilter(const char* filter, const char* value) -{ - setOption(filter, value); -} - -// allows the user to clear all filters from the command line -void -Context::clearFilters() -{ - for (auto& curr : p->filters) - curr.clear(); -} - -// allows the user to override procedurally the bool options from the command -// line -void -Context::setOption(const char* option, bool value) -{ - setOption(option, value ? "true" : "false"); -} - -// allows the user to override procedurally the int options from the command -// line -void -Context::setOption(const char* option, int value) -{ - setOption(option, toString(value).c_str()); -} - -// allows the user to override procedurally the string options from the command -// line -void -Context::setOption(const char* option, const char* value) -{ - auto argv = String("-") + option + "=" + value; - auto lvalue = argv.c_str(); - parseArgs(1, &lvalue); -} - -// users should query this in their main() and exit the program if true -bool -Context::shouldExit() -{ - return p->exit; -} - -void -Context::setAsDefaultForAssertsOutOfTestCases() -{ - g_cs = p; -} - -void -Context::setAssertHandler(detail::assert_handler ah) -{ - p->ah = ah; -} - -void -Context::setCout(std::ostream* out) -{ - p->cout = out; -} - -static class DiscardOStream : public std::ostream -{ -private: - class : public std::streambuf - { - private: - // allowing some buffering decreases the amount of calls to overflow - char buf[1024]; - - protected: - std::streamsize xsputn(const char_type*, std::streamsize count) override - { - return count; - } - - int_type overflow(int_type ch) override - { - setp(std::begin(buf), std::end(buf)); - return traits_type::not_eof(ch); - } - } discardBuf; - -public: - DiscardOStream() - : std::ostream(&discardBuf) - { - } -} discardOut; - -// the main function that does all the filtering and test running -int -Context::run() -{ - using namespace detail; - - // save the old context state in case such was setup - for using asserts out - // of a testing context - auto old_cs = g_cs; - // this is the current contest - g_cs = p; - is_running_in_test = true; - - g_no_colors = p->no_colors; - p->resetRunData(); - - std::fstream fstr; - if (p->cout == nullptr) { - if (p->quiet) { - p->cout = &discardOut; - } else if (p->out.size()) { - // to a file if specified - fstr.open(p->out.c_str(), std::fstream::out); - p->cout = &fstr; - } else { - // stdout by default - p->cout = &std::cout; - } - } - - FatalConditionHandler::allocateAltStackMem(); - - auto cleanup_and_return = [&]() { - FatalConditionHandler::freeAltStackMem(); - - if (fstr.is_open()) - fstr.close(); - - // restore context - g_cs = old_cs; - is_running_in_test = false; - - // we have to free the reporters which were allocated when the run started - for (auto& curr : p->reporters_currently_used) - delete curr; - p->reporters_currently_used.clear(); - - if (p->numTestCasesFailed && !p->no_exitcode) - return EXIT_FAILURE; - return EXIT_SUCCESS; - }; - - // setup default reporter if none is given through the command line - if (p->filters[8].empty()) - p->filters[8].push_back("console"); - - // check to see if any of the registered reporters has been selected - for (auto& curr : getReporters()) { - if (matchesAny( - curr.first.second.c_str(), p->filters[8], false, p->case_sensitive)) - p->reporters_currently_used.push_back(curr.second(*g_cs)); - } - - // TODO: check if there is nothing in reporters_currently_used - - // prepend all listeners - for (auto& curr : getListeners()) - p->reporters_currently_used.insert(p->reporters_currently_used.begin(), - curr.second(*g_cs)); - -#ifdef DOCTEST_PLATFORM_WINDOWS - if (isDebuggerActive() && p->no_debug_output == false) - p->reporters_currently_used.push_back(new DebugOutputWindowReporter(*g_cs)); -#endif // DOCTEST_PLATFORM_WINDOWS - - // handle version, help and no_run - if (p->no_run || p->version || p->help || p->list_reporters) { - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, QueryData()); - - return cleanup_and_return(); - } - - std::vector testArray; - for (auto& curr : getRegisteredTests()) - testArray.push_back(&curr); - p->numTestCases = testArray.size(); - - // sort the collected records - if (!testArray.empty()) { - if (p->order_by.compare("file", true) == 0) { - std::sort(testArray.begin(), testArray.end(), fileOrderComparator); - } else if (p->order_by.compare("suite", true) == 0) { - std::sort(testArray.begin(), testArray.end(), suiteOrderComparator); - } else if (p->order_by.compare("name", true) == 0) { - std::sort(testArray.begin(), testArray.end(), nameOrderComparator); - } else if (p->order_by.compare("rand", true) == 0) { - std::srand(p->rand_seed); - - // random_shuffle implementation - const auto first = &testArray[0]; - for (size_t i = testArray.size() - 1; i > 0; --i) { - int idxToSwap = std::rand() % (i + 1); - - const auto temp = first[i]; - - first[i] = first[idxToSwap]; - first[idxToSwap] = temp; - } - } else if (p->order_by.compare("none", true) == 0) { - // means no sorting - beneficial for death tests which call into the - // executable with a specific test case in mind - we don't want to slow - // down the startup times - } - } - - std::set testSuitesPassingFilt; - - bool query_mode = p->count || p->list_test_cases || p->list_test_suites; - std::vector queryResults; - - if (!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_start, DOCTEST_EMPTY); - - // invoke the registered functions if they match the filter criteria (or just - // count them) - for (auto& curr : testArray) { - const auto& tc = *curr; - - bool skip_me = false; - if (tc.m_skip && !p->no_skip) - skip_me = true; - - if (!matchesAny(tc.m_file.c_str(), p->filters[0], true, p->case_sensitive)) - skip_me = true; - if (matchesAny(tc.m_file.c_str(), p->filters[1], false, p->case_sensitive)) - skip_me = true; - if (!matchesAny(tc.m_test_suite, p->filters[2], true, p->case_sensitive)) - skip_me = true; - if (matchesAny(tc.m_test_suite, p->filters[3], false, p->case_sensitive)) - skip_me = true; - if (!matchesAny(tc.m_name, p->filters[4], true, p->case_sensitive)) - skip_me = true; - if (matchesAny(tc.m_name, p->filters[5], false, p->case_sensitive)) - skip_me = true; - - if (!skip_me) - p->numTestCasesPassingFilters++; - - // skip the test if it is not in the execution range - if ((p->last < p->numTestCasesPassingFilters && p->first <= p->last) || - (p->first > p->numTestCasesPassingFilters)) - skip_me = true; - - if (skip_me) { - if (!query_mode) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_skipped, tc); - continue; - } - - // do not execute the test if we are to only count the number of filter - // passing tests - if (p->count) - continue; - - // print the name of the test and don't execute it - if (p->list_test_cases) { - queryResults.push_back(&tc); - continue; - } - - // print the name of the test suite if not done already and don't execute it - if (p->list_test_suites) { - if ((testSuitesPassingFilt.count(tc.m_test_suite) == 0) && - tc.m_test_suite[0] != '\0') { - queryResults.push_back(&tc); - testSuitesPassingFilt.insert(tc.m_test_suite); - p->numTestSuitesPassingFilters++; - } - continue; - } - - // execute the test if it passes all the filtering - { - p->currentTest = &tc; - - p->failure_flags = TestCaseFailureReason::None; - p->seconds = 0; - - // reset atomic counters - p->numAssertsFailedCurrentTest_atomic = 0; - p->numAssertsCurrentTest_atomic = 0; - - p->fullyTraversedSubcases.clear(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_start, tc); - - p->timer.start(); - - bool run_test = true; - - do { - // reset some of the fields for subcases (except for the set of fully - // passed ones) - p->reachedLeaf = false; - // May not be empty if previous subcase exited via exception. - p->subcaseStack.clear(); - p->currentSubcaseDepth = 0; - - p->shouldLogCurrentException = true; - - // reset stuff for logging with INFO() - p->stringifiedContexts.clear(); - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - // MSVC 2015 diagnoses fatalConditionHandler as unused (because - // reset() is a static method) - DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH( - 4101) // unreferenced local variable - FatalConditionHandler fatalConditionHandler; // Handle signals - // execute the test - tc.m_test(); - fatalConditionHandler.reset(); - DOCTEST_MSVC_SUPPRESS_WARNING_POP -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - } catch (const TestFailureException&) { - p->failure_flags |= TestCaseFailureReason::AssertFailure; - } catch (...) { - DOCTEST_ITERATE_THROUGH_REPORTERS( - test_case_exception, { translateActiveException(), false }); - p->failure_flags |= TestCaseFailureReason::Exception; - } -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - - // exit this loop if enough assertions have failed - even if there are - // more subcases - if (p->abort_after > 0 && - p->numAssertsFailed + p->numAssertsFailedCurrentTest_atomic >= - p->abort_after) { - run_test = false; - p->failure_flags |= TestCaseFailureReason::TooManyFailedAsserts; - } - - if (!p->nextSubcaseStack.empty() && run_test) - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_reenter, tc); - if (p->nextSubcaseStack.empty()) - run_test = false; - } while (run_test); - - p->finalizeTestCaseData(); - - DOCTEST_ITERATE_THROUGH_REPORTERS(test_case_end, *g_cs); - - p->currentTest = nullptr; - - // stop executing tests if enough assertions have failed - if (p->abort_after > 0 && p->numAssertsFailed >= p->abort_after) - break; - } - } - - if (!query_mode) { - DOCTEST_ITERATE_THROUGH_REPORTERS(test_run_end, *g_cs); - } else { - QueryData qdata; - qdata.run_stats = g_cs; - qdata.data = queryResults.data(); - qdata.num_data = unsigned(queryResults.size()); - DOCTEST_ITERATE_THROUGH_REPORTERS(report_query, qdata); - } - - return cleanup_and_return(); -} - -DOCTEST_DEFINE_INTERFACE(IReporter) - -int -IReporter::get_num_active_contexts() -{ - return detail::g_infoContexts.size(); -} -const IContextScope* const* -IReporter::get_active_contexts() -{ - return get_num_active_contexts() ? &detail::g_infoContexts[0] : nullptr; -} - -int -IReporter::get_num_stringified_contexts() -{ - return detail::g_cs->stringifiedContexts.size(); -} -const String* -IReporter::get_stringified_contexts() -{ - return get_num_stringified_contexts() ? &detail::g_cs->stringifiedContexts[0] - : nullptr; -} - -namespace detail { -void -registerReporterImpl(const char* name, - int priority, - reporterCreatorFunc c, - bool isReporter) -{ - if (isReporter) - getReporters().insert( - reporterMap::value_type(reporterMap::key_type(priority, name), c)); - else - getListeners().insert( - reporterMap::value_type(reporterMap::key_type(priority, name), c)); -} -} // namespace detail - -} // namespace doctest - -#endif // DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH( - 4007) // 'function' : must be 'attribute' - see issue #182 -int -main(int argc, char** argv) -{ - return doctest::Context(argc, argv).run(); -} -DOCTEST_MSVC_SUPPRESS_WARNING_POP -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -DOCTEST_CLANG_SUPPRESS_WARNING_POP -DOCTEST_MSVC_SUPPRESS_WARNING_POP -DOCTEST_GCC_SUPPRESS_WARNING_POP - -DOCTEST_SUPPRESS_COMMON_WARNINGS_POP - -#endif // DOCTEST_LIBRARY_IMPLEMENTATION -#endif // DOCTEST_CONFIG_IMPLEMENT diff --git a/test/include/cnpy.hpp b/test/include/cnpy.hpp deleted file mode 100644 index 80cc0096f..000000000 --- a/test/include/cnpy.hpp +++ /dev/null @@ -1,317 +0,0 @@ -// Copyright (C) 2011 Carl Rogers -// Released under MIT License -// license available in LICENSE file, or at -// http://www.opensource.org/licenses/mit-license.php - -#ifndef PROXSUITE_TEST_CNPY_HPP -#define PROXSUITE_TEST_CNPY_HPP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define CNPY_FWD(x) static_cast(x) -#define CNPY_ASSERT(Cond) \ - ((Cond) \ - ? (void)0 \ - : ::cnpy::detail::terminate_with_message( \ - "assertion failed: " #Cond, sizeof("assertion failed: " #Cond) - 1)) - -#define CNPY_LITERAL(X) X, sizeof(X) - 1 - -namespace cnpy { -using usize = decltype(sizeof(0)); -namespace detail { - -enum struct LoadVecResult : int -{ - success = 0, - failed_file = 1, - failed_dtype = 2, - failed_ndim = 3, -}; - -enum struct LoadMatResult : int -{ - success = 0, - success_transpose = -1, - - failed_file = 1, - failed_dtype = 2, - failed_ndim = 3, -}; - -void -terminate_with_message(char const* msg, usize len); - -template -struct TypeCode; -template<> -struct TypeCode -{ - static constexpr char value = 'f'; -}; -template<> -struct TypeCode -{ - static constexpr char value = 'f'; -}; - -struct FromByteRepr -{}; -struct FromLiteral -{}; -struct FromRawParts -{}; -struct FromRange -{}; - -struct StrView -{ - char const* data; - usize size; - - StrView(FromRawParts /*tag*/, char const* data_, usize size_) noexcept - : data{ data_ } - , size{ size_ } - { - } - - template - StrView(FromRange /*tag*/, T const& str) noexcept - : data{ str.data() } - , size{ str.size() } - { - } - - template - StrView(FromByteRepr /*tag*/, T const& val) noexcept - : data{ &reinterpret_cast(val) } - , size{ sizeof(T) } - { - } - - template - constexpr StrView(FromLiteral /*tag*/, char const (&literal)[N]) noexcept - : data{ literal } - , size{ N - 1 } - { - } -}; - -} // namespace detail - -namespace detail { -inline auto -BigEndianTest() -> char -{ - int x = 1; - char buf[sizeof(x)]; - std::memcpy(&buf, &x, sizeof(x)); - return buf[0] != 0 ? '<' : '>'; -} -template -auto -create_npy_header(std::vector const& shape) -> std::vector; - -auto -create_npy_header(std::vector const& shape, - usize sizeof_T, - char type_code) -> std::vector; -void -parse_npy_header(FILE* fp, - usize& word_size, - std::vector& shape, - bool& fortran_order); -void -parse_npy_header(unsigned char* buffer, - usize& word_size, - std::vector& shape, - bool& fortran_order); - -void -npy_vsave(char const* fname, - void const* vdata, - usize sizeof_T, - char type_code, - usize const* shape, - usize ndim, - char const* mode); - -auto -npy_vload_vec(std::string const& fname, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows)) -> LoadVecResult; -auto -npy_vload_mat(std::string const& fname, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows, usize cols)) -> LoadMatResult; -} // namespace detail - -template -void -npy_save_mat(std::string const& fname, - Eigen::MatrixBase const& mat, - std::string const& mode = "w") -{ - - auto const& eval = mat.eval(); - usize rowcol[] = { usize(eval.rows()), usize(eval.cols()) }; - - using T = typename D::Scalar; - - detail::npy_vsave( // - fname.c_str(), - eval.data(), - sizeof(T), - detail::TypeCode::value, - &rowcol[0], - 2, - mode.c_str()); -} - -template -void -npy_save_vec(std::string const& fname, - Eigen::MatrixBase const& vec, - const std::string& mode = "w") -{ - - auto const& eval = vec.eval(); - using T = typename D::Scalar; - CNPY_ASSERT(vec.cols() == 1); - usize size = vec.rows(); - - detail::npy_vsave( // - fname.c_str(), - vec.data(), - sizeof(T), - detail::TypeCode::value, - &size, - 1, - mode.c_str()); -} - -template -auto -npy_load_vec(std::string const& fname) -> Eigen::Matrix -{ - using Vec = Eigen::Matrix; - Vec out; - - using Res = detail::LoadVecResult; - using detail::terminate_with_message; - - Res res = detail::npy_vload_vec( // - fname.c_str(), - sizeof(T), - std::addressof(out), - +[](void* vec) -> void* { return static_cast(vec)->data(); }, - +[](void* vec, usize rows) -> void { - static_cast(vec)->resize(Eigen::Index(rows), 1); - }); - - if (res == Res::failed_file) { - terminate_with_message(CNPY_LITERAL("libnpy: could not load file")); - } - if (res == Res::failed_dtype) { - terminate_with_message(CNPY_LITERAL("libnpy: mismatching scalar type")); - } - if (res == Res::failed_ndim) { - char buf[4096]; - usize len = usize( - std::snprintf(&buf[0], - 4096, - "libnpy: wrong number of dimensions. expected %zu, got %zu", - usize{ 2 }, - usize(res) - usize(Res::failed_ndim))); - CNPY_ASSERT(len + 1 < 4096); - terminate_with_message(&buf[0], len); - } - return out; -} - -template -auto -npy_load_mat(std::string const& fname) - -> Eigen::Matrix -{ - using Mat = Eigen::Matrix; - Mat out; - - using Res = detail::LoadMatResult; - using detail::terminate_with_message; - - Res res = detail::npy_vload_mat( // - fname.c_str(), - sizeof(T), - std::addressof(out), - +[](void* mat) -> void* { return static_cast(mat)->data(); }, - +[](void* mat, usize rows, usize cols) -> void { - static_cast(mat)->resize(Eigen::Index(rows), Eigen::Index(cols)); - }); - - if (res == Res::failed_file) { - terminate_with_message(CNPY_LITERAL("libnpy: could not load file")); - } - if (res == Res::failed_dtype) { - terminate_with_message(CNPY_LITERAL("libnpy: mismatching scalar type")); - } - if (res == Res::failed_ndim) { - char buf[4096]; - usize len = usize( - std::snprintf(&buf[0], - 4096, - "libnpy: wrong number of dimensions. expected %zu, got %zu", - usize{ 2 }, - usize(res) - usize(Res::failed_ndim))); - CNPY_ASSERT(len + 1 < 4096); - terminate_with_message(&buf[0], len); - } - if (res == Res::success_transpose) { - auto rowmajor = Eigen::Map< // - Eigen::Matrix< // - T, // - Eigen::Dynamic, // - Eigen::Dynamic, // - Eigen::RowMajor // - > // - >{ - out.data(), - out.rows(), - out.cols(), - }; - Mat tmp = rowmajor; - out = tmp; - } - return out; -} - -extern template auto -npy_load_mat(std::string const&) - -> Eigen::Matrix; -extern template auto -npy_load_mat(std::string const&) - -> Eigen::Matrix; - -extern template auto -npy_load_vec(std::string const&) - -> Eigen::Matrix; -extern template auto -npy_load_vec(std::string const&) - -> Eigen::Matrix; - -} // namespace cnpy - -#endif /* end of include guard PROXSUITE_TEST_CNPY_HPP */ diff --git a/test/include/utils.hpp b/test/include/utils.hpp deleted file mode 100644 index 490d0622a..000000000 --- a/test/include/utils.hpp +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -#include "util_f32.hpp" -#include "util_f64.hpp" diff --git a/test/packaging/cmake-components/CMakeLists.txt b/test/packaging/cmake-components/CMakeLists.txt new file mode 100644 index 000000000..507670720 --- /dev/null +++ b/test/packaging/cmake-components/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.22) + +project(myproject) +find_package(proxsuite CONFIG REQUIRED COMPONENTS proxsuite vectorized) + +add_executable(run-proxqp ${CMAKE_CURRENT_LIST_DIR}/../src/run-proxqp.cpp) +target_link_libraries(run-proxqp PUBLIC proxsuite::proxsuite-vectorized) diff --git a/test/packaging/cmake/CMakeLists.txt b/test/packaging/cmake/CMakeLists.txt index 4699225ca..cc3dcc513 100644 --- a/test/packaging/cmake/CMakeLists.txt +++ b/test/packaging/cmake/CMakeLists.txt @@ -1,8 +1,7 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.22) -project(ExternalLib CXX) +project(myproject) find_package(proxsuite REQUIRED) -set(CMAKE_CXX_STANDARD 17) add_executable(run-proxqp ${CMAKE_CURRENT_LIST_DIR}/../src/run-proxqp.cpp) target_link_libraries(run-proxqp PUBLIC proxsuite::proxsuite) diff --git a/test/packaging/external/CMakeLists.txt b/test/packaging/external/CMakeLists.txt deleted file mode 100644 index ed21543ee..000000000 --- a/test/packaging/external/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -cmake_minimum_required(VERSION 3.22) -project(ExtraLib CXX) - -message(STATUS "PROXSUITE_GIT_REPOSITORY: $ENV{PROXSUITE_GIT_REPOSITORY}") -message(STATUS "PROXSUITE_GIT_TAG: $ENV{PROXSUITE_GIT_TAG}") - -include(FetchContent) -FetchContent_Declare( - proxsuite-c++ - GIT_REPOSITORY $ENV{PROXSUITE_GIT_REPOSITORY} - GIT_TAG $ENV{PROXSUITE_GIT_TAG} - GIT_SHALLOW ON -) -FetchContent_MakeAvailable(proxsuite-c++) - -add_executable(run-proxqp ${CMAKE_CURRENT_LIST_DIR}/../src/run-proxqp.cpp) -target_link_libraries(run-proxqp PUBLIC proxsuite) diff --git a/test/packaging/fetchcontent/CMakeLists.txt b/test/packaging/fetchcontent/CMakeLists.txt new file mode 100644 index 000000000..bc779d521 --- /dev/null +++ b/test/packaging/fetchcontent/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_minimum_required(VERSION 3.22) +project(myproject) + +cmake_path( + CONVERT "${PROXSUITE_FETCHCONTENT_SOURCE_DIR}" + TO_CMAKE_PATH_LIST PROXSUITE_FETCHCONTENT_SOURCE_DIR + NORMALIZE +) +message(STATUS "PROXSUITE_FETCHCONTENT_SOURCE_DIR: ${PROXSUITE_FETCHCONTENT_SOURCE_DIR}") + +include(FetchContent) +FetchContent_Declare(proxsuite SOURCE_DIR ${PROXSUITE_FETCHCONTENT_SOURCE_DIR}) +FetchContent_MakeAvailable(proxsuite) + +add_executable(run-proxqp ${CMAKE_CURRENT_LIST_DIR}/../src/run-proxqp.cpp) +target_link_libraries(run-proxqp PUBLIC proxsuite::proxsuite) diff --git a/test/python/CMakeLists.txt b/test/python/CMakeLists.txt new file mode 100644 index 000000000..717ddc079 --- /dev/null +++ b/test/python/CMakeLists.txt @@ -0,0 +1,25 @@ +function(proxsuite_python_add_test name) + add_test( + NAME proxsuite-test-python.${name} + COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${name}.py + ) + set_tests_properties( + proxsuite-test-python.${name} + PROPERTIES ENVIRONMENT "PYTHONPATH=$/.." LABELS python + ) +endfunction() + +proxsuite_python_add_test(test_cvxpy) +proxsuite_python_add_test(test_dense_qp_solve) +proxsuite_python_add_test(test_dense_qp_wrapper) + +if(BUILD_WITH_OPENMP_SUPPORT) + proxsuite_python_add_test(test_parallel_qp_solve) +endif() + +if(BUILD_WITH_SERIALIZATION) + proxsuite_python_add_test(test_serialization) +endif() + +proxsuite_python_add_test(test_sparse_qp_solve) +proxsuite_python_add_test(test_sparse_qp_wrapper) diff --git a/test/src/cvxpy.py b/test/python/test_cvxpy.py similarity index 100% rename from test/src/cvxpy.py rename to test/python/test_cvxpy.py diff --git a/test/src/dense_qp_solve.py b/test/python/test_dense_qp_solve.py similarity index 100% rename from test/src/dense_qp_solve.py rename to test/python/test_dense_qp_solve.py diff --git a/test/src/dense_qp_wrapper.py b/test/python/test_dense_qp_wrapper.py similarity index 99% rename from test/src/dense_qp_wrapper.py rename to test/python/test_dense_qp_wrapper.py index 844224009..65250c3d2 100644 --- a/test/src/dense_qp_wrapper.py +++ b/test/python/test_dense_qp_wrapper.py @@ -4,6 +4,7 @@ import proxsuite import numpy as np import scipy.sparse as spa +import scipy.sparse.linalg as spla import unittest np.printoptions(precision=16) @@ -4844,7 +4845,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_eigen_option( 10000, ) ) - vals, _ = spa.linalg.eigs(H, which="SR") + vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) qp.init( H, @@ -4876,7 +4877,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_manual_option( qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in) qp.settings.verbose = False qp.settings.initial_guess = proxsuite.proxqp.InitialGuess.NO_INITIAL_GUESS - vals, _ = spa.linalg.eigs(H, which="SR") + vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) qp.init( H, @@ -4917,7 +4918,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_power_iter_option( 10000, ) ) - vals, _ = spa.linalg.eigs(H, which="SR") + vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) qp.init( H, diff --git a/test/src/parallel_qp_solve.py b/test/python/test_parallel_qp_solve.py similarity index 100% rename from test/src/parallel_qp_solve.py rename to test/python/test_parallel_qp_solve.py diff --git a/test/src/serialization.py b/test/python/test_serialization.py similarity index 100% rename from test/src/serialization.py rename to test/python/test_serialization.py diff --git a/test/src/sparse_qp_solve.py b/test/python/test_sparse_qp_solve.py similarity index 100% rename from test/src/sparse_qp_solve.py rename to test/python/test_sparse_qp_solve.py diff --git a/test/src/sparse_qp_wrapper.py b/test/python/test_sparse_qp_wrapper.py similarity index 99% rename from test/src/sparse_qp_wrapper.py rename to test/python/test_sparse_qp_wrapper.py index bd79834db..36734f5a4 100644 --- a/test/src/sparse_qp_wrapper.py +++ b/test/python/test_sparse_qp_wrapper.py @@ -4,6 +4,7 @@ import proxsuite import numpy as np import scipy.sparse as spa +import scipy.sparse.linalg as spla import unittest @@ -4642,7 +4643,7 @@ def test_sparse_infeasibility_solving( # qp.settings.estimate_method_option = ( # proxsuite.proxqp.EigenValueEstimateMethodOption.EigenRegularization # ) - # vals, _ = spa.linalg.eigs(H, which="SR") + # vals, _ = spla.eigs(H, which="SR") # min_eigenvalue = float(np.min(vals)) # qp.init( # H, @@ -4676,7 +4677,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_manual_option( qp = proxsuite.proxqp.sparse.QP(n, n_eq, n_in) qp.settings.verbose = False qp.settings.initial_guess = proxsuite.proxqp.InitialGuess.NO_INITIAL_GUESS - vals, _ = spa.linalg.eigs(H, which="SR") + vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) qp.init( H, @@ -4711,7 +4712,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_power_iter_option( estimate_minimal_eigen_value = proxsuite.proxqp.sparse.estimate_minimal_eigen_value_of_symmetric_matrix( H, 1.0e-10, 100000 ) - vals, _ = spa.linalg.eigs(H, which="SR") + vals, _ = spla.eigs(H, which="SR") min_eigenvalue = float(np.min(vals)) qp.init( H, @@ -4723,7 +4724,7 @@ def test_minimal_eigenvalue_estimation_nonconvex_power_iter_option( np.asfortranarray(u), manual_minimal_H_eigenvalue=estimate_minimal_eigen_value, ) - # vals_bis, _ = spa.linalg.eigs(H, which="LM") + # vals_bis, _ = spla.eigs(H, which="LM") # print(f"{vals_bis}=") # print(f"{vals}=") # print(f"{min_eigenvalue=}") diff --git a/test/src/backward.cpp b/test/src/backward.cpp deleted file mode 100644 index 34dcf2b72..000000000 --- a/test/src/backward.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -namespace backward { -SignalHandling const sh; -} // namespace backward diff --git a/test/src/cnpy.cpp b/test/src/cnpy.cpp deleted file mode 100644 index 0f0ac2562..000000000 --- a/test/src/cnpy.cpp +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright (C) 2011 Carl Rogers -// Released under MIT License -// license available in LICENSE file, or at -// http://www.opensource.org/licenses/mit-license.php - -#include "cnpy.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace cnpy { -namespace detail { - -struct File -{ - File(File&& rhs) noexcept - : ptr(rhs.ptr) - { - rhs.ptr = nullptr; - } - File(File const&) = delete; - auto operator=(File&& rhs) noexcept -> File& - { - - // put rhs in temporary to handle aliasing - File tmp = CNPY_FWD(rhs); - - // clear current File - { - File tmp2 = static_cast(*this); - } - - ptr = tmp.ptr; - tmp.ptr = nullptr; - - return *this; - } - auto operator=(File const&) -> File& = delete; - - std::FILE* ptr; - File(char const* fname, char const* mode) - : ptr{ std::fopen(fname, mode) } - { - } - ~File() noexcept - { - if (ptr != nullptr) { - std::fclose(ptr); - } - } -}; - -void -terminate_with_message(char const* msg, usize len) -{ - std::fwrite(msg, 1, len, stderr); - std::fputc('\n', stderr); - std::terminate(); -} - -void -append_bytes(std::vector& lhs, StrView rhs) -{ - usize old_size = lhs.size(); - lhs.resize(old_size + rhs.size); - std::memcpy(lhs.data() + old_size, rhs.data, rhs.size); -} -void -npy_vsave(char const* fname, - void const* vdata, - usize sizeof_T, - char type_code, - usize const* shape, - usize ndim, - char const* mode) -{ - - std::FILE* fp{}; - std::vector - true_data_shape; // if appending, the shape of existing + new data - - if (std::strcmp(mode, "a") == 0) { - fp = std::fopen(fname, "r+b"); // NOLINT - } - - if (fp != nullptr) { - // file exists. we need to append to it. read the header, modify the array - // size - usize word_size = 0; - bool fortran_order = false; - detail::parse_npy_header(fp, word_size, true_data_shape, fortran_order); - CNPY_ASSERT(!fortran_order); - - if (word_size != sizeof_T) { - std::fprintf( // NOLINT - stderr, - "libnpy error: %s has word size %zu but npy_save is appending data " - "sized %zu\n", - fname, - word_size, - sizeof_T); - - CNPY_ASSERT(word_size == sizeof_T); - } - if (true_data_shape.size() != ndim) { - std::fprintf( // NOLINT - stderr, - "libnpy error: npy_save attempting to append misdimensioned data to " - "%s\n", - fname); - - CNPY_ASSERT(true_data_shape.size() != ndim); - } - - for (usize i = 1; i < ndim; i++) { - if (shape[i] != true_data_shape[i]) { - std::fprintf( // NOLINT - stderr, - "libnpy error: npy_save attempting to append misshaped data to " - "%s\n", - fname); - - CNPY_ASSERT(shape[i] == true_data_shape[i]); - } - } - true_data_shape[0] += shape[0]; - } else { - fp = std::fopen(fname, "wb"); // NOLINT - true_data_shape = {}; - true_data_shape.insert(true_data_shape.end(), shape, shape + ndim); - } - - std::vector header = - detail::create_npy_header(true_data_shape, sizeof_T, type_code); - usize nels = - usize(std::accumulate(shape, shape + ndim, 1, std::multiplies())); - - std::fseek(fp, 0, SEEK_SET); - std::fwrite(&header[0], sizeof(char), header.size(), fp); - std::fseek(fp, 0, SEEK_END); - std::fwrite(vdata, sizeof_T, nels, fp); - std::fclose(fp); -} -auto -create_npy_header(std::vector const& shape, - usize sizeof_T, - char type_code) -> std::vector -{ - - std::vector dict; - detail::append_bytes(dict, { FromLiteral{}, "{'descr': '" }); - detail::append_bytes(dict, { FromByteRepr{}, detail::BigEndianTest() }); - detail::append_bytes(dict, { FromByteRepr{}, type_code }); - { - auto str = std::to_string(sizeof_T); - detail::append_bytes(dict, { FromRange{}, std::to_string(sizeof_T) }); - } - detail::append_bytes( - dict, { FromLiteral{}, "', 'fortran_order': False, 'shape': (" }); - detail::append_bytes(dict, { FromRange{}, std::to_string(shape[0]) }); - for (usize i = 1; i < shape.size(); i++) { - detail::append_bytes(dict, { FromLiteral{}, ", " }); - detail::append_bytes(dict, { FromRange{}, std::to_string(shape[i]) }); - } - if (shape.size() == 1) { - detail::append_bytes(dict, { FromLiteral{}, ", " }); - } - detail::append_bytes(dict, { FromLiteral{}, "), }" }); - - // pad with spaces so that preamble+dict is modulo 16 bytes. preamble is 10 - // bytes. dict needs to end with \n - usize remainder = 16 - (10 + dict.size()) % 16; - dict.insert(dict.end(), remainder, ' '); - dict.back() = '\n'; - - std::vector header; - detail::append_bytes(header, { FromLiteral{}, "\x93NUMPY\x01\x00" }); - detail::append_bytes(header, { FromByteRepr{}, uint16_t(dict.size()) }); - detail::append_bytes(header, { FromRange{}, dict }); - - return header; -} - -void -parse_npy_header(std::FILE* fp, - usize& word_size, - std::vector& shape, - bool& fortran_order) -{ - char buffer[256]; - CNPY_ASSERT(std::fread(&buffer[0], sizeof(char), 11, fp) == 11); - std::string header = std::fgets(&buffer[0], 256, fp); - CNPY_ASSERT(header[header.size() - 1] == '\n'); - - usize loc1 = 0; - usize loc2 = 0; - - // fortran order - loc1 = header.find("fortran_order"); - CNPY_ASSERT( - !(loc1 == std::string::npos) && - "parse_npy_header: failed to find header keyword: 'fortran_order'"); - loc1 += 16; - fortran_order = (header.substr(loc1, 4) == "True"); - - // shape - loc1 = header.find('('); - loc2 = header.find(')'); - CNPY_ASSERT(!(loc1 == std::string::npos || loc2 == std::string::npos) && - "parse_npy_header: failed to find header keyword: '(' or ')'"); - - std::regex num_regex("[0-9][0-9]*"); - std::smatch sm; - shape.clear(); - - std::string str_shape = header.substr(loc1 + 1, loc2 - loc1 - 1); - while (std::regex_search(str_shape, sm, num_regex)) { - shape.push_back(std::stoul(sm[0].str())); - str_shape = sm.suffix().str(); - } - - // endian, word size, data type - // byte order code | stands for not applicable. - // not sure when this applies except for byte array - loc1 = header.find("descr"); - CNPY_ASSERT(!(loc1 == std::string::npos) && - "parse_npy_header: failed to find header keyword: 'descr'"); - loc1 += 9; - bool littleEndian = (header[loc1] == '<' || header[loc1] == '|'); - CNPY_ASSERT(littleEndian); - - char type = header[loc1 + 1]; - CNPY_ASSERT(type == 'f'); - - std::string str_ws = header.substr(loc1 + 2); - loc2 = str_ws.find('\''); - word_size = std::stoul(str_ws.substr(0, loc2)); -} - -auto -load_npy_vec(std::FILE* fp, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows)) -> LoadVecResult -{ - std::vector shape; - - usize word_size{}; - bool fortran_order{}; - - cnpy::detail::parse_npy_header(fp, word_size, shape, fortran_order); - if (word_size != sizeof_T) { - return LoadVecResult::failed_dtype; - } - if (shape.size() != 1) { - return LoadVecResult(int(LoadVecResult::failed_ndim) + shape.size()); - } - - usize nbytes = word_size * shape[0]; - resize(vec, shape[0]); - - CNPY_ASSERT(std::fread(ptr(vec), 1, nbytes, fp) == nbytes && - "load_the_npy_file: failed fread"); - return LoadVecResult::success; -} - -auto -load_npy_mat(std::FILE* fp, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows, usize cols)) -> LoadMatResult -{ - std::vector shape; - - usize word_size{}; - bool fortran_order{}; - - cnpy::detail::parse_npy_header(fp, word_size, shape, fortran_order); - if (word_size != sizeof_T) { - return LoadMatResult::failed_dtype; - } - if (shape.size() != 2) { - return LoadMatResult(int(LoadMatResult::failed_ndim) + shape.size()); - } - usize nbytes = word_size * shape[0] * shape[1]; - resize(vec, shape[0], shape[1]); - - CNPY_ASSERT(std::fread(ptr(vec), 1, nbytes, fp) == nbytes && - "load_the_npy_file: failed fread"); - - if (fortran_order) { - return LoadMatResult::success; - } else { - return LoadMatResult::success_transpose; - } -} - -auto -npy_vload_vec(std::string const& fname, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows)) -> LoadVecResult -{ - File fp{ fname.c_str(), "rb" }; // NOLINT - - CNPY_ASSERT(fp.ptr != nullptr); - return detail::load_npy_vec(fp.ptr, sizeof_T, vec, ptr, resize); -} - -auto -npy_vload_mat(std::string const& fname, - usize sizeof_T, - void* vec, - void* (*ptr)(void*), - void (*resize)(void*, usize rows, usize cols)) -> LoadMatResult -{ - File fp{ fname.c_str(), "rb" }; // NOLINT - - CNPY_ASSERT(fp.ptr != nullptr); - return detail::load_npy_mat(fp.ptr, sizeof_T, vec, ptr, resize); -} -} // namespace detail - -template auto -npy_load_mat(std::string const&) - -> Eigen::Matrix; -template auto -npy_load_mat(std::string const&) - -> Eigen::Matrix; - -template auto -npy_load_vec(std::string const&) - -> Eigen::Matrix; -template auto -npy_load_vec(std::string const&) - -> Eigen::Matrix; -} // namespace cnpy